]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
DraCo misc updates, some Casablanca updates.
authorToni Wilen <twilen@winuae.net>
Mon, 22 Jan 2024 16:49:50 +0000 (18:49 +0200)
committerToni Wilen <twilen@winuae.net>
Mon, 22 Jan 2024 16:49:50 +0000 (18:49 +0200)
custom.cpp
draco.cpp
gfxboard.cpp
newcpu.cpp
x86.cpp

index 1e5b3664f39c93a8972aa9ff5b14c9f42058c1e0..35413289f24b39ca8f6ea87d61cf61bb267e4956 100644 (file)
@@ -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);
                }
index aadb3d7d07c79dd7714824583a046f314e2faaad..55c221be116cd1607515a9121d46e34deac853d4 100644 (file)
--- 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);
 }
 
 
index 10f772722136fe679fbf1147f2e62636a6180597..aced8bc4731a3483d4860c8a47c3c00f228aa59e 100644 (file)
@@ -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) {
index 31e88ee976b4270bdb27ad9133da16ceaa9b795a..d92df9dea393c867d24d508558c2bae839d6b114 100644 (file)
@@ -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 a4f8ba1feed29e15d6e7b9552eadb6bea5b6bfa4..d72dc78a752e45eacc0d87a82c0fba508a7f5769 100644 (file)
--- 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;
                                }