From 9b6b4b31e8cb284ad6a68fe16d458e36bbfb46fa Mon Sep 17 00:00:00 2001 From: Leo C Date: Sun, 27 Jul 2014 23:23:07 +0200 Subject: [PATCH] First real hardware test. --- avr/Tupfile | 4 +- avr/debug.h | 2 +- avr/z180-stamp-avr.c | 241 ++++++++++++++++++++++++++++++++++--------- avr/z80-if.c | 127 ++++++++++------------- avr/z80-if.h | 2 +- 5 files changed, 252 insertions(+), 124 deletions(-) diff --git a/avr/Tupfile b/avr/Tupfile index b43a822..a90b7b5 100644 --- a/avr/Tupfile +++ b/avr/Tupfile @@ -6,8 +6,8 @@ SRC_Z = ../z180/hdrom.c #TARGETS = $(PROG).elf MCU_TARGET = atmega1281 -F_CPU = 16000000UL -DEFS = -DF_CPU=$(F_CPU) -DBAUD=115200 +F_CPU = 18432000UL +DEFS = -DF_CPU=$(F_CPU) -DBAUD=115200UL INCLUDES += ../z180 diff --git a/avr/debug.h b/avr/debug.h index c341301..ea67a99 100644 --- a/avr/debug.h +++ b/avr/debug.h @@ -6,7 +6,7 @@ #ifdef DEBUG #define DBG_P(lvl, format, ...) if (DEBUG>=lvl) \ - fprintf_P( stderr, PSTR(format), ##__VA_ARGS__ ) + fprintf_P( stdout, PSTR(format), ##__VA_ARGS__ ) #else #define DBG_P(lvl, ...) #endif diff --git a/avr/z180-stamp-avr.c b/avr/z180-stamp-avr.c index 4ea4d47..09f323c 100644 --- a/avr/z180-stamp-avr.c +++ b/avr/z180-stamp-avr.c @@ -5,7 +5,7 @@ #include //#include //#include -//#include +#include //#include //#include //#include @@ -30,8 +30,10 @@ volatile int_fast8_t timeout_1s; -volatile uint_least8_t Stat; +//volatile uint_least8_t Stat; +#define Stat GPIOR0 +unsigned int to_counter; /****************************************************************/ @@ -55,41 +57,31 @@ typedef union { -void z80_setaddress(uint32_t addr) -{ - addr_t x; - - x.l = addr; - P_ADL = x.b[0]; - P_ADH = x.b[1]; - PIN_ADB = ((x.b[2] << ADB_SHIFT) ^ P_ADB) & MASK(ADB_WIDTH) << ADB_SHIFT ; - -} - -/****************************************************************/ - /*--------------------------------------------------------------------------*/ +/*---------------------------------------------------------*/ +/* 1000Hz timer interrupt generated by OC1A */ +/*---------------------------------------------------------*/ -void sys_tick_handler(void) +ISR(TIMER1_COMPA_vect) { - static int_fast8_t tick_10ms = 0; - static int_fast16_t count_ms = 0; + static int_fast8_t tick_10ms; +// static int_fast16_t count_ms; int_fast8_t i; - ++tick_10ms; - if (tick_10ms == 10) - { - Stat |= S_10MS_TO; - tick_10ms = 0; - + i = tick_10ms + 1; + if (i == 10) { + i = 0; + Stat |= S_10MS_TO; /* Drive timer procedure of low level disk I/O module */ //disk_timerproc(); } + tick_10ms = i; +#if 0 count_ms++; if (count_ms == 1000) { count_ms = 0; @@ -98,6 +90,7 @@ void sys_tick_handler(void) if (i) timeout_1s = i - 1; } +#endif } @@ -108,18 +101,19 @@ static uint32_t z80_sram_cmp(uint32_t addr, uint32_t length, uint8_t wval, int i uint8_t rval; int_fast8_t errors = 0; - DBG_P(1, "SRAM: Check %#.5x byte... ", length); + DBG_P(1, "SRAM: Check 0x%.5lx byte... ", length); while (length--) { if ((rval = z80_read(addr)) != wval) { if (errors == 0) { - printf("\nSRAM: Address W R\n" \ - " -------------\n"); -// 12345 00 11 + DBG_P(1, "\nSRAM: Address W R\n" \ + " ------------------\n"); } - printf(" %.5lx %.2x %.2x\n", addr, wval, rval); - - if (++errors > 16 ) + errors++; + if (errors > 20) { + DBG_P(1, " ...\n"); break; + } + DBG_P(1, " 0x%.5lx 0x%.2x 0x%.2x\n", addr, wval, rval); } addr++; wval += inc; @@ -129,10 +123,9 @@ static uint32_t z80_sram_cmp(uint32_t addr, uint32_t length, uint8_t wval, int i return addr; } -#if 0 -static void z80_sram_fill(uint32_t addr, int length, uint8_t startval, int inc) +static void z80_sram_fill(uint32_t addr, uint32_t length, uint8_t startval, int inc) { - printf("SRAM: Write %#.5x byte... ", length); //fflush(stdout); + printf("SRAM: Write 0x%.5lx byte... ", length); while (length--) { z80_write(addr, startval); ++addr; @@ -142,6 +135,7 @@ static void z80_sram_fill(uint32_t addr, int length, uint8_t startval, int inc) } +#if 0 void z80_sram_fill_string(uint32_t addr, int length, const char *text) { char c; @@ -192,6 +186,8 @@ uint8_t z80_get_byte(uint32_t adr) static void do_10ms(void) { + if (to_counter) + to_counter--; } /*--------------------------------------------------------------------------*/ @@ -344,6 +340,22 @@ void check_msg_fifo(void) } +/*--------------------------------------------------------------------------*/ + +void dump_mem(const __flash uint8_t *addr, uint32_t len) +{ + DBG_P(1, "hdrom dump:"); + while (len) { + DBG_P(1, "\n %.5x:", addr); + for (unsigned i = 0; i<16; i++) + DBG_P(1, " %.2x", *addr++); + len -= len > 16 ? 16 : len; + } + DBG_P(1, "\n"); +} + +/*--------------------------------------------------------------------------*/ + void z80_load_mem(void) { unsigned sec = 0; @@ -357,56 +369,171 @@ void z80_load_mem(void) hdrom_address[sec]+hdrom_length_of_sections[sec] - 1, hdrom_length_of_sections[sec]); - z80_write_block((unsigned char *) &hdrom[sec_base], /* src */ + z80_write_block((const __flash unsigned char *) &hdrom[sec_base], /* src */ hdrom_address[sec], /* dest */ hdrom_length_of_sections[sec]); /* len */ sec_base+=hdrom_length_of_sections[sec]; sec++; } } + +/*--------------------------------------------------------------------------*/ + +void z80_dump_mem(uint32_t addr, uint32_t len) +{ + DBG_P(1, "Memory dump:"); + while (len) { + DBG_P(1, "\n %.5lx:", addr); + for (unsigned i = 0; i<16; i++) + DBG_P(1, " %.2x", z80_read(addr++)); + len -= len > 16 ? 16 : len; + } + DBG_P(1, "\n"); +} + /*--------------------------------------------------------------------------*/ +void setup_rtc(void) +{ + /* TODO: */ +} + +void setup_avr(void) +{ + /* WD */ + + /* CPU */ + + /* Disable JTAG Interface regardless of the JTAGEN fuse setting. */ + MCUCR = _BV(JTD); + MCUCR = _BV(JTD); + + /* disable unused periphels */ + PRR0 = _BV(PRTIM2) | _BV(PRTIM0) | _BV(PRADC); + PRR1 = _BV(PRTIM5) | _BV(PRTIM4) | _BV(PRTIM3) | + _BV(PRUSART3) | _BV(PRUSART2) | _BV(PRUSART1); + + /* disable analog comparator */ + ACSR = _BV(ACD); + /* Ports */ + + /* Clock */ + CLKPR = _BV(CLKPCE); + CLKPR = 0; + + /* Timer */ + + OCR1A = F_CPU / 8 / 1000 - 1; // Timer1: 1000Hz interval (OC1A) + TCCR1B = 0b00001010; + TIMSK1 = _BV(OCIE1A); // Enable TC1.oca interrupt +} + +const __flash uint8_t iniprog[] = { + 0xAF, // xor a + 0xED, 0x39, 0x36, // out0 (rcr),a ;disable DRAM refresh + 0x3E, 0x30, // ld a,030h + 0xED, 0x39, 0x32 //out0 (dcntl),a ;0 mem, max i/0 wait states +}; + +const __flash uint8_t sertest[] = { + 0xAF, // xor a + 0xED, 0x39, 0x36, // out0 (rcr),a ;disable DRAM refresh + 0x3E, 0x30, // ld a,030h + 0xED, 0x39, 0x32, // out0 (dcntl),a ;0 mem, max i/0 wait states + 0x3E, 0x80, // ld a,M_MPBT ;no MP, PS=10, DR=16, SS=0 + 0xED, 0x39, 0x03, // out0 (cntlb1),a + 0x3E, 0x64, // ld a,M_RE + M_TE + M_MOD2 ; + 0xED, 0x39, 0x01, // out0 (cntla1),a + 0x3E, 0x00, // ld a,0 + 0xED, 0x39, 0x05, // out0 (stat1),a ;Enable rx interrupts + 0xED, 0x38, 0x05, //l0:in0 a,(stat1) + 0xE6, 0x80, // and 80h + 0x28, 0xF9, // jr z,l0 + 0xED, 0x00, 0x09, // in0 b,(rdr1) + 0xED, 0x38, 0x05, //l1:in0 a,(stat1) + 0xE6, 0x02, // and 02h + 0x28, 0xF9, // jr z,l1 + 0xED, 0x01, 0x07, // out0 (tdr1),b + 0x18, 0xEA, // jr l0 +}; + +const __flash uint8_t test1[] = { + 0xAF, // xor a + 0xED, 0x39, 0x36, // out0 (rcr),a ;disable DRAM refresh + 0x3E, 0x30, // ld a,030h + 0xED, 0x39, 0x32, // out0 (dcntl),a ;0 mem, max i/0 wait states + 0x21, 0x1E, 0x00, // ld hl,dmclrt ;load DMA registers + 0x06, 0x08, // ld b,dmct_e-dmclrt + 0x0E, 0x20, // ld c,sar0l + 0xED, 0x93, // otimr + 0x3E, 0xC3, // ld a,0c3h ;dst +1, src +1, burst + 0xED, 0x39, 0x31, // out0 (dmode),a ; + 0x3E, 0x62, // ld a,062h ;enable dma0, + 0xED, 0x39, 0x30, //cl_1: out0 (dstat),a ;copy 64k + 0x18, 0xFB, // jr cl_1 ; + 0x00, 0x00, //dmclrt: dw 0 ;src (inc) + 0x00, // db 0 ;src + 0x00, 0x00, // dw 0 ;dst (inc), + 0x00, // db 0 ;dst + 0x00, 0x00, // dw 0 ;count (64k) +}; + + int main(void) { int_fast8_t state = 0; int ch; -// setvbuf(stdout, NULL, _IONBF, 0); + setup_avr(); serial_setup(); -// printf("\n(STM32F100+HD64180)_stamp Tester\n"); - printf("\n(ATMEGA1281+HD64180)_stamp Tester\n"); + setup_rtc(); + sei(); + + printf_P(PSTR("\n(ATMEGA1281+HD64180)_stamp Tester\n")); DBG_P(1, "z80_setup_bus... "); z80_setup_msg_fifo(); z80_setup_bus(); DBG_P(1, "done.\n"); - DBG_P(1, "Get bus... "); z80_busreq(LOW); z80_reset(HIGH); z80_request_bus(); DBG_P(1, "got it!\n"); +// z80_sram_fill(0, (uint32_t)512 * 1024, 0x00, 3); +// z80_sram_cmp(0, (uint32_t)512 * 1024, 0x00, 3); +// z80_dump_mem(0, 0x400); + z80_memset(0, 0x76, 0x80000); - //z80_sram_fill(0, 512 * 1024, 0x76, 0); - z80_sram_cmp(0, (uint32_t)512 * 1024, 0x76, 0); +// z80_memset(0, 0x00, 0x80000); +// z80_write_block(test1, 0, sizeof(test1)); + +// z80_dump_mem(0, 0x100); + +// z80_sram_cmp(0, (uint32_t)512 * 1024, 0x76, 0); z80_load_mem(); +// z80_write(0, 0x76); +// z80_dump_mem(0, 0x200); + + z80_reset(LOW); DBG_P(1, "Bus released!\n"); z80_release_bus(); z80_reset(HIGH); DBG_P(1, "Reset released!\n"); - + to_counter = 200; + while (1) { if (Stat & S_10MS_TO) { Stat &= ~S_10MS_TO; do_10ms(); } - + if ((ch = serial_getc()) >= 0) { switch (state) { @@ -414,8 +541,12 @@ int main(void) if (ch == ESCCHAR) { state = 1; /* TODO: Timer starten */ - } else - z80_memfifo_putc(fifo_out, ch); + } else { +// z80_memfifo_putc(fifo_out, ch); + serial_putc(ch); + if (ch == '\r') + serial_putc('\n'); + } break; case 1: switch (ch) { @@ -424,16 +555,32 @@ int main(void) z80_reset_pulse(); break; + case 'b': + z80_request_bus(); + z80_dump_mem(0, 0x2d20); + z80_release_bus(); + break; + + case 'e': + z80_request_bus(); + z80_dump_mem(0x80000-0x4000, 0x800); + z80_dump_mem(0x80000-0x200, 0x200); + z80_release_bus(); + break; + case ESCCHAR: default: - z80_memfifo_putc(fifo_out, ch); +// z80_memfifo_putc(fifo_out, ch); + serial_putc(ch); + if (ch == '\r') + serial_putc('\n'); } state = 0; break; } } - check_msg_fifo(); +// check_msg_fifo(); } return 0; diff --git a/avr/z80-if.c b/avr/z80-if.c index 955a61a..207aed1 100644 --- a/avr/z80-if.c +++ b/avr/z80-if.c @@ -95,6 +95,7 @@ struct bits { #define BUSREQ 7 #define DDR_BUSREQ DDRD #define P_BUSACK PORTD +#define PIN_BUSACK PIND #define BUSACK 6 #define DDR_BUSACK DDRD //#define P_HALT PORTA @@ -117,8 +118,8 @@ struct bits { #define P_ADH PORTC #define P_ADB PORTE #define PIN_ADB PINE -#define DDR_ADL DDRE -#define DDR_ADH DDRE +#define DDR_ADL DDRA +#define DDR_ADH DDRC #define DDR_ADB DDRE #define ADB_WIDTH 3 @@ -126,49 +127,16 @@ struct bits { //#define ADB_PORT PORTE - -#define ADp1_OFS 0 -#define ADp1_WIDTH 8 -#define ADp1_SHIFT 1 -#define ADp1_PORT GPIOA - -#define ADp2_OFS ADp1_WIDTH -#define ADp2_WIDTH 8 -#define ADp2_SHIFT 0 -#define ADp2_PORT GPIOC - -#define ADp3_OFS (ADp2_OFS+ADp2_WIDTH) -#define ADp3_WIDTH 3 -#define ADp3_SHIFT 10 -#define ADp3_PORT GPIOC - -#define ADunbuff1_WIDTH 1 -#define ADunbuff1_SHIFT 8 -#define ADunbuff1_PORT GPIOA - -#define ADunbuff2_WIDTH 2 -#define ADunbuff2_SHIFT 6 -#define ADunbuff2_PORT GPIOC - -#define ADunbuff3_WIDTH 3 -#define ADunbuff3_SHIFT 10 -#define ADunbuff3_PORT GPIOC - -#define DB_OFS 0 -#define DB_WIDTH 8 -#define DB_SHIFT 8 -#define DB_PORT GPIOB - - #define Z80_O_MREQ SBIT(P_MREQ, 4) #define Z80_O_RD SBIT(P_RD, 3) #define Z80_O_WR SBIT(P_WR, 2) #define Z80_O_BUSREQ SBIT(P_BUSREQ, 7) //#define Z80_O_NMI SBIT(P_NMI, ) #define Z80_O_RST SBIT(P_RST, 5) -#define Z80_I_BUSACK SBIT(P_BUSACK, 6) +#define Z80_I_BUSACK SBIT(PIN_BUSACK, 6) //#define Z80_I_HALT SBIT(P_HALT, ) + void z80_busreq(level_t level) { Z80_O_BUSREQ = level; @@ -210,25 +178,31 @@ typedef union { /*--------------------------------------------------------------------------*/ - -/* - * A0..A6, A8..A13 are buffered. No need to disable. - * A7, A14..A18: set to input. - */ - -static void z80_setup_adrbus_tristate(void) +static void z80_setup_addrbus_tristate(void) { + /* /MREQ, /RD, /WR: Input, no pullup */ + DDR_MREQ &= ~(_BV(MREQ) | _BV(RD) | _BV(WR)); + Z80_O_MREQ = 0; + Z80_O_RD = 0; + Z80_O_WR = 0; + P_ADL = 0; 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_setup_adrbus_active(void) +static void z80_setup_addrbus_active(void) { + /* /MREQ, /RD, /WR: Output and high */ + Z80_O_MREQ = 1; + Z80_O_RD = 1; + Z80_O_WR = 1; + DDR_MREQ |= _BV(MREQ) | _BV(RD) | _BV(WR); + DDR_ADL = 0xff; DDR_ADH = 0xff; DDR_ADB = DDR_ADB | (MASK(ADB_WIDTH) << ADB_SHIFT); @@ -247,66 +221,66 @@ static void z80_setup_dbus_out(void) DDR_DB = 0xff; } -static -void z80_setaddress(uint32_t addr) -{ - addr_t x; x.l = addr; - - P_ADL = x.b[0]; - P_ADH = x.b[1]; - PIN_ADB = ((x.b[2] << ADB_SHIFT) ^ P_ADB) & MASK(ADB_WIDTH) << ADB_SHIFT ; -} - void z80_setup_bus(void) { + /* /ZRESET: Output and low */ Z80_O_RST = 0; DDR_RST |= _BV(RST); + /* /BUSREQ: Output and high */ Z80_O_BUSREQ = 1; DDR_BUSREQ |= _BV(BUSREQ); -// Z80_O_NMI = 1; -// DDR_NMI |= _BV(NMI); - - Z80_O_MREQ = 1; - Z80_O_RD = 1; - Z80_O_WR = 1; - DDR_MREQ |= _BV(MREQ) | _BV(RD) | _BV(WR); - + /* /BUSACK: Input, no pullup */ DDR_BUSACK &= ~_BV(BUSACK); P_BUSACK &= ~_BV(BUSACK); + /* /IOCS1: Input, no pullup */ DDR_IOCS1 &= ~_BV(IOCS1); P_IOCS1 &= ~_BV(IOCS1); - //Z80_O_BUSREQ = 0; - //while(Z80_I_BUSACK == 1); - - z80_setup_adrbus_tristate(); + z80_setup_addrbus_tristate(); z80_setup_dbus_in(); } +/*--------------------------------------------------------------------------*/ + void z80_request_bus(void) { Z80_O_BUSREQ = 0; while(Z80_I_BUSACK == 1); - z80_setup_adrbus_active(); + z80_setup_addrbus_active(); } void z80_release_bus(void) { z80_setup_dbus_in(); - z80_setup_adrbus_tristate(); + z80_setup_addrbus_tristate(); Z80_O_BUSREQ = 1; - while(Z80_I_BUSACK == 0); + //while(Z80_I_BUSACK == 0); +} + +/*--------------------------------------------------------------------------*/ + +static +//inline __attribute__ ((always_inline)) +void z80_setaddress(uint32_t addr) +{ + addr_t x; x.l = addr; + + P_ADL = x.b[0]; + P_ADH = x.b[1]; + PIN_ADB = ((x.b[2] << ADB_SHIFT) ^ P_ADB) & MASK(ADB_WIDTH) << ADB_SHIFT ; } void z80_write(uint32_t addr, uint8_t data) { z80_setaddress(addr); Z80_O_MREQ = 0; - P_DB = data; z80_setup_dbus_out(); + P_DB = data; + P_DB = data; + Z80_O_WR = 0; Z80_O_WR = 0; Z80_O_WR = 1; Z80_O_MREQ = 1; @@ -321,6 +295,7 @@ uint8_t z80_read(uint32_t addr) z80_setup_dbus_in(); Z80_O_RD = 0; Z80_O_RD = 0; + Z80_O_RD = 0; data = PIN_DB; Z80_O_RD = 1; Z80_O_MREQ = 1; @@ -336,13 +311,15 @@ void z80_memset(uint32_t addr, uint8_t data, uint32_t length) while(length--) { z80_setaddress(addr++); P_DB = data; + P_DB = data; + Z80_O_WR = 0; Z80_O_WR = 0; Z80_O_WR = 1; } Z80_O_MREQ = 1; } -void z80_write_block(uint8_t *src, uint32_t dest, uint32_t length) +void z80_write_block(const __flash uint8_t *src, uint32_t dest, uint32_t length) { uint8_t data; @@ -352,6 +329,8 @@ void z80_write_block(uint8_t *src, uint32_t dest, uint32_t length) z80_setaddress(dest++); data = *src++; P_DB = data; + P_DB = data; + Z80_O_WR = 0; Z80_O_WR = 0; Z80_O_WR = 1; } @@ -547,6 +526,7 @@ int z80_msg_fifo_getc(void) { int c = -1; +#if 0 if (msg_fifo.count != (NELEMS(msg_fifo.buf) /*- DMA1_CNDTR4 */ )) { c = msg_fifo.buf[msg_fifo.count]; if (++msg_fifo.count == NELEMS(msg_fifo.buf)) @@ -558,6 +538,7 @@ int z80_msg_fifo_getc(void) z80_release_bus(); } } +#endif return c; } diff --git a/avr/z80-if.h b/avr/z80-if.h index 1068225..7d08df4 100644 --- a/avr/z80-if.h +++ b/avr/z80-if.h @@ -10,7 +10,7 @@ void z80_memset(uint32_t addr, uint8_t data, uint32_t length); void z80_reset(level_t level); void z80_reset_pulse(void); void z80_busreq(level_t level); -void z80_write_block(uint8_t *src, uint32_t dest, uint32_t length); +void z80_write_block(const __flash uint8_t *src, uint32_t dest, uint32_t length); int z80_stat_halt(void); -- 2.39.2