From: Toni Wilen Date: Sat, 10 Mar 2018 10:41:18 +0000 (+0200) Subject: CSA Magnum 40 emulation. X-Git-Tag: 4000~153 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=35970e2499e57d115e55b6fff1cf93c658cc5b53;p=francis%2Fwinuae.git CSA Magnum 40 emulation. --- diff --git a/cpuboard.cpp b/cpuboard.cpp index 84cb5a05..c2b78cd6 100644 --- a/cpuboard.cpp +++ b/cpuboard.cpp @@ -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) { diff --git a/devices.cpp b/devices.cpp index 8fc1d067..ca4ad4c8 100644 --- a/devices.cpp +++ b/devices.cpp @@ -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(); diff --git a/expansion.cpp b/expansion.cpp index a11e0a27..26d76de8 100644 --- a/expansion.cpp +++ b/expansion.cpp @@ -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 } diff --git a/include/cpuboard.h b/include/cpuboard.h index 4cebf174..db408e06 100644 --- a/include/cpuboard.h +++ b/include/cpuboard.h @@ -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 */ diff --git a/include/ncr_scsi.h b/include/ncr_scsi.h index bc4a095d..b730238f 100644 --- a/include/ncr_scsi.h +++ b/include/ncr_scsi.h @@ -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 */ diff --git a/include/rommgr.h b/include/rommgr.h index 1df9f1db..71ce34f7 100644 --- a/include/rommgr.h +++ b/include/rommgr.h @@ -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 diff --git a/ncr_scsi.cpp b/ncr_scsi.cpp index efd1534d..3dccd651 100644 --- a/ncr_scsi.cpp +++ b/ncr_scsi.cpp @@ -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 diff --git a/qemuvga/lsi53c710.cpp b/qemuvga/lsi53c710.cpp index 36da4482..655b7bb3 100644 --- a/qemuvga/lsi53c710.cpp +++ b/qemuvga/lsi53c710.cpp @@ -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)) { diff --git a/rommgr.cpp b/rommgr.cpp index 62d5fd08..eb04364a 100644 --- a/rommgr.cpp +++ b/rommgr.cpp @@ -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 },