X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp.git/blobdiff_plain/26331e248f87b8d640054c91b581f482cd89bede..4b0604a43b1bd832797ec17fd8f849fc08ff3393:/avr/z80-if.c diff --git a/avr/z80-if.c b/avr/z80-if.c index 4544997..ae3bd66 100644 --- a/avr/z80-if.c +++ b/avr/z80-if.c @@ -1,63 +1,63 @@ +/* + * (C) Copyright 2014 Leo C. + * + * SPDX-License-Identifier: GPL-2.0 + */ + /** * * Pin assignments * - * | Z180-Sig | AVR-Port | Dir | Special Function | - * +------------+---------------+-------+-----------------------+ - * | A0 | PA 0 | O | | - * | A1 | PA 1 | O | | - * | A2 | PA 2 | O | | - * | A3 | PA 3 | O | | - * | A4 | PA 4 | O | | - * | A5 | PA 5 | O | | - * | A6 | PA 6 | O | | - * | A7 | PA 7 | O | | - * | A8 | PC 0 | O | | - * | A9 | PC 1 | O | | - * | A10 | PC 2 | O | | - * | A11 | PC 3 | O | | - * | A12 | PC 4 | O | | - * | A13 | PC 5 | O | | - * | A14 | PC 6 | O | | - * | A15 | PC 7 | O | | - * | A16 | PE 2 | O | | - * | A17 | PE 3 | O | | - * | A18 | PE 4 | O | | - * | D0 | PF 0 | I/O | | - * | D1 | PF 1 | I/O | | - * | D2 | PF 2 | I/O | | - * | D3 | PF 3 | I/O | | - * | D4 | PF 4 | I/O | | - * | D5 | PF 5 | I/O | | - * | D6 | PF 6 | I/O | | - * | D7 | PF 7 | I/O | | - * | RD | PD 3 | O | | - * | WR | PD 2 | O | | - * | MREQ | PD 4 | O | | - * | RST | PD 5 | O | | - * | BUSREQ | PD 7 | O | | - * | BUSACK | PD 6 | I | | - * | IOCS1 | PE 5 | I | | - * |* HALT | P | | | - * |* NMI | P | | | - * | | P | | | - * | | P | | af1 USART1_TX | - * | | P | | af1 USART1_RX | - * | | P |JTDI | remap SPI1_NSS' | - * | | P |JTDO | remap SPI1_SCK' | - * | | P |JTRST | remap SPI1_MISO' | - * | | P | | remap SPI1_MOSI' | - * | | P | | af1 OSC32 | - * | | P | | af1 OSC32 | - + * | Z180-Sig | AVR-Port | Dir | + * +------------+---------------+-------+ + * | A0 | PA 0 | O | + * | A1 | PA 1 | O | + * | A2 | PA 2 | O | + * | A3 | PA 3 | O | + * | A4 | PA 4 | O | + * | A5 | PA 5 | O | + * | A6 | PA 6 | O | + * | A7 | PA 7 | O | + * | A8 | PC 0 | O | + * | A9 | PC 1 | O | + * | A10 | PC 2 | O | + * | A11 | PC 3 | O | + * | A12 | PC 4 | O | + * | A13 | PC 5 | O | + * | A14 | PC 6 | O | + * | A15 | PC 7 | O | + * | A16 | PE 2 | O | + * | A17 | PE 3 | O | + * | A18 | PE 4 | O | + * | D0 | PF 0 | I/O | + * | D1 | PF 1 | I/O | + * | D2 | PF 2 | I/O | + * | D3 | PF 3 | I/O | + * | D4 | PF 4 | I/O | + * | D5 | PF 5 | I/O | + * | D6 | PF 6 | I/O | + * | D7 | PF 7 | I/O | + * | RD | PD 3 | O | + * | WR | PD 2 | O | + * | MREQ | PD 4 | O | + * | RST | PD 5 | O | + * | BUSREQ | PD 7 | O | + * | BUSACK | PD 6 | I | + * | + * | Optional + * +------------------------------------+ + * | STEP | PG 0 | O | + * | RUN | PG 1 | O | + * | WAIT | PG 2 | I | */ -#include "common.h" + +#include "z80-if.h" #include #include "debug.h" -#include "z80-if.h" - +#include "config.h" +#include "env.h" //#define P_ZCLK PORTB @@ -77,13 +77,6 @@ #define PIN_BUSACK PIND #define BUSACK 6 #define DDR_BUSACK DDRD -//#define P_HALT PORTA -//#define HALT 12 -#define P_IOCS1 PORTE -#define IOCS1 5 -#define DDR_IOCS1 DDRE -//#define P_NMI PORTB -//#define NMI 7 #define P_RST PORTD #define DDR_RST DDRD #define RST 5 @@ -116,24 +109,52 @@ #define Z80_I_BUSACK SBIT(PIN_BUSACK, 6) //#define Z80_I_HALT SBIT(P_HALT, ) +/* Optional */ +#define P_RUN PORTG +#define RUN 1 +#define DDR_RUN DDRG +#define P_STEP PORTG +#define STEP 0 +#define DDR_STEP DDRG +#define P_WAIT PORTG +#define WAIT 2 +#define DDR_WAIT DDRG +/* All three signals are on the same Port (PortG) */ +#define PORT_SS PORTG +#define DDR_SS DDRG +#define PIN_SS PING +#define Z80_O_RUN SBIT(PORT_SS, RUN) +#define Z80_O_STEP SBIT(PORT_SS, STEP) +#define Z80_I_WAIT SBIT(PORT_SS, WAIT) + + +#define BUS_TO 20 + #define MASK(n) ((1<<(n))-1) #define SMASK(w,s) (MASK(w) << (s)) -typedef union { - uint32_t l; - uint16_t w[2]; - uint8_t b[4]; -} addr_t; +static zstate_t zstate; +static volatile uint8_t timer; /* used for bus timeout */ + +/*---------------------------------------------------------*/ +/* 10Hz timer interrupt generated by OC4A */ +/*---------------------------------------------------------*/ + +ISR(TIMER5_COMPA_vect) +{ + uint8_t i = timer; -static zstate_t zstate; + if (i) + timer = i - 1; +} /*--------------------------------------------------------------------------*/ -static void z80_addrbus_set_tristate(void) +static void z80_addrbus_set_in(void) { /* /MREQ, /RD, /WR: Input, no pullup */ DDR_MREQ &= ~(_BV(MREQ) | _BV(RD) | _BV(WR)); @@ -145,12 +166,12 @@ static void z80_addrbus_set_tristate(void) DDR_ADL = 0; P_ADH = 0; DDR_ADH = 0; - PIN_ADB = P_ADB & ~(MASK(ADB_WIDTH) << ADB_SHIFT); + PIN_ADB = P_ADB & (MASK(ADB_WIDTH) << ADB_SHIFT); DDR_ADB = DDR_ADB & ~(MASK(ADB_WIDTH) << ADB_SHIFT); } -static void z80_addrbus_set_active(void) +static void z80_addrbus_set_out(void) { /* /MREQ, /RD, /WR: Output and high */ Z80_O_MREQ = 1; @@ -187,26 +208,39 @@ static void z80_reset_pulse(void) void z80_setup_bus(void) { - /* /ZRESET: Output and low */ - Z80_O_RST = 0; - DDR_RST |= _BV(RST); + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { - /* /BUSREQ: Output and high */ - Z80_O_BUSREQ = 1; - DDR_BUSREQ |= _BV(BUSREQ); + /* /ZRESET: Output and low */ + Z80_O_RST = 0; + DDR_RST |= _BV(RST); - /* /BUSACK: Input, no pullup */ - DDR_BUSACK &= ~_BV(BUSACK); - P_BUSACK &= ~_BV(BUSACK); + /* /BUSREQ: Output and high */ + Z80_O_BUSREQ = 1; + DDR_BUSREQ |= _BV(BUSREQ); - /* /IOCS1: Input, no pullup */ - DDR_IOCS1 &= ~_BV(IOCS1); - P_IOCS1 &= ~_BV(IOCS1); + /* /BUSACK: Input, no pullup */ + DDR_BUSACK &= ~_BV(BUSACK); + P_BUSACK &= ~_BV(BUSACK); - z80_addrbus_set_tristate(); - z80_dbus_set_in(); + z80_addrbus_set_in(); + z80_dbus_set_in(); + + if (getenv_yesno(PSTR(ENV_SINGLESTEP))) { + /* /RUN & /STEP: output, /WAIT: input */ + + PORT_SS = (PORT_SS & ~_BV(RUN)) | _BV(STEP); + DDR_SS = (DDR_SS & ~_BV(WAIT)) | _BV(RUN) | _BV(STEP); + } + + zstate = RESET; + } + + /* Timer 5 */ + PRR1 &= ~_BV(PRTIM5); + OCR5A = F_CPU / 1024 / 10 - 1; /* Timer: 10Hz interval (OC4A) */ + TCCR5B = (0b01<> 8; + PIN_ADB = (((addr >> 16) << ADB_SHIFT) ^ P_ADB) & MASK(ADB_WIDTH) << ADB_SHIFT; } void z80_write(uint32_t addr, uint8_t data) @@ -411,8 +471,25 @@ void z80_memset(uint32_t addr, uint8_t data, uint32_t length) { z80_dbus_set_out(); Z80_O_MREQ = 0; + P_DB = data; while(length--) { z80_setaddress(addr++); + Z80_O_WR = 0; + Z80_O_WR = 0; + Z80_O_WR = 1; + } + Z80_O_MREQ = 1; +} + +void z80_write_block_P(const FLASH uint8_t *src, uint32_t dest, uint32_t length) +{ + uint8_t data; + + z80_dbus_set_out(); + Z80_O_MREQ = 0; + while(length--) { + z80_setaddress(dest++); + data = *src++; P_DB = data; P_DB = data; Z80_O_WR = 0; @@ -422,7 +499,7 @@ void z80_memset(uint32_t addr, uint8_t data, uint32_t length) Z80_O_MREQ = 1; } -void z80_write_block(const __flash uint8_t *src, uint32_t dest, uint32_t length) +void z80_write_block(const uint8_t *src, uint32_t dest, uint32_t length) { uint8_t data; @@ -440,6 +517,25 @@ void z80_write_block(const __flash uint8_t *src, uint32_t dest, uint32_t length) Z80_O_MREQ = 1; } +void z80_read_block (uint8_t *dest, uint32_t src, size_t length) +{ + uint8_t data; + + Z80_O_MREQ = 0; + z80_dbus_set_in(); + while(length--) { + z80_setaddress(src++); + Z80_O_RD = 0; + Z80_O_RD = 0; + Z80_O_RD = 0; + data = PIN_DB; + Z80_O_RD = 1; + *dest++ = data; + } + Z80_O_MREQ = 1; +} + + /* 0179' rx.bs_mask: ds 1 ; (buf_len - 1) 017A' rx.in_idx: ds 1 ; @@ -481,10 +577,9 @@ void z80_memfifo_init(const fifo_t f, uint32_t addr) { fifo_dsc[f].base = addr; - if (addr != 0) { - DBG_P(2, "z80_memfifo_init: %i, %lx\n", f, addr); + if (addr != 0) { z80_bus_cmd(Request); fifo_dsc[f].mask = z80_read(addr + FIFO_BUFSIZE_MASK); fifo_dsc[f].idx_in = z80_read(addr + FIFO_INDEX_IN); @@ -514,7 +609,7 @@ int z80_memfifo_is_empty(const fifo_t f) int z80_memfifo_is_full(const fifo_t f) { - int rc = 1; + int rc = 0; if (fifo_dsc[f].base != 0) { z80_bus_cmd(Request);