return NULL;
}
-#define NEXT_ROM_ID 124
+#define NEXT_ROM_ID 126
static struct romheader romheaders[] = {
{ _T("Freezer Cartridges"), 1 },
{ _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,
{ _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)
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 {
#define NCR5380_DEBUG 0
#define NCR5380_SUPRA 1
+#define NONCR_GOLEM 2
extern int log_scsiemu;
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)
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)
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;
#if NCR5380_DEBUG
write_log(_T("DMA initiator recv\n"));
#endif
+ dma_check(scsi);
break;
}
ncr5380_check_phase(scsi);
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;
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 {
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
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);
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)
{
int roms[2];
struct romconfig *rc = NULL;
+ scsi->configured = 0;
+
if (devnum > 0 && !scsi->enabled)
return &expamem_null;
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;
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) {
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++) {