]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
SupraDrive 2000 DMA emulation, preliminary Kupke Golem emulation.
authorToni Wilen <twilen@winuae.net>
Fri, 27 Feb 2015 16:17:36 +0000 (18:17 +0200)
committerToni Wilen <twilen@winuae.net>
Fri, 27 Feb 2015 16:17:36 +0000 (18:17 +0200)
include/rommgr.h
include/scsi.h
rommgr.cpp
scsi.cpp

index 7ed659a5112306fe5ac7142059d7e43977523035..9b1e4f2bec1b5174987f90ca76c7fc9423ba935b 100644 (file)
@@ -56,6 +56,7 @@ extern int decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size);
 #define ROMTYPE_MASOBOSHI      0x0010000d
 #define ROMTYPE_SUPRA          0x0010000e
 #define ROMTYPE_A2090          0x0010000f
+#define ROMTYPE_GOLEM          0x00100010
 
 #define ROMTYPE_QUAD           0x01000000
 #define ROMTYPE_EVEN           0x02000000
index 72b7d776ec802bed22b783ce2e626e918c53041c..3c8848a0b3953fde4c848f4398030cff3cb247fb 100644 (file)
@@ -160,3 +160,5 @@ void ncr5380scsi_reset(void);
 addrbank *supra_init(int devnum);
 int supra_add_scsi_unit(int ch, struct uaedev_config_info *ci);
 
+addrbank *golem_init(int devnum);
+int golem_add_scsi_unit(int ch, struct uaedev_config_info *ci);
index eb460abeb09729a4cf4337a5cff8b0c58043e775..5172368bc3d15945cfd00a1cfb66c47f935baf18 100644 (file)
@@ -95,7 +95,7 @@ struct romdata *getromdatabypath (const TCHAR *path)
        return NULL;
 }
 
-#define NEXT_ROM_ID 124
+#define NEXT_ROM_ID 126
 
 static struct romheader romheaders[] = {
        { _T("Freezer Cartridges"), 1 },
@@ -121,6 +121,13 @@ static struct romdata roms[] = {
        { _T("Cloanto Amiga Forever 2010 ROM key"), 0, 0, 0, 0, 0, 1544, 73, 0, 1, ROMTYPE_KEY, 0, 0, NULL,
        0x8c4dd05c, 0x05034f62,0x0b5bb7b2,0x86954ea9,0x164fdb90,0xfb2897a4 },
 
+       { _T("KS ROM Velvet 23.93"), 23, 93, 23, 93, _T("VELVET\0"), 131072, 125, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
+       0xadcb44c9, 0x7c36b2ba,0x298da3da,0xce60d0ba,0x8511d470,0x76a40d5c, NULL, NULL },
+       ALTROMPN(125, 1, 1, 32768, ROMTYPE_QUAD | ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x1d988ab8, 0xee3988a2, 0xb2693334, 0x0239d1d9, 0xf50d4fb3, 0xe0daf3bc)
+       ALTROMPN(125, 1, 2, 32768, ROMTYPE_QUAD | ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xe466b28f, 0x3e197d69, 0xcffa3e1a, 0x0c291d57, 0xb53f7d1f, 0xcb858cf7)
+       ALTROMPN(125, 1, 3, 32768, ROMTYPE_QUAD | ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x715988a9, 0x08c36600, 0x3948c4c5, 0x4216ef8c, 0x17ebe16c, 0xc91d3b7a)
+       ALTROMPN(125, 1, 4, 32768, ROMTYPE_QUAD | ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xc4dc7e6a, 0x66b231d0, 0x8425c858, 0xdfcd36d2, 0xd38a0df8, 0x518e06a4)
+
        { _T("KS ROM v1.0 (A1000)(NTSC)"), 1, 0, 1, 0, _T("A1000\0"), 262144, 1, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
        0x299790ff, 0x00C15406,0xBEB4B8AB,0x1A16AA66,0xC05860E1,0xA7C1AD79 },
        { _T("KS ROM v1.1 (A1000)(NTSC)"), 1, 1, 31, 34, _T("A1000\0"), 262144, 2, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
@@ -354,6 +361,10 @@ static struct romdata roms[] = {
        { _T("GVP A3001 Series I ROM"), 3, 3, 3, 3, _T("A3001SI\0"), 8192, 114, 0, 0, ROMTYPE_CB_A3001S1, 0, 0, NULL,
        0xaaff7c65, 0x424cf3da,0xcc9da794,0x0ba74446,0x69dd1691,0x44ae87ee, NULL, NULL },
 
+       { _T("Kupke Golem v3.9 ROM"), 3, 9, 3, 9, _T("GOLEM\0"), 16384, 124, 0, 0, ROMTYPE_GOLEM, 0, 0, NULL,
+       0x49157dd0, 0x03b615c9,0x2befa474,0xa37303ca,0xdc3e830d,0x3c0d9a9f, NULL, NULL },
+       ALTROMPN(124, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x713298ad, 0x2ad7d6f3, 0xd696fd2c, 0x51a256ee, 0xea185c47, 0x52906e04)
+       ALTROMPN(124, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x88cf2ec5, 0x59680f8d, 0xae520893, 0xff9ada35, 0xac9a1146, 0x4f87453c)
        { _T("GVP Series I v1.0 ROM"), 1, 0, 1, 16, _T("GVPI\0"), 16384, 123, 0, 0, ROMTYPE_GVPS1, 0, 0, NULL,
        0x1a4c20aa, 0xb9a3377e,0x2d9b5163,0x28693c63,0x19ffb65b,0x40ae3618, NULL, NULL },
        ALTROMPN(123, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xa723193e, 0x05b4a072, 0x785c7824, 0x54e003c3, 0x6d88bd9b, 0xf5f561b9)
@@ -1299,10 +1310,21 @@ struct zfile *read_rom (struct romdata *prd)
                                add = 1;
                                i++;
                        } else if (flags & ROMTYPE_QUAD) {
-                               for (int k = 0; k < 4; k++) {
-                                       read_rom_file (buf2, rd2 + k + 1);
-                                       for (j = 0; j < size; j += 4)
-                                               buf[j + k] = buf2[j / 4];
+                               if (i == 0) {
+                                       for (int k = 0; k < 4; k++) {
+                                               read_rom_file (buf2, rd2 + k + 1);
+                                               for (j = 0; j < size; j += 4)
+                                                       buf[j + k] = buf2[j / 4];
+                                       }
+                               } else {
+                                       for (int kk = 0; kk < 2; kk++) {
+                                               for (int k = 0; k < 2; k++) {
+                                                       read_rom_file (buf2, rd2 + k + kk * 2 + 1);
+                                                       for (j = 0; j < size / 2; j += 2) {
+                                                               buf[j + k + kk * (rd2->size / 2)] = buf2[j / 2];
+                                                       }
+                                               }
+                                       }
                                }
                                add = 4;
                        } else {
index 30df2ecb631a2e696894426c2e2db92d3ba4dd92..76a8f295eac0d6ac3c91fcba5928fa7d8af66c00 100644 (file)
--- a/scsi.cpp
+++ b/scsi.cpp
@@ -27,6 +27,7 @@
 #define NCR5380_DEBUG 0
 
 #define NCR5380_SUPRA 1
+#define NONCR_GOLEM 2
 
 extern int log_scsiemu;
 
@@ -562,6 +563,11 @@ struct ncr5380_scsi
        int type;
        int subtype;
        int dma_direction;
+
+       int dmac_direction;
+       uaecptr dmac_address;
+       int dmac_length;
+       int dmac_active;
 };
 
 void raw_scsi_reset(struct raw_scsi *rs)
@@ -880,14 +886,49 @@ void apolloscsi_reset(void)
 
 
 static struct ncr5380_scsi suprascsi[2];
+static struct ncr5380_scsi golemscsi[2];
 
 static struct ncr5380_scsi *ncr5380devices[] =
 {
        &suprascsi[0],
        &suprascsi[1],
+       &golemscsi[0],
+       &golemscsi[1],
        NULL
 };
 
+uae_u8 ncr5380_bget(struct ncr5380_scsi *scsi, int reg);
+void ncr5380_bput(struct ncr5380_scsi *scsi, int reg, uae_u8 v);
+
+static void supra_do_dma(struct ncr5380_scsi *ncr)
+{
+       int len = ncr->dmac_length;
+       for (int i = 0; i < len; i++) {
+               if (ncr->dmac_direction < 0) {
+                       x_put_byte(ncr->dmac_address, ncr5380_bget(ncr, 0));
+               } else if (ncr->dmac_direction > 0) {
+                       ncr5380_bput(ncr, 0, x_get_byte(ncr->dmac_address));
+               }
+               ncr->dmac_length--;
+               ncr->dmac_address++;
+       }
+}
+
+static void dma_check(struct ncr5380_scsi *ncr)
+{
+       if (ncr->dmac_active && ncr->dma_direction) {
+               if (ncr->type ==NCR5380_SUPRA && ncr->subtype == 4) {
+                       if (ncr->dmac_direction != ncr->dma_direction)  {
+                               write_log(_T("SUPRADMA: mismatched direction\n"));
+                               ncr->dmac_active = 0;
+                               return;
+                       }
+                       supra_do_dma(ncr);
+               }
+               ncr->dmac_active = 0;
+       }
+}
+
 // NCR 53C80
 
 void ncr80_rethink(void)
@@ -1012,9 +1053,11 @@ void ncr5380_bput(struct ncr5380_scsi *scsi, int reg, uae_u8 v)
                break;
                case 5:
                scsi->regs[reg] = old;
+               scsi->dma_direction = 1;
 #if NCR5380_DEBUG
                write_log(_T("DMA send\n"));
 #endif
+               dma_check(scsi);
                break;
                case 6:
                scsi->dma_direction = 1;
@@ -1027,6 +1070,7 @@ void ncr5380_bput(struct ncr5380_scsi *scsi, int reg, uae_u8 v)
 #if NCR5380_DEBUG
                write_log(_T("DMA initiator recv\n"));
 #endif
+               dma_check(scsi);
                break;
        }
        ncr5380_check_phase(scsi);
@@ -1058,6 +1102,63 @@ static int suprareg(struct ncr5380_scsi *ncr, uaecptr addr, bool write)
        return reg;
 }
 
+static uae_u8 read_supra_dma(struct ncr5380_scsi *ncr, uaecptr addr)
+{
+       uae_u8 val = 0;
+
+       addr &= 0x1f;
+       switch (addr)
+       {
+               case 0:
+               val = ncr->dmac_active ? 0x00 : 0x80;
+               break;
+               case 4:
+               val = 0;
+               break;
+       }
+
+       write_log(_T("SUPRA DMA GET %08x %02x %08x\n"), addr, val, M68K_GETPC);
+       return val;
+}
+
+static void write_supra_dma(struct ncr5380_scsi *ncr, uaecptr addr, uae_u8 val)
+{
+       write_log(_T("SUPRA DMA PUT %08x %02x %08x\n"), addr, val, M68K_GETPC);
+
+       addr &= 0x1f;
+       switch (addr)
+       {
+               case 5: // OCR
+               ncr->dmac_direction = (val & 0x80) ? -1 : 1;
+               break;
+               case 7:
+               ncr->dmac_active = (val & 0x80) != 0;
+               break;
+               case 10: // MTCR
+               ncr->dmac_length &= 0x000000ff;
+               ncr->dmac_length |= val << 8;
+               break;
+               case 11: // MTCR
+               ncr->dmac_length &= 0x0000ff00;
+               ncr->dmac_length |= val << 0;
+               break;
+               case 12: // MAR
+               break;
+               case 13: // MAR
+               ncr->dmac_address &= 0x0000ffff;
+               ncr->dmac_address |= val << 16;
+               break;
+               case 14: // MAR
+               ncr->dmac_address &= 0x00ff00ff;
+               ncr->dmac_address |= val << 8;
+               break;
+               case 15: // MAR
+               ncr->dmac_address &= 0x00ffff00;
+               ncr->dmac_address |= val << 0;
+               break;
+       }
+}
+
 static uae_u32 ncr80_bget2(struct ncr5380_scsi *ncr, uaecptr addr)
 {
        int reg = -1;
@@ -1068,7 +1169,13 @@ static uae_u32 ncr80_bget2(struct ncr5380_scsi *ncr, uaecptr addr)
 
        if (ncr->type == NCR5380_SUPRA) {
 
-               if (ncr->subtype == 3) {
+               if (ncr->subtype == 4) {
+                       if ((addr & 0xc000) == 0xc000) {
+                               v = read_supra_dma(ncr, addr);
+                       } else if (addr & 0x8000) {
+                               addresstype = (addr & 1) ? 0 : 1;
+                       }
+               } else if (ncr->subtype == 3) {
                        if ((addr & 0x8000) && !(addr & 1))
                                addresstype = 0;
                } else {
@@ -1089,10 +1196,15 @@ static uae_u32 ncr80_bget2(struct ncr5380_scsi *ncr, uaecptr addr)
                                v = ncr5380_bget(ncr, reg);
                }
 
+       } else if (ncr->type == NONCR_GOLEM) {
+
+               if (addr < 16384)
+                       v = ncr->rom[addr];
+
        }
 
 #if NCR5380_DEBUG > 1
-       if (addr < 0x8000)
+       if (addr < 0x80 || addr > 0x2000)
                write_log(_T("GET %08x %02x %d %08x\n"), addr, v, reg, M68K_GETPC);
 #endif
 
@@ -1106,19 +1218,27 @@ static void ncr80_bput2(struct ncr5380_scsi *ncr, uaecptr addr, uae_u32 val)
 
        addr &= ncr->board_mask;
 
-       if (ncr->subtype == 3) {
-               if ((addr & 0x8000) && !(addr & 1))
-                       addresstype = 0;
-       } else {
-               if (ncr->subtype != 1 && (addr & 1))
-                       return;
-               if (!(addr & 0x8000))
-                       addresstype = 0;
-       }
-       if (addresstype == 0) {
-               reg = suprareg(ncr, addr, true);
-               if (reg >= 0)
-                       ncr5380_bput(ncr, reg, val);
+       if (ncr->type == NCR5380_SUPRA) {
+               if (ncr->subtype == 4) {
+                       if ((addr & 0xc000) == 0xc000) {
+                               write_supra_dma(ncr, addr, val);
+                       } else if (addr & 0x8000) {
+                               addresstype = (addr & 1) ? 0 : 1;
+                       }
+               } else if (ncr->subtype == 3) {
+                       if ((addr & 0x8000) && !(addr & 1))
+                               addresstype = 0;
+               } else {
+                       if (ncr->subtype != 1 && (addr & 1))
+                               return;
+                       if (!(addr & 0x8000))
+                               addresstype = 0;
+               }
+               if (addresstype == 0) {
+                       reg = suprareg(ncr, addr, true);
+                       if (reg >= 0)
+                               ncr5380_bput(ncr, reg, val);
+               }
        }
 #if NCR5380_DEBUG > 1
        write_log(_T("PUT %08x %02x %d %08x\n"), addr, val, reg, M68K_GETPC);
@@ -1231,12 +1351,32 @@ static addrbank ncr_bank_supra = {
        dummy_lgeti, dummy_wgeti, ABFLAG_IO
 };
 
-#define SUPRA_ROM_OFFSET 0x8000
+static uae_u8 *REGPARAM2 golem_xlate(struct ncr5380_scsi *ncr, uaecptr addr)
+{
+       addr &= 8191;
+       return ncr->rom + addr;
+}
+
+static uae_u8 *REGPARAM2 ncr_golem_xlate(uaecptr addr)
+{
+       return golem_xlate(&golemscsi[0], addr);
+}
+static int REGPARAM2 ncr_golem_check(uaecptr addr, uae_u32 size)
+{
+       addr &= 65535;
+       return addr < 8192;
+}
+
 
-static const uae_u8 supra_autoconfig_byte[16] = { 0xd1, 13, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, SUPRA_ROM_OFFSET >> 8, SUPRA_ROM_OFFSET & 0xff };
-static const uae_u8 supra_autoconfig_word[16] = { 0xd1, 12, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, SUPRA_ROM_OFFSET >> 8, SUPRA_ROM_OFFSET & 0xff };
-static const uae_u8 supra_autoconfig_500[16] = { 0xd1, 8, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, SUPRA_ROM_OFFSET >> 8, SUPRA_ROM_OFFSET & 0xff };
-static const uae_u8 supra_autoconfig_4x4[16] = { 0xc1, 1, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+SCSI_MEMORY_FUNCTIONS(ncr_golem, ncr80, golemscsi[0]);
+SCSI_MEMORY_FUNCTIONS(ncr2_golem, ncr80, golemscsi[1]);
+DECLARE_MEMORY_FUNCTIONS(ncr_supra)
+static addrbank ncr_bank_golem = {
+       ncr_golem_lget, ncr_golem_wget, ncr_golem_bget,
+       ncr_golem_lput, ncr_golem_wput, ncr_golem_bput,
+       ncr_golem_xlate, ncr_golem_check, NULL, NULL, _T("Golem"),
+       ncr_golem_lget, ncr_golem_wget, ABFLAG_IO | ABFLAG_SAFE
+};
 
 addrbank *supra_init(int devnum)
 {
@@ -1244,6 +1384,8 @@ addrbank *supra_init(int devnum)
        int roms[2];
        struct romconfig *rc = NULL;
        
+       scsi->configured = 0;
+
        if (devnum > 0 && !scsi->enabled)
                return &expamem_null;
 
@@ -1261,6 +1403,7 @@ addrbank *supra_init(int devnum)
        memset(scsi->rom, 0xff, 2 * 16384);
 
        rc = get_device_romconfig(&currprefs, devnum, ROMTYPE_SUPRA);
+       const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_SUPRA);
        if (rc) {
                struct zfile *z = NULL;
                scsi->subtype = rc->subtype;
@@ -1270,8 +1413,7 @@ addrbank *supra_init(int devnum)
                                romwarning(roms);
                }
                for (int i = 0; i < 16; i++) {
-                       uae_u8 b = scsi->subtype == 3 ? supra_autoconfig_4x4[i] :
-                               (scsi->subtype == 2 ? supra_autoconfig_500[i] : (scsi->subtype == 1 ? supra_autoconfig_word[i] : supra_autoconfig_byte[i]));
+                       uae_u8 b = ert->subtypes[rc->subtype].autoconfig[i];
                        ew(scsi, i * 4, b);
                }
                if (z) {
@@ -1300,6 +1442,68 @@ int supra_add_scsi_unit(int ch, struct uaedev_config_info *ci)
        return 0;
 }
 
+addrbank *golem_init(int devnum)
+{
+       struct ncr5380_scsi *scsi = &golemscsi[devnum];
+       int roms[2];
+       struct romconfig *rc = NULL;
+       
+       scsi->configured = 0;
+
+       if (devnum > 0 && !scsi->enabled)
+               return &expamem_null;
+
+       roms[0] = 124;
+       roms[1] = -1;
+
+       memset(scsi->acmemory, 0xff, sizeof scsi->acmemory);
+
+       scsi->board_size = 65536;
+       scsi->board_mask = scsi->board_size - 1;
+       scsi->bank = &ncr_bank_golem;
+       scsi->rom = xcalloc(uae_u8, 8192);
+       scsi->type = NONCR_GOLEM;
+       scsi->subtype = 0;
+       memset(scsi->rom, 0xff, 8192);
+
+       rc = get_device_romconfig(&currprefs, devnum, ROMTYPE_GOLEM);
+       if (rc) {
+               struct zfile *z = NULL;
+               if (!rc->autoboot_disabled) {
+                       z = read_device_rom(&currprefs, devnum, ROMTYPE_GOLEM, roms);
+                       if (!z && is_device_rom(&currprefs, devnum, ROMTYPE_GOLEM))
+                               romwarning(roms);
+               }
+               if (z) {
+                       write_log(_T("GOLEM BOOT ROM '%s'\n"), zfile_getname(z));
+                       if (rc->autoboot_disabled)
+                               zfile_fseek(z, 8192, SEEK_SET);
+                       for (int i = 0; i < 8192; i++) {
+                               uae_u8 b;
+                               zfile_fread(&b, 1, 1, z);
+                               if (i < sizeof scsi->acmemory)
+                                       scsi->acmemory[i] = b;
+                               scsi->rom[i] = b;
+                       }
+                       zfile_fclose(z);
+               }
+       }
+       return scsi->bank;
+}
+
+int golem_add_scsi_unit(int ch, struct uaedev_config_info *ci)
+{
+       struct raw_scsi *rs = &golemscsi[ci->controller_type_unit].rscsi;
+       raw_scsi_reset(rs);
+       if (ci->type == UAEDEV_CD)
+               return add_scsi_cd(rs->device, ch, ci->device_emu_unit);
+       else if (ci->type == UAEDEV_TAPE)
+               return add_scsi_tape(rs->device, ch, ci->rootdir, ci->readonly);
+       else
+               return add_scsi_hd(rs->device, ch, NULL, ci, 1);
+       return 0;
+}
+
 void ncr5380scsi_free(void)
 {
        for (int i = 0; ncr5380devices[i]; i++) {