]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
CSA Magnum 40 emulation.
authorToni Wilen <twilen@winuae.net>
Sat, 10 Mar 2018 10:41:18 +0000 (12:41 +0200)
committerToni Wilen <twilen@winuae.net>
Sat, 10 Mar 2018 10:41:18 +0000 (12:41 +0200)
cpuboard.cpp
devices.cpp
expansion.cpp
include/cpuboard.h
include/ncr_scsi.h
include/rommgr.h
ncr_scsi.cpp
qemuvga/lsi53c710.cpp
rommgr.cpp

index 84cb5a056cef26923471bb45c9761ce1fcd930a5..c2b78cd6ec6e052c4988095b1531c3824742a755 100644 (file)
@@ -329,6 +329,10 @@ static bool is_ivsvector(struct uae_prefs *p)
 {
        return ISCPUBOARDP(p, BOARD_IVS, BOARD_IVS_VECTOR);
 }
+static bool is_magnum40(struct uae_prefs *p)
+{
+       return ISCPUBOARDP(p, BOARD_CSA, BOARD_CSA_MAGNUM40);
+}
 static bool is_aca500(struct uae_prefs *p)
 {
        return false; //return ISCPUBOARDP(p, BOARD_IC, BOARD_IC_ACA500);
@@ -739,7 +743,7 @@ static uae_u32 REGPARAM2 blizzardea_wget(uaecptr addr)
 }
 static uae_u32 REGPARAM2 blizzardea_bget(uaecptr addr)
 {
-       uae_u8 v;
+       uae_u8 v = 0;
 
        addr &= blizzardea_bank.mask;
        if (is_tekmagic(&currprefs)) {
@@ -947,7 +951,7 @@ static void cyberstorm_copymaprom(void)
 }
 static void cyberstormmk2_copymaprom(void)
 {
-       if (blizzardmaprom_bank.baseaddr) {
+       if (a3000hmem_bank.baseaddr) {
                uae_u8 *src = a3000hmem_bank.baseaddr + a3000hmem_bank.allocated_size - 524288;
                uae_u8 *dst = kickmem_bank.baseaddr;
                protect_roms(false);
@@ -968,6 +972,20 @@ static void cyberstormmk1_copymaprom(void)
        }
 }
 
+static void csamagnum40_domaprom(void)
+{
+       if (!maprom_state) {
+               reload_roms();
+       } else if (a3000hmem_bank.baseaddr && a3000hmem_bank.allocated_size >= 0x1000000) {
+               uae_u8 *src = a3000hmem_bank.baseaddr + 0xf80000;
+               uae_u8 *dst = kickmem_bank.baseaddr;
+               protect_roms(false);
+               memcpy(dst, src, 524288);
+               protect_roms(true);
+               set_roms_modified();
+       }
+}
+
 bool cpuboard_is_ppcboard_irq(void)
 {
        if (is_csmk3(&currprefs) || is_blizzardppc(&currprefs)) {
@@ -1109,7 +1127,17 @@ static uae_u32 REGPARAM2 blizzardio_bget(uaecptr addr)
 {
        uae_u8 v = 0;
        //write_log(_T("CS IO XBGET %08x=%02X PC=%08x\n"), addr, v & 0xff, M68K_GETPC);
-       if (is_csmk3(&currprefs) || is_blizzardppc(&currprefs)) {
+       if (is_magnum40(&currprefs)) {
+               if (regs.s && (addr & 0xff0f) == 0x0c0c) {
+                       int reg = (addr >> 4) & 7;
+                       v = io_reg[reg];
+                       if (reg >= 0 && reg <= 3)
+                               v &= ~0x04; // REV0 to REV3
+                       if (reg == 0)
+                               v |= 0x04; // REV0=1
+                       write_log(_T("CSA Magnum40 read reg %0d = %d %08x\n"), reg, v, M68K_GETPC);
+               }
+       } else if (is_csmk3(&currprefs) || is_blizzardppc(&currprefs)) {
                uae_u32 bank = addr & 0x10000;
                if (bank == 0) {
                        int reg = (addr & 0xff) / 8;
@@ -1207,7 +1235,18 @@ static void REGPARAM2 blizzardio_bput(uaecptr addr, uae_u32 v)
 #if CPUBOARD_IO_LOG > 1
        write_log(_T("CS IO XBPUT %08x %02x PC=%08x\n"), addr, v & 0xff, M68K_GETPC);
 #endif
-       if (is_fusionforty(&currprefs)) {
+       if (is_magnum40(&currprefs)) {
+               if (regs.s && (addr & 0xff0f) == 0x0c0c) {
+                       int reg = (addr >> 4) & 7;
+                       if (reg == 3 && ((v ^ io_reg[reg]) & 1)) {
+                               maprom_state = v & 1;
+                               write_log(_T("CSA Magnum40 MAPROM=%d\n"), maprom_state);
+                               csamagnum40_domaprom();
+                       }
+                       io_reg[reg] = (uae_u8)v;
+                       write_log(_T("CSA Magnum40 write reg %0d = %02x %08x\n"), reg, v & 0xff, M68K_GETPC);
+               }
+       } else if (is_fusionforty(&currprefs)) {
                write_log(_T("FusionForty IO XBPUT %08x %02x PC=%08x\n"), addr, v & 0xff, M68K_GETPC);
        } else if (is_csmk2(&currprefs)) {
                csmk2_flashaddressing = addr & 3;
@@ -1474,6 +1513,10 @@ void cpuboard_map(void)
 
        bool fallback_cpu = currprefs.cpu_model < 68020;
 
+       if (is_magnum40(&currprefs)) {
+               map_banks(&blizzardio_bank, 0x0c0c0000 >> 16, 0x10000 >> 16, 0);
+       }
+
        if (is_blizzard1230mk2(&currprefs) || is_blizzard1230mk3(&currprefs)) {
                map_banks(&blizzardram_bank, blizzardram_bank.start >> 16, cpuboard_size >> 16, 0);
                map_banks(&blizzardio_bank, BLIZZARD_MAPROM_ENABLE >> 16, 65536 >> 16, 0);
@@ -2307,6 +2350,15 @@ bool cpuboard_autoconfig_init(struct autoconfig_info *aci)
                }
                break;
 
+               case BOARD_CSA:
+               switch(p->cpuboard_subtype)
+               {
+               case BOARD_CSA_MAGNUM40:
+                       aci->addrbank = &expamem_null;
+                       return true;
+               }
+               break;
+
                case BOARD_DKB:
                switch(p->cpuboard_subtype)
                {
index 8fc1d067112d6d6eb28c3fb8c8383be266ad5549..ca4ad4c8ad2cd3da7d702f92306b1c262a766bb0 100644 (file)
@@ -145,6 +145,7 @@ void devices_vsync_pre(void)
        cd32_fmv_vsync_handler();
 #endif
        cpuboard_vsync();
+       ncr_vsync();
        statusline_vsync();
 #ifdef WITH_X86
        x86_bridge_vsync();
index a11e0a27812f602147fe4e608a43a9b2b22af114..26d76de863a36945c875979e1f2ddff378381480 100644 (file)
@@ -5882,6 +5882,23 @@ static const struct cpuboardsubtype pps_sub[] = {
        }
 };
 
+static const struct cpuboardsubtype csa_sub[] = {
+       {
+               _T("Magnum 40/4"),
+               _T("Magnum40"),
+               ROMTYPE_CB_MAGNUM40, 0,
+               magnum40_add_scsi_unit, EXPANSIONTYPE_SCSI,
+               BOARD_MEMORY_HIGHMEM,
+               128 * 1024 * 1024,
+               0,
+               ncr710_magnum40_autoconfig_init, NULL, BOARD_AUTOCONFIG_Z2, 1,
+               NULL, NULL
+       },
+       {
+               NULL
+       }
+};
+
 static const struct expansionboardsettings apollo_settings[] = {
        {
                _T("SCSI module installed"),
@@ -6014,6 +6031,11 @@ const struct cpuboardtype cpuboards[] = {
                _T("Progressive Peripherals & Software"),
                pps_sub, 0
        },
+       {
+               BOARD_CSA,
+               _T("Computer System Associates"),
+               csa_sub, 0
+       },
        {
                NULL
        }
index 4cebf174a6383189cd392c65532fc094c1b8ed0d..db408e064f2eb1c2f9096efe9777992dfbc49209 100644 (file)
@@ -98,5 +98,7 @@ void blizzardppc_irq_setonly(int id, int level);
 #define BOARD_PPS 13
 #define BOARD_PPS_ZEUS040 0
 
+#define BOARD_CSA 14
+#define BOARD_CSA_MAGNUM40 0
 
 #endif /* UAE_CPUBOARD_H */
index bc4a095dbc6c6fa793b3c97cdfc638641e4dc8ee..b730238f429b922c7129395dce58fa37568ddc8f 100644 (file)
@@ -17,10 +17,12 @@ extern void ncr_init(void);
 extern void ncr_free(void);
 extern void ncr_reset(void);
 extern void ncr_rethink(void);
+extern void ncr_vsync(void);
 
 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);
 
 void cpuboard_ncr710_io_bput(uaecptr addr, uae_u32 v);
 uae_u32 cpuboard_ncr710_io_bget(uaecptr addr);
@@ -36,5 +38,6 @@ extern void blizzardppc_add_scsi_unit(int ch, struct uaedev_config_info *ci, str
 extern void a4091_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 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);
 
 #endif /* UAE_NCR_SCSI_H */
index 1df9f1db4a9ee826cca3cb1b716fb9800804bd96..71ce34f71f131cded0c02e25908990582058e80c 100644 (file)
@@ -43,6 +43,7 @@ extern int decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size);
 #define ROMTYPE_CB_B1230MK3    0x00040016
 #define ROMTYPE_CB_VECTOR      0x00040017
 #define ROMTYPE_CB_ZEUS040     0x00040018
+#define ROMTYPE_CB_MAGNUM40    0x00040019
 
 #define ROMTYPE_FREEZER                0x00080000
 #define ROMTYPE_AR                     0x00080001
index efd1534d3802da0b9a3f27e3504fb7c6727c254f..3dccd651f121918966db672507bf7f28b2f4d8ae 100644 (file)
@@ -71,6 +71,7 @@ struct ncr_state
        bool enabled;
        int rom_start, rom_end, rom_offset;
        int io_start, io_end;
+       uae_u8 state[8];
        addrbank *bank;
        bool irq;
        bool irqlevel;
@@ -166,6 +167,7 @@ static struct ncr_state *ncr_a4000t;
 static struct ncr_state *ncra4091[MAX_DUPLICATE_EXPANSION_BOARDS];
 static struct ncr_state *ncr_wildfire;
 static struct ncr_state *ncr_zeus040;
+static struct ncr_state *ncr_magnum40;
 
 static void set_irq2(int id, int level)
 {
@@ -376,6 +378,34 @@ int pci710_dma_rw(PCIDevice *dev, dma_addr_t addr, void *buf, dma_addr_t len, DM
        return 0;
 }
 
+void ncr_vsync(void)
+{
+       for (int i = 0; ncr_units[i]; i++) {
+               if (ncr_units[i] == ncr_magnum40) {
+                       struct ncr_state *ncr = ncr_units[i];
+                       if (ncr->state[1] & 1) {
+                               int v = (ncr->state[5] << 16) | (ncr->state[6] << 8) | (ncr->state[7]);
+                               if (v > 0) {
+                                       v -= 2304;
+                                       ncr->state[5] = (v >> 16) & 0xff;
+                                       ncr->state[6] = (v >> 8) & 0xff;
+                                       ncr->state[7] = (v >> 0) & 0xff;
+                               }
+                               if (v <= 0) {
+                                       ncr->state[0] |= 1;
+                                       ncr->state[5] = ncr->state[2];
+                                       ncr->state[6] = ncr->state[3];
+                                       ncr->state[7] = ncr->state[4];
+                               }
+                       }
+                       if (ncr->state[0] & 1) {
+                               set_irq2(ncr->id, 1);
+                       }
+               }
+       }
+
+}
+
 static uae_u8 read_rombyte(struct ncr_state *ncr, uaecptr addr)
 {
        uae_u8 v = ncr->rom[addr];
@@ -413,6 +443,38 @@ static void ncr_bput2 (struct ncr_state *ncr, uaecptr addr, uae_u32 val)
 {
        uae_u32 v = val;
        addr &= ncr->board_mask;
+
+       if (ncr == ncr_magnum40 && addr >= 0xa000 && addr <= 0xa200) {
+               int reg = (addr >> 4) & 31;
+               switch (reg)
+               {
+                       case 0x10: // timer control
+                       ncr->state[1] = (uae_u8)v;
+                       if (ncr->state[1] & 1) {
+                               ncr->state[5] = ncr->state[2];
+                               ncr->state[6] = ncr->state[3];
+                               ncr->state[7] = ncr->state[4];
+                       }
+                       break;
+                       case 0x13: // timer hi
+                       ncr->state[2] = (uae_u8)v;
+                       break;
+                       case 0x14: // timer med
+                       ncr->state[3] = (uae_u8)v;
+                       break;
+                       case 0x15: // timer lo
+                       ncr->state[4] = (uae_u8)v;
+                       break;
+                       case 0x1a: // timer ZDS
+                       if (ncr->state[0] & 1)
+                               set_irq2(ncr->id, 0);
+                       ncr->state[0] &= ~1;
+                       break;
+               }
+               return;
+       }
+
+
        if (ncr->io_end && (addr < ncr->io_start || addr >= ncr->io_end)) {
 #if NCR_DEBUG > 1
                write_log(_T("ncr_bput none %08x %02x %08x\n"), addr, v & 0xff, M68K_GETPC);
@@ -447,6 +509,11 @@ uae_u32 cpuboard_ncr710_io_bget(uaecptr addr)
        return ncr710_io_bget(ncr_cpuboard, addr);
 }
 
+static bool isncrboard(struct ncr_state *ncr, struct ncr_state **ncrb)
+{
+       return ncr == ncrb[0] || ncr == ncrb[1] || ncr == ncrb[2] || ncr == ncrb[3];
+}
+
 static uae_u32 ncr_bget2 (struct ncr_state *ncr, uaecptr addr)
 {
        uae_u32 v = 0;
@@ -454,13 +521,28 @@ static uae_u32 ncr_bget2 (struct ncr_state *ncr, uaecptr addr)
        addr &= ncr->board_mask;
        if (ncr->rom && addr >= ncr->rom_start && addr < ncr->rom_end)
                return read_rombyte (ncr, addr - ncr->rom_offset);
-       if (addr == A4091_DIP_OFFSET) {
-               uae_u8 v2 = 0;
-               v2 |= ncr->rc->device_id;
-               v2 |= ncr->rc->device_settings << 3;
-               v2 ^= 0xff & ~7;
-               return v2;
+
+       if (isncrboard(ncr, ncra4091)) {
+               if (addr == A4091_DIP_OFFSET) {
+                       uae_u8 v2 = 0;
+                       v2 |= ncr->rc->device_id;
+                       v2 |= ncr->rc->device_settings << 3;
+                       v2 ^= 0xff & ~7;
+                       return v2;
+               }
+       }
+
+       if (ncr == ncr_magnum40 && addr >= 0xa000 && addr <= 0xa200) {
+               int reg = (addr >> 4) & 31;
+               switch(reg)
+               {
+                       case 0x0c: // jumpers (68230 port C)
+                       return 0x00;
+                       case 0x1a: // timer ZDS
+                       return ncr->state[0] & 1;
+               }
        }
+
        if (ncr->io_end && (addr < ncr->io_start || addr >= ncr->io_end)) {
 #if NCR_DEBUG > 1
                write_log(_T("ncr_bget none %08x %02x %08x\n"), addr, v, M68K_GETPC);
@@ -482,13 +564,8 @@ static uae_u32 REGPARAM2 ncr_lget (struct ncr_state *ncr, uaecptr addr)
        uae_u32 v = 0;
        if (ncr) {
                addr &= ncr->board_mask;
-               if (addr >= A4091_IO_ALT) {
-                       v = (ncr_bget2 (ncr, addr + 3) << 0) | (ncr_bget2 (ncr, addr + 2) << 8) |
-                               (ncr_bget2 (ncr, addr + 1) << 16) | (ncr_bget2 (ncr, addr + 0) << 24);
-               } else {
-                       v = (ncr_bget2 (ncr, addr + 3) << 0) | (ncr_bget2 (ncr, addr + 2) << 8) |
-                               (ncr_bget2 (ncr, addr + 1) << 16) | (ncr_bget2 (ncr, addr + 0) << 24);
-               }
+               v = (ncr_bget2 (ncr, addr + 3) << 0) | (ncr_bget2 (ncr, addr + 2) << 8) |
+                       (ncr_bget2 (ncr, addr + 1) << 16) | (ncr_bget2 (ncr, addr + 0) << 24);
        }
        return v;
 }
@@ -523,17 +600,10 @@ static void REGPARAM2 ncr_lput (struct ncr_state *ncr, uaecptr addr, uae_u32 l)
        if (!ncr)
                return;
        addr &= ncr->board_mask;
-       if (addr >= A4091_IO_ALT) {
-               ncr_bput2 (ncr, addr + 3, l >> 0);
-               ncr_bput2 (ncr, addr + 2, l >> 8);
-               ncr_bput2 (ncr, addr + 1, l >> 16);
-               ncr_bput2 (ncr, addr + 0, l >> 24);
-       } else {
-               ncr_bput2 (ncr, addr + 3, l >> 0);
-               ncr_bput2 (ncr, addr + 2, l >> 8);
-               ncr_bput2 (ncr, addr + 1, l >> 16);
-               ncr_bput2 (ncr, addr + 0, l >> 24);
-       }
+       ncr_bput2 (ncr, addr + 3, l >> 0);
+       ncr_bput2 (ncr, addr + 2, l >> 8);
+       ncr_bput2 (ncr, addr + 1, l >> 16);
+       ncr_bput2 (ncr, addr + 0, l >> 24);
 }
 
 static void REGPARAM2 ncr_wput (struct ncr_state *ncr, uaecptr addr, uae_u32 w)
@@ -918,6 +988,38 @@ bool ncr710_zeus040_autoconfig_init(struct autoconfig_info *aci)
        return true;
 }
 
+bool ncr710_magnum40_autoconfig_init(struct autoconfig_info *aci)
+{
+       if (!aci->doinit) {
+               load_rom_rc(aci->rc, ROMTYPE_CB_MAGNUM40, 65536, 0, aci->autoconfig_raw, 128, 0);
+               return true;
+       }
+
+       struct ncr_state *ncr = getscsi(aci->rc);
+       if (!ncr)
+               return false;
+
+       xfree(ncr->rom);
+       ncr->rom = NULL;
+
+       ncr->enabled = true;
+       memset(ncr->acmemory, 0xff, sizeof ncr->acmemory);
+       ncr->rom_start = 0;
+       ncr->rom_offset = 0;
+       ncr->rom_end = 0x8000;
+       ncr->io_start = 0x8000;
+       ncr->io_end = 0x9000;
+
+
+       ncr->rom = xcalloc(uae_u8, 32768);
+       load_rom_rc(aci->rc, ROMTYPE_CB_MAGNUM40, 65536, 0, ncr->rom, 32768, 0);
+       memcpy(ncr->acmemory, ncr->rom, sizeof ncr->acmemory);
+
+       ncr_reset_board(ncr);
+
+       aci->addrbank = &ncr_bank_generic;
+       return true;
+}
 
 void ncr_free(void)
 {
@@ -1071,4 +1173,12 @@ void zeus040_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconf
        ncr_zeus040->z2 = true;
 }
 
+void magnum40_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
+{
+       ncr_add_scsi_unit(&ncr_magnum40, ch, ci, rc, false);
+       ncr_magnum40->irq_func = set_irq6;
+       ncr_magnum40->irqlevel = true;
+       ncr_magnum40->z2 = true;
+}
+
 #endif
index 36da44828caa1612102477de1c946cb12b14ce76..655b7bb30e688a17096ed2f6da9f31c3ce6c2d0c 100644 (file)
@@ -1190,8 +1190,10 @@ again:
                 s->scntl1 |= LSI_SCNTL1_CON;
                 if (insn & (1 << 24)) {
                     s->socl |= LSI_SOCL_ATN;
-                }
-                lsi_set_phase(s, PHASE_MO);
+                                       lsi_set_phase(s, PHASE_MO);
+                               } else {
+                                       lsi_set_phase(s, PHASE_CMD);
+                               }
                 break;
             case 1: /* Disconnect */
                 DPRINTF("Wait Disconnect\n");
@@ -1880,7 +1882,12 @@ static void lsi_reg_writeb(LSIState710 *s, int offset, uint8_t val)
             lsi_execute_script(s);
                }
         break;
-    CASE_SET_REG32(scratch, 0x34)
+       case 0x30:
+       case 0x31:
+       case 0x32:
+       case 0x33:
+               break;
+       CASE_SET_REG32(scratch, 0x34)
        case 0x38: /* DMODE */
 #if 0
                if (val & (LSI_DMODE_SIOM | LSI_DMODE_DIOM)) {
index 62d5fd089e56546950cee214bbe5412eeeaba9b7..eb04364aab3e29cff5ea5bea192f13988ee057c1 100644 (file)
@@ -95,7 +95,7 @@ struct romdata *getromdatabypath (const TCHAR *path)
        return NULL;
 }
 
-#define NEXT_ROM_ID 226
+#define NEXT_ROM_ID 227
 
 #define ALTROM(id,grp,num,size,flags,crc32,a,b,c,d,e) \
 { _T("X"), 0, 0, 0, 0, 0, size, id, 0, 0, flags, (grp << 16) | num, 0, NULL, crc32, a, b, c, d, e },
@@ -389,6 +389,8 @@ static struct romdata roms[] = {
        0x2c609194, 0x9a91cf45,0x6816067a,0x943c18f1,0xbd30effe,0x482d4aaf, NULL, NULL },
        ALTROMPN(225, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xc0bea5dd, 0x1540a755, 0x36066da4, 0x8bcb3dd4, 0xf13f179b, 0x9439f379)
        ALTROMPN(225, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x7989684f, 0x9dc4d885, 0x242bf7eb, 0xe75a01b2, 0x483c9e3c, 0x8013896b)
+       { _T("CSA Magnum 040"), 0, 0, 0, 0, _T("MAGNUM040\0"), 65536, 226, 0, 0, ROMTYPE_CB_MAGNUM40, 0, 0, NULL,
+       0xb94e805b, 0x4c1859ba,0x7ea2cedb,0xf5251bed,0xfbb76e6c,0x0617300e },
 
        { _T("A2620/A2630 -07"), 0, 0, 0, 0, _T("A2620\0A2630\0"), 65536, 105, 0, 0, ROMTYPE_CB_A26x0, 0, 0, _T("390282-07/390283-07"),
        0x169d80e9, 0x41f518cb,0x41c1dc1f,0xcc636383,0x20676af5,0x4969010c, NULL, NULL },