From: Toni Wilen Date: Mon, 22 Jan 2024 16:49:50 +0000 (+0200) Subject: DraCo misc updates, some Casablanca updates. X-Git-Tag: 5200~51 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=90eed801155c72e97fab9dfaf7910fe7dbac862a;p=francis%2Fwinuae.git DraCo misc updates, some Casablanca updates. --- diff --git a/custom.cpp b/custom.cpp index 1e5b3664..35413289 100644 --- a/custom.cpp +++ b/custom.cpp @@ -14579,7 +14579,7 @@ void custom_reset(bool hardreset, bool keyboardreset) maxhpos_short = maxhpos; updateextblk(); - if (currprefs.cs_compatible == CP_DRACO) { + if (currprefs.cs_compatible == CP_DRACO || currprefs.cs_compatible == CP_CASABLANCA) { // fake draco interrupts INTENA(0x8000 | 0x4000 | 0x1000 | 0x2000 | 0x0080 | 0x0010 | 0x0008 | 0x0001); } diff --git a/draco.cpp b/draco.cpp index aadb3d7d..55c221be 100644 --- a/draco.cpp +++ b/draco.cpp @@ -37,6 +37,23 @@ static int maxcnt = 100; .asciz "buserr" | 7: nmi: bus timeout */ +// CASABLANCA +// INTENA : 0x02000043 +// INTPEN : 0x02000083 +// INTFRC : 0x020000c3 +// ? : 0x02000143 +// SuperIO : 0x02400000 (PC-style serial, parallel, WD floppy) +// Interrupt + +// Bit 0: Master enable / Soft INT1 +// Bit 1: INT4 +// Bit 2: INT2 +// Bit 3: INT6 +// Bit 4: INT1 +// Bit 5: +// Bit 6: INT5 (SuperIO) + +// DRACO // INTENA : 0x01000001 // INTPEN : 0x01400001 // INTFRC : 0x01800001 @@ -51,15 +68,13 @@ static int maxcnt = 100; // Interrupt -// Bit 0: Master enable / INT1 +// Bit 0: Master enable / Soft INT1 // Bit 1: INT4 (SCSI) // Bit 2: INT2 (Timer) // Bit 3: INT6 - // SVGA vblank: INT3 // SuperIO: INT5 - // IO: // IO_control : 01 @@ -165,6 +180,44 @@ static int draco_scsi_intpen, draco_serial_intpen; static bool draco_have_vmotion = false; +static void casa_irq(void) +{ + uae_u16 irq = 0; + if (draco_scsi_intpen) { + draco_intpen |= 2; + } else { + draco_intpen &= ~2; + } + if (draco_intena & 1) { + uae_u16 mask = draco_intena & draco_intpen; + if (mask) { + if (mask & 1) { // INT1 + irq |= 1; + } + if (mask & 2) { // INT4 + irq |= 0x80; + } + if (mask & 4) { // INT2 + irq |= 8; + } + if (mask & 8) { // INT6 + irq |= 0x2000; + } + } + if (draco_intfrc & 1) { + irq |= 1; // software interrupt + } + if (draco_svga_irq_state) { + irq |= 0x0010; // INT3 + } + } + INTREQ_f(0x7fff); + if (irq) { + INTREQ_f(0x8000 | irq); + doint(); + } +} + static void draco_irq(void) { uae_u16 irq = 0; @@ -210,13 +263,22 @@ static void draco_irq(void) INTREQ_f(0x8000 | irq); doint(); } +} +static void dc_irq(void) +{ + if (currprefs.cs_compatible == CP_DRACO) { + draco_irq(); + } + if (currprefs.cs_compatible == CP_CASABLANCA) { + casa_irq(); + } } void draco_svga_irq(bool state) { draco_svga_irq_state = state; - draco_irq(); + dc_irq(); } static uae_u8 draco_kbd_state; @@ -733,8 +795,87 @@ static uaecptr draco_convert_cia_addr(uaecptr addr) void draco_bustimeout(uaecptr addr) { - write_log("draco bus timeout %08x\n", addr); - draco_reg[3] |= DRSTAT_BUSTIMO; + write_log("draco bus timeout %08x PC=%08x\n", addr, M68K_GETPC); + if (currprefs.cs_compatible == CP_DRACO) { + draco_reg[3] |= DRSTAT_BUSTIMO; + } else { + draco_reg[2] |= 0x80; + } +} + +static const uae_u8 casa_video_config20[] = { 0x00, 0xce, 0x17, 0x47, 0x54, 0x1f, 0x28, 0x05, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04 }; + +static uae_u8 casa_video_bget(uaecptr addr) +{ + uae_u8 v = 0; + if (addr < 0x28000000) { + if (addr & 3) { + draco_bustimeout(addr); + } else { + int reg = (addr >> 2) & 15; + v = casa_video_config20[reg]; + } + } else { + if ((addr & 3) != 3) { + draco_bustimeout(addr); + } + } + return v; +} + +static uae_u8 casa_read_io(uaecptr addr) +{ + int reg = ((addr & 0xfc0) >> 6) & 0x1f; + uae_u8 v = draco_reg[reg]; + switch(reg) + { + case 0x02: + if (draco_reg[0] & 1) { + //v |= 0x80; + } + break; + // casablanca revision + case 0x1f: // 0x7c3 + v = draco_revision; + break; + } + return v; +} + +static uae_u8 draco_read_io(uaecptr addr) +{ + // io + int reg = addr & 0x1f; + uae_u8 v = draco_reg[reg]; + switch (reg) + { + case 3: + draco_keyboard_read(); + draco_1wire_read(); + v = draco_reg[reg]; + break; + case 5: +#if KBD_DEBUG > 1 + write_log("draco keyboard scan code read %02x\n", v); +#endif + draco_reg[3] &= ~DRSTAT_KBDRECV; + break; + case 9: + v = draco_revision; + draco_timer_latched = true; + break; + case 0xb: + v = (draco_timer_latched ? draco_timer_latch : draco_timer) >> 8; + break; + case 0xd: + v = (draco_timer_latched ? draco_timer_latch : draco_timer) >> 0; + draco_timer_latched = false; + break; + case 0x1d: + v = draco_floppy_get_data(); + break; + } + return v; } static uae_u32 REGPARAM2 draco_bget(uaecptr addr) @@ -742,7 +883,9 @@ static uae_u32 REGPARAM2 draco_bget(uaecptr addr) uae_u8 v = 0; if (maxcnt >= 0) { - write_log(_T("draco_bget %08x %08x\n"), addr, M68K_GETPC); + if (addr != 0x020007c3) { + write_log(_T("draco_bget %08x %08x\n"), addr, M68K_GETPC); + } maxcnt--; } @@ -756,8 +899,12 @@ static uae_u32 REGPARAM2 draco_bget(uaecptr addr) } if (addr >= 0x20000000) { - draco_bustimeout(addr); - return 0; + if (currprefs.cs_compatible == CP_CASABLANCA) { + v = casa_video_bget(addr); + } else { + draco_bustimeout(addr); + } + return v; } if ((addr & 0x07c00000) == 0x04000000) { @@ -830,41 +977,12 @@ static uae_u32 REGPARAM2 draco_bget(uaecptr addr) } else if ((addr & 0x07c00000) == 0x02000000) { - // io - int reg = addr & 0x1f; - v = draco_reg[reg]; - switch(reg) - { - case 3: - draco_keyboard_read(); - draco_1wire_read(); - v = draco_reg[reg]; - break; - case 5: -#if KBD_DEBUG > 1 - write_log("draco keyboard scan code read %02x\n", v); -#endif - break; - case 9: - v = draco_revision; - draco_timer_latched = true; - break; - case 0xb: - v = (draco_timer_latched ? draco_timer_latch : draco_timer) >> 8; - break; - case 0xd: - v = (draco_timer_latched ? draco_timer_latch : draco_timer) >> 0; - draco_timer_latched = false; - break; - case 0x1d: - v = draco_floppy_get_data(); - break; + if (currprefs.cs_compatible == CP_DRACO) { + v = draco_read_io(addr); + } else { + v = casa_read_io(addr); } - // casablanca revision - if (addr == 0x020007c3) - v = draco_revision; - } else if ((addr & 0x07c00000) == 0x02800000) { // CIA (no CIAs if rev4+) @@ -966,7 +1084,7 @@ static void REGPARAM2 draco_lput(uaecptr addr, uae_u32 l) cpuboard_ncr710_io_bput(reg + 1, l >> 16); cpuboard_ncr710_io_bput(reg + 0, l >> 24); - } else { + } else if (addr < 0x28000000) { write_log(_T("draco_lput %08x %08x %08x\n"), addr, l, M68K_GETPC); } @@ -976,6 +1094,81 @@ static void REGPARAM2 draco_wput(uaecptr addr, uae_u32 w) write_log(_T("draco_wput %08x %04x %08x\n"), addr, w & 0xffff, M68K_GETPC); } +static void casa_write_io(uaecptr addr, uae_u8 b) +{ + int reg = ((addr & 0xfc0) >> 6) & 0x1f; + draco_reg[reg] = b; + switch (reg) + { + case 1: + draco_intena = b & 63; + casa_irq(); + break; + case 2: + draco_intpen = b & 63; + casa_irq(); + break; + case 3: + draco_intfrc = b & 63; + casa_irq(); + break; + case 4: + casa_irq(); + break; + } +} + +static void draco_write_io(uaecptr addr, uae_u8 b) +{ + int reg = addr & 0x1f; + uae_u8 oldval = draco_reg[reg]; + draco_reg[reg] = b; + + //write_log(_T("draco_bput %08x %02x %08x\n"), addr, b & 0xff, M68K_GETPC); + switch (reg) + { + case 1: + if (b & DRCNTRL_WDOGDAT) { + draco_watchdog = 0; + } + draco_irq(); + draco_keyboard_write(b); + break; + case 3: // RO + draco_reg[reg] = oldval; + break; + case 7: + draco_irq(); + break; + case 9: + draco_reg[7] &= ~DRSTAT2_TMRIRQPEN; + break; + case 0x0b: + draco_timer &= 0x00ff; + draco_timer |= b << 8; + break; + case 0x0d: + draco_timer &= 0xff00; + draco_timer |= b; + break; + case 0x11: + draco_1wire_send(0); + break; + case 0x13: + draco_1wire_send(1); + break; + case 0x15: + draco_1wire_reset(); + break; + case 0x17: + draco_keyboard_done(); + break; + case 0x19: + draco_reg[3] &= ~DRSTAT_BUSTIMO; + break; + } +} + static void REGPARAM2 draco_bput(uaecptr addr, uae_u32 b) { if (maxcnt >= 0) { @@ -983,13 +1176,14 @@ static void REGPARAM2 draco_bput(uaecptr addr, uae_u32 b) write_log(_T("draco_bput %08x %02x %08x\n"), addr, b & 0xff, M68K_GETPC); } - if (addr >= 0x28000000 && addr < 0x30000000 && draco_have_vmotion) { - vmotion_write(addr & 0x07ffffff, b); - return; - } - if (addr >= 0x20000000) { - draco_bustimeout(addr); + if (currprefs.cs_compatible == CP_DRACO) { + if (addr >= 0x28000000 && addr < 0x30000000 && draco_have_vmotion) { + vmotion_write(addr & 0x07ffffff, b); + return; + } + draco_bustimeout(addr); + } return; } @@ -1076,54 +1270,10 @@ static void REGPARAM2 draco_bput(uaecptr addr, uae_u32 b) } else if ((addr & 0x07c00000) == 0x02000000) { - // IO - - int reg = addr & 0x1f; - uae_u8 oldval = draco_reg[reg]; - draco_reg[reg] = b; - - //write_log(_T("draco_bput %08x %02x %08x\n"), addr, b & 0xff, M68K_GETPC); - switch(reg) - { - case 1: - if (b & DRCNTRL_WDOGDAT) { - draco_watchdog = 0; - } - draco_irq(); - draco_keyboard_write(b); - break; - case 3: // RO - draco_reg[reg] = oldval; - break; - case 7: - draco_irq(); - break; - case 9: - draco_reg[7] &= ~DRSTAT2_TMRIRQPEN; - break; - case 0x0b: - draco_timer &= 0x00ff; - draco_timer |= b << 8; - break; - case 0x0d: - draco_timer &= 0xff00; - draco_timer |= b; - break; - case 0x11: - draco_1wire_send(0); - break; - case 0x13: - draco_1wire_send(1); - break; - case 0x15: - draco_1wire_reset(); - break; - case 0x17: - draco_keyboard_done(); - break; - case 0x19: - draco_reg[3] &= ~DRSTAT_BUSTIMO; - break; + if (currprefs.cs_compatible == CP_DRACO) { + draco_write_io(addr, b); + } else { + casa_write_io(addr, b); } } else if ((addr & 0x07000000) == 0x01000000) { @@ -1187,7 +1337,6 @@ static addrbank draco_bank = { draco_lget, draco_wget, ABFLAG_IO, S_READ, S_WRITE }; - void draco_ext_interrupt(bool i6) { if (i6) { @@ -1195,7 +1344,7 @@ void draco_ext_interrupt(bool i6) } else { draco_intpen |= 4; } - draco_irq(); + dc_irq(); } void draco_keycode(uae_u16 scancode, uae_u8 state) @@ -1214,48 +1363,63 @@ static void draco_hsync(void) uae_u16 tm = 5, ot; static int hcnt; - ot = draco_timer; - draco_timer -= tm; - if ((draco_timer > 0xf000 && ot < 0x1000) || (draco_timer < 0x1000 && ot > 0xf000)) { - draco_reg[7] |= DRSTAT2_TMRIRQPEN; - if (draco_reg[7] & DRSTAT2_TMRINTENA) { - draco_irq(); +#if 0 + if (currprefs.cs_compatible == CP_CASABLANCA) { + static int casa_timer; + casa_timer++; + if (casa_timer >= maxvpos) { + draco_svga_irq(true); + } else { + draco_svga_irq(false); } } - x86_floppy_run(); +#endif - if (draco_kbd_buffer_len > 0) { - draco_keyboard_send(); - } + if (currprefs.cs_compatible == CP_DRACO) { + ot = draco_timer; + draco_timer -= tm; + if ((draco_timer > 0xf000 && ot < 0x1000) || (draco_timer < 0x1000 && ot > 0xf000)) { + draco_reg[7] |= DRSTAT2_TMRIRQPEN; + if (draco_reg[7] & DRSTAT2_TMRINTENA) { + draco_irq(); + } + } - if (draco_kbd_buffer_len == 0 && draco_kbd_in_buffer_len > 0 && !(draco_reg[3] & DRSTAT_KBDRECV)) { - uae_u8 code = (uae_u8)draco_kbd_in_buffer[0]; - uae_u8 state = (draco_kbd_in_buffer[0] & 0x8000) ? 1 : 0; - for (int i = 1; i < draco_kbd_in_buffer_len; i++) { - draco_kbd_in_buffer[i - i] = draco_kbd_in_buffer[i]; + if (draco_kbd_buffer_len > 0) { + draco_keyboard_send(); } - draco_kbd_in_buffer_len--; - draco_key_process(code, state); - } - hcnt++; - if (hcnt >= 60) { - draco_1wire_rtc_count(); - hcnt = 0; - } + if (draco_kbd_buffer_len == 0 && draco_kbd_in_buffer_len > 0 && !(draco_reg[3] & DRSTAT_KBDRECV)) { + uae_u8 code = (uae_u8)draco_kbd_in_buffer[0]; + uae_u8 state = (draco_kbd_in_buffer[0] & 0x8000) ? 1 : 0; + for (int i = 1; i < draco_kbd_in_buffer_len; i++) { + draco_kbd_in_buffer[i - i] = draco_kbd_in_buffer[i]; + } + draco_kbd_in_buffer_len--; + draco_key_process(code, state); + } + + hcnt++; + if (hcnt >= 60) { + draco_1wire_rtc_count(); + hcnt = 0; + } - draco_watchdog++; - if (0 && draco_watchdog > 312 * 50) { - IRQ_forced(7, -1); - activate_debugger(); - draco_watchdog = 0; + draco_watchdog++; + if (0 && draco_watchdog > 312 * 50) { + IRQ_forced(7, -1); + activate_debugger(); + draco_watchdog = 0; + } } + + x86_floppy_run(); } void draco_set_scsi_irq(int id, int level) { draco_scsi_intpen = level; - draco_irq(); + dc_irq(); } @@ -1266,7 +1430,7 @@ static void x86_irq(int irq, bool state) } else { draco_fdc_intpen = state; } - draco_irq(); + dc_irq(); } void draco_free(void) @@ -1371,6 +1535,7 @@ void draco_init(void) if (currprefs.cs_compatible == CP_CASABLANCA) { draco_revision = 9; + draco_cias = 3; draco_reset(1); device_add_rethink(draco_irq); @@ -1399,6 +1564,7 @@ void casablanca_map_overlay(void) // KS ROM is here map_banks(&kickmem_bank, 0x02c00000 >> 16, 524288 >> 16, 0); map_banks(&draco_bank, 0x03000000 >> 16, 0x01000000 >> 16, 0); + map_banks(&draco_bank, 0x20000000 >> 16, 0x20000000 >> 16, 0); } diff --git a/gfxboard.cpp b/gfxboard.cpp index 10f77272..aced8bc4 100644 --- a/gfxboard.cpp +++ b/gfxboard.cpp @@ -4489,7 +4489,10 @@ bool gfxboard_init_memory (struct autoconfig_info *aci) } aci->parent = aci; if (!aci->doinit) { - if (gb->rbc->rtgmem_type == GFXBOARD_ID_VGA) { + if (gb->rbc->rtgmem_type == GFXBOARD_ID_ALTAIS_Z3) { + aci->start = 0x20000000; + aci->size = 0x1000000; + } else if (gb->rbc->rtgmem_type == GFXBOARD_ID_VGA) { static const int parent[] = { ROMTYPE_A1060, ROMTYPE_A2088, ROMTYPE_A2088T, ROMTYPE_A2286, ROMTYPE_A2386, 0 }; aci->parent_romtype = parent; } else if (gb->board->bustype == GFXBOARD_BUSTYPE_PCI) { diff --git a/newcpu.cpp b/newcpu.cpp index 31e88ee9..d92df9de 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -4218,6 +4218,23 @@ static void do_trace(void) } } +static void int_request_do(bool i6) +{ + if (i6) { + if (currprefs.cs_compatible == CP_DRACO || currprefs.cs_compatible == CP_CASABLANCA) { + draco_ext_interrupt(true); + } else { + INTREQ_f(0x8000 | 0x2000); + } + } else { + if (currprefs.cs_compatible == CP_DRACO || currprefs.cs_compatible == CP_CASABLANCA) { + draco_ext_interrupt(false); + } else { + INTREQ_f(0x8000 | 0x0008); + } + } +} + static void check_uae_int_request(void) { bool irq2 = false; @@ -4227,14 +4244,14 @@ static void check_uae_int_request(void) if (!irq2 && uae_interrupts2[i]) { uae_atomic v = atomic_and(&uae_interrupts2[i], 0); if (v) { - INTREQ_f(0x8000 | 0x0008); + int_request_do(false); irq2 = true; } } if (!irq6 && uae_interrupts6[i]) { uae_atomic v = atomic_and(&uae_interrupts6[i], 0); if (v) { - INTREQ_f(0x8000 | 0x2000); + int_request_do(true); irq6 = true; } } @@ -4242,11 +4259,11 @@ static void check_uae_int_request(void) } if (uae_int_requested) { if (!irq2 && (uae_int_requested & 0x00ff)) { - INTREQ_f(0x8000 | 0x0008); + int_request_do(false); irq2 = true; } if (!irq6 && (uae_int_requested & 0xff00)) { - INTREQ_f(0x8000 | 0x2000); + int_request_do(true); irq6 = true; } if (uae_int_requested & 0xff0000) { @@ -4276,7 +4293,7 @@ void safe_interrupt_set(int num, int id, bool i6) atomic_or(p, 1 << id); atomic_or(&uae_interrupt, 1); } else { - if (currprefs.cs_compatible == CP_DRACO) { + if (currprefs.cs_compatible == CP_DRACO || currprefs.cs_compatible == CP_CASABLANCA) { draco_ext_interrupt(i6); } else { int inum = i6 ? 13 : 3; diff --git a/x86.cpp b/x86.cpp index a4f8ba1f..d72dc78a 100644 --- a/x86.cpp +++ b/x86.cpp @@ -787,11 +787,13 @@ static void floppy_format(struct x86_bridge *xb, bool real) uae_u8 cx = 0, hx = 0, rx = 0, nx = 0; if (floppy_specify_pio) { if (real) { - cx = *pioptr++; - hx = *pioptr++; - rx = *pioptr++; - nx = *pioptr++; floppy_pio_cnt += 4; + if (floppy_pio_cnt <= floppy_pio_len) { + cx = *pioptr++; + hx = *pioptr++; + rx = *pioptr++; + nx = *pioptr++; + } } else { floppy_pio_len += 4; }