/* * (C) Copyright 2014 Leo C. * * SPDX-License-Identifier: GPL-2.0+ */ #include "common.h" #include #include "background.h" #include "serial.h" #include "z80-if.h" #include "debug.h" #include "z180-serv.h" /*--------------------------------------------------------------------------*/ uint8_t z80_get_byte(uint32_t adr) { uint8_t data; z80_bus_cmd(Request); data = z80_read(adr); z80_bus_cmd(Release); return data; } /*--------------------------------------------------------------------------*/ struct msg_item { uint8_t fct; uint8_t sub_min, sub_max; void (*func)(uint8_t, int, uint8_t *); }; 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; } void do_msg_ini_memfifo(uint8_t subf, int len, uint8_t * msg) { (void)len; z80_memfifo_init(subf, msg_to_addr(msg)); } void do_msg_char_out(uint8_t subf, int len, uint8_t * msg) { (void)subf; while (len--) putchar(*msg++); } const FLASH struct msg_item z80_messages[] = { { 0, /* fct nr. */ 1, 3, /* sub fct nr. from, to */ do_msg_ini_memfifo}, { 1, 1, 1, do_msg_char_out}, { 0xff, /* end mark */ 0, 0, 0}, }; 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) { if (z80_messages[i].fct == 0xff) { DBG_P(1, "do_message: Unknown function: %i, %i\n", fct, sub_fct); return; /* TODO: unknown message # */ } ++i; } 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); } } #define CTRBUF_LEN 256 void check_msg_fifo(void) { int ch; static int_fast8_t state; static int msglen,idx; static uint8_t buffer[CTRBUF_LEN]; while ((ch = z80_memfifo_getc(fifo_msgin)) >= 0) { switch (state) { case 0: /* wait for start of message */ if (ch == 0xAE) { /* TODO: magic number */ 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) { do_message(msglen, buffer); state = 0; } break; } } } int msg_handling(int state) { uint8_t pending; ATOMIC_BLOCK(ATOMIC_FORCEON) { pending = (Stat & S_MSG_PENDING) != 0; Stat &= ~S_MSG_PENDING; } if (pending) { switch (state) { case 0: z80_bus_cmd(Request); uint32_t addr = z80_read(0x40) + ((uint16_t) z80_read(0x41) << 8) + ((uint32_t) z80_read(0x42) << 16); z80_bus_cmd(Release); if (addr != 0) { z80_memfifo_init(fifo_msgin, addr); state = 1; } break; case 1: check_msg_fifo(); break; } } return state; } static int handle_msg_handling; void setup_z180_serv(void) { handle_msg_handling = bg_register(msg_handling, 0); } void restart_z180_serv(void) { z80_bus_cmd(Request); z80_write(0x40, 0); z80_write(0x41, 0); z80_write(0x42, 0); z80_bus_cmd(Release); for (int i = 0; i < NUM_FIFOS; i++) z80_memfifo_init(i, 0); bg_setstat(handle_msg_handling, 0); } /*--------------------------------------------------------------------------*/ 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) };