]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
X-Surf IDE port emulation
authorToni Wilen <twilen@winuae.net>
Mon, 5 Jan 2026 17:48:47 +0000 (19:48 +0200)
committerToni Wilen <twilen@winuae.net>
Mon, 5 Jan 2026 17:48:47 +0000 (19:48 +0200)
expansion.cpp
idecontrollers.cpp
include/idecontrollers.h
qemuvga/ne2000.cpp

index 4d5fb4ee01737b64eebcccbdce89dbe9a3897d28..ad52e506292d9b0b1f4b12ffef6ba0d40455005b 100644 (file)
@@ -5079,6 +5079,12 @@ void ethernet_updateselection(void)
        }
 }
 
+static bool xsurf_init_common(struct autoconfig_info *aci)
+{
+       xsurf_init_ide(aci);
+       return xsurf_init(aci);
+}
+
 static void fastlane_memory_callback(struct romconfig *rc, uae_u8 *ac, int size)
 {
        struct zfile *z = read_device_from_romconfig(rc, NULL);
@@ -6365,11 +6371,11 @@ const struct expansionromtype expansionroms[] = {
        },
        {
                _T("xsurf"), _T("X-Surf"), _T("Individual Computers"),
-               NULL, xsurf_init, NULL, NULL, ROMTYPE_XSURF | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true,
+               NULL, xsurf_init_common, NULL, xsurf_add_ide_unit, ROMTYPE_XSURF | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true,
                NULL, 0,
-               false, EXPANSIONTYPE_NET,
+               false, EXPANSIONTYPE_NET | EXPANSIONTYPE_IDE,
                0, 0, 0, false, NULL,
-               false, 0, ethernet_settings,
+               false, 2, ethernet_settings,
                { 0xc1, 0x17, 0x00, 0x00, 4626 >> 8, 4626 & 255, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
        },
        {
index 7d764658f007525fb1275ad33a36f07378eace65..a666aceb37e55944e9a663d32eb607e7cae99fba 100644 (file)
@@ -59,7 +59,8 @@
 #define DOTTO_IDE (TANDEM_IDE + MAX_DUPLICATE_EXPANSION_BOARDS)
 #define DEV_IDE (DOTTO_IDE + MAX_DUPLICATE_EXPANSION_BOARDS)
 #define RIPPLE_IDE (DEV_IDE + MAX_DUPLICATE_EXPANSION_BOARDS)
-#define TOTAL_IDE (RIPPLE_IDE + 2 * MAX_DUPLICATE_EXPANSION_BOARDS)
+#define XSURF_IDE (RIPPLE_IDE + 2 * MAX_DUPLICATE_EXPANSION_BOARDS)
+#define TOTAL_IDE (XSURF_IDE + MAX_DUPLICATE_EXPANSION_BOARDS)
 
 #define ALF_ROM_OFFSET 0x0100
 #define GVP_IDE_ROM_OFFSET 0x8000
@@ -126,6 +127,7 @@ static struct ide_board *tandem_board[MAX_DUPLICATE_EXPANSION_BOARDS];
 static struct ide_board *dotto_board[MAX_DUPLICATE_EXPANSION_BOARDS];
 static struct ide_board *dev_board[MAX_DUPLICATE_EXPANSION_BOARDS];
 static struct ide_board *ripple_board[MAX_DUPLICATE_EXPANSION_BOARDS];
+static struct ide_board *xsurf_board[MAX_DUPLICATE_EXPANSION_BOARDS];
 
 static struct ide_hdf *idecontroller_drive[TOTAL_IDE * 2];
 static struct ide_thread_state idecontroller_its;
@@ -517,6 +519,19 @@ static int get_buddha_reg(uaecptr addr, struct ide_board *board, int *portnum, i
        return reg;
 }
 
+static int get_xsurf_reg(uaecptr addr, struct ide_board *board, int *portnum)
+{
+       int reg = -1;
+       if ((addr & 0xf000) == 0xb000) {
+               *portnum = 0;
+               reg = (addr >> 2) & 7;
+       } else if ((addr & 0xf000) == 0xd000) {
+               *portnum = 1;
+               reg = (addr >> 2) & 7;
+       }
+       return reg;
+}
+
 static int get_rochard_reg(uaecptr addr, struct ide_board *board, int *portnum)
 {
        int reg = -1;
@@ -723,6 +738,19 @@ static uae_u32 ide_read_byte2(struct ide_board *board, uaecptr addr)
                        v = board->rom[offset];
                }
 
+       } else if (board->type == XSURF_IDE) {
+
+               int portnum;
+               int regnum = get_xsurf_reg(addr, board, &portnum);
+               if (regnum >= 0) {
+                       if (board->ide[portnum]) {
+                               v = get_ide_reg_multi(board, regnum, portnum, 1);
+                       }
+               } else if ((addr & 0x80ff) == 0x7e) {
+                       v = ide_irq_check(board->ide[0], false) ? 0x80 : 0x00;
+                       v |= ide_irq_check(board->ide[1], false) ? 0x80 : 0x00;
+               }
+
        } else if (board->type == ALF_IDE || board->type == TANDEM_IDE) {
 
                if (addr < 0x1100 || (addr & 1)) {
@@ -1203,6 +1231,20 @@ static uae_u32 ide_read_word(struct ide_board *board, uaecptr addr)
 #endif
                        }
 
+               } else if (board->type == XSURF_IDE) {
+
+                       int portnum;
+                       int regnum = get_xsurf_reg(addr, board, &portnum);
+                       if (regnum >= 0) {
+                               if (regnum == IDE_DATA) {
+                                       if (board->ide[portnum])
+                                               v = get_ide_reg_multi(board, IDE_DATA, portnum, 1);
+                               } else {
+                                       v = ide_read_byte(board, addr) << 8;
+                                       v |= ide_read_byte(board, addr + 1);
+                               }
+                       }
+
                } else if (board->type == GOLEMFAST_IDE) {
 
                        if ((addr & 0x8700) == 0x8100) {
@@ -1578,6 +1620,16 @@ static void ide_write_byte(struct ide_board *board, uaecptr addr, uae_u8 v)
                                board->flashenabled = false;
                        }
 
+               } else if (board->type == XSURF_IDE) {
+
+                       int portnum;
+                       int regnum = get_xsurf_reg(addr, board, &portnum);
+                       if (regnum >= 0) {
+                               if (board->ide[portnum]) {
+                                       put_ide_reg_multi(board, regnum, v, portnum, 1);
+                               }
+                       }
+
                } else  if (board->type == ALF_IDE || board->type == TANDEM_IDE) {
 
                        int regnum = get_alf_reg(addr, board);
@@ -1919,6 +1971,19 @@ static void ide_write_word(struct ide_board *board, uaecptr addr, uae_u16 v)
 #endif
                        }
 
+               } else if (board->type == XSURF_IDE) {
+
+                       int portnum;
+                       int regnum = get_xsurf_reg(addr, board, &portnum);
+                       if (regnum >= 0) {
+                               if (regnum == IDE_DATA) {
+                                       if (board->ide[portnum])
+                                               put_ide_reg_multi(board, IDE_DATA, v, portnum, 1);
+                               } else {
+                                       ide_write_byte(board, addr, v >> 8);
+                                       ide_write_byte(board, addr + 1, (uae_u8)v);
+                               }
+                       }
 
                } else if (board->type == GOLEMFAST_IDE) {
 
@@ -3366,6 +3431,59 @@ void ripple_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig
        add_ide_standard_unit(ch, ci, rc, ripple_board, RIPPLE_IDE, false, false, 4);
 }
 
+bool xsurf_init_ide(struct autoconfig_info *aci)
+{
+       // xsurf_init() handles autoconfig stuff
+
+       ide_add_reset();
+       if (!aci->doinit) {
+               return true;
+       }
+
+       struct ide_board *ide = getide(aci);
+       if (!ide)
+               return false;
+
+       ide->bank = &ide_bank_generic;
+       ide->type = XSURF_IDE;
+       ide->configured = 1;
+       ide->baseaddress = aci->start;
+       ide->mask = 0xffff;
+       ide->intena = true;
+
+       aci->addrbank = ide->bank;
+       return true;
+}
+
+void xsurf_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
+{
+       add_ide_standard_unit(ch, ci, rc, xsurf_board, XSURF_IDE, false, false, 4);
+}
+
+uae_u32 xsurf_ide_read(uaecptr addr, int size)
+{
+       if (size == 1) {
+               return ide_generic_bget(addr);
+       } else if (size == 2) {
+               return ide_generic_wget(addr);
+       } else {
+               uae_u32 v = ide_generic_wget(addr) << 16;
+               v |= ide_generic_wget(addr + 2);
+               return v;
+       }
+}
+void xsurf_ide_write(uaecptr addr, int size, uae_u32 val)
+{
+       if (size == 1) {
+               ide_generic_bput(addr, val);
+       } else if (size == 2) {
+               ide_generic_wput(addr, val);
+       } else {
+               ide_generic_wput(addr, val >> 16);
+               ide_generic_wput(addr + 2, val & 0xffff);
+       }
+}
+
 #ifdef WITH_X86
 extern void x86_xt_ide_bios(struct zfile*, struct romconfig*);
 static bool x86_at_hd_init(struct autoconfig_info *aci, int type)
index f21aa5b2cab95eb84dd4420b7c25ae044d6e2e3c..5e03248a141845603681921c1b8dd08ce6bb1ba3 100644 (file)
@@ -70,6 +70,11 @@ bool dev_hd_init(struct autoconfig_info* aci);
 void ripple_add_ide_unit(int ch, struct uaedev_config_info* ci, struct romconfig* rc);
 bool ripple_init(struct autoconfig_info* aci);
 
+void xsurf_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+bool xsurf_init_ide(struct autoconfig_info *aci);
+uae_u32 xsurf_ide_read(uaecptr addr, int size);
+void xsurf_ide_write(uaecptr addr, int size, uae_u32 val);
+
 uae_u32 REGPARAM3 apollo_ide_lget (uaecptr addr) REGPARAM;
 uae_u32 REGPARAM3 apollo_ide_wget (uaecptr addr) REGPARAM;
 uae_u32 REGPARAM3 apollo_ide_bget (uaecptr addr) REGPARAM;
index dbfe3598db0d2a3957436756e01854ed6ffcffaa..89f2ad63b8b6b1746402221ea90dcc5ce0ba4359 100644 (file)
@@ -36,6 +36,7 @@
 #include "debug.h"
 #include "sana2.h"
 #include "devices.h"
+#include "idecontrollers.h"
 
 #include "qemuuaeglue.h"
 #include "queue.h"
@@ -1609,6 +1610,7 @@ static uae_u8 isapnp_read_data(struct isapnp *pnp)
 
 static int toariadne2(struct ne2000_s *ne, uaecptr addr, uae_u32 *vp, int size, bool *bs)
 {
+       uaecptr orgaddr = addr;
        addr &= 0xffff;
        *bs = false;
        uae_u32 v = *vp;
@@ -1694,14 +1696,20 @@ static int toariadne2(struct ne2000_s *ne, uaecptr addr, uae_u32 *vp, int size,
                        return addr;
                }
        } else if (ne->ne2000_romtype == ROMTYPE_XSURF) {
-               if (addr == 0x7e && size == -1) {
-                       ne->flags &= ~1;
-                       ne->flags |= (v & 0x80) ? 1 : 0;
+               if ((addr & 0x80ff) == 0x007e) {
+                       if (size == -1) {
+                               ne->flags &= ~1;
+                               ne->flags |= (v & 0x80) ? 1 : 0;
+                       } else if (size == 1) {
+                               *vp = xsurf_ide_read(orgaddr, size);
+                       } else if (size == 2) {
+                               *vp = xsurf_ide_read(orgaddr, 1) << 8;
+                       }
                } else if (addr == 0xf00) {
                        // driver uses this (undocumented) address to detect if X-Surf or X-Surf 100!
                        *vp = 0xff;
                        return -1;
-               } else if (addr >= 0x40 && addr < 0x8000) {
+               } else if ((addr & 0x80ff) == 0x0040) {
                        *vp = ne->ariadne2_irq ? ((1 << 5) | (1 << 7)) : 0;
                        return -1;
                }
@@ -1723,6 +1731,14 @@ static int toariadne2(struct ne2000_s *ne, uaecptr addr, uae_u32 *vp, int size,
                                return isa_addr;
                        }
                }
+               if ((addr >= 0xb000 && addr < 0xc000) || (addr >= 0xd000 && addr < 0xe000)) {
+                       if (size > 0) {
+                               *vp = xsurf_ide_read(orgaddr, size);
+                       } else {
+                               xsurf_ide_write(orgaddr, -size, *vp);
+                       }
+                       return -1;
+               }
        } else if (ne->ne2000_romtype == ROMTYPE_XSURF100Z2 || ne->ne2000_romtype == ROMTYPE_XSURF100Z3) {
                int bank = addr >> 8;
                int baddr = addr & 255;