/* */ #include //#include //#include //#include //#include //#include //#include #include #include "debug.h" #include "serial.h" #include "z80-if.h" #define const const __flash #include "../z180/hdrom.h" #undef const #define FLASH __flash #define ESCCHAR ('^'-0x40) #define S_10MS_TO (1<<0) static volatile int_fast8_t timeout_1s; static volatile uint_least8_t Stat; /*--------------------------------------------------------------------------*/ void sys_tick_handler(void) { static int_fast8_t tick_10ms = 0; static int_fast16_t count_ms = 0; int_fast8_t i; ++tick_10ms; if (tick_10ms == 10) { Stat |= S_10MS_TO; tick_10ms = 0; /* Drive timer procedure of low level disk I/O module */ //disk_timerproc(); } count_ms++; if (count_ms == 1000) { count_ms = 0; i = timeout_1s; if (i) timeout_1s = i - 1; } } static void do_10ms(void) { } /*--------------------------------------------------------------------------*/ static uint32_t z80_sram_cmp(uint32_t addr, uint32_t length, uint8_t wval, int inc) { uint8_t rval; int_fast8_t errors = 0; 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 } printf(" %.5lx %.2x %.2x\n", addr, wval, rval); if (++errors > 16 ) break; } addr++; wval += inc; } DBG_P(1, "Done.\n"); return addr; } #if 0 static void z80_sram_fill(uint32_t addr, int length, uint8_t startval, int inc) { printf("SRAM: Write %#.5x byte... ", length); //fflush(stdout); while (length--) { z80_write(addr, startval); ++addr; startval += inc; } printf("Done.\n"); } void z80_sram_fill_string(uint32_t addr, int length, const char *text) { char c; const char *p = text; while (length--) { z80_write(addr++, c = *p++); if (c == 0) p = text; } } uint32_t z80_sram_cmp_string(uint32_t addr, int length, const char *text) { char c; const char *p = text; while (length--) { c = *p++; if (z80_read(addr) != c) break; ++addr; if (c == 0) p = text; } return addr; } const char * const qbfox = "Zhe quick brown fox jumps over the lazy dog!"; const char * const qbcat = "Zhe quick brown fox jumps over the lazy cat!"; #endif /*--------------------------------------------------------------------------*/ uint8_t z80_get_byte(uint32_t adr) { uint8_t data; z80_request_bus(); data = z80_read(adr), z80_release_bus(); return data; } /*--------------------------------------------------------------------------*/ struct msg_item { uint8_t fct; uint8_t sub_min, sub_max; void (*func)(uint8_t, int, uint8_t *); }; static uint32_t msg_to_addr(uint8_t *msg) { union { uint32_t as32; uint8_t as8[4]; } addr; addr.as8[0] = msg[0]; addr.as8[1] = msg[1]; addr.as8[2] = msg[2]; addr.as8[3] = 0; return addr.as32; } static void do_msg_ini_msgfifo(uint8_t subf, int len, uint8_t * msg) { (void)subf; (void)len; z80_init_msg_fifo(msg_to_addr(msg)); } static void do_msg_ini_memfifo(uint8_t subf, int len, uint8_t * msg) { (void)len; z80_memfifo_init(subf - 1, msg_to_addr(msg)); } static void do_msg_char_out(uint8_t subf, int len, uint8_t * msg) { (void)subf; while (len--) putchar(*msg++); } static const FLASH struct msg_item z80_messages[] = { { 0, /* fct nr. */ 0, 0, /* sub fct nr. from, to */ &do_msg_ini_msgfifo}, { 0, 1, 2, &do_msg_ini_memfifo}, { 1, 1, 1, &do_msg_char_out}, { 0xff, /* end mark */ 0, 0, 0}, }; static void do_message(int len, uint8_t *msg) { uint8_t fct, sub_fct; int_fast8_t i = 0; if (len >= 2) { fct = *msg++; sub_fct = *msg++; len -= 2; while (fct != z80_messages[i].fct) ++i; if (z80_messages[i].fct == 0xff) { DBG_P(1, "do_message: Unknown function: %i, %i\n", fct, sub_fct); return; /* TODO: unknown message # */ } while (fct == z80_messages[i].fct) { if (sub_fct >= z80_messages[i].sub_min && sub_fct <= z80_messages[i].sub_max ) break; ++i; } if (z80_messages[i].fct != fct) { DBG_P(1, "do_message: Unknown sub function: %i, %i\n", fct, sub_fct); return; /* TODO: unknown message sub# */ } (z80_messages[i].func)(sub_fct, len, msg); } else { /* TODO: error */ DBG_P(1, "do_message: to few arguments (%i); this shouldn't happen!\n", len); } } //TODO: #define CTRBUF_LEN 256 static void check_msg_fifo(void) { int ch; static int_fast8_t state; static int msglen,idx; static uint8_t buffer[CTRBUF_LEN]; while (state != 3 && (ch = z80_msg_fifo_getc()) >= 0) { switch (state) { case 0: /* wait for start of message */ if (ch == 0x81) { msglen = 0; idx = 0; state = 1; } break; case 1: /* get msg len */ if (ch > 0 && ch <= CTRBUF_LEN) { msglen = ch; state = 2; } else state = 0; break; case 2: /* get message */ buffer[idx++] = ch; if (idx == msglen) state = 3; break; } } if (state == 3) { do_message(msglen, buffer); state = 0; } } static void z80_load_mem(void) { unsigned sec = 0; uint32_t sec_base = hdrom_start; DBG_P(1, "Loading z80 memory... \n"); while (sec < hdrom_sections) { DBG_P(2, " From: 0x%.5lX to: 0x%.5lX (%5li bytes)\n", hdrom_address[sec], hdrom_address[sec]+hdrom_length_of_sections[sec] - 1, hdrom_length_of_sections[sec]); z80_write_block((unsigned char *) &hdrom[sec_base], /* src */ hdrom_address[sec], /* dest */ hdrom_length_of_sections[sec]); /* len */ sec_base+=hdrom_length_of_sections[sec]; sec++; } } /*--------------------------------------------------------------------------*/ int main(void) { int_fast8_t state = 0; int ch; // setvbuf(stdout, NULL, _IONBF, 0); serial_setup(); printf("\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_memset(0, 0x76, 0x80000); //z80_sram_fill(0, 512 * 1024, 0x76, 0); z80_sram_cmp(0, (uint32_t)512 * 1024, 0x76, 0); z80_load_mem(); z80_reset(LOW); DBG_P(1, "Bus released!\n"); z80_release_bus(); z80_reset(HIGH); DBG_P(1, "Reset released!\n"); while (1) { if (Stat & S_10MS_TO) { Stat &= ~S_10MS_TO; do_10ms(); } if ((ch = serial_getc()) >= 0) { switch (state) { case 0: if (ch == ESCCHAR) { state = 1; /* TODO: Timer starten */ } else z80_memfifo_putc(fifo_out, ch); break; case 1: switch (ch) { case 'r': z80_reset_pulse(); break; case ESCCHAR: default: z80_memfifo_putc(fifo_out, ch); } state = 0; break; } } check_msg_fifo(); } return 0; }