diff --git a/casablanca.cpp b/casablanca.cpp
deleted file mode 100644
index f73cb9ce..00000000
--- a/casablanca.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-#include "sysconfig.h"
-#include "sysdeps.h"
-
-#include "options.h"
-#include "uae.h"
-#include "memory.h"
-#include "newcpu.h"
-#include "casablanca.h"
-
-/*
-
- 53C710 (SCSI)
- Base: 0x04000000
- IRQ: 4
- INTREQ: 7 (AUD0)
-
- DracoMotion
- Base: 0x20000000
- IRQ: 3
- INTREQ: 4 (COPER)
- Size: 128k
- Autoconfig: 83 17 30 00 47 54 00 00 00 00 00 00 00 00 00 00 (18260/23)
-
- Mouse
- Base: 0x02400BE3
- IRQ: 4
- INTREQ: 9 (AUD2)
-
- Serial
- Base: 0x02400FE3
- IRQ: 4
- INTREQ: 10 (AUD3)
-
- Floppy:
- Base: 0x02400003
- IRQ: 5
- INTREQ: 11 (RBF)
-*/
-
-static uae_u32 REGPARAM2 casa_lget(uaecptr addr)
-{
- static int max = 100;
- if (max < 0) {
- write_log(_T("casa_lget %08x %08x\n"), addr, M68K_GETPC);
- max--;
- }
-
- return 0;
-}
-static uae_u32 REGPARAM2 casa_wget(uaecptr addr)
-{
- static int max = 100;
- if (max >= 0) {
- write_log(_T("casa_wget %08x %08x\n"), addr, M68K_GETPC);
- max--;
- }
-
- return 0;
-}
-
-static uae_u32 REGPARAM2 casa_bget(uaecptr addr)
-{
- uae_u8 v = 0;
-
- static int max = 100;
- if (max >= 0) {
- write_log(_T("casa_bget %08x %08x\n"), addr, M68K_GETPC);
- max--;
- }
-
-
- // casa
- if (addr == 0x020007c3)
- v = 4;
-
- // draco
- if (addr == 0x02000009)
- v = 4;
-
- return v;
-}
-
-static void REGPARAM2 casa_lput(uaecptr addr, uae_u32 l)
-{
- static int max = 100;
- if (max < 0)
- return;
- max--;
-
- write_log(_T("casa_lput %08x %08x %08x\n"), addr, l, M68K_GETPC);
-}
-static void REGPARAM2 casa_wput(uaecptr addr, uae_u32 w)
-{
- static int max = 100;
- if (max < 0)
- return;
- max--;
-
- write_log(_T("casa_wput %08x %04x %08x\n"), addr, w & 0xffff, M68K_GETPC);
-}
-
-static void REGPARAM2 casa_bput(uaecptr addr, uae_u32 b)
-{
- static int max = 100;
- if (max < 0)
- return;
- max--;
-
- write_log(_T("casa_bput %08x %02x %08x\n"), addr, b & 0xff, M68K_GETPC);
-}
-
-static addrbank casa_ram_bank = {
- casa_lget, casa_wget, casa_bget,
- casa_lput, casa_wput, casa_bput,
- default_xlate, default_check, NULL, NULL, _T("Casablanca IO"),
- dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE,
-};
-
-
-void casablanca_map_overlay(void)
-{
- // Casablanca has ROM at address zero, no chip ram, no overlay.
- map_banks(&kickmem_bank, 524288 >> 16, 524288 >> 16, 0);
- map_banks(&extendedkickmem_bank, 0 >> 16, 524288 >> 16, 0);
- map_banks(&casa_ram_bank, 0x02000000 >> 16, 0x01000000 >> 16, 0);
- // at least draco has rom here
- map_banks(&kickmem_bank, 0x02c00000 >> 16, 524288 >> 16, 0);
-}
diff --git a/cfgfile.cpp b/cfgfile.cpp
index 40df0b42..537220dc 100644
--- a/cfgfile.cpp
+++ b/cfgfile.cpp
@@ -9457,7 +9457,7 @@ static int bip_casablanca(struct uae_prefs *p, int config, int compa, int romche
case 2:
p->cpu_model = 68060;
p->fpu_model = 68060;
- p->mmu_model = 68040;
+ p->mmu_model = 68060;
break;
}
p->chipset_mask = CSMASK_AGA | CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
@@ -9472,6 +9472,30 @@ static int bip_casablanca(struct uae_prefs *p, int config, int compa, int romche
return configure_rom(p, roms, romcheck);
}
+static int bip_draco(struct uae_prefs *p, int config, int compa, int romcheck)
+{
+ int roms[8];
+
+ roms[0] = 16;
+ roms[1] = -1;
+
+ p->bogomem.size = 0;
+ p->chipmem.size = 0x200000;
+ p->cpu_model = 68060;
+ p->fpu_model = 68060;
+ p->mmu_model = 68060;
+ p->chipset_mask = CSMASK_AGA | CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
+ p->cpu_compatible = p->address_space_24 = 0;
+ p->m68k_speed = -1;
+ p->immediate_blits = 0;
+ p->produce_sound = 2;
+ p->floppyslots[0].dfxtype = DRV_NONE;
+ p->floppyslots[1].dfxtype = DRV_NONE;
+ p->cs_compatible = CP_DRACO;
+ built_in_chipset_prefs(p);
+ return configure_rom(p, roms, romcheck);
+}
+
int built_in_prefs (struct uae_prefs *p, int model, int config, int compa, int romcheck)
{
int v = 0;
@@ -9521,6 +9545,9 @@ int built_in_prefs (struct uae_prefs *p, int model, int config, int compa, int r
case 13:
v = bip_super (p, config, compa, romcheck);
break;
+ case 14:
+ v = bip_draco(p, config, compa, romcheck);
+ break;
}
if ((p->cpu_model >= 68020 || !p->cpu_memory_cycle_exact) && !p->immediate_blits)
p->waiting_blits = 1;
diff --git a/custom.cpp b/custom.cpp
index 04d03855..cd1b401a 100644
--- a/custom.cpp
+++ b/custom.cpp
@@ -14551,6 +14551,11 @@ void custom_reset(bool hardreset, bool keyboardreset)
maxhpos = ntsc ? MAXHPOS_NTSC : MAXHPOS_PAL;
maxhpos_short = maxhpos;
updateextblk();
+
+ if (currprefs.cs_compatible == CP_DRACO) {
+ // fake draco interrupts
+ INTENA(0x8000 | 0x4000 | 0x1000 | 0x2000 | 0x0080 | 0x0010 | 0x0008 | 0x0001);
+ }
}
specialmonitor_reset();
diff --git a/devices.cpp b/devices.cpp
index 5c111794..aaf8444d 100644
--- a/devices.cpp
+++ b/devices.cpp
@@ -63,6 +63,7 @@
#ifdef RETROPLATFORM
#include "rp.h"
#endif
+#include "draco.h"
#include "dsp3210/dsp_glue.h"
#define MAX_DEVICE_ITEMS 64
@@ -351,7 +352,9 @@ void virtualdevice_free(void)
#endif
ethernet_enumerate_free();
rtarea_free();
-
+#ifdef WITH_DRACO
+ draco_reset();
+#endif
execute_device_items(device_leaves, device_leave_cnt);
}
@@ -410,6 +413,9 @@ void virtualdevice_init (void)
#ifdef WITH_TABLETLIBRARY
tabletlib_install ();
#endif
+#ifdef WITH_DRACO
+ draco_init();
+#endif
}
void devices_restore_start(void)
diff --git a/draco.cpp b/draco.cpp
new file mode 100644
index 00000000..395f3760
--- /dev/null
+++ b/draco.cpp
@@ -0,0 +1,992 @@
+
+/* MacroSystem DraCo
+ *
+ * Toni Wilen 2023-2024
+ */
+
+#include "sysconfig.h"
+#include "sysdeps.h"
+
+#include "options.h"
+#include "uae.h"
+#include "memory.h"
+#include "newcpu.h"
+#include "devices.h"
+#include "custom.h"
+#include "debug.h"
+#include "x86.h"
+#include "ncr_scsi.h"
+#include "draco.h"
+#include "zfile.h"
+
+static int maxcnt = 100;
+
+
+/*
+ .asciz "kbd/soft" | 1: native keyboard, soft ints
+ .asciz "cia/zbus" | 2: cia, PORTS
+ .asciz "lclbus" | 3: local bus, e.g. Altais vbl
+ .asciz "drscsi" | 4: mainboard scsi
+ .asciz "superio" | 5: superio chip
+ .asciz "lcl/zbus" | 6: lcl/zorro lev6
+ .asciz "buserr" | 7: nmi: bus timeout
+*/
+
+// INTENA : 0x01000001
+// INTPEN : 0x01400001
+// INTFRC : 0x01800001
+// ? : 0x01c00001
+// IO : 0x02000000 (Misc control, 1-wire RTC)
+// SuperIO : 0x02400000 (PC-style serial, parallel, WD floppy) PC IO = Amiga address >> 2
+// CIA : 0x02800000 (only in pre-4 revisions)
+// KS ROM : 0x02c00000 (A3000 KS 3.1)
+// Z2 : 0x03e80000
+// SCSI : 0x04000000 (53C710)
+// SVGA : 0x20000000 (NCR 77C32BLT)
+
+// Interrupt
+
+// Bit 0: Master enable / INT1
+// Bit 1: INT4 (SCSI)
+// Bit 2: INT2 (Timer)
+// Bit 3: INT6
+
+// SVGA vblank: INT3
+// SuperIO: INT5
+
+
+// IO:
+
+// IO_control : 01
+#define DRCNTRL_FDCINTENA 1
+#define DRCNTRL_KBDDATOUT 2
+#define DRCNTRL_KBDCLKOUT 4
+#define DRCNTRL_WDOGDIS 8
+#define DRCNTRL_WDOGDAT 16
+#define DRCNTRL_KBDINTENA 32
+#define DRCNTRL_KBDKBDACK 64
+#define DRCNTRL_SCSITERM 128
+
+// IO_status : 03
+#define DRSTAT_CLKDAT 1 // (1-wire data)
+#define DRSTAT_KBDDATIN 2
+#define DRSTAT_KBDCLKIN 4
+#define DRSTAT_KBDRECV 8
+#define DRSTAT_CLKBUSY 16 // (1-wire, busy)
+#define DRSTAT_BUSTIMO 32
+#define DRSTAT_SCSILED 64
+
+// IO_KBD_data : 05
+
+// IO_status2 : 07
+#define DRSTAT2_KBDBUSY 1
+#define DRSTAT2_PARIRQPEN 4
+#define DRSTAT2_PARIRQENA 8
+#define DRSTAT2_TMRINTENA 16
+#define DRSTAT2_TMRIRQPEN 32
+
+// Revision : 09 (write=timer reset)
+// IO_TimerHI : 0B
+// IO_TimerLO : 0D
+// unused : 0F
+// IO_clockw0 : 11 (1-wire, write 1)
+// IO_clockw1 : 13 (1-wire, write 0)
+// IO_clockrst : 15 (1-wire, reset)
+// IO_KBD_Reset : 17
+// IO_bustimeout: 19
+// IO_scsiledres: 1b
+// IO_fdcread : 1d
+// IO_parrst : 1f
+
+
+/*
+
+ 53C710 (SCSI)
+ Base: 0x04000000
+ IRQ: 4
+ INTREQ: 7 (AUD0)
+
+ DracoMotion
+ Base: 0x20000000
+ IRQ: 3
+ INTREQ: 4 (COPER)
+ Size: 128k
+ Autoconfig: 83 17 30 00 47 54 00 00 00 00 00 00 00 00 00 00 (18260/23)
+
+ Mouse
+ Base: 0x02400BE3
+ IRQ: 4
+ INTREQ: 9 (AUD2)
+
+ Serial
+ Base: 0x02400FE3
+ IRQ: 4
+ INTREQ: 10 (AUD3)
+
+ Floppy:
+ Base: 0x02400003
+ IRQ: 5
+ INTREQ: 11 (RBF)
+*/
+
+void serial_reset();
+void serial_write(uint16_t addr, uint8_t val, void *p);
+uint8_t serial_read(uint16_t addr, void *p);
+void draco_serial_init(void **s1, void **s2);
+
+static void *draco_serial[2];
+
+static uae_u8 draco_intena, draco_intpen, draco_svga_irq_state;
+static uae_u16 draco_timer, draco_timer_latch;
+static bool draco_timer_latched;
+static bool draco_fdc_intpen;
+static uae_u8 draco_superio_cfg[16];
+static uae_s8 draco_superio_idx;
+static uae_u8 draco_reg[0x20];
+
+static void draco_irq(void)
+{
+ uae_u16 irq = 0;
+ 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_svga_irq_state) {
+ irq |= 0x0010; // INT3
+ }
+ if (draco_fdc_intpen && (draco_reg[1] & DRCNTRL_FDCINTENA)) {
+ irq = 0x1000; // INT5
+ }
+ if ((draco_reg[7] & DRSTAT2_TMRINTENA) && (draco_reg[7] & DRSTAT2_TMRIRQPEN)) {
+ irq |= 1;
+ }
+ if ((draco_reg[3] & DRSTAT_KBDRECV) && (draco_reg[1] & DRCNTRL_KBDINTENA)) {
+ irq |= 1;
+ }
+ }
+ INTREQ_f(0x7fff);
+ if (irq) {
+ INTREQ_f(0x8000 | irq);
+ doint();
+ }
+
+}
+
+void draco_svga_irq(bool state)
+{
+ draco_svga_irq_state = state;
+ draco_irq();
+}
+
+static uae_u8 draco_kbd_state, draco_kbd_state2;
+static uae_u16 draco_kbd_code;
+static int draco_kbd_poll;
+static uae_u8 draco_kbd_buffer[10];
+static uae_u8 draco_kbd_buffer_len;
+
+static uae_u8 draco_keyboard_read(uae_u8 v)
+{
+ if (draco_kbd_state2) {
+ draco_reg[3] &= ~DRSTAT_KBDCLKIN;
+
+ draco_kbd_poll++;
+ if (draco_kbd_state2 > 0 && draco_kbd_poll >= 4) {
+ draco_reg[3] |= DRSTAT_KBDCLKIN;
+ draco_kbd_code >>= 1;
+ draco_kbd_code |= (draco_reg[1] & DRCNTRL_KBDDATOUT) ? 0x8000 : 0;
+ draco_kbd_state2++;
+ draco_kbd_poll = 0;
+ }
+ }
+ return v;
+}
+static void draco_keyboard_write(uae_u8 v)
+{
+ v &= DRCNTRL_KBDDATOUT | DRCNTRL_KBDCLKOUT;
+ if (v == draco_kbd_state) {
+ return;
+ }
+
+ // start receive
+ if ((v & DRCNTRL_KBDCLKOUT) && !(draco_kbd_state & DRCNTRL_KBDCLKOUT)) {
+ draco_reg[3] |= DRSTAT_KBDCLKIN;
+ draco_kbd_code = 0;
+ draco_kbd_state2 = 1;
+ draco_kbd_poll = 0;
+ }
+
+ draco_kbd_state = v;
+}
+
+static void draco_keyboard_done(void)
+{
+
+ if (draco_kbd_state2 == 12) {
+ draco_kbd_code >>= 5;
+ draco_kbd_code &= 0xff;
+ write_log("draco received keyboard data %04x\n", draco_kbd_code);
+ if (draco_kbd_code == 0xf2) {
+ draco_kbd_buffer[0] = 0xab;
+ draco_kbd_buffer[1] = 0x83;
+ draco_kbd_buffer_len = 2;
+ }
+ }
+ draco_reg[3] &= ~DRSTAT_KBDCLKIN;
+ draco_reg[3] &= ~DRSTAT_KBDRECV;
+ draco_kbd_state2 = 0;
+ draco_kbd_poll = 0;
+}
+
+static void draco_keyboard_send(void)
+{
+ if (draco_kbd_buffer_len <= 0) {
+ return;
+ }
+ if (!(draco_reg[3] & DRSTAT_KBDRECV)) {
+ draco_kbd_buffer_len--;
+ uae_u8 code = draco_kbd_buffer[draco_kbd_buffer_len];
+ draco_reg[5] = code;
+ draco_reg[3] |= DRSTAT_KBDRECV;
+ draco_irq();
+ }
+}
+
+static uae_u8 draco_1wire_data[40], draco_1wire_state, draco_1wire_dir;
+static uae_u8 draco_1wire_sram[512 + 32], draco_1wire_scratchpad[32 + 3], draco_1wire_rom[8];
+static uae_u8 draco_1wire_cmd, draco_1wire_bytes, draco_1wire_dat;
+static uae_s16 draco_1wire_sram_offset, draco_1wire_sram_offset_copy;
+static uae_s8 draco_1wire_rom_offset, draco_1wire_cnt, draco_1wire_busycnt;
+static bool draco_1wire_bit;
+
+#define DS_ROM_MATCH 0x55
+#define DS_ROM_SEARCH 0xf0
+#define DS_ROM_SKIP 0xcc
+#define DS_ROM_READ 0x33
+#define DS_WRITE_SCRATCHPAD 0x0f
+#define DS_READ_SCRATCHPAD 0xaa
+#define DS_COPY_SCRATCHPAD 0x55
+
+static void draco_1wire_rtc_count(void)
+{
+ uae_u8 *rtc = draco_1wire_sram + 512;
+ rtc[2]++;
+ if (rtc[2] == 0) {
+ rtc[3]++;
+ if (rtc[3] == 0) {
+ rtc[4]++;
+ if (rtc[4] == 0) {
+ rtc[5]++;
+ }
+ }
+ }
+}
+
+static void draco_1wire_rtc_validate(void)
+{
+ uae_u8 *rtc = draco_1wire_sram + 512;
+ rtc[0] &= ~7;
+ draco_1wire_rtc_count();
+}
+
+static void draco_1wire_set_bit(void)
+{
+ uae_u8 *dptr = NULL;
+ int maxlen = 0;
+ if (draco_1wire_cmd == DS_ROM_SEARCH) {
+ dptr = draco_1wire_sram;
+ maxlen = sizeof(draco_1wire_sram);
+ } else if (draco_1wire_cmd == DS_READ_SCRATCHPAD) {
+ dptr = draco_1wire_scratchpad;
+ maxlen = sizeof(draco_1wire_scratchpad);
+ }
+ if (dptr && draco_1wire_sram_offset >= 0 && draco_1wire_dir) {
+ if (draco_1wire_rom_offset >= 0) {
+ draco_1wire_dat = draco_1wire_rom[draco_1wire_rom_offset];
+ uae_u8 bit = (draco_1wire_rom[draco_1wire_rom_offset] >> draco_1wire_cnt) & 1;
+ draco_1wire_bit = bit != 0;
+ } else {
+ if (draco_1wire_sram_offset >= maxlen) {
+ draco_1wire_dat = 0xff;
+ draco_1wire_bit = true;
+ } else {
+ if (draco_1wire_sram_offset >= 0) {
+ draco_1wire_dat = dptr[draco_1wire_sram_offset];
+ uae_u8 bit = (dptr[draco_1wire_sram_offset] >> draco_1wire_cnt) & 1;
+ draco_1wire_bit = bit != 0;
+ }
+ }
+ }
+ }
+}
+
+static uae_u8 draco_1wire_read(uae_u8 v)
+{
+ if (draco_1wire_bit) {
+ draco_reg[3] |= DRSTAT_CLKDAT;
+ v |= DRSTAT_CLKDAT;
+ } else {
+ draco_reg[3] &= ~DRSTAT_CLKDAT;
+ v &= ~DRSTAT_CLKDAT;
+ }
+
+ if (draco_1wire_cnt == 8 && !(draco_reg[3] & DRSTAT_CLKBUSY)) {
+ write_log("draco read 1-wire SRAM byte %02x, %02x\n", draco_1wire_dat, draco_1wire_bytes);
+ draco_1wire_cnt = 0;
+ draco_1wire_bytes++;
+ if (draco_1wire_rom_offset >= 0) {
+ if (draco_1wire_rom_offset == sizeof(draco_1wire_rom)) {
+ draco_1wire_rom_offset = -1;
+ }
+ } else if (draco_1wire_cmd == DS_READ_SCRATCHPAD) {
+ if (draco_1wire_sram_offset == 2) {
+ draco_1wire_sram_offset = (draco_1wire_sram_offset_copy & 31) + 3;
+ } else if (draco_1wire_sram_offset < 2) {
+ draco_1wire_sram_offset++;
+ } else {
+ draco_1wire_sram_offset++;
+ draco_1wire_sram_offset -= 3;
+ draco_1wire_sram_offset &= 31;
+ draco_1wire_sram_offset += 3;
+ }
+ } else {
+ draco_1wire_sram_offset++;
+ }
+ }
+
+ if (draco_reg[3] & DRSTAT_CLKBUSY) {
+ draco_1wire_busycnt--;
+ if (draco_1wire_busycnt < 0) {
+ draco_reg[3] &= ~DRSTAT_CLKBUSY;
+ }
+ }
+
+ return v;
+}
+
+static void draco_1wire_busy(void)
+{
+ draco_reg[3] |= DRSTAT_CLKBUSY;
+ draco_1wire_busycnt = 3;
+}
+
+
+static void draco_1wire_send(int bit)
+{
+ if (draco_1wire_dir) {
+ draco_1wire_set_bit();
+ draco_1wire_cnt++;
+ draco_1wire_busy();
+ }
+
+ if (!draco_1wire_dir) {
+ draco_1wire_data[0] >>= 1;
+ draco_1wire_data[0] |= bit ? 0x80 : 0;
+ draco_1wire_cnt++;
+ draco_1wire_busy();
+ }
+ if (draco_1wire_cnt == 8 && !draco_1wire_dir) {
+ bool gotcmd = false;
+ if (!draco_1wire_state) {
+ draco_1wire_cmd = draco_1wire_data[0];
+ if (draco_1wire_cmd != DS_ROM_SKIP) {
+ draco_1wire_state = 1;
+ gotcmd = true;
+ } else {
+ draco_1wire_rom_offset = -1;
+ }
+ }
+ for (int i = sizeof(draco_1wire_data) - 1; i >= 1; i--) {
+ draco_1wire_data[i] = draco_1wire_data[i - 1];
+ }
+ write_log("draco received 1-wire byte %02x, cnt %02x\n", draco_1wire_data[0], draco_1wire_bytes);
+ draco_1wire_cnt = 0;
+ draco_1wire_bytes++;
+ // read data command + 2 address bytes?
+ if (draco_1wire_cmd == DS_ROM_SEARCH && draco_1wire_data[3] == DS_ROM_SEARCH) {
+ draco_1wire_sram_offset = (draco_1wire_data[1] << 8) | draco_1wire_data[2];
+ draco_1wire_dir = 1;
+ draco_1wire_bytes = 0;
+ write_log("draco received 1-wire SRAM read command, offset %04x\n", draco_1wire_sram_offset);
+ }
+ // write scratchpad + 2 address bytes?
+ if (draco_1wire_cmd == DS_WRITE_SCRATCHPAD && draco_1wire_data[3] == DS_WRITE_SCRATCHPAD) {
+ draco_1wire_sram_offset = (draco_1wire_data[1] << 8) | draco_1wire_data[2];
+ draco_1wire_sram_offset_copy = draco_1wire_sram_offset;
+ memset(draco_1wire_scratchpad, 0, sizeof(draco_1wire_scratchpad));
+ write_log("draco received 1-wire SRAM scratchpad write command, offset %04x\n", draco_1wire_sram_offset);
+ }
+ // read scratchpad
+ if (draco_1wire_cmd == DS_READ_SCRATCHPAD) {
+ draco_1wire_sram_offset = 0;
+ draco_1wire_dir = 1;
+ draco_1wire_bytes = 0;
+ draco_1wire_set_bit();
+ write_log("draco received 1-wire SRAM scratchpad read command\n");
+ }
+ // copy scratchpad
+ if (draco_1wire_cmd == DS_COPY_SCRATCHPAD && draco_1wire_data[4] == DS_COPY_SCRATCHPAD) {
+ draco_1wire_sram_offset = 0;
+ uae_u8 status = draco_1wire_data[1];
+ if (status == draco_1wire_scratchpad[2] &&
+ draco_1wire_data[2] == draco_1wire_scratchpad[1] &&
+ draco_1wire_data[3] == draco_1wire_scratchpad[0]) {
+ int start = draco_1wire_sram_offset_copy & 31;
+ int offset = draco_1wire_sram_offset_copy & ~31;
+ write_log("draco received 1-wire SRAM scratchpad copy command, accepted\n");
+ for (int i = 0; i < 32; i++) {
+ draco_1wire_sram[offset + start] = draco_1wire_scratchpad[start + 3];
+ write_log("draco 1-wire SRAM scratchpad copy %02x -> %04x\n", draco_1wire_sram[offset + start], offset + start);
+ if (start == (draco_1wire_scratchpad[2] & 31)) {
+ break;
+ }
+ start++;
+ start &= 31;
+ }
+ draco_1wire_scratchpad[0] |= 0x80;
+ draco_1wire_rtc_validate();
+ draco_1wire_busy();
+ draco_1wire_bit = 0;
+ } else {
+ write_log("draco received 1-wire SRAM scratchpad copy command, rejected\n");
+ draco_1wire_busy();
+ }
+ }
+ }
+}
+static void draco_1wire_reset(void)
+{
+ if (draco_1wire_state) {
+ // write scratchpad
+ if (draco_1wire_cmd == DS_WRITE_SCRATCHPAD) {
+ int len = draco_1wire_bytes - 4;
+ int start = draco_1wire_sram_offset_copy;
+ for (int i = 0; i < len; i++) {
+ draco_1wire_scratchpad[(start & 31) + 3] = draco_1wire_data[len - i];
+ start++;
+ start &= 31;
+ }
+ draco_1wire_scratchpad[0] = draco_1wire_sram_offset_copy >> 0;
+ draco_1wire_scratchpad[1] = draco_1wire_sram_offset_copy >> 8;
+ draco_1wire_scratchpad[2] = (start - 1) & 31;
+ if (len > 32) {
+ draco_1wire_scratchpad[2] |= 0x40;
+ } else if (len < 32) {
+ draco_1wire_scratchpad[2] |= 0x20;
+ }
+ write_log("draco received 1-wire SRAM scratchpad write, %d bytes received\n", len);
+ }
+ }
+
+ memset(draco_1wire_data, 0, sizeof(draco_1wire_data));
+ draco_1wire_cnt = 0;
+ draco_1wire_state = 0;
+ draco_1wire_dir = 0;
+ draco_1wire_bytes = 0;
+ draco_1wire_sram_offset = -1;
+ draco_1wire_rom_offset = 0;
+ write_log("draco 1-wire reset\n");
+}
+
+static uae_u32 REGPARAM2 draco_lget(uaecptr addr)
+{
+ uae_u32 l = 0;
+
+ if ((addr & 0x07c00000) == 0x04000000) {
+
+ write_log("draco scsi lput %08x %08x\n", addr, l);
+ int reg = addr & 0xffff;
+ l = cpuboard_ncr710_io_bget(reg + 0) << 24;
+ l |= cpuboard_ncr710_io_bget(reg + 1) << 16;
+ l |= cpuboard_ncr710_io_bget(reg + 2) << 8;
+ l |= cpuboard_ncr710_io_bget(reg + 3) << 0;
+ } else {
+ write_log(_T("draco_lget %08x %08x\n"), addr, M68K_GETPC);
+ }
+
+ return l;
+}
+static uae_u32 REGPARAM2 draco_wget(uaecptr addr)
+{
+ write_log(_T("draco_wget %08x %08x\n"), addr, M68K_GETPC);
+
+ return 0;
+}
+
+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);
+ maxcnt--;
+ }
+
+ if (addr >= 0x20000000) {
+ write_log("draco bus timeout %08x\n", addr);
+ draco_reg[3] |= DRSTAT_BUSTIMO;
+ return 0;
+ }
+
+ if ((addr & 0x07c00000) == 0x04000000) {
+
+ int reg = addr & 0xffff;
+ v = cpuboard_ncr710_io_bget(reg);
+ write_log("draco scsi read %08x\n", addr);
+
+ } else if ((addr & 0x07c00000) == 0x02400000) {
+
+ // super io
+
+ int reg = (addr & 0x7fff) >> 2;
+ switch(reg)
+ {
+ case 0x3f0:
+ if (draco_superio_idx >= 0) {
+ v = draco_superio_idx;
+ } else {
+ v = x86_infloppy(reg);
+ }
+ break;
+ case 0x3f1:
+ if (draco_superio_idx >= 0 && draco_superio_idx < 16) {
+ v = draco_superio_cfg[draco_superio_idx];
+ } else {
+ v = x86_infloppy(reg);
+ }
+ break;
+
+ case 0x3f2:
+ case 0x3f3:
+ case 0x3f4:
+ case 0x3f5:
+ case 0x3f7:
+ v = x86_infloppy(reg);
+ break;
+
+ case 0x3f8:
+ case 0x3f9:
+ case 0x3fa:
+ case 0x3fb:
+ case 0x3fc:
+ case 0x3fd:
+ case 0x3fe:
+ case 0x3ff:
+ v = serial_read(reg, draco_serial[0]);
+ break;
+
+ case 0x2f8:
+ case 0x2f9:
+ case 0x2fa:
+ case 0x2fb:
+ case 0x2fc:
+ case 0x2fd:
+ case 0x2fe:
+ case 0x2ff:
+ v = serial_read(reg, draco_serial[1]);
+ break;
+
+ default:
+ write_log("draco superio read %04x = %02x\n", (addr >> 2) & 0xfff, v);
+ break;
+ }
+
+
+ } else if ((addr & 0x07c00000) == 0x02000000) {
+
+ // io
+ if ((addr & 0xffffff) > 0x1f)
+ write_log("x");
+
+ int reg = addr & 0x1f;
+ v = draco_reg[reg];
+ switch(reg)
+ {
+ case 3:
+ v = draco_keyboard_read(v);
+ v = draco_1wire_read(v);
+ break;
+ case 9:
+ v = 4;
+ 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;
+ }
+
+ } else if ((addr & 0x07c00000) == 0x02800000) {
+
+ // CIA (no CIAs if rev4+)
+
+ } else if ((addr & 0x07000000) == 0x01000000) {
+
+ // interrupt control
+ int reg = (addr & 0x0c00001);
+ switch(reg)
+ {
+ case 0x000001:
+ v = draco_intena;
+ break;
+ case 0x400001:
+ v = draco_intpen;
+ break;
+ case 0x800001:
+ v = 0;
+ break;
+ case 0xc0001:
+ v = 0;
+ break;
+ }
+ } else {
+
+ write_log("draco unknown bank read %08x\n", addr);
+ }
+
+ return v;
+}
+
+static void REGPARAM2 draco_lput(uaecptr addr, uae_u32 l)
+{
+ if ((addr & 0x07c00000) == 0x04000000) {
+
+ write_log("draco scsi lput %08x %08x\n", addr, l);
+ int reg = addr & 0xffff;
+ cpuboard_ncr710_io_bput(reg + 0, l >> 24);
+ cpuboard_ncr710_io_bput(reg + 1, l >> 16);
+ cpuboard_ncr710_io_bput(reg + 2, l >> 8);
+ cpuboard_ncr710_io_bput(reg + 3, l >> 0);
+
+ } else {
+
+ write_log(_T("draco_lput %08x %08x %08x\n"), addr, l, M68K_GETPC);
+ }
+}
+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 REGPARAM2 draco_bput(uaecptr addr, uae_u32 b)
+{
+ if (maxcnt >= 0) {
+ maxcnt--;
+ write_log(_T("draco_bput %08x %02x %08x\n"), addr, b & 0xff, M68K_GETPC);
+ }
+
+ if (addr >= 0x20000000) {
+ draco_reg[3] |= DRSTAT_BUSTIMO;
+ return;
+ }
+
+ if ((addr & 0x07c00000) == 0x04000000) {
+
+ write_log("draco scsi put %08x\n", addr);
+ int reg = addr & 0xffff;
+ cpuboard_ncr710_io_bput(reg, b);
+
+ } else if ((addr & 0x07c00000) == 0x02400000) {
+
+ // super io
+ int reg = (addr & 0x7fff) >> 2;
+ switch (reg)
+ {
+ case 0x3f0:
+ if (b == 0x55 && draco_superio_idx < 0) {
+ draco_superio_idx++;
+ } else if (b == 0xaa && draco_superio_idx >= 0) {
+ draco_superio_idx = -2;
+ } else if (draco_superio_idx >= 0) {
+ draco_superio_idx = b;
+ } else {
+ x86_outfloppy(reg, b);
+ }
+ break;
+ case 0x3f1:
+ if (draco_superio_idx >= 0 && draco_superio_idx < 16) {
+ draco_superio_cfg[draco_superio_idx] = b;
+ } else {
+ x86_outfloppy(reg, b);
+ }
+ break;
+
+ case 0x3f2:
+ case 0x3f3:
+ case 0x3f4:
+ case 0x3f5:
+ case 0x3f7:
+ x86_outfloppy(reg, b);
+ draco_superio_idx = -2;
+ break;
+
+ case 0x3f8:
+ case 0x3f9:
+ case 0x3fa:
+ case 0x3fb:
+ case 0x3fc:
+ case 0x3fd:
+ case 0x3fe:
+ case 0x3ff:
+ serial_write(reg, b, draco_serial[0]);
+ break;
+
+ case 0x2f8:
+ case 0x2f9:
+ case 0x2fa:
+ case 0x2fb:
+ case 0x2fc:
+ case 0x2fd:
+ case 0x2fe:
+ case 0x2ff:
+ serial_write(reg, b, draco_serial[1]);
+ break;
+ default:
+ write_log("draco superio write %04x = %02x\n", (addr >> 2) & 0xfff, b);
+ break;
+ }
+
+ } else if ((addr & 0x07c00000) == 0x02800000) {
+
+ // CIA (no CIAs if rev4+)
+
+ } else if ((addr & 0x07c00000) == 0x02000000) {
+
+ // IO
+
+ int reg = addr & 0x1f;
+ uae_u8 oldval = draco_reg[reg];
+ draco_reg[reg] = b;
+ //draco_reg[1] |= DRCNTRL_FDCINTENA;
+
+ //write_log(_T("draco_bput %08x %02x %08x\n"), addr, b & 0xff, M68K_GETPC);
+ switch(reg)
+ {
+ case 1:
+ 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;
+ }
+ } else if ((addr & 0x07000000) == 0x01000000) {
+
+ // interrupt control
+ int reg = (addr & 0x0c00001);
+ switch (reg)
+ {
+ case 0x000001:
+ draco_intena = b & 15;
+ draco_irq();
+ break;
+ case 0x400001:
+ draco_intpen = b & 15;
+ if (b)
+ write_log("draco interrupt 0x400001 write %02x\n", b);
+ draco_irq();
+ break;
+ case 0x800001:
+ if (b)
+ write_log("draco interrupt 0x800001 write %02x\n", b);
+ draco_intpen |= b & 15;
+ draco_irq();
+ break;
+ case 0xc00001:
+ if (b)
+ write_log("draco interrupt 0xc00001 write %02x\n", b);
+ draco_irq();
+ break;
+ }
+
+ } else {
+
+ write_log("draco unknown bank write %08x\n", addr);
+
+ }
+}
+
+static addrbank draco_bank = {
+ draco_lget, draco_wget, draco_bget,
+ draco_lput, draco_wput, draco_bput,
+ default_xlate, default_check, NULL, NULL, _T("DraCo mainboard"),
+ dummy_lgeti, dummy_wgeti, ABFLAG_IO, S_READ, S_WRITE
+};
+
+
+void casablanca_map_overlay(void)
+{
+ // Casablanca has ROM at address zero, no chip ram, no overlay.
+ map_banks(&kickmem_bank, 524288 >> 16, 524288 >> 16, 0);
+ map_banks(&extendedkickmem_bank, 0 >> 16, 524288 >> 16, 0);
+ map_banks(&draco_bank, 0x02000000 >> 16, 0x01000000 >> 16, 0);
+ // KS ROM is here
+ map_banks(&kickmem_bank, 0x02c00000 >> 16, 524288 >> 16, 0);
+ map_banks(&draco_bank, 0x03000000 >> 16, 0x01000000 >> 16, 0);
+}
+
+static void draco_hsync(void)
+{
+ uae_u16 tm = 1, 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();
+ }
+ }
+ x86_floppy_run();
+
+ if (draco_kbd_buffer_len > 0) {
+ draco_keyboard_send();
+ }
+ hcnt++;
+ if (hcnt >= 60) {
+ draco_1wire_rtc_count();
+ hcnt = 0;
+ }
+}
+
+void draco_set_scsi_irq(int id, int level)
+{
+ if (level) {
+ draco_intpen |= 2;
+ } else {
+ draco_intpen &= ~2;
+ }
+ draco_irq();
+}
+
+
+static void x86_irq(int irq, bool state)
+{
+ draco_fdc_intpen = state;
+ draco_irq();
+}
+
+void draco_reset(void)
+{
+ TCHAR path[MAX_DPATH];
+ cfgfile_resolve_path_out_load(currprefs.flashfile, path, MAX_DPATH, PATH_ROM);
+ struct zfile *draco_flashfile = zfile_fopen(path, _T("wb"), ZFD_NORMAL);
+ if (draco_flashfile) {
+ uae_u8 zeros[8] = { 0 };
+ zfile_fwrite(draco_1wire_rom, sizeof(draco_1wire_rom), 1, draco_flashfile);
+ zfile_fwrite(zeros, sizeof(zeros), 1, draco_flashfile);
+ zfile_fwrite(draco_1wire_sram, sizeof(draco_1wire_sram), 1, draco_flashfile);
+ zfile_fclose(draco_flashfile);
+ }
+}
+
+void draco_init(void)
+{
+ if (currprefs.cs_compatible != CP_DRACO) {
+ return;
+ }
+
+ draco_intena = 0;
+ draco_intpen = 0;
+ draco_timer = 0;
+ draco_timer_latched = 0;
+ draco_timer_latched = false;
+ draco_svga_irq_state = 0;
+ draco_fdc_intpen = false;
+ draco_superio_idx = -2;
+ draco_kbd_buffer_len = 0;
+ draco_kbd_state2 = 0;
+ memset(draco_superio_cfg, 0, sizeof(draco_superio_cfg));
+ draco_superio_cfg[0] = 0x3b;
+ draco_superio_cfg[1] = 0x9f;
+ draco_superio_cfg[2] = 0xdc;
+ draco_superio_cfg[3] = 0x78;
+ draco_superio_cfg[6] = 0xff;
+ draco_superio_cfg[13] = 0x65;
+ draco_superio_cfg[14] = 1;
+ memset(draco_reg, 0, sizeof(draco_reg));
+
+ draco_1wire_rtc_validate();
+ draco_1wire_rom[0] = 0x04;
+ draco_1wire_rom[1] = 1;
+ draco_1wire_rom[2] = 2;
+ draco_1wire_rom[3] = 3;
+ draco_1wire_rom[4] = 4;
+ draco_1wire_rom[5] = 5;
+ draco_1wire_rom[6] = 6;
+ draco_1wire_rom[7] = 0xaa;
+
+ TCHAR path[MAX_DPATH];
+ cfgfile_resolve_path_out_load(currprefs.flashfile, path, MAX_DPATH, PATH_ROM);
+ struct zfile *draco_flashfile = zfile_fopen(path, _T("rb"), ZFD_NORMAL);
+ if (draco_flashfile) {
+ zfile_fread(draco_1wire_rom, sizeof(draco_1wire_rom), 1, draco_flashfile);
+ zfile_fseek(draco_flashfile, 8, SEEK_CUR);
+ zfile_fread(draco_1wire_sram, sizeof(draco_1wire_sram), 1, draco_flashfile);
+ zfile_fclose(draco_flashfile);
+ }
+
+ x86_initfloppy(x86_irq);
+ draco_serial_init(&draco_serial[0], &draco_serial[1]);
+
+ device_add_rethink(draco_irq);
+ device_add_hsync(draco_hsync);
+}
+
+void draco_map_overlay(void)
+{
+ // hide custom registers
+ map_banks(&dummy_bank, 0xd00000 >> 16, 0x200000 >> 16, 0);
+ // hide cias
+ map_banks(&dummy_bank, 0xa00000 >> 16, 0x200000 >> 16, 0);
+
+ map_banks(&extendedkickmem_bank, 0 >> 16, 524288 >> 16, 0);
+ map_banks(&draco_bank, 0x01000000 >> 16, 0x01c00000 >> 16, 0);
+ map_banks(&kickmem_bank, 0x02c00000 >> 16, 524288 >> 16, 0);
+ map_banks(&draco_bank, 0x04000000 >> 16, 0x01000000 >> 16, 0);
+ map_banks(&draco_bank, 0x21000000 >> 16, 0x1f000000 >> 16, 0);
+}
diff --git a/expansion.cpp b/expansion.cpp
index b338293b..229de393 100644
--- a/expansion.cpp
+++ b/expansion.cpp
@@ -3614,6 +3614,17 @@ static void expansion_add_autoconfig(struct uae_prefs *p)
cards_set[cardno++].map = NULL;
}
+ for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+ struct rtgboardconfig *rbc = &p->rtgboards[i];
+ int type = gfxboard_get_configtype(rbc);
+ if (rbc->rtgmem_size && rbc->rtgmem_type >= GFXBOARD_HARDWARE && type == BOARD_NONAUTOCONFIG_BEFORE) {
+ cards_set[cardno].flags = 4 | (i << 16);
+ cards_set[cardno].name = _T("MainBoardRTG");
+ cards_set[cardno].zorro = BOARD_NONAUTOCONFIG_BEFORE;
+ cards_set[cardno++].initnum = gfxboard_init_memory;
+ }
+ }
+
// add possible non-autoconfig boards
add_cpu_expansions(p, BOARD_NONAUTOCONFIG_BEFORE, NULL);
add_expansions(p, BOARD_NONAUTOCONFIG_BEFORE, NULL, 0);
@@ -3677,7 +3688,8 @@ static void expansion_add_autoconfig(struct uae_prefs *p)
#ifdef GFXBOARD
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
struct rtgboardconfig *rbc = &p->rtgboards[i];
- if (rbc->rtgmem_size && rbc->rtgmem_type >= GFXBOARD_HARDWARE && gfxboard_get_configtype(rbc) <= 2) {
+ int type = gfxboard_get_configtype(rbc);
+ if (rbc->rtgmem_size && rbc->rtgmem_type >= GFXBOARD_HARDWARE && type <= 2) {
cards_set[cardno].flags = 4 | (i << 16);
if (gfxboard_get_func(rbc)) {
cards_set[cardno].name = _T("Z2RTG");
@@ -6869,6 +6881,22 @@ static const struct cpuboardsubtype harms_sub[] = {
}
};
+static const struct cpuboardsubtype draco_sub[] = {
+ {
+ _T("DraCo"),
+ _T("draco"),
+ ROMTYPE_CB_DRACO | ROMTYPE_NONE, 0, 4,
+ draco_add_scsi_unit, EXPANSIONTYPE_SCSI,
+ BOARD_MEMORY_HIGHMEM,
+ 128 * 1024 * 1024,
+ 0,
+ ncr710_draco_init, NULL, BOARD_NONAUTOCONFIG_BEFORE, 1,
+ },
+ {
+ NULL
+ }
+};
+
static const struct cpuboardsubtype dummy_sub[] = {
{ NULL }
};
@@ -6959,6 +6987,11 @@ const struct cpuboardtype cpuboards[] = {
_T("Harms"),
harms_sub, 0
},
+ {
+ BOARD_DRACO,
+ _T("Draco"),
+ draco_sub, 0
+ },
{
NULL
}
diff --git a/gfxboard.cpp b/gfxboard.cpp
index b5b63901..f2cd6b0e 100644
--- a/gfxboard.cpp
+++ b/gfxboard.cpp
@@ -125,7 +125,7 @@ struct gfxboard
struct gfxboard_func *func;
device_t *pcemdev;
uae_u8 er_flags;
- bool pci;
+ int bustype;
};
#define ISP4() (gb->rbc->rtgmem_type == GFXBOARD_ID_PICASSO4_Z2 || gb->rbc->rtgmem_type == GFXBOARD_ID_PICASSO4_Z3)
@@ -249,6 +249,13 @@ static const struct gfxboard boards[] =
0x00000000, 0x00100000, 0x00400000, 0x00400000, 0, 3, 2, false, false,
0, 0, NULL, &ncr_retina_z3_device
},
+ {
+ GFXBOARD_ID_ALTAIS_Z3,
+ _T("Altais [DracoBus]"), _T("MacroSystem"), _T("Altais"),
+ 18260, 19, 0, 0,
+ 0x00000000, 0x00400000, 0x00400000, 0x00400000, 0, 4, 3, false, false,
+ 0, 0, NULL, &ncr_retina_z3_device, 0, GFXBOARD_BUSTYPE_DRACO
+ },
{
GFXBOARD_ID_HARLEQUIN,
_T("Harlequin [Zorro II]"), _T("ACS"), _T("Harlequin_PAL"),
@@ -270,14 +277,14 @@ static const struct gfxboard boards[] =
0, 0, 0, 0,
0x00000000, 0x01000000, 0x01000000, 0x01000000, 0, 0, -1, false, false,
ROMTYPE_VOODOO3,
- 0, NULL, &voodoo_3_3000_device, 0, true
+ 0, NULL, &voodoo_3_3000_device, 0, GFXBOARD_BUSTYPE_PCI
},
{
GFXBOARD_ID_S3VIRGE_PCI,
_T("Virge [PCI]"), _T("S3"), _T("S3VIRGE_PCI"),
0, 0, 0, 0,
0x00000000, 0x00400000, 0x00400000, 0x10000000, 0, 0, -1, false, false,
- 0, 0, NULL, &s3_virge_device, 0, true
+ 0, 0, NULL, &s3_virge_device, 0, GFXBOARD_BUSTYPE_PCI
},
{
GFXBOARD_ID_VGA,
@@ -784,9 +791,12 @@ static void gfxboard_rethink(void)
{
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
struct rtggfxboard *gb = &rtggfxboards[i];
- if (gb->pcemdev && gb->pcemobject && gb->gfxboard_intreq && gb->gfxboard_intena) {
+ if (gb->pcemdev && gb->pcemobject) {
int irq = 0;
- if (gb->board->irq > 0) {
+ if (gb->board->bustype == GFXBOARD_BUSTYPE_DRACO) {
+ void draco_svga_irq(bool state);
+ draco_svga_irq(gb->gfxboard_intreq);
+ } else if (gb->gfxboard_intreq &&gb->gfxboard_intena) {
if (gb->board->irq == 2 && gb->gfxboard_intena != 6)
irq = 2;
else
@@ -892,7 +902,7 @@ static void init_board (struct rtggfxboard *gb)
gb->gfxmem_bank->flags |= ABFLAG_ALLOCINDIRECT | ABFLAG_PPCIOSPACE;
gb->gfxmem_bank->label = _T("*");
mapped_malloc(gb->gfxmem_bank);
- } else if (gb->board->pci) {
+ } else if (gb->board->bustype == GFXBOARD_BUSTYPE_PCI) {
// We don't know VRAM address until PCI bridge and
// PCI display card's BARs have been initialized
;
@@ -915,7 +925,7 @@ static void init_board (struct rtggfxboard *gb)
//gb->gfxmem_bank->baseaddr = gb->vram;
// restore original value because this is checked against
// configured size in expansion.cpp
- if (!gb->board->pci) {
+ if (!gb->board->bustype) {
gb->gfxmem_bank->allocated_size = rbc->rtgmem_size;
gb->gfxmem_bank->reserved_size = rbc->rtgmem_size;
}
@@ -3628,7 +3638,7 @@ void gfxboard_voodoo_lfb_endianswap(int m)
{
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
struct rtggfxboard *gb = &rtggfxboards[i];
- if (gb->active && gb->board->pci) {
+ if (gb->active && gb->board->bustype == GFXBOARD_BUSTYPE_PCI) {
if (gb->lfbbyteswapmode != m) {
gb->lfbbyteswapmode = m;
if (gb->original_pci_bank) {
@@ -3943,7 +3953,7 @@ void gfxboard_s3virge_lfb_endianswap(int m)
{
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
struct rtggfxboard *gb = &rtggfxboards[i];
- if (gb->active && gb->board->pci) {
+ if (gb->active && gb->board->bustype == GFXBOARD_BUSTYPE_PCI) {
gb->lfbbyteswapmode = m;
}
}
@@ -3952,7 +3962,7 @@ void gfxboard_s3virge_lfb_endianswap2(int m)
{
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
struct rtggfxboard *gb = &rtggfxboards[i];
- if (gb->active && gb->board->pci) {
+ if (gb->active && gb->board->bustype == GFXBOARD_BUSTYPE_PCI) {
gb->mmiobyteswapmode = m;
}
}
@@ -4473,7 +4483,7 @@ bool gfxboard_init_memory (struct autoconfig_info *aci)
gb->monswitch_keep_trying = true;
}
}
- if (gb->board->pci) {
+ if (gb->board->bustype > 0) {
aci->zorro = -1;
}
aci->parent = aci;
@@ -4481,7 +4491,7 @@ bool gfxboard_init_memory (struct autoconfig_info *aci)
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->pci) {
+ } else if (gb->board->bustype == GFXBOARD_BUSTYPE_PCI) {
static const int parent[] = { ROMTYPE_GREX, ROMTYPE_MEDIATOR, ROMTYPE_PROMETHEUS, 0 };
aci->parent_romtype = parent;
} else {
@@ -4548,7 +4558,7 @@ bool gfxboard_init_memory (struct autoconfig_info *aci)
gb->active = true;
- if (gb->board->pci) {
+ if (gb->board->bustype == GFXBOARD_BUSTYPE_PCI) {
TCHAR path[MAX_DPATH];
fetch_rompath(path, sizeof path / sizeof(TCHAR));
@@ -4583,6 +4593,28 @@ bool gfxboard_init_memory (struct autoconfig_info *aci)
gb->gfxboard_intena = 1;
return true;
}
+ if (gb->board->bustype == GFXBOARD_BUSTYPE_DRACO) {
+ gb->gfxboard_bank_memory.bget = gfxboard_bget_mem;
+ gb->gfxboard_bank_memory.bput = gfxboard_bput_mem;
+ gb->gfxboard_bank_memory.wput = gfxboard_wput_mem;
+ uaecptr start = 0x20000000;
+ gb->gfxboardmem_start = start + 0xc00000;
+ init_board(gb);
+ copyvrambank(&gb->gfxboard_bank_memory, gb->gfxmem_bank, true);
+ copyvrambank(&gb->gfxboard_bank_vram_pcem, gb->gfxmem_bank, true);
+ map_banks(&gb->gfxboard_bank_vram_pcem, gb->gfxboardmem_start >> 16, gb->gfxboard_bank_vram_pcem.allocated_size >> 16, 0);
+ map_banks(&gb->gfxboard_bank_mmio_wbs_pcem, (start + 0xb00000) >> 16, 1, 0);
+ map_banks(&gb->gfxboard_bank_special_pcem, (start + 0x000000) >> 16, 1, 0);
+ gb->pcem_vram_offset = 0x800000;
+ gb->pcem_vram_mask = 0x3fffff;
+ gb->pcem_io_mask = 0x3fff;
+ gb->pcem_mmio_offset = 0x00300000;
+ gb->pcem_mmio_mask = 0xff;
+ gb->configured_regs = gb->gfxmem_bank->start >> 16;
+ gb->gfxboard_intena = 1;
+ gb->configured_mem = 1;
+ gb->configured_regs = 1;
+ }
if (gb->rbc->rtgmem_type == GFXBOARD_ID_VGA) {
init_board(gb);
@@ -5513,7 +5545,14 @@ static void special_pcem_put(uaecptr addr, uae_u32 v, int size)
write_log(_T("PCEM SPECIAL PUT %08x %08x %d PC=%08x\n"), addr, v, size, M68K_GETPC);
#endif
- if (boardnum == GFXBOARD_ID_RETINA_Z2) {
+ if (boardnum == GFXBOARD_ID_ALTAIS_Z3) {
+
+ addr &= 0xffff;
+ if (addr >= 0x40) {
+ gfxboard_bput_io_swap_pcem(addr, v);
+ }
+
+ } else if (boardnum == GFXBOARD_ID_RETINA_Z2) {
addr &= 0x1ffff;
if (addr & 0x10000) {
@@ -5859,7 +5898,32 @@ static uae_u32 special_pcem_get(uaecptr addr, int size)
write_log(_T("PCEM SPECIAL GET %08x %d PC=%08x\n"), addr, size, M68K_GETPC);
#endif
- if (boardnum == GFXBOARD_ID_RETINA_Z2) {
+ if (boardnum == GFXBOARD_ID_ALTAIS_Z3) {
+
+ addr &= 0xffff;
+ if (addr >= 0x40) {
+ v = gfxboard_bget_io_swap_pcem(addr);
+ } else {
+ switch(addr)
+ {
+ case 3:
+ v = 2 + 4 + 8;
+ break;
+ case 7:
+ v = 19;
+ break;
+ case 11:
+ v = 0x47;
+ break;
+ case 15:
+ v = 0x54;
+ break;
+
+
+ }
+ }
+
+ } else if (boardnum == GFXBOARD_ID_RETINA_Z2) {
addr &= 0x1ffff;
if (addr & 0x10000) {
diff --git a/include/casablanca.h b/include/casablanca.h
deleted file mode 100644
index b1b15b17..00000000
--- a/include/casablanca.h
+++ /dev/null
@@ -1,2 +0,0 @@
-
-void casablanca_map_overlay(void);
diff --git a/include/cpuboard.h b/include/cpuboard.h
index 9f26ea7e..2a95a128 100644
--- a/include/cpuboard.h
+++ b/include/cpuboard.h
@@ -116,4 +116,7 @@ void cpuboard_gvpmaprom(int);
#define BOARD_HARMS 16
#define BOARD_HARMS_SUB_3KPRO 0
+#define BOARD_DRACO 17
+#define BOARD_DRACO_SUB_DRACO 0
+
#endif /* UAE_CPUBOARD_H */
diff --git a/include/draco.h b/include/draco.h
new file mode 100644
index 00000000..d98e7f77
--- /dev/null
+++ b/include/draco.h
@@ -0,0 +1,6 @@
+
+void casablanca_map_overlay(void);
+void draco_map_overlay(void);
+void draco_init(void);
+void draco_reset(void);
+
diff --git a/include/gfxboard.h b/include/gfxboard.h
index 0f8c42af..985c77a1 100644
--- a/include/gfxboard.h
+++ b/include/gfxboard.h
@@ -83,7 +83,12 @@ int pcem_getvramsize(void);
#define GFXBOARD_ID_PIXEL64 20
#define GFXBOARD_ID_RETINA_Z2 21
#define GFXBOARD_ID_RETINA_Z3 22
-#define GFXBOARD_ID_VOODOO5_PCI 23
+#define GFXBOARD_ID_ALTAIS_Z3 23
+#define GFXBOARD_ID_VOODOO5_PCI 24
+
+#define GFXBOARD_BUSTYPE_Z 0
+#define GFXBOARD_BUSTYPE_PCI 1
+#define GFXBOARD_BUSTYPE_DRACO 2
struct gfxboard_mode
{
@@ -115,5 +120,4 @@ struct gfxboard_func
GFXBOARD_CONFIGURED configured;
};
-
#endif /* UAE_GFXBOARD_H */
diff --git a/include/ncr_scsi.h b/include/ncr_scsi.h
index 324d38de..e61f147c 100644
--- a/include/ncr_scsi.h
+++ b/include/ncr_scsi.h
@@ -19,6 +19,7 @@ extern bool ncr710_a4091_autoconfig_init(struct autoconfig_info *aci);
extern bool ncr710_warpengine_autoconfig_init(struct autoconfig_info *aci);
extern bool ncr710_zeus040_autoconfig_init(struct autoconfig_info *aci);
extern bool ncr710_magnum40_autoconfig_init(struct autoconfig_info *aci);
+extern bool ncr710_draco_init(struct autoconfig_info *aci);
void cpuboard_ncr710_io_bput(uaecptr addr, uae_u32 v);
uae_u32 cpuboard_ncr710_io_bget(uaecptr addr);
@@ -38,5 +39,6 @@ extern void a4091_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct ro
extern void wildfire_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
extern void zeus040_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
extern void magnum40_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+extern void draco_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
#endif /* UAE_NCR_SCSI_H */
diff --git a/include/rommgr.h b/include/rommgr.h
index 52c39857..f166632b 100644
--- a/include/rommgr.h
+++ b/include/rommgr.h
@@ -54,6 +54,7 @@ extern int decode_cloanto_rom_do(uae_u8 *mem, int size, int real_size);
#define ROMTYPE_CB_12GAUGE 0x0004001f
#define ROMTYPE_CB_HARMS3KP 0x00040020
#define ROMTYPE_CB_A1230S1 0x00040021
+#define ROMTYPE_CB_DRACO 0x00040022
#define ROMTYPE_FREEZER 0x00080000
#define ROMTYPE_AR 0x00080001
@@ -207,6 +208,7 @@ extern int decode_cloanto_rom_do(uae_u8 *mem, int size, int real_size);
#define ROMTYPE_CSMK1SCSI 0x0010008d
#define ROMTYPE_GVPA1208 0x0010008e
#define ROMTYPE_DSP3210 0x0010008f
+#define ROMTYPE_ALTAIS 0x00100090
#define ROMTYPE_NOT 0x00800000
#define ROMTYPE_QUAD 0x01000000
diff --git a/include/x86.h b/include/x86.h
index 208388f1..ee2ba110 100644
--- a/include/x86.h
+++ b/include/x86.h
@@ -17,4 +17,11 @@ void x86_mouse(int port, int x, int y, int z, int b);
int is_x86_cpu(struct uae_prefs*);
+typedef void (*X86_INTERRUPT_CALLBACK)(int,bool);
+
+uae_u8 x86_infloppy(int portnum);
+void x86_outfloppy(int portnum, uae_u8 v);
+void x86_initfloppy(X86_INTERRUPT_CALLBACK);
+void x86_floppy_run(void);
+
#endif /* UAE_X86_H */
diff --git a/memory.cpp b/memory.cpp
index 951f4ad6..0416e652 100644
--- a/memory.cpp
+++ b/memory.cpp
@@ -41,7 +41,7 @@
#include "uae/ppc.h"
#include "devices.h"
#include "inputdevice.h"
-#include "casablanca.h"
+#include "draco.h"
bool canbang;
uaecptr highest_ram;
@@ -2536,7 +2536,11 @@ static void allocate_memory (void)
a3000hmem_bank.reserved_size = currprefs.mbresmem_high.size;
a3000hmem_bank.mask = a3000hmem_bank.reserved_size - 1;
- a3000hmem_bank.start = 0x08000000;
+ if (currprefs.cs_compatible == CP_DRACO) {
+ a3000hmem_bank.start = 0x40000000;
+ } else {
+ a3000hmem_bank.start = 0x08000000;
+ }
if (a3000hmem_bank.reserved_size) {
if (!mapped_malloc (&a3000hmem_bank)) {
write_log (_T("Out of memory for a3000highmem.\n"));
@@ -2688,6 +2692,10 @@ void map_overlay (int chip)
casablanca_map_overlay();
return;
}
+ if (currprefs.cs_compatible == CP_DRACO) {
+ draco_map_overlay();
+ return;
+ }
size = chipmem_bank.allocated_size >= 0x180000 ? (chipmem_bank.allocated_size >> 16) : 32;
if (bogomem_aliasing)
@@ -3550,11 +3558,23 @@ void restore_banks(void)
}
}
+static void map_banks_draco(addrbank *bank, int start, int size, int realsize)
+{
+ // draco has Z2 space mapped at 0x03e80000-0x03fffff
+ if (start >= 0xe8 && start < 0xf0) {
+ map_banks(bank, 0x0300 + start, size, realsize);
+ }
+}
+
void map_banks (addrbank *bank, int start, int size, int realsize)
{
if (start == 0xffffffff)
return;
+ if (currprefs.cs_compatible == CP_DRACO) {
+ map_banks_draco(bank, start, size, realsize);
+ }
+
#ifdef JIT
if ((bank->jit_read_flag | bank->jit_write_flag) & S_N_ADDR) {
jit_n_addr_unsafe = 1;
diff --git a/ncr_scsi.cpp b/ncr_scsi.cpp
index d84c1ceb..f6835134 100644
--- a/ncr_scsi.cpp
+++ b/ncr_scsi.cpp
@@ -1074,6 +1074,29 @@ bool ncr710_magnum40_autoconfig_init(struct autoconfig_info *aci)
return true;
}
+bool ncr710_draco_init(struct autoconfig_info *aci)
+{
+ device_add_reset(ncr_reset);
+ if (!aci->doinit) {
+ return true;
+ }
+
+ struct ncr_state *ncr = getscsi(aci->rc);
+ if (!ncr)
+ return false;
+
+ ncr->enabled = true;
+ ncr->io_start = 0;
+ ncr->io_end = 0xffff;
+ ncr->io_mask = 0x7f;
+
+ ncr_reset_board(ncr);
+
+ aci->addrbank = &ncr_bank_generic;
+ return true;
+}
+
+
static void allocscsidevice(struct ncr_state *ncr, int ch, struct scsi_data *handle, int uae_unitnum)
{
handle->privdata = ncr;
@@ -1223,4 +1246,14 @@ void magnum40_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romcon
ncr_magnum40->z2 = true;
}
+extern void draco_set_scsi_irq(int, int);
+
+void draco_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
+{
+ ncr_add_scsi_unit(&ncr_cpuboard, ch, ci, rc, false);
+ ncr_cpuboard->irq_func = draco_set_scsi_irq;
+ ncr_cpuboard->irqlevel = true;
+ ncr_cpuboard->bank = &ncr_bank_generic;
+}
+
#endif
diff --git a/od-win32/sysconfig.h b/od-win32/sysconfig.h
index 62499a03..3bbf51cf 100644
--- a/od-win32/sysconfig.h
+++ b/od-win32/sysconfig.h
@@ -118,6 +118,7 @@
#define FLOPPYBRIDGE
#define WITH_MIDIEMU
#define WITH_DSP
+#define WITH_DRACO
#else
diff --git a/od-win32/winuae_msvc15/winuae_msvc.vcxproj b/od-win32/winuae_msvc15/winuae_msvc.vcxproj
index 4d4fcd2a..5782f181 100644
--- a/od-win32/winuae_msvc15/winuae_msvc.vcxproj
+++ b/od-win32/winuae_msvc15/winuae_msvc.vcxproj
@@ -1305,7 +1305,7 @@
-
+
diff --git a/od-win32/winuae_msvc15/winuae_msvc.vcxproj.filters b/od-win32/winuae_msvc15/winuae_msvc.vcxproj.filters
index 5e358ac8..50433bf1 100644
--- a/od-win32/winuae_msvc15/winuae_msvc.vcxproj.filters
+++ b/od-win32/winuae_msvc15/winuae_msvc.vcxproj.filters
@@ -820,7 +820,7 @@
common
-
+
common
diff --git a/pcem/serial.cpp b/pcem/serial.cpp
index 570da45f..30dc5f56 100644
--- a/pcem/serial.cpp
+++ b/pcem/serial.cpp
@@ -299,3 +299,13 @@ void serial2_remove()
{
io_removehandler(serial2.addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
}
+
+void draco_serial_init(void **s1, void **s2)
+{
+ serial_reset();
+ serial1.has_fifo = 1;
+ serial2.has_fifo = 1;
+ *s1 = &serial1;
+ *s2 = &serial2;
+}
+
diff --git a/rommgr.cpp b/rommgr.cpp
index 1045e5d3..910356ad 100644
--- a/rommgr.cpp
+++ b/rommgr.cpp
@@ -97,7 +97,7 @@ struct romdata *getromdatabypath (const TCHAR *path)
return NULL;
}
-#define NEXT_ROM_ID 311
+#define NEXT_ROM_ID 312
#if NEXT_ROM_ID >= MAX_ROMMGR_ROMS
#error Increase MAX_ROMMGR_ROMS!
@@ -299,6 +299,8 @@ static struct romdata roms[] = {
ALTROMPN(231, 1, 2, 524288, ROMTYPE_ODD , _T("74095 00 717 02 02 U5"), 0x6ccb0431, 0xa2a43444,0xbeda38be,0x1fa5cabe,0x75fc4def,0x063bcd7a)
{ _T("DraCo Boot ROM v1.3"), 1, 3, 1, 3, _T("DRACO\0"), 131072, 234, 2 | 4, 0, ROMTYPE_EXTCDTV, 0, 0, NULL,
0x0e9c5899,0x82151324,0x01207554,0x60c8a068,0x4793ec18,0x3f744d74, NULL, NULL, 4 },
+ { _T("DraCo Boot ROM v1.5"), 1, 5, 1, 5, _T("DRACO\0"), 131072, 311, 2 | 4, 0, ROMTYPE_EXTCDTV, 0, 0, NULL,
+ 0x0f2959d5,0xe8fd5d15,0x08797693,0x99f1df97,0x2fe792fd,0x8146cf1d, NULL, NULL, 4 },
{ _T("CD32 KS ROM v3.1"), 3, 1, 40, 60, _T("CD32\0"), 524288, 18, 1, 0, ROMTYPE_KICKCD32, 0, 0, NULL,
0x1e62d4a5, 0x3525BE88,0x87F79B59,0x29E017B4,0x2380A79E,0xDFEE542D, NULL, NULL, 1 },
diff --git a/x86.cpp b/x86.cpp
index 6093e107..074feef5 100644
--- a/x86.cpp
+++ b/x86.cpp
@@ -19,7 +19,7 @@
#define X86_DEBUG_BRIDGE_IRQ 0
#define X86_IO_PORT_DEBUG 0
#define X86_DEBUG_SPECIAL_IO 0
-#define FLOPPY_DEBUG 0
+#define FLOPPY_DEBUG 1
#define EMS_DEBUG 0
#define DEBUG_DMA 0
@@ -199,6 +199,8 @@ struct x86_bridge
bool vlsi_config;
int a2386flipper;
bool a2386_amigapcdrive;
+
+ X86_INTERRUPT_CALLBACK irq_callback;
};
static int x86_found;
@@ -528,15 +530,21 @@ void x86_ack_keyboard(void)
void x86_clearirq(uint8_t irqnum)
{
struct x86_bridge *xb = bridges[0];
-
- picintc(1 << irqnum);
+ if (xb->irq_callback) {
+ xb->irq_callback(irqnum, false);
+ } else {
+ picintc(1 << irqnum);
+ }
}
void x86_doirq(uint8_t irqnum)
{
struct x86_bridge *xb = bridges[0];
-
- picint(1 << irqnum);
+ if (xb->irq_callback) {
+ xb->irq_callback(irqnum, true);
+ } else {
+ picint(1 << irqnum);
+ }
}
struct pc_floppy
@@ -1049,10 +1057,16 @@ static void floppy_do_cmd(struct x86_bridge *xb)
}
break;
+ case 16:
+ floppy_status[0] = 0x90;
+ floppy_cmd_len = 1;
+ break;
+
default:
floppy_status[0] = 0x80;
floppy_cmd_len = 1;
break;
+
}
end:
@@ -1072,6 +1086,8 @@ end:
}
}
+static int draco_force_irq;
+
static void outfloppy(struct x86_bridge *xb, int portnum, uae_u8 v)
{
switch (portnum)
@@ -1096,6 +1112,9 @@ static void outfloppy(struct x86_bridge *xb, int portnum, uae_u8 v)
}
#endif
floppy_dpc = v;
+ if (xb->type < 0 && 1) {
+ floppy_dpc |= 8;
+ }
floppy_num = v & 3;
for (int i = 0; i < 2; i++) {
disk_reserved_setinfo(0, floppy_pc[i].cyl, floppy_pc[i].head, floppy_selected() == i);
@@ -1104,6 +1123,7 @@ static void outfloppy(struct x86_bridge *xb, int portnum, uae_u8 v)
case 0x3f5: // data reg
floppy_cmd[floppy_idx] = v;
if (floppy_idx == 0) {
+ floppy_cmd_len = -1;
switch(v & 31)
{
case 3: // specify
@@ -1127,16 +1147,31 @@ static void outfloppy(struct x86_bridge *xb, int portnum, uae_u8 v)
case 10: // read id
floppy_cmd_len = 2;
break;
+ case 12: // perpendiculaor mode
+ if (xb->type < 0) {
+ floppy_cmd_len = 2;
+ }
+ break;
case 13: // format track
floppy_cmd_len = 6;
break;
case 15: // seek
floppy_cmd_len = 3;
break;
- default:
+ case 16: // get versionm
+ if (xb->type < 0) {
+ floppy_cmd_len = 1;
+ }
+ break;
+ case 19: // configure
+ if (xb->type < 0) {
+ floppy_cmd_len = 4;
+ }
+ break;
+ }
+ if (floppy_cmd_len < 0) {
write_log(_T("Floppy unimplemented command %02x\n"), v);
floppy_cmd_len = 1;
- break;
}
}
floppy_idx++;
@@ -1168,6 +1203,30 @@ static uae_u8 infloppy(struct x86_bridge *xb, int portnum)
uae_u8 v = 0;
switch (portnum)
{
+ case 0x3f0: // PS/2 status A (draco)
+ if (xb->type < 0) {
+ struct floppy_reserved fr = { 0 };
+ bool valid_floppy = disk_reserved_getinfo(floppy_num, &fr);
+ v |= floppy_irq ? 0x80 : 0x00;
+ v |= 0x40;
+ v |= fr.wrprot ? 0 : 2;
+ v |= fr.cyl == 0 ? 0 : 16;
+ }
+ break;
+ case 0x3f1: // PS/2 status B (draco)
+ if (xb->type < 0) {
+ v |= 0x80 | 0x40;
+ if (floppy_dpc & 1)
+ v |= 0x20;
+ if ((floppy_dpc >> 4) & 1)
+ v |= 0x01;
+ if ((floppy_dpc >> 4) & 2)
+ v |= 0x02;
+ }
+ break;
+ case 0x3f2:
+ v = floppy_dpc;
+ break;
case 0x3f4: // main status
v = 0;
if (!floppy_delay_hsync && (floppy_dpc & 4))
@@ -4037,3 +4096,29 @@ bool isa_expansion_init(struct autoconfig_info *aci)
aci->zorro = 0;
return true;
}
+
+void x86_outfloppy(int portnum, uae_u8 v)
+{
+ struct x86_bridge *b = bridges[0];
+ outfloppy(b, portnum, v);
+}
+uae_u8 x86_infloppy(int portnum)
+{
+ struct x86_bridge *b = bridges[0];
+ return infloppy(b, portnum);
+}
+void x86_floppy_run(void)
+{
+ check_floppy_delay();
+}
+void x86_initfloppy(X86_INTERRUPT_CALLBACK irq_callback)
+{
+ struct x86_bridge *xb = bridges[0];
+ if (!xb) {
+ xb = x86_bridge_alloc();
+ bridges[0] = xb;
+ }
+ xb->type = -1;
+ xb->irq_callback = irq_callback;
+ floppy_hardreset();
+}