X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp.git/blobdiff_plain/54678798da1da8c4b53a9e201a098ef284b8498e..refs/tags/hexrel-2:/avr/z80-if.c diff --git a/avr/z80-if.c b/avr/z80-if.c index 20efa9e..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); +} + + +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; +} -static void z80_setup_addrbus_tristate(void) +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,19 +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; - - /* Timer0: CTC: Toggle OC0A on compare match */ - PRR0 &= ~_BV(PRTIM0); - TCCR0A = _BV(COM0A0) | _BV(WGM01); - OCR0A = 0; - TCCR0B = (0x01 << CS00); -} void z80_setup_bus(void) { @@ -243,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; } @@ -258,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; @@ -270,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(); } } @@ -309,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; @@ -323,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; @@ -331,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; @@ -343,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; @@ -368,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: @@ -420,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; @@ -435,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; @@ -449,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++); @@ -466,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++);