summaryrefslogtreecommitdiff
path: root/avr/z80-if.c
diff options
context:
space:
mode:
Diffstat (limited to 'avr/z80-if.c')
-rw-r--r--avr/z80-if.c141
1 files changed, 103 insertions, 38 deletions
diff --git a/avr/z80-if.c b/avr/z80-if.c
index 726e50b..c0f128e 100644
--- a/avr/z80-if.c
+++ b/avr/z80-if.c
@@ -157,8 +157,87 @@ static zstate_t zstate;
/*--------------------------------------------------------------------------*/
+static
+void z80_setup_clock(void)
+{
+ /* ZCLK: Output and low */
+ DDR_ZCLK |= _BV(ZCLK);
+ Z80_O_ZCLK = 0;
+
+ DDRB |= _BV(6); /* Debug */
+ PORTB |= _BV(6); /* Debug */
+
+ PRR0 &= ~_BV(PRTIM1);
+
+ /* Timer1: CTC: Toggle OC1C on compare match */
+ OCR1A = 0;
+ OCR1C = 0;
+ TCCR1A = (0b01 << COM1C0) | (0b00 << WGM10);
+ TCCR1B = (0b01 << WGM12) | (0b001 << CS10);
+}
-static void z80_setup_addrbus_tristate(void)
+
+int z80_clock_set(unsigned long freq)
+{
+ unsigned long ocrval = F_CPU / freq / 2;
+ uint8_t prescale = 0;
+
+ while (ocrval > (1L<<16)) {
+ prescale++;
+ if (prescale < 3)
+ ocrval = ocrval / 8;
+ else
+ ocrval = ocrval / 4;
+ }
+
+ if ((ocrval == 0) || (prescale > 4))
+ return -1;
+
+ ocrval -= 1;
+
+ PINB |= _BV(6); /* Debug */
+
+ /* Stop Timer */
+ TCCR1B = (0b01 << WGM12) | (0b000 << CS10);
+ TCNT1 = 0;
+
+ OCR1A = ocrval;
+ OCR1CL = ocrval;
+ TCCR1A = (0b01 << COM1C0) | (0b00 << WGM10);
+ TCCR1B = (0b01 << WGM12) | ((prescale+1) << CS10);
+
+ if (ocrval == 0) {
+// TCCR1C |= _BV(FOC1C);
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+ TCNT1 = 0xFFFF;
+ }
+ }
+
+ PINB |= _BV(6); /* Debug */
+
+ return 0;
+}
+
+uint32_t z80_clock_get(void)
+{
+ uint32_t count = (OCR1A + 1L) * 2;
+ uint8_t pre = (TCCR1B & 7) - 1;
+
+ while (pre) {
+ if (pre > 2)
+ count *= 4;
+ else
+ count *= 8;
+ pre--;
+
+ }
+
+ return F_CPU/count;
+}
+
+
+
+static void z80_addrbus_set_tristate(void)
{
/* /MREQ, /RD, /WR: Input, no pullup */
DDR_MREQ &= ~(_BV(MREQ) | _BV(RD) | _BV(WR));
@@ -175,7 +254,7 @@ static void z80_setup_addrbus_tristate(void)
}
-static void z80_setup_addrbus_active(void)
+static void z80_addrbus_set_active(void)
{
/* /MREQ, /RD, /WR: Output and high */
Z80_O_MREQ = 1;
@@ -189,14 +268,14 @@ static void z80_setup_addrbus_active(void)
}
-static void z80_setup_dbus_in(void)
+static void z80_dbus_set_in(void)
{
DDR_DB = 0;
P_DB = 0;
}
-static void z80_setup_dbus_out(void)
+static void z80_dbus_set_out(void)
{
DDR_DB = 0xff;
}
@@ -209,20 +288,6 @@ static void z80_reset_pulse(void)
Z80_O_RST = 1;
}
-static
-void z80_setup_clock(void)
-{
- /* ZCLK: Output and low */
- DDR_ZCLK |= _BV(ZCLK);
- Z80_O_ZCLK = 0;
-
- /* Timer1: CTC: Toggle OC1C on compare match */
- PRR0 &= ~_BV(PRTIM1);
- OCR1A = 0;
- OCR1C = 0;
- TCCR1A = (0b01 << COM1C0) | (0b00 << WGM10);
- TCCR1B = (0b01 << WGM12) | (0b001 << CS10);
-}
void z80_setup_bus(void)
{
@@ -244,8 +309,8 @@ void z80_setup_bus(void)
DDR_IOCS1 &= ~_BV(IOCS1);
P_IOCS1 &= ~_BV(IOCS1);
- z80_setup_addrbus_tristate();
- z80_setup_dbus_in();
+ z80_addrbus_set_tristate();
+ z80_dbus_set_in();
zstate = RESET;
}
@@ -259,8 +324,8 @@ zstate_t z80_bus_state(void)
static void z80_busreq_hpulse(void)
{
- z80_setup_dbus_in();
- z80_setup_addrbus_tristate();
+ z80_dbus_set_in();
+ z80_addrbus_set_tristate();
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
Z80_O_BUSREQ = 1;
@@ -271,7 +336,7 @@ static void z80_busreq_hpulse(void)
if (zstate & ZST_ACQUIRED) {
while(Z80_I_BUSACK == 1)
;
- z80_setup_addrbus_active();
+ z80_addrbus_set_active();
}
}
@@ -310,8 +375,8 @@ zstate_t z80_bus_cmd(bus_cmd_t cmd)
switch (cmd) {
case Reset:
- z80_setup_dbus_in();
- z80_setup_addrbus_tristate();
+ z80_dbus_set_in();
+ z80_addrbus_set_tristate();
Z80_O_RST = 0;
Z80_O_BUSREQ = 1;
zstate = RESET;
@@ -324,7 +389,7 @@ zstate_t z80_bus_cmd(bus_cmd_t cmd)
Z80_O_RST = 1;
while(Z80_I_BUSACK == 1)
;
- z80_setup_addrbus_active();
+ z80_addrbus_set_active();
zstate = RESET_AQRD;
break;
@@ -332,7 +397,7 @@ zstate_t z80_bus_cmd(bus_cmd_t cmd)
Z80_O_BUSREQ = 0;
while(Z80_I_BUSACK == 1)
;
- z80_setup_addrbus_active();
+ z80_addrbus_set_active();
zstate = RUNNING_AQRD;
break;
@@ -344,15 +409,15 @@ zstate_t z80_bus_cmd(bus_cmd_t cmd)
case Release:
switch (zstate) {
case RESET_AQRD:
- z80_setup_dbus_in();
- z80_setup_addrbus_tristate();
+ z80_dbus_set_in();
+ z80_addrbus_set_tristate();
Z80_O_RST = 0;
Z80_O_BUSREQ = 1;
zstate = RESET;
break;
case RUNNING_AQRD:
- z80_setup_dbus_in();
- z80_setup_addrbus_tristate();
+ z80_dbus_set_in();
+ z80_addrbus_set_tristate();
Z80_O_BUSREQ = 1;
zstate = RUNNING;
break;
@@ -369,10 +434,10 @@ zstate_t z80_bus_cmd(bus_cmd_t cmd)
break;
case RESET_AQRD:
- z80_setup_dbus_in();
- z80_setup_addrbus_tristate();
+ z80_dbus_set_in();
+ z80_addrbus_set_tristate();
z80_reset_pulse();
- z80_setup_addrbus_active();
+ z80_addrbus_set_active();
zstate = RUNNING_AQRD;
break;
default:
@@ -421,7 +486,7 @@ void z80_write(uint32_t addr, uint8_t data)
{
z80_setaddress(addr);
Z80_O_MREQ = 0;
- z80_setup_dbus_out();
+ z80_dbus_set_out();
P_DB = data;
P_DB = data;
Z80_O_WR = 0;
@@ -436,7 +501,7 @@ uint8_t z80_read(uint32_t addr)
z80_setaddress(addr);
Z80_O_MREQ = 0;
- z80_setup_dbus_in();
+ z80_dbus_set_in();
Z80_O_RD = 0;
Z80_O_RD = 0;
Z80_O_RD = 0;
@@ -450,7 +515,7 @@ uint8_t z80_read(uint32_t addr)
void z80_memset(uint32_t addr, uint8_t data, uint32_t length)
{
- z80_setup_dbus_out();
+ z80_dbus_set_out();
Z80_O_MREQ = 0;
while(length--) {
z80_setaddress(addr++);
@@ -467,7 +532,7 @@ void z80_write_block(const __flash uint8_t *src, uint32_t dest, uint32_t length)
{
uint8_t data;
- z80_setup_dbus_out();
+ z80_dbus_set_out();
Z80_O_MREQ = 0;
while(length--) {
z80_setaddress(dest++);