From 65c88685488653ca4e9cbbfe18d05e9ac375a74d Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 1 Feb 2015 16:51:00 +0200 Subject: [PATCH] New IDE/SCSI controllers. --- a2091.cpp | 684 ++++++++++++++++----------- cdtv.cpp | 3 +- cfgfile.cpp | 83 +++- cpuboard.cpp | 78 +++- devices.cpp | 2 + expansion.cpp | 120 ++++- filesys.cpp | 86 +++- gayle.cpp | 2 +- ide.cpp | 18 +- idecontrollers.cpp | 968 +++++++++++++++++++++++++++++++-------- include/a2091.h | 7 +- include/cpuboard.h | 3 +- include/filesys.h | 50 +- include/ide.h | 35 +- include/idecontrollers.h | 18 + include/ncr9x_scsi.h | 5 + include/options.h | 7 +- include/rommgr.h | 9 +- include/scsi.h | 15 + ncr9x_scsi.cpp | 234 ++++++++-- qemuvga/esp.cpp | 9 +- rommgr.cpp | 25 +- scsi.cpp | 426 ++++++++++++++--- 23 files changed, 2217 insertions(+), 670 deletions(-) diff --git a/a2091.cpp b/a2091.cpp index 36ef0c51..ef7a3874 100644 --- a/a2091.cpp +++ b/a2091.cpp @@ -9,7 +9,8 @@ * */ -#define GVP_DEBUG_IO 0 +#define GVP_S1_DEBUG_IO 0 +#define GVP_S2_DEBUG_IO 0 #define A2091_DEBUG 0 #define A2091_DEBUG_IO 0 #define XT_DEBUG 0 @@ -38,10 +39,13 @@ #include "autoconf.h" #include "cdtv.h" #include "savestate.h" +#include "cpuboard.h" #define CDMAC_ROM_VECTOR 0x2000 #define CDMAC_ROM_OFFSET 0x2000 #define GVP_ROM_OFFSET 0x8000 +#define GVP_SERIES_I_RAM_OFFSET 0x4000 +#define GVP_SERIES_I_RAM_MASK 16383 /* SuperDMAC CNTR bits. */ #define SCNTR_TCEN (1<<5) @@ -278,7 +282,8 @@ static void reset_dmac(struct wd_state *wd) { switch (wd->dmac_type) { - case GVP_DMAC: + case GVP_DMAC_S1: + case GVP_DMAC_S2: wd->gdmac.cntr = 0; wd->gdmac.dma_on = 0; break; @@ -297,7 +302,9 @@ static bool isirq(struct wd_state *wd) return false; switch (wd->dmac_type) { - case GVP_DMAC: + case GVP_DMAC_S1: + return wd->gdmac.cntr && (wd->wc.auxstatus & ASR_INT) != 0; + case GVP_DMAC_S2: if (wd->wc.auxstatus & ASR_INT) wd->gdmac.cntr |= 2; if ((wd->gdmac.cntr & (2 | 8)) == 10) @@ -325,7 +332,8 @@ static void set_dma_done(struct wd_state *wds) { switch (wds->dmac_type) { - case GVP_DMAC: + case GVP_DMAC_S1: + case GVP_DMAC_S2: wds->gdmac.dma_on = -1; break; case COMMODORE_SDMAC: @@ -339,7 +347,9 @@ static bool is_dma_enabled(struct wd_state *wds) { switch (wds->dmac_type) { - case GVP_DMAC: + case GVP_DMAC_S1: + return true; + case GVP_DMAC_S2: return wds->gdmac.dma_on > 0; case COMMODORE_SDMAC: case COMMODORE_DMAC: @@ -471,13 +481,27 @@ static bool decreasetc(struct wd_chip_state *wd) return tc == 0; } -static bool canwddma(struct wd_chip_state *wd) +static bool canwddma(struct wd_state *wds) { + struct wd_chip_state *wd = &wds->wc; uae_u8 mode = wd->wdregs[WD_CONTROL] >> 5; - if (mode != 0 && mode != 4 && mode != 1) { - write_log (_T("%s weird DMA mode %d!!\n"), WD33C93, mode); + switch(wds->dmac_type) + { + case COMMODORE_DMAC: + case COMMODORE_SDMAC: + case GVP_DMAC_S2: + if (mode != 0 && mode != 4 && mode != 1) { + write_log (_T("%s weird DMA mode %d!!\n"), WD33C93, mode); + } + return mode == 4 || mode == 1; + case GVP_DMAC_S1: + if (mode != 0 && mode != 2) { + write_log (_T("%s weird DMA mode %d!!\n"), WD33C93, mode); + } + return mode == 2; + default: + return false; } - return mode == 4 || mode == 1; } #if WD33C93_DEBUG > 0 @@ -565,13 +589,52 @@ static bool do_dma_commodore(struct wd_state *wd, struct scsi_data *scsi) return false; } -static bool do_dma_gvp(struct wd_state *wd, struct scsi_data *scsi) +static bool do_dma_gvp_s1(struct wd_state *wd, struct scsi_data *scsi) +{ + if (scsi->direction < 0) { + for (;;) { + uae_u8 v; + int status = scsi_receive_data (scsi, &v); + wd->gdmac.buffer[wd->wc.wd_dataoffset++] = v; + wd->wc.wd_dataoffset &= GVP_SERIES_I_RAM_MASK; + if (decreasetc (&wd->wc)) + break; + if (status) + break; + } +#if WD33C93_DEBUG > 0 + write_log (_T("%s Done DMA from WD, %d/%d\n"), WD33C93, scsi->offset, scsi->data_len); +#endif + return true; + } else if (scsi->direction > 0) { + for (;;) { + int status; + uae_u8 v = wd->gdmac.buffer[wd->wc.wd_dataoffset++]; + wd->wc.wd_dataoffset &= GVP_SERIES_I_RAM_MASK; + status = scsi_send_data (scsi, v); + wd->gdmac.addr++; + if (decreasetc (&wd->wc)) + break; + if (status) + break; + } +#if WD33C93_DEBUG > 0 + write_log (_T("%s Done DMA to WD, %d/%d\n"), WD33C93, scsi->offset, scsi->data_len); +#endif + return true; + } + return false; +} + + +static bool do_dma_gvp_s2(struct wd_state *wd, struct scsi_data *scsi) { #if WD33C93_DEBUG > 0 uae_u32 dmaptr = wd->gdmac.addr; #endif if (!is_dma_enabled(wd)) return false; + if (scsi->direction < 0) { if (wd->gdmac.cntr & 0x10) { write_log(_T("GVP DMA: mismatched direction when reading!\n")); @@ -629,8 +692,10 @@ static bool do_dma(struct wd_state *wd) case COMMODORE_DMAC: case COMMODORE_SDMAC: return do_dma_commodore(wd, scsi); - case GVP_DMAC: - return do_dma_gvp(wd, scsi); + case GVP_DMAC_S2: + return do_dma_gvp_s2(wd, scsi); + case GVP_DMAC_S1: + return do_dma_gvp_s1(wd, scsi); } return false; } @@ -853,7 +918,7 @@ static void wd_cmd_sel_xfer (struct wd_chip_state *wd, struct wd_state *wds, boo } if (wd->scsi->direction) { - if (canwddma (wd)) { + if (canwddma (wds)) { if (scsi->direction <= 0) { do_dma(wds); if (scsi->offset < scsi->data_len) { @@ -928,8 +993,9 @@ static void wd_cmd_sel_xfer (struct wd_chip_state *wd, struct wd_state *wds, boo wd->wd_selected = 0; } -static void wd_cmd_trans_info (struct wd_chip_state *wd, struct scsi_data *scsi) +static void wd_cmd_trans_info (struct wd_state *wds, struct scsi_data *scsi) { + struct wd_chip_state *wd = &wds->wc; if (wd->wdregs[WD_COMMAND_PHASE] == 0x20) { wd->wdregs[WD_COMMAND_PHASE] = 0x30; scsi->status = 0; @@ -959,7 +1025,7 @@ static void wd_cmd_trans_info (struct wd_chip_state *wd, struct scsi_data *scsi) scsi->data_len = gettc (wd); } - if (canwddma (wd)) { + if (canwddma (wds)) { wd->wd_data_avail = -1; } else { wd->wd_data_avail = 1; @@ -1965,7 +2031,7 @@ addrbank dmaca2091_2_bank = { dmac_a20912_lgeti, dmac_a20912_wgeti, ABFLAG_IO | ABFLAG_SAFE }; -/* GVP Series II */ +/* GVP Series I and II */ extern addrbank gvp_bank; extern addrbank gvp_2_bank; @@ -1975,42 +2041,69 @@ static uae_u32 dmac_gvp_read_byte(struct wd_state *wd, uaecptr addr) uae_u32 v = 0; addr &= 0xffff; - if (addr < 0x40) { + if (addr < 0x3e) { v = wd->dmacmemory[addr]; } else if (addr >= GVP_ROM_OFFSET) { - if (addr & 1) { - v = wd->gdmac.version; + if (wd->gdmac.series2) { + if (addr & 1) { + v = wd->gdmac.version; + } else { + if (wd->rom) { + if (wd->rombankswitcher && (addr & 0xffe0) == GVP_ROM_OFFSET) + wd->rombank = (addr & 0x02) >> 1; + v = wd->rom[(addr - GVP_ROM_OFFSET) / 2 + wd->rombank * 16384]; + } + } } else { if (wd->rom) { - if (wd->rombankswitcher && (addr & 0xffe0) == GVP_ROM_OFFSET) - wd->rombank = (addr & 0x02) >> 1; - v = wd->rom[(addr - GVP_ROM_OFFSET) / 2 + wd->rombank * 16384]; + v = wd->rom[addr - GVP_ROM_OFFSET]; } } + } else if (addr >= GVP_SERIES_I_RAM_OFFSET && !wd->gdmac.series2) { + v = wd->gdmac.buffer[wd->gdmac.bufoffset++]; + wd->gdmac.bufoffset &= GVP_SERIES_I_RAM_MASK; } else if (wd->configured) { - switch (addr) - { - case 0x40: - v = wd->gdmac.cntr >> 8; - break; - case 0x41: - v = wd->gdmac.cntr; - break; - case 0x61: // SASR - v = wdscsi_getauxstatus(&wd->wc); - break; - case 0x63: // SCMD - v = wdscsi_get(&wd->wc, wd); - break; - default: - write_log(_T("gvp_bget_unk %04X PC=%08X\n"), addr, M68K_GETPC); - break; + if (wd->gdmac.series2) { + switch (addr) + { + case 0x40: + v = wd->gdmac.cntr >> 8; + break; + case 0x41: + v = wd->gdmac.cntr; + break; + case 0x61: // SASR + v = wdscsi_getauxstatus(&wd->wc); + break; + case 0x63: // SCMD + v = wdscsi_get(&wd->wc, wd); + break; + default: + write_log(_T("gvp_s2_bget_unk %04X PC=%08X\n"), addr, M68K_GETPC); + break; + } + } else { + switch (addr) + { + case 0x3e: + v = wd->wc.auxstatus & ASR_INT; + break; + case 0x60: // SASR + v = wdscsi_getauxstatus(&wd->wc); + break; + case 0x62: // SCMD + v = wdscsi_get(&wd->wc, wd); + break; + default: + write_log(_T("gvp_s1_bget_unk %04X PC=%08X\n"), addr, M68K_GETPC); + break; + } } } else { v = 0xff; } -#if GVP_DEBUG_IO > 0 +#if GVP_S2_DEBUG_IO > 0 write_log(_T("gvp_bget %04X=%02X PC=%08X\n"), addr, v, M68K_GETPC); #endif @@ -2021,43 +2114,65 @@ static uae_u32 dmac_gvp_read_word(struct wd_state *wd, uaecptr addr) uae_u32 v = 0; addr &= 0xffff; - if (addr < 0x40) { + if (addr < 0x3e) { v = (wd->dmacmemory[addr] << 8) | wd->dmacmemory[addr + 1]; } else if (addr >= GVP_ROM_OFFSET) { - if (wd->rom) { - if (wd->rombankswitcher && (addr & 0xffe0) == GVP_ROM_OFFSET) - wd->rombank = (addr & 0x02) >> 1; - v = (wd->rom[(addr - GVP_ROM_OFFSET) / 2 + wd->rombank * 16384] << 8) | wd->gdmac.version; + if (wd->gdmac.series2) { + if (wd->rom) { + if (wd->rombankswitcher && (addr & 0xffe0) == GVP_ROM_OFFSET) + wd->rombank = (addr & 0x02) >> 1; + v = (wd->rom[(addr - GVP_ROM_OFFSET) / 2 + wd->rombank * 16384] << 8) | wd->gdmac.version; + } else { + v = wd->gdmac.version; + } } else { - v = wd->gdmac.version; + if (wd->rom) { + v = (wd->rom[addr - GVP_ROM_OFFSET] << 8) | (wd->rom[addr - GVP_ROM_OFFSET + 1]); + } } + } else if (addr >= GVP_SERIES_I_RAM_OFFSET && !wd->gdmac.series2) { +#if GVP_S1_DEBUG_IO > 1 + int off = wd->gdmac.bufoffset; +#endif + v = wd->gdmac.buffer[wd->gdmac.bufoffset++] << 8; + wd->gdmac.bufoffset &= GVP_SERIES_I_RAM_MASK; + v |= wd->gdmac.buffer[wd->gdmac.bufoffset++] << 0; + wd->gdmac.bufoffset &= GVP_SERIES_I_RAM_MASK; +#if GVP_S1_DEBUG_IO > 1 + write_log(_T("gvp_s1_wget sram %d %04x\n"), off, v); +#endif } else if (wd->configured) { - switch (addr) - { - case 0x40: - v = wd->gdmac.cntr; - break; - case 0x68: - v = wd->gdmac.bank; - break; - case 0x70: - v = wd->gdmac.addr >> 16; - break; - case 0x72: - v = wd->gdmac.addr; - break; - default: - write_log(_T("gvp_wget_unk %04X PC=%08X\n"), addr, M68K_GETPC); - break; + if (wd->gdmac.series2) { + switch (addr) + { + case 0x40: + v = wd->gdmac.cntr; + break; + case 0x68: + v = wd->gdmac.bank; + break; + case 0x70: + v = wd->gdmac.addr >> 16; + break; + case 0x72: + v = wd->gdmac.addr; + break; + default: + write_log(_T("gvp_s2_wget_unk %04X PC=%08X\n"), addr, M68K_GETPC); + break; + } +#if GVP_S2_DEBUG_IO > 0 + write_log(_T("gvp_s2_wget %04X=%04X PC=%08X\n"), addr, v, M68K_GETPC); +#endif + } else { +#if GVP_S1_DEBUG_IO > 0 + write_log(_T("gvp_s1_wget %04X=%04X PC=%08X\n"), addr, v, M68K_GETPC); +#endif } } else { v = 0xffff; } -#if GVP_DEBUG_IO > 0 - write_log(_T("gvp_wget %04X=%04X PC=%08X\n"), addr, v, M68K_GETPC); -#endif - return v; } @@ -2068,39 +2183,59 @@ static void dmac_gvp_write_word(struct wd_state *wd, uaecptr addr, uae_u32 b) if (addr >= GVP_ROM_OFFSET) return; -#if GVP_DEBUG_IO > 0 - write_log(_T("gvp_wput %04X=%04X PC=%08X\n"), addr, b & 65535, M68K_GETPC); + if (addr >= GVP_SERIES_I_RAM_OFFSET && !wd->gdmac.series2) { +#if GVP_S1_DEBUG_IO > 1 + int off = wd->gdmac.bufoffset; +#endif + wd->gdmac.buffer[wd->gdmac.bufoffset++] = b >> 8; + wd->gdmac.bufoffset &= GVP_SERIES_I_RAM_MASK; + wd->gdmac.buffer[wd->gdmac.bufoffset++] = b; + wd->gdmac.bufoffset &= GVP_SERIES_I_RAM_MASK; +#if GVP_S1_DEBUG_IO > 1 + write_log(_T("gvp_s1_wput sram %d %04x\n"), off, b); +#endif + return; + } + + if (wd->gdmac.series2) { +#if GVP_S2_DEBUG_IO > 0 + write_log(_T("gvp_s2_wput %04X=%04X PC=%08X\n"), addr, b & 65535, M68K_GETPC); +#endif + switch (addr) + { + case 0x40: + b &= ~(1 | 2); + wd->gdmac.cntr = b; + break; + case 0x70: // ACR + wd->gdmac.addr &= 0x0000ffff; + wd->gdmac.addr |= (b & 0xff) << 16; + wd->gdmac.addr &= wd->gdmac.addr_mask; + break; + case 0x72: // ACR + wd->gdmac.addr &= 0xffff0000; + wd->gdmac.addr |= b; + wd->gdmac.addr &= wd->gdmac.addr_mask; + break; + case 0x76: // START DMA + wd->gdmac.dma_on = 1; + break; + case 0x78: // STOP DMA + wd->gdmac.dma_on = 0; + break; + case 0x74: // "secret1" + case 0x7a: // "secret2" + case 0x7c: // "secret3" + write_log(_T("gvp_s2_wput_config %04X=%04X PC=%08X\n"), addr, b & 65535, M68K_GETPC); + break; + default: + write_log(_T("gvp_s2_wput_unk %04X=%04X PC=%08X\n"), addr, b & 65535, M68K_GETPC); + break; + } + } else { +#if GVP_S1_DEBUG_IO > 0 + write_log(_T("gvp_s1_wput %04X=%04X PC=%08X\n"), addr, b & 65535, M68K_GETPC); #endif - switch (addr) - { - case 0x40: - b &= ~(1 | 2); - wd->gdmac.cntr = b; - break; - case 0x70: // ACR - wd->gdmac.addr &= 0x0000ffff; - wd->gdmac.addr |= (b & 0xff) << 16; - wd->gdmac.addr &= wd->gdmac.addr_mask; - break; - case 0x72: // ACR - wd->gdmac.addr &= 0xffff0000; - wd->gdmac.addr |= b; - wd->gdmac.addr &= wd->gdmac.addr_mask; - break; - case 0x76: // START DMA - wd->gdmac.dma_on = 1; - break; - case 0x78: // STOP DMA - wd->gdmac.dma_on = 0; - break; - case 0x74: // "secret1" - case 0x7a: // "secret2" - case 0x7c: // "secret3" - write_log(_T("gvp_wput_config %04X=%04X PC=%08X\n"), addr, b & 65535, M68K_GETPC); - break; - default: - write_log(_T("gvp_wput_unk %04X=%04X PC=%08X\n"), addr, b & 65535, M68K_GETPC); - break; } } @@ -2111,38 +2246,90 @@ static void dmac_gvp_write_byte(struct wd_state *wd, uaecptr addr, uae_u32 b) if (addr >= GVP_ROM_OFFSET) return; -#if GVP_DEBUG_IO > 0 - write_log(_T("gvp_bput %04X=%02X PC=%08X\n"), addr, b & 255, M68K_GETPC); + if (addr >= GVP_SERIES_I_RAM_OFFSET && !wd->gdmac.series2) { + wd->gdmac.buffer[wd->gdmac.bufoffset++] = b; + wd->gdmac.bufoffset &= GVP_SERIES_I_RAM_MASK; + return; + } + + if (wd->gdmac.series2) { +#if GVP_S2_DEBUG_IO > 0 + write_log(_T("gvp_s2_bput %04X=%02X PC=%08X\n"), addr, b & 255, M68K_GETPC); #endif - switch (addr) - { - case 0x40: - wd->gdmac.cntr &= 0x00ff; - wd->gdmac.cntr |= b << 8; - break; - case 0x41: - b &= ~(1 | 2); - wd->gdmac.cntr &= 0xff00; - wd->gdmac.cntr |= b << 0; - break; - case 0x61: // SASR - wdscsi_sasr(&wd->wc, b); - break; - case 0x63: // SCMD - wdscsi_put(&wd->wc, wd, b); - break; - case 0x74: // "secret1" - case 0x75: - case 0x7a: // "secret2" - case 0x7b: - case 0x7c: // "secret3" - case 0x7d: - write_log(_T("gvp_bput_config %04X=%04X PC=%08X\n"), addr, b & 255, M68K_GETPC); - break; - default: - write_log(_T("gvp_bput_unk %04X=%02X PC=%08X\n"), addr, b & 255, M68K_GETPC); - break; + switch (addr) + { + case 0x40: + wd->gdmac.cntr &= 0x00ff; + wd->gdmac.cntr |= b << 8; + break; + case 0x41: + b &= ~(1 | 2); + wd->gdmac.cntr &= 0xff00; + wd->gdmac.cntr |= b << 0; + break; + case 0x61: // SASR + wdscsi_sasr(&wd->wc, b); + break; + case 0x63: // SCMD + wdscsi_put(&wd->wc, wd, b); + break; + + case 0x74: // "secret1" + case 0x75: + case 0x7a: // "secret2" + case 0x7b: + case 0x7c: // "secret3" + case 0x7d: + write_log(_T("gvp_s2_bput_config %04X=%04X PC=%08X\n"), addr, b & 255, M68K_GETPC); + break; + default: + write_log(_T("gvp_s2_bput_unk %04X=%02X PC=%08X\n"), addr, b & 255, M68K_GETPC); + break; + } + } else { +#if GVP_S1_DEBUG_IO > 0 + write_log(_T("gvp_s1_bput %04X=%02X PC=%08X\n"), addr, b & 255, M68K_GETPC); +#endif + switch (addr) + { + case 0x60: // SASR + wdscsi_sasr(&wd->wc, b); + break; + case 0x62: // SCMD + wdscsi_put(&wd->wc, wd, b); + break; + + // 68: + // 00 CPU SRAM access + // ff WD SRAM access + + // 6c: + // 28 0010 startup reset? + // b8 1011 before CPU reading from SRAM + // a8 1100 before CPU writing to SRAM + // e8 1110 before starting WD write DMA + // f8 1111 access done/start WD read DMA + // 08 = intena? + + case 0x68: +#if GVP_S1_DEBUG_IO > 0 + write_log(_T("gvp_s1_bput_s1 %04X=%04X PC=%08X\n"), addr, b & 255, M68K_GETPC); +#endif + wd->gdmac.bufoffset = 0; + break; + case 0x6c: +#if GVP_S1_DEBUG_IO > 0 + write_log(_T("gvp_s1_bput_s1 %04X=%04X PC=%08X\n"), addr, b & 255, M68K_GETPC); +#endif + wd->gdmac.cntr = b & 8; + break; + + default: + write_log(_T("gvp_s1_bput_unk %04X=%02X PC=%08X\n"), addr, b & 255, M68K_GETPC); + break; + } } + } static uae_u32 REGPARAM2 dmac_gvp_lget(struct wd_state *wd, uaecptr addr) @@ -2230,10 +2417,12 @@ static uae_u32 REGPARAM2 dmac_gvp_wgeti(struct wd_state *wd, uaecptr addr) special_mem |= S_READ; #endif addr &= 65535; - if (addr >= GVP_ROM_OFFSET) + if (addr >= GVP_ROM_OFFSET) { + addr -= GVP_ROM_OFFSET; v = (wd->rom[addr & wd->rom_mask] << 8) | wd->rom[(addr + 1) & wd->rom_mask]; - else + } else { write_log(_T("Invalid GVP instruction access %08x\n"), addr); + } return v; } static uae_u32 REGPARAM2 dmac_gvp_lgeti(struct wd_state *wd, uaecptr addr) @@ -2306,11 +2495,53 @@ addrbank gvp_bank = { dmac_gvp_xlate, dmac_gvp_check, NULL, NULL, _T("GVP"), dmac_gvp_lgeti, dmac_gvp_wgeti, ABFLAG_IO | ABFLAG_SAFE }; + +static uae_u8 *REGPARAM2 dmac_gvp_2_xlate(uaecptr addr) +{ + return dmac_gvp_xlate(&wd_gvp_2, addr); +} +static int REGPARAM2 dmac_gvp_2_check(uaecptr addr, uae_u32 size) +{ + return dmac_gvp_check(&wd_gvp_2, addr, size); +} +static uae_u32 REGPARAM2 dmac_gvp_2_lgeti(uaecptr addr) +{ + return dmac_gvp_lgeti(&wd_gvp_2, addr); +} +static uae_u32 REGPARAM2 dmac_gvp_2_wgeti(uaecptr addr) +{ + return dmac_gvp_wgeti(&wd_gvp_2, addr); +} +static uae_u32 REGPARAM2 dmac_gvp_2_bget(uaecptr addr) +{ + return dmac_gvp_bget(&wd_gvp_2, addr); +} +static uae_u32 REGPARAM2 dmac_gvp_2_wget(uaecptr addr) +{ + return dmac_gvp_wget(&wd_gvp_2, addr); +} +static uae_u32 REGPARAM2 dmac_gvp_2_lget(uaecptr addr) +{ + return dmac_gvp_lget(&wd_gvp_2, addr); +} +static void REGPARAM2 dmac_gvp_2_bput(uaecptr addr, uae_u32 b) +{ + dmac_gvp_bput(&wd_gvp_2, addr, b); +} +static void REGPARAM2 dmac_gvp_2_wput(uaecptr addr, uae_u32 b) +{ + dmac_gvp_wput(&wd_gvp_2, addr, b); +} +static void REGPARAM2 dmac_gvp_2_lput(uaecptr addr, uae_u32 b) +{ + dmac_gvp_lput(&wd_gvp_2, addr, b); +} + addrbank gvp_2_bank = { - dmac_gvp_lget, dmac_gvp_wget, dmac_gvp_bget, - dmac_gvp_lput, dmac_gvp_wput, dmac_gvp_bput, - dmac_gvp_xlate, dmac_gvp_check, NULL, NULL, _T("GVP #2"), - dmac_gvp_lgeti, dmac_gvp_wgeti, ABFLAG_IO | ABFLAG_SAFE + dmac_gvp_2_lget, dmac_gvp_2_wget, dmac_gvp_2_bget, + dmac_gvp_2_lput, dmac_gvp_2_wput, dmac_gvp_2_bput, + dmac_gvp_2_xlate, dmac_gvp_2_check, NULL, NULL, _T("GVP #2"), + dmac_gvp_2_lgeti, dmac_gvp_2_wgeti, ABFLAG_IO | ABFLAG_SAFE }; /* SUPERDMAC (A3000 mainboard built-in) */ @@ -2616,7 +2847,7 @@ static void *scsi_thread (void *wdv) wd_cmd_sel_xfer (wd, wds, false); break; case WD_CMD_TRANS_INFO: - wd_cmd_trans_info (wd, wd->scsi); + wd_cmd_trans_info (wds, wd->scsi); break; case WD_CMD_TRANS_ADDR: wd_cmd_trans_addr(wd, wds); @@ -2660,109 +2891,15 @@ void init_wd_scsi (struct wd_state *wd) } } -static void freescsi (struct scsi_data *sd) -{ - if (!sd) - return; - hdf_hd_close (sd->hfd); - scsi_free (sd); -} - -int add_wd_scsi_hd (struct wd_state *wd, int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci, int scsi_level) -{ - freescsi (wd->scsis[ch]); - wd->scsis[ch] = NULL; - if (!hfd) { - hfd = xcalloc (struct hd_hardfiledata, 1); - memcpy (&hfd->hfd.ci, ci, sizeof (struct uaedev_config_info)); - } - if (!hdf_hd_open (hfd)) - return 0; - hfd->ansi_version = scsi_level; - wd->scsis[ch] = scsi_alloc_hd (ch, hfd); - return wd->scsis[ch] ? 1 : 0; -} - -int add_wd_scsi_cd (struct wd_state *wd, int ch, int unitnum) -{ - device_func_init (0); - freescsi (wd->scsis[ch]); - wd->scsis[ch] = scsi_alloc_cd (ch, unitnum, false); - return wd->scsis[ch] ? 1 : 0; -} - -int add_wd_scsi_tape (struct wd_state *wd, int ch, const TCHAR *tape_directory, bool readonly) -{ - freescsi (wd->scsis[ch]); - wd->scsis[ch] = scsi_alloc_tape (ch, tape_directory, readonly); - return wd->scsis[ch] ? 1 : 0; -} - -static void freenativescsi (struct wd_state *wd) -{ - int i; - for (i = 0; i < 8; i++) { - freescsi (wd->scsis[i]); - wd->scsis[i] = NULL; - } -} - -static void addnativescsi (struct wd_state *wd) -{ - int i, j; - int devices[MAX_TOTAL_SCSI_DEVICES]; - int types[MAX_TOTAL_SCSI_DEVICES]; - struct device_info dis[MAX_TOTAL_SCSI_DEVICES]; - - freenativescsi (wd); - i = 0; - while (i < MAX_TOTAL_SCSI_DEVICES) { - types[i] = -1; - devices[i] = -1; - if (sys_command_open (i)) { - if (sys_command_info (i, &dis[i], 0)) { - devices[i] = i; - types[i] = 100 - i; - if (dis[i].type == INQ_ROMD) - types[i] = 1000 - i; - } - sys_command_close (i); - } - i++; - } - i = 0; - while (devices[i] >= 0) { - j = i + 1; - while (devices[j] >= 0) { - if (types[i] > types[j]) { - int tmp = types[i]; - types[i] = types[j]; - types[j] = tmp; - } - j++; - } - i++; - } - i = 0; j = 0; - while (devices[i] >= 0 && j < 7) { - if (wd->scsis[j] == NULL) { - wd->scsis[j] = scsi_alloc_native(j, devices[i]); - write_log (_T("SCSI: %d:'%s'\n"), j, dis[i].label); - i++; - } - j++; - } -} - int a3000_add_scsi_unit (int ch, struct uaedev_config_info *ci) { struct wd_state *wd = &wd_a3000; if (ci->type == UAEDEV_CD) - return add_wd_scsi_cd (wd, ch, ci->device_emu_unit); + return add_scsi_cd (wd->scsis, ch, ci->device_emu_unit); else if (ci->type == UAEDEV_TAPE) - return add_wd_scsi_tape (wd, ch, ci->rootdir, ci->readonly); + return add_scsi_tape (wd->scsis, ch, ci->rootdir, ci->readonly); else - return add_wd_scsi_hd (wd, ch, NULL, ci, 2); + return add_scsi_hd (wd->scsis, ch, NULL, ci, 2); } void a3000scsi_reset (void) @@ -2781,7 +2918,7 @@ void a3000scsi_reset (void) void a3000scsi_free (void) { struct wd_state *wd = &wd_a3000; - freenativescsi (wd); + scsi_freenative(wd->scsis); if (wd->scsi_thread_running > 0) { wd->scsi_thread_running = 0; write_comm_pipe_u32 (&wd->requests, 0xffffffff, 1); @@ -2796,11 +2933,11 @@ int a2091_add_scsi_unit(int ch, struct uaedev_config_info *ci, int devnum) struct wd_state *wd = wda2091[devnum]; if (ci->type == UAEDEV_CD) - return add_wd_scsi_cd(wd, ch, ci->device_emu_unit); + return add_scsi_cd(wd->scsis, ch, ci->device_emu_unit); else if (ci->type == UAEDEV_TAPE) - return add_wd_scsi_tape(wd, ch, ci->rootdir, ci->readonly); + return add_scsi_tape(wd->scsis, ch, ci->rootdir, ci->readonly); else - return add_wd_scsi_hd(wd, ch, NULL, ci, 1); + return add_scsi_hd(wd->scsis, ch, NULL, ci, 1); } int gvp_add_scsi_unit(int ch, struct uaedev_config_info *ci, int devnum) @@ -2808,16 +2945,16 @@ int gvp_add_scsi_unit(int ch, struct uaedev_config_info *ci, int devnum) struct wd_state *wd = gvpscsi[devnum]; if (ci->type == UAEDEV_CD) - return add_wd_scsi_cd(wd, ch, ci->device_emu_unit); + return add_scsi_cd(wd->scsis, ch, ci->device_emu_unit); else if (ci->type == UAEDEV_TAPE) - return add_wd_scsi_tape(wd, ch, ci->rootdir, ci->readonly); + return add_scsi_tape(wd->scsis, ch, ci->rootdir, ci->readonly); else - return add_wd_scsi_hd(wd, ch, NULL, ci, 2); + return add_scsi_hd(wd->scsis, ch, NULL, ci, 2); } void a2091_free_device (struct wd_state *wd) { - freenativescsi (wd); + scsi_freenative(wd->scsis); xfree (wd->rom); wd->rom = NULL; } @@ -2835,7 +2972,7 @@ static void a2091_reset_device(struct wd_state *wd) wd->dmac_type = COMMODORE_DMAC; wd->cdmac.old_dmac = 0; if (currprefs.scsi == 2) - addnativescsi (wd); + scsi_addnative(wd->scsis); wd_cmd_reset (&wd->wc, false); reset_dmac(wd); if (wd == &wd_a2091) @@ -2927,7 +3064,7 @@ addrbank *a2091_init (int devnum) void gvp_free_device (struct wd_state *wd) { - freenativescsi (wd); + scsi_freenative(wd->scsis); xfree (wd->rom); wd->rom = NULL; } @@ -2942,13 +3079,9 @@ static void gvp_reset_device(struct wd_state *wd) wd->configured = 0; wd->wc.wd_used = 0; wd->wc.wd33c93_ver = 1; - wd->dmac_type = GVP_DMAC; - wd->gdmac.version = GVP_SERIESII; - if (wd->gdmac.series2) - wd->gdmac.version |= 1; - wd->gdmac.addr_mask = 0x00ffffff; + wd->dmac_type = wd->gdmac.series2 ? GVP_DMAC_S2 : GVP_DMAC_S1; if (currprefs.scsi == 2) - addnativescsi (wd); + scsi_addnative(wd->scsis); wd_cmd_reset (&wd->wc, false); reset_dmac(wd); if (wd == &wd_gvp) @@ -2966,13 +3099,14 @@ void gvp_reset (void) static const uae_u8 gvp_scsi_i_autoconfig[16] = { 0xd1, 0x09, 0x00, 0x00, 0x07, 0xe1, 0xee, 0xee, 0xee, 0xee, 0x80, 0x00 }; static const uae_u8 gvp_scsi_ii_autoconfig[16] = { 0xd1, 0x0b, 0x00, 0x00, 0x07, 0xe1, 0xee, 0xee, 0xee, 0xee, 0x80, 0x00 }; -addrbank *gvp_init(int devnum) +addrbank *gvp_init(int devnum, bool series2) { struct wd_state *wd = gvpscsi[devnum]; int roms[6]; struct romlist *rl; + struct boardromconfig *brc = series2 ? &currprefs.gvps2rom : &currprefs.gvps1rom; - if (devnum > 0 && !wd->enabled) + if (devnum > 0 && !wd->enabled && currprefs.cpuboard_type != BOARD_GVP_A530) return &expamem_null; init_wd_scsi(wd); @@ -2981,6 +3115,13 @@ addrbank *gvp_init(int devnum) wd->autoconfig = true; wd->rombankswitcher = 0; memset(wd->dmacmemory, 0xff, sizeof wd->dmacmemory); + wd->gdmac.series2 = series2; + wd->gdmac.version = GVP_SERIESII; + wd->gdmac.addr_mask = 0x00ffffff; + if (currprefs.cpuboard_type == BOARD_GVP_A530) { + wd->gdmac.version = GVP_A530_SCSI; + wd->gdmac.addr_mask = 0x01ffffff; + } roms[0] = 109; roms[1] = 110; @@ -2990,36 +3131,45 @@ addrbank *gvp_init(int devnum) wd->rom_size = 32768; wd->rom = xcalloc(uae_u8, wd->rom_size); memset(wd->rom, 0xff, wd->rom_size); - wd->rom_mask = wd->rom_size - 1; - wd->gdmac.series2 = true; - - for (int i = 0; i < 16; i++) { - uae_u8 b = wd->gdmac.series2 ? gvp_scsi_ii_autoconfig[i] : gvp_scsi_i_autoconfig[i]; - ew(wd, i * 4, b); - } + wd->rom_mask = 32768 - 1; - if (_tcscmp (currprefs.gvprom.roms[0].romfile, _T(":NOROM"))) { - const TCHAR *romname = devnum && currprefs.gvprom.roms[1].romfile[0] ? currprefs.gvprom.roms[1].romfile : currprefs.gvprom.roms[0].romfile; + if (_tcscmp (brc->roms[0].romfile, _T(":NOROM"))) { + const TCHAR *romname = devnum && brc->roms[1].romfile[0] ? brc->roms[1].romfile : brc->roms[0].romfile; struct zfile *z = read_rom_name(romname); if (!z) { rl = getromlistbyids(roms, romname); if (rl) { z = read_rom(rl->rd); } - if (rl && rl->rd && rl->rd->id == 111) - wd->gdmac.series2 = false; } if (z) { write_log(_T("GVP BOOT ROM '%s'\n"), zfile_getname(z)); - int size = zfile_fread(wd->rom, 1, wd->rom_size, z); + int size = zfile_size(z); + if (series2) { + zfile_fread(wd->rom, 1, wd->rom_size, z); + } else { + xfree(wd->gdmac.buffer); + wd->gdmac.buffer = xcalloc(uae_u8, GVP_SERIES_I_RAM_MASK + 1); + for (int i = 0; i < 16384; i++) { + uae_u8 b; + zfile_fread(&b, 1, 1, z); + wd->rom[i] = b; + } + } zfile_fclose(z); - if (size > 16384) { + if (series2 && size > 16384) { wd->rombankswitcher = 1; } } else { romwarning(roms); } } + + for (int i = 0; i < 16; i++) { + uae_u8 b = wd->gdmac.series2 ? gvp_scsi_ii_autoconfig[i] : gvp_scsi_i_autoconfig[i]; + ew(wd, i * 4, b); + } + gvp_reset_device(wd); return wd == &wd_gvp ? &gvp_bank : &gvp_2_bank; } @@ -3163,19 +3313,19 @@ uae_u8 *restore_scsi_device (int wdtype, uae_u8 *src) wd->cdmac.xt_control = restore_u8(); } if (size) - add_wd_scsi_hd (wd, num, hfd, NULL, s->hfd->ansi_version); + add_scsi_hd (wd->scsis, num, hfd, NULL, s->hfd->ansi_version); xfree (path); break; case UAEDEV_CD: num2 = restore_u32 (); - add_wd_scsi_cd (wd, num, num2); + add_scsi_cd (wd->scsis, num, num2); break; case UAEDEV_TAPE: num2 = restore_u32 (); blocksize = restore_u32 (); readonly = restore_u32 (); path = restore_string (); - add_wd_scsi_tape (wd, num, path, readonly != 0); + add_scsi_tape (wd->scsis, num, path, readonly != 0); xfree (path); break; } diff --git a/cdtv.cpp b/cdtv.cpp index 02ba686d..0c4fe643 100644 --- a/cdtv.cpp +++ b/cdtv.cpp @@ -30,6 +30,7 @@ #include "a2091.h" #include "uae.h" #include "savestate.h" +#include "scsi.h" /* DMAC CNTR bits. */ #define CNTR_TCEN (1<<7) @@ -1635,7 +1636,7 @@ uae_u8 cdtv_battram_read (int addr) int cdtv_add_scsi_hd_unit (int ch, struct uaedev_config_info *ci) { - return add_wd_scsi_hd (&wd_cdtv, ch, NULL, ci, 1); + return add_scsi_hd (wd_cdtv.scsis, ch, NULL, ci, 1); } void cdtv_free (void) diff --git a/cfgfile.cpp b/cfgfile.cpp index 86148bd0..edd03b6c 100644 --- a/cfgfile.cpp +++ b/cfgfile.cpp @@ -225,6 +225,8 @@ static const TCHAR *cpuboards[] = { _T("FusionForty"), _T("A3001SI"), _T("A3001SII"), + _T("Apollo"), + _T("GVPA530"), NULL }; static const TCHAR *ppc_implementations[] = { @@ -251,16 +253,34 @@ static const TCHAR *ppc_cpu_idle[] = { static const TCHAR *waitblits[] = { _T("disabled"), _T("automatic"), _T("noidleonly"), _T("always"), 0 }; static const TCHAR *autoext2[] = { _T("disabled"), _T("copy"), _T("replace"), 0 }; static const TCHAR *leds[] = { _T("power"), _T("df0"), _T("df1"), _T("df2"), _T("df3"), _T("hd"), _T("cd"), _T("fps"), _T("cpu"), _T("snd"), _T("md"), 0 }; -static int leds_order[] = { 3, 6, 7, 8, 9, 4, 5, 2, 1, 0, 9 }; +static const int leds_order[] = { 3, 6, 7, 8, 9, 4, 5, 2, 1, 0, 9 }; static const TCHAR *lacer[] = { _T("off"), _T("i"), _T("p"), 0 }; static const TCHAR *hdcontrollers[] = { _T("uae"), - _T("ide%d"), _T("ide%d_mainboard"), _T("ide%d_a3001"), - _T("scsi%d"), _T("scsi%d_a2091"), _T("scsi%d_a2091-2"), _T("scsi%d_gvp"), _T("scsi%d_gvp-2"), _T("scsi%d_a4091"), _T("scsi%d_a4091-2"), + + _T("ide%d"), + _T("ide%d_mainboard"), + _T("ide%d_a3001"), + _T("ide%d_alfa"), _T("ide%d_alfa-2"), + _T("ide%d_apollo"), _T("ide%d_apollo-2"), + _T("ide%d_masoboshi"), _T("ide%d_masoboshi-2"), + //_T("ide%d_adide"), _T("ide%d_adide-2"), + + _T("scsi%d"), + _T("scsi%d_a2091"), _T("scsi%d_a2091-2"), + _T("scsi%d_gvp"), _T("scsi%d_gvp-2"), + _T("scsi%d_a4091"), _T("scsi%d_a4091-2"), _T("scsi%d_fastlane"), _T("scsi%d_fastlane-2"), _T("scsi%d_oktagon2008"), _T("scsi%d_oktagon2008-2"), - _T("scsi%d_a3000"), _T("scsi%d_a4000t"), _T("scsi%d_cdtv"), _T("scsi%d_cpuboard"), - _T("scsram"), _T("scide") + _T("scsi%d_apollo"), _T("scsi%d_apollo-2"), + _T("scsi%d_masoboshi"), _T("scsi%d_masoboshi-2"), + _T("scsi%d_a3000"), + _T("scsi%d_a4000t"), + _T("scsi%d_cdtv"), + _T("scsi%d_cpuboard"), + + _T("scsram"), + _T("scide") }; static const TCHAR *z3mapping[] = { _T("auto"), @@ -290,6 +310,16 @@ static const TCHAR *obsolete[] = { _T("gfx_filter_vert_offset"), _T("gfx_filter_horiz_offset"), _T("rtg_vert_zoom_multf"), _T("rtg_horiz_zoom_multf"), + // created by some buggy beta + _T("uaehf0%s,%s"), + _T("uaehf1%s,%s"), + _T("uaehf2%s,%s"), + _T("uaehf3%s,%s"), + _T("uaehf4%s,%s"), + _T("uaehf5%s,%s"), + _T("uaehf6%s,%s"), + _T("uaehf7%s,%s"), + NULL }; @@ -1030,10 +1060,15 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_write_str (f, _T("kickstart_ext_rom="), p->romextident); cfgfile_write_board_rom(f, &p->path_rom, &p->a2091rom, _T("a2091")); - cfgfile_write_board_rom(f, &p->path_rom, &p->gvprom, _T("gvp")); + cfgfile_write_board_rom(f, &p->path_rom, &p->gvps1rom, _T("gvp1")); + cfgfile_write_board_rom(f, &p->path_rom, &p->gvps2rom, _T("gvp")); cfgfile_write_board_rom(f, &p->path_rom, &p->a4091rom, _T("a4091")); cfgfile_write_board_rom(f, &p->path_rom, &p->fastlanerom, _T("fastlane")); cfgfile_write_board_rom(f, &p->path_rom, &p->oktagonrom, _T("oktagon2008")); + cfgfile_write_board_rom(f, &p->path_rom, &p->alfrom, _T("alfapower")); + cfgfile_write_board_rom(f, &p->path_rom, &p->alfplusrom, _T("alfapowerplus")); + cfgfile_write_board_rom(f, &p->path_rom, &p->apollorom, _T("apollo")); + cfgfile_write_board_rom(f, &p->path_rom, &p->masoboshirom, _T("masoboshi")); cfgfile_write_rom(f, &p->path_rom, p->acceleratorromfile, _T("cpuboard_rom_file")); if (p->acceleratorromident[0]) @@ -3136,7 +3171,7 @@ static void get_filesys_controller (const TCHAR *hdc, int *type, int *num) const TCHAR *ext2 = _tcsrchr(hdcontrollers[i], '_'); if (ext2) { ext2++; - if (!_tcsicmp(ext, ext2)) { + if (!_tcsicmp(ext, ext2) && hdc[0] == hdcontrollers[i][0]) { hdcv = i; break; } @@ -3841,7 +3876,9 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->a2091rom, _T("a2091"), ROMTYPE_A2091)) return 1; - if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->gvprom, _T("gvp"), ROMTYPE_GVP)) + if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->gvps1rom, _T("gvp1"), ROMTYPE_GVPS1)) + return 1; + if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->gvps2rom, _T("gvp"), ROMTYPE_GVPS2)) return 1; if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->a4091rom, _T("a4091"), ROMTYPE_A4091)) return 1; @@ -3849,6 +3886,14 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH return 1; if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->oktagonrom, _T("oktagon2008"), ROMTYPE_OKTAGON)) return 1; + if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->alfrom, _T("alfapower"), ROMTYPE_ALFA)) + return 1; + if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->alfplusrom, _T("alfapowerplus"), ROMTYPE_ALFAPLUS)) + return 1; + if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->apollorom, _T("apollo"), ROMTYPE_APOLLO)) + return 1; + if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->masoboshirom, _T("masoboshi"), ROMTYPE_MASOBOSHI)) + return 1; for (i = 0; i < 4; i++) { _stprintf (tmpbuf, _T("floppy%d"), i); @@ -4435,9 +4480,13 @@ static int cfgfile_load_2 (struct uae_prefs *p, const TCHAR *filename, bool real for (i = 0; i < MAX_BOARD_ROMS; i++) { subst(p->path_rom.path[0], p->a2091rom.roms[i].romfile, MAX_DPATH / sizeof(TCHAR)); - subst(p->path_rom.path[0], p->gvprom.roms[i].romfile, MAX_DPATH / sizeof(TCHAR)); + subst(p->path_rom.path[0], p->gvps1rom.roms[i].romfile, MAX_DPATH / sizeof(TCHAR)); + subst(p->path_rom.path[0], p->gvps2rom.roms[i].romfile, MAX_DPATH / sizeof(TCHAR)); subst(p->path_rom.path[0], p->a4091rom.roms[i].romfile, MAX_DPATH / sizeof(TCHAR)); subst(p->path_rom.path[0], p->fastlanerom.roms[i].romfile, MAX_DPATH / sizeof (TCHAR)); + subst(p->path_rom.path[0], p->alfrom.roms[i].romfile, MAX_DPATH / sizeof (TCHAR)); + subst(p->path_rom.path[0], p->alfplusrom.roms[i].romfile, MAX_DPATH / sizeof (TCHAR)); + subst(p->path_rom.path[0], p->masoboshirom.roms[i].romfile, MAX_DPATH / sizeof (TCHAR)); } return 1; @@ -6093,6 +6142,8 @@ static int bip_a1200 (struct uae_prefs *p, int config, int compa, int romcheck) roms[2] = 31; roms[3] = -1; p->cs_rtc = 0; + p->cs_compatible = CP_A1200; + built_in_chipset_prefs (p); switch (config) { case 1: @@ -6132,8 +6183,6 @@ static int bip_a1200 (struct uae_prefs *p, int config, int compa, int romcheck) break; } set_68020_compa (p, compa, 0); - p->cs_compatible = CP_A1200; - built_in_chipset_prefs (p); return configure_rom (p, roms, romcheck); } @@ -6145,6 +6194,9 @@ static int bip_a600 (struct uae_prefs *p, int config, int compa, int romcheck) roms[1] = 9; roms[2] = 8; roms[3] = -1; + set_68000_compa (p, compa); + p->cs_compatible = CP_A600; + built_in_chipset_prefs (p); p->bogomem_size = 0; p->chipmem_size = 0x100000; if (config > 0) @@ -6154,9 +6206,6 @@ static int bip_a600 (struct uae_prefs *p, int config, int compa, int romcheck) if (config == 2) p->fastmem_size = 0x400000; p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE; - set_68000_compa (p, compa); - p->cs_compatible = CP_A600; - built_in_chipset_prefs (p); return configure_rom (p, roms, romcheck); } @@ -6166,6 +6215,9 @@ static int bip_a500p (struct uae_prefs *p, int config, int compa, int romcheck) roms[0] = 7; roms[1] = -1; + set_68000_compa (p, compa); + p->cs_compatible = CP_A500P; + built_in_chipset_prefs (p); p->bogomem_size = 0; p->chipmem_size = 0x100000; if (config > 0) @@ -6175,9 +6227,6 @@ static int bip_a500p (struct uae_prefs *p, int config, int compa, int romcheck) if (config == 2) p->fastmem_size = 0x400000; p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE; - set_68000_compa (p, compa); - p->cs_compatible = CP_A500P; - built_in_chipset_prefs (p); return configure_rom (p, roms, romcheck); } static int bip_a500 (struct uae_prefs *p, int config, int compa, int romcheck) diff --git a/cpuboard.cpp b/cpuboard.cpp index b7857919..cbfdbed4 100644 --- a/cpuboard.cpp +++ b/cpuboard.cpp @@ -28,6 +28,8 @@ #include "flashrom.h" #include "uae.h" #include "uae/ppc.h" +#include "idecontrollers.h" +#include "scsi.h" #define CPUBOARD_IO_LOG 0 #define CPUBOARD_IRQ_LOG 0 @@ -266,6 +268,10 @@ static bool is_fusionforty(void) { return currprefs.cpuboard_type == BOARD_FUSIONFORTY; } +static bool is_apollo(void) +{ + return currprefs.cpuboard_type == BOARD_APOLLO; +} DECLARE_MEMORY_FUNCTIONS(blizzardio); static addrbank blizzardio_bank = { @@ -756,7 +762,7 @@ static void REGPARAM2 blizzarde8_bput(uaecptr addr, uae_u32 b) addr &= 65535; if (addr == 0x48 && !configured) { map_banks(&blizzardea_bank, b, 0x20000 >> 16, 0x20000); - write_log(_T("Blizzard/CyberStorm Z2 autoconfigured at %02X0000\n"), b); + write_log(_T("Accelerator Z2 board autoconfigured at %02X0000\n"), b); configured = 1; expamem_next (&blizzardea_bank, NULL); return; @@ -1310,6 +1316,9 @@ void cpuboard_map(void) map_banks(&blizzardio_bank, 0x021d0000 >> 16, 65536 >> 16, 0); map_banks(&blizzardram_bank, blizzardram_bank.start >> 16, cpuboard_size >> 16, 0); } + if (is_apollo()) { + map_banks(&blizzardf0_bank, 0xf00000 >> 16, 131072 >> 16, 0); + } } void cpuboard_reset(void) @@ -1403,6 +1412,13 @@ void cpuboard_init(void) blizzardea_bank.mask = blizzardea_bank.allocated - 1; mapped_malloc(&blizzardea_bank); + } else if (is_apollo()) { + + blizzardf0_bank.start = 0x00f00000; + blizzardf0_bank.allocated = 131072; + blizzardf0_bank.mask = blizzardf0_bank.allocated - 1; + mapped_malloc(&blizzardf0_bank); + } else if (is_fusionforty()) { blizzardf0_bank.start = 0x00f40000; @@ -1635,8 +1651,10 @@ int cpuboard_memorytype(struct uae_prefs *p) case BOARD_TEKMAGIC: case BOARD_FUSIONFORTY: case BOARD_DKB1200: // ?? + case BOARD_APOLLO: return BOARD_MEMORY_HIGHMEM; case BOARD_A2630: + case BOARD_GVP_A530: return BOARD_MEMORY_Z2; case BOARD_BLIZZARD_1230_IV: case BOARD_BLIZZARD_1230_IV_SCSI: @@ -1819,6 +1837,11 @@ addrbank *cpuboard_autoconfig_init(void) roms[0] = 105; roms[1] = 106; break; + case BOARD_GVP_A530: + return &expamem_null; + case BOARD_APOLLO: + roms[0] = 119; + break; case BOARD_A3001_I: case BOARD_A3001_II: return &expamem_null; @@ -1869,31 +1892,36 @@ addrbank *cpuboard_autoconfig_init(void) return &expamem_null; } - struct romlist *rl = getromlistbyids(roms, romname); - if (!rl) { - rd = getromdatabyids(roms); - if (!rd) - return &expamem_null; - } else { - rd = rl->rd; + struct romlist *rl = NULL; + if (roms[0] >= 0) { + getromlistbyids(roms, romname); + if (!rl) { + rd = getromdatabyids(roms); + if (!rd) + return &expamem_null; + } else { + rd = rl->rd; + } + defaultromname = rd->defaultfilename; } - defaultromname = rd->defaultfilename; - if (rl && !isflashrom) { + if (!isflashrom) { if (romname) autoconfig_rom = zfile_fopen(romname, _T("rb")); if (!autoconfig_rom && defaultromname) autoconfig_rom = zfile_fopen(defaultromname, _T("rb")); - if (autoconfig_rom) { - struct romdata *rd2 = getromdatabyids(roms); - // Do not use image if it is not long enough (odd or even only?) - if (!rd2 || zfile_size(autoconfig_rom) < rd2->size) { - zfile_fclose(autoconfig_rom); - autoconfig_rom = NULL; + if (rl) { + if (autoconfig_rom) { + struct romdata *rd2 = getromdatabyids(roms); + // Do not use image if it is not long enough (odd or even only?) + if (!rd2 || zfile_size(autoconfig_rom) < rd2->size) { + zfile_fclose(autoconfig_rom); + autoconfig_rom = NULL; + } } + if (!autoconfig_rom) + autoconfig_rom = read_rom(rl->rd); } - if (!autoconfig_rom) - autoconfig_rom = read_rom(rl->rd); - } else if (isflashrom) { + } else { autoconfig_rom = flashfile_open(romname); if (!autoconfig_rom) { if (rl) @@ -1913,8 +1941,12 @@ addrbank *cpuboard_autoconfig_init(void) write_log (_T("ROM id %d not found for CPU board emulation\n"), roms[0]); return &expamem_null; } - if (autoconfig_rom) - write_log(_T("CPUBoard ROM '%s' %lld loaded\n"), zfile_getname(autoconfig_rom), zfile_size(autoconfig_rom)); + if (!autoconfig_rom) { + write_log(_T("Couldn't open CPU board rom '%s'\n"), defaultromname); + return &expamem_null; + } + + write_log(_T("CPUBoard ROM '%s' %lld loaded\n"), zfile_getname(autoconfig_rom), zfile_size(autoconfig_rom)); protect_roms(false); cpuboard_non_byte_ea = true; @@ -1923,6 +1955,10 @@ addrbank *cpuboard_autoconfig_init(void) zfile_fread(blizzardf0_bank.baseaddr, 1, f0rom_size, autoconfig_rom); autoconf = false; autoconf_stop = true; + } else if (is_apollo()) { + f0rom_size = 131072; + zfile_fread(blizzardf0_bank.baseaddr, 1, 131072, autoconfig_rom); + autoconf = false; } else if (is_fusionforty()) { f0rom_size = 262144; zfile_fread(blizzardf0_bank.baseaddr, 1, 131072, autoconfig_rom); diff --git a/devices.cpp b/devices.cpp index 58fd34c8..e656636e 100644 --- a/devices.cpp +++ b/devices.cpp @@ -65,6 +65,7 @@ void devices_reset(int hardreset) DISK_reset (); CIA_reset (); gayle_reset (0); + apolloscsi_reset(); #ifdef A2091 a2091_reset (); gvp_reset (); @@ -274,6 +275,7 @@ void do_leave_program (void) gvp_free (); a3000scsi_free (); #endif + apolloscsi_free(); #ifdef NCR ncr710_free(); ncr_free(); diff --git a/expansion.cpp b/expansion.cpp index 17d5b28d..fc28c202 100644 --- a/expansion.cpp +++ b/expansion.cpp @@ -1066,6 +1066,9 @@ static addrbank *expamem_init_fastcard_2 (int boardnum) int allocated = boardnum ? fastmem2_bank.allocated : fastmem_bank.allocated; uae_u32 serial = 1; + if (allocated == 0) + return &expamem_null; + expamem_init_clear (); if (allocated == 65536) type |= Z2_MEM_64KB; @@ -1095,10 +1098,22 @@ static addrbank *expamem_init_fastcard_2 (int boardnum) pid = commodore_a2091_ram; mid = commodore; serial = 0; - } else if (cfgfile_board_enabled(&currprefs.gvprom) || currprefs.cpuboard_type == BOARD_A3001_I || currprefs.cpuboard_type == BOARD_A3001_II) { + } else if (cfgfile_board_enabled(&currprefs.gvps1rom) || cfgfile_board_enabled(&currprefs.gvps2rom) || currprefs.cpuboard_type == BOARD_A3001_I || currprefs.cpuboard_type == BOARD_A3001_II) { pid = 10; mid = 2017; serial = 0; + } else if (cfgfile_board_enabled(&currprefs.alfrom) || cfgfile_board_enabled(&currprefs.alfplusrom)) { + pid = 8; + mid = 2092; + serial = 0; + } else if (cfgfile_board_enabled(&currprefs.apollorom)) { + pid = 0; + mid = 8738; + serial = 0; + } else if (cfgfile_board_enabled(&currprefs.masoboshirom)) { + pid = 3; + mid = 2157; + serial = 0; } else { pid = currprefs.maprom && !currprefs.cpuboard_type ? 1 : 81; mid = uae_id; @@ -1644,6 +1659,34 @@ uaecptr need_uae_boot_rom (void) return v; } +static addrbank *expamem_init_masoboshi(void) +{ + return masoboshi_init (0); +} +static addrbank *expamem_init_masoboshi_2(void) +{ + return masoboshi_init (1); +} +static addrbank *expamem_init_alf(void) +{ + return alf_init (0); +} +static addrbank *expamem_init_alf_2(void) +{ + return alf_init (1); +} +static addrbank *expamem_init_apollo(void) +{ + return apollo_init (0); +} +static addrbank *expamem_init_apollo_2(void) +{ + return apollo_init (1); +} +static addrbank *expamem_init_apollo_cpu(void) +{ + return apollo_init (-1); +} #ifdef WITH_TOCCATA static addrbank *expamem_init_toccata(void) { @@ -1667,23 +1710,27 @@ static addrbank *expamem_init_a2091(void) { return a2091_init (0); } -#endif -#ifdef A2091 static addrbank *expamem_init_a2091_2(void) { return a2091_init (1); } #endif #ifdef A2091 -static addrbank *expamem_init_gvp(void) +static addrbank *expamem_init_gvp_s1(void) { - return gvp_init(0); + return gvp_init(0, false); } -#endif -#ifdef A2091 -static addrbank *expamem_init_gvp_2(void) +static addrbank *expamem_init_gvp_s1_2(void) { - return gvp_init(1); + return gvp_init(1, false); +} +static addrbank *expamem_init_gvp_s2(void) +{ + return gvp_init(0, true); +} +static addrbank *expamem_init_gvp_s2_2(void) +{ + return gvp_init(1, true); } #endif #ifdef NCR @@ -1820,6 +1867,18 @@ void expamem_reset (void) card_init[cardno] = expamem_init_a3001_ide; card_map[cardno++] = NULL; } + if (currprefs.cpuboard_type == BOARD_GVP_A530) { + card_flags[cardno] = 1; + card_name[cardno] = _T("GVP A530"); + card_init[cardno] = expamem_init_gvp_s2_2; + card_map[cardno++] = NULL; + } + + if (currprefs.cpuboard_type == BOARD_APOLLO) { + card_name[cardno] = _T("Apollo"); + card_init[cardno] = expamem_init_apollo_cpu; + card_map[cardno++] = NULL; + } #ifdef A2091 if (cfgfile_board_enabled(&currprefs.a2091rom)) { @@ -1833,13 +1892,22 @@ void expamem_reset (void) } #endif #ifdef A2091 - if (cfgfile_board_enabled(&currprefs.gvprom)) { + if (cfgfile_board_enabled(&currprefs.gvps2rom)) { + card_flags[cardno] = 0; + card_name[cardno] = _T("GVP SII"); + card_init[cardno] = expamem_init_gvp_s2; + card_map[cardno++] = NULL; + card_name[cardno] = _T("GVP SII #2"); + card_init[cardno] = expamem_init_gvp_s2_2; + card_map[cardno++] = NULL; + } + if (cfgfile_board_enabled(&currprefs.gvps1rom)) { card_flags[cardno] = 0; - card_name[cardno] = _T("GVP"); - card_init[cardno] = expamem_init_gvp; + card_name[cardno] = _T("GVP SI"); + card_init[cardno] = expamem_init_gvp_s1; card_map[cardno++] = NULL; - card_name[cardno] = _T("GVP #2"); - card_init[cardno] = expamem_init_gvp_2; + card_name[cardno] = _T("GVP SI #2"); + card_init[cardno] = expamem_init_gvp_s1_2; card_map[cardno++] = NULL; } #endif @@ -1853,6 +1921,30 @@ void expamem_reset (void) card_map[cardno++] = NULL; } #endif + if (cfgfile_board_enabled(&currprefs.alfrom) || cfgfile_board_enabled(&currprefs.alfplusrom)) { + card_name[cardno] = _T("ALF"); + card_init[cardno] = expamem_init_alf; + card_map[cardno++] = NULL; + card_name[cardno] = _T("ALF #2"); + card_init[cardno] = expamem_init_alf_2; + card_map[cardno++] = NULL; + } + if (cfgfile_board_enabled(&currprefs.apollorom)) { + card_name[cardno] = _T("Apollo"); + card_init[cardno] = expamem_init_apollo; + card_map[cardno++] = NULL; + card_name[cardno] = _T("Apollo #2"); + card_init[cardno] = expamem_init_apollo_2; + card_map[cardno++] = NULL; + } + if (cfgfile_board_enabled(&currprefs.masoboshirom)) { + card_name[cardno] = _T("Masoboshi"); + card_init[cardno] = expamem_init_masoboshi; + card_map[cardno++] = NULL; + card_name[cardno] = _T("Masoboshi #2"); + card_init[cardno] = expamem_init_masoboshi_2; + card_map[cardno++] = NULL; + } #ifdef CDTV if (currprefs.cs_cdtvcd && !currprefs.cs_cdtvcr) { card_flags[cardno] = 0; diff --git a/filesys.cpp b/filesys.cpp index e758dfb0..33870a90 100644 --- a/filesys.cpp +++ b/filesys.cpp @@ -455,8 +455,10 @@ TCHAR *validatevolumename (TCHAR *s, const TCHAR *def) stripsemicolon (s); fixcharset (s); striplength (s, 30); - if (_tcslen(s) == 0 && def) - _tcscpy(s, def); + if (_tcslen(s) == 0 && def) { + xfree(s); + s = my_strdup(def); + } return s; } TCHAR *validatedevicename (TCHAR *s, const TCHAR *def) @@ -465,8 +467,10 @@ TCHAR *validatedevicename (TCHAR *s, const TCHAR *def) stripspace (s); fixcharset (s); striplength (s, 30); - if (_tcslen(s) == 0 && def) - _tcscpy(s, def); + if (_tcslen(s) == 0 && def) { + xfree(s); + s = my_strdup(def); + } return s; } @@ -484,7 +488,7 @@ TCHAR *filesys_createvolname (const TCHAR *volname, const TCHAR *rootdir, struct if (zv && zv->volumename && _tcslen(zv->volumename) > 0) { nvol = my_strdup(zv->volumename); - validatevolumename (nvol, def); + nvol = validatevolumename (nvol, def); return nvol; } @@ -523,7 +527,7 @@ TCHAR *filesys_createvolname (const TCHAR *volname, const TCHAR *rootdir, struct else nvol = my_strdup (_T("")); } - validatevolumename (nvol, def); + nvol = validatevolumename (nvol, def); xfree (p); return nvol; } @@ -812,6 +816,13 @@ static bool add_cpuboard_scsi_unit(int unit, struct uaedev_config_info *uci) added = true; } #endif + if (currprefs.cpuboard_type == BOARD_APOLLO) { + apollo_add_scsi_unit(unit, uci, 0); + added = true; + } else if (currprefs.cpuboard_type == BOARD_GVP_A530) { + gvp_add_scsi_unit(unit, uci, 1); + added = true; + } return added; } @@ -824,8 +835,40 @@ static bool add_ide_unit(int type, int unit, struct uaedev_config_info *uci) added = true; } } else if (type == HD_CONTROLLER_TYPE_IDE_GVP) { - gvp_add_ide_unit(unit, uci); - added = true; + if (currprefs.cpuboard_type == BOARD_A3001_I || currprefs.cpuboard_type == BOARD_A3001_II) { + gvp_add_ide_unit(unit, uci); + added = true; + } + } else if (type == HD_CONTROLLER_TYPE_IDE_ALFA) { + if (cfgfile_board_enabled(&currprefs.alfrom) || cfgfile_board_enabled(&currprefs.alfplusrom)) { + alf_add_ide_unit(unit, uci, 0); + added = true; + } + } else if (type == HD_CONTROLLER_TYPE_IDE_ALFA_2) { + if (cfgfile_board_enabled(&currprefs.alfrom) || cfgfile_board_enabled(&currprefs.alfplusrom)) { + alf_add_ide_unit(unit, uci, 1); + added = true; + } + } else if (type == HD_CONTROLLER_TYPE_IDE_APOLLO) { + if (cfgfile_board_enabled(&currprefs.apollorom)) { + apollo_add_ide_unit(unit, uci, 0); + added = true; + } + } else if (type == HD_CONTROLLER_TYPE_IDE_APOLLO_2) { + if (cfgfile_board_enabled(&currprefs.apollorom)) { + apollo_add_ide_unit(unit, uci, 1); + added = true; + } + } else if (type == HD_CONTROLLER_TYPE_IDE_MASOBOSHI) { + if (cfgfile_board_enabled(&currprefs.masoboshirom)) { + masoboshi_add_ide_unit(unit, uci, 0); + added = true; + } + } else if (type == HD_CONTROLLER_TYPE_IDE_MASOBOSHI_2) { + if (cfgfile_board_enabled(&currprefs.masoboshirom)) { + masoboshi_add_ide_unit(unit, uci, 1); + added = true; + } } return added; } @@ -872,15 +915,14 @@ static bool add_scsi_unit(int type, int unit, struct uaedev_config_info *uci) #endif } else if (type == HD_CONTROLLER_TYPE_SCSI_GVP) { #ifdef A2091 - if (cfgfile_board_enabled(&currprefs.gvprom)) { + if (cfgfile_board_enabled(&currprefs.gvps2rom) || cfgfile_board_enabled(&currprefs.gvps1rom)) { gvp_add_scsi_unit(unit, uci, 0); added = true; } #endif - } - else if (type == HD_CONTROLLER_TYPE_SCSI_GVP_2) { + } else if (type == HD_CONTROLLER_TYPE_SCSI_GVP) { #ifdef A2091 - if (cfgfile_board_enabled(&currprefs.gvprom)) { + if (cfgfile_board_enabled(&currprefs.gvps2rom) || cfgfile_board_enabled(&currprefs.gvps1rom)) { gvp_add_scsi_unit(unit, uci, 1); added = true; } @@ -927,6 +969,26 @@ static bool add_scsi_unit(int type, int unit, struct uaedev_config_info *uci) added = true; } #endif + } else if (type == HD_CONTROLLER_TYPE_SCSI_APOLLO) { + if (cfgfile_board_enabled(&currprefs.apollorom)) { + apollo_add_scsi_unit(unit, uci, 0); + added = true; + } + } else if (type == HD_CONTROLLER_TYPE_SCSI_APOLLO_2) { + if (cfgfile_board_enabled(&currprefs.apollorom)) { + apollo_add_scsi_unit(unit, uci, 1); + added = true; + } + } else if (type == HD_CONTROLLER_TYPE_SCSI_MASOBOSHI) { + if (cfgfile_board_enabled(&currprefs.masoboshirom)) { + masoboshi_add_scsi_unit(unit, uci, 0); + added = true; + } + } else if (type == HD_CONTROLLER_TYPE_SCSI_MASOBOSHI_2) { + if (cfgfile_board_enabled(&currprefs.masoboshirom)) { + masoboshi_add_scsi_unit(unit, uci, 1); + added = true; + } } return added; } diff --git a/gayle.cpp b/gayle.cpp index 38d50be7..cf4df931 100644 --- a/gayle.cpp +++ b/gayle.cpp @@ -909,7 +909,7 @@ addrbank mbres_bank = { void gayle_hsync (void) { - if (ide_interrupt_check(idedrive, TOTAL_IDE * 2)) + if (ide_interrupt_check(idedrive[0]) || ide_interrupt_check(idedrive[2]) || ide_interrupt_check(idedrive[4])) rethink_gayle (); } diff --git a/ide.cpp b/ide.cpp index 79509fe3..89030e84 100644 --- a/ide.cpp +++ b/ide.cpp @@ -128,11 +128,11 @@ static bool ide_interrupt_do (struct ide_hdf *ide) return true; } -bool ide_interrupt_check(struct ide_hdf **idetable, int num) +bool ide_interrupt_check(struct ide_hdf *idep) { bool irq = false; - for (int i = 0; i < num; i++) { - struct ide_hdf *ide = idetable[i]; + for (int i = 0; i < 2; i++) { + struct ide_hdf *ide = i == 0 ? idep : idep->pair; if (ide) { if (ide->irq_delay > 0) { ide->irq_delay--; @@ -588,8 +588,8 @@ static void do_process_rw_command (struct ide_hdf *ide) bool last; ide->data_offset = 0; - get_lbachs (ide, &lba, &cyl, &head, &sec); nsec = get_nsec (ide); + get_lbachs (ide, &lba, &cyl, &head, &sec); if (IDE_LOG > 1) write_log (_T("IDE%d off=%d, nsec=%d (%d) lba48=%d\n"), ide->num, (uae_u32)lba, nsec, ide->multiple_mode, ide->lba48 + ide->lba48cmd); if (nsec * ide->blocksize > ide->hdhfd.size - lba * ide->blocksize) { @@ -759,6 +759,8 @@ static void ide_do_command (struct ide_hdf *ide, uae_u8 cmd) ide_set_features (ide); } else if (cmd == 0x00) { /* nop */ ide_fail (ide); + } else if (cmd == 0x70) { /* seek */ + ide_interrupt (ide); } else if (cmd == 0xe0 || cmd == 0xe1 || cmd == 0xe7 || cmd == 0xea) { /* standby now/idle/flush cache/flush cache ext */ ide_interrupt (ide); } else if (cmd == 0xe5) { /* check power mode */ @@ -776,8 +778,6 @@ uae_u16 ide_get_data (struct ide_hdf *ide) bool irq = false; uae_u16 v; - if (IDE_LOG > 4) - write_log (_T("IDE%d DATA read\n"), ide->num); if (ide->data_size == 0) { if (IDE_LOG > 0) write_log (_T("IDE%d DATA but no data left!? %02X PC=%08X\n"), ide->num, ide->regs.ide_status, m68k_getpc ()); @@ -787,6 +787,8 @@ uae_u16 ide_get_data (struct ide_hdf *ide) } if (ide->packet_state) { v = ide->secbuf[ide->packet_data_offset + ide->data_offset + 1] | (ide->secbuf[ide->packet_data_offset + ide->data_offset + 0] << 8); + if (IDE_LOG > 4) + write_log (_T("IDE%d DATA read %04x\n"), ide->num, v); ide->data_offset += 2; if (ide->data_size < 0) ide->data_size += 2; @@ -807,6 +809,8 @@ uae_u16 ide_get_data (struct ide_hdf *ide) } } else { v = ide->secbuf[ide->data_offset + 1] | (ide->secbuf[ide->data_offset + 0] << 8); + if (IDE_LOG > 4) + write_log (_T("IDE%d DATA read %04x\n"), ide->num, v); ide->data_offset += 2; if (ide->data_size < 0) { ide->data_size += 2; @@ -876,7 +880,7 @@ uae_u32 ide_read_reg (struct ide_hdf *ide, int ide_reg) if (ide_reg == IDE_STATUS && ide->pair->irq) ide->pair->irq = 0; if (ide_isdrive (ide->pair)) - v = 0x00; + v = 0x01; else v = 0xff; goto end; diff --git a/idecontrollers.cpp b/idecontrollers.cpp index 7dfe7c24..1cb2738e 100644 --- a/idecontrollers.cpp +++ b/idecontrollers.cpp @@ -24,54 +24,129 @@ #include "custom.h" #include "rommgr.h" #include "cpuboard.h" +#include "scsi.h" +#include "ncr9x_scsi.h" #define DEBUG_IDE 0 +#define DEBUG_IDE_GVP 0 +#define DEBUG_IDE_ALF 0 +#define DEBUG_IDE_APOLLO 0 +#define DEBUG_IDE_MASOBOSHI 0 #define GVP_IDE 0 // GVP A3001 -#define TOTAL_IDE 1 +#define ALF_IDE 1 +#define APOLLO_IDE 3 +#define MASOBOSHI_IDE 5 +#define TOTAL_IDE 7 +#define ALF_ROM_OFFSET 0x0100 #define GVP_IDE_ROM_OFFSET 0x8000 +#define APOLLO_ROM_OFFSET 0x8000 +#define MASOBOSHI_ROM_OFFSET 0x0080 +#define MASOBOSHI_ROM_OFFSET_END 0xf000 +#define MASOBOSHI_SCSI_OFFSET 0xf800 +#define MASOBOSHI_SCSI_OFFSET_END 0xfc00 + +/* masoboshi: + +IDE + +- FFCC = base address, data (0) +- FF81 = -004B +- FF41 = -008B +- FF01 = -01CB +- FEC1 = -010B +- FE81 = -014B +- FE41 = -018B select (6) +- FE01 = -01CB status (7) +- FE03 = command (7) + +- FA00 = ESP, 2 byte register spacing +- F9CC = data + +- F047 = -0F85 (-0FB9) interrupt request? (bit 3) +- F040 = -0F8C interrupt request? (bit 1) Write anything = clear irq? +- F000 = some status register + +- F04C = DMA address (long) +- F04A = number of words +- F044 = ??? +- F047 = bit 7 = start dma + +*/ static struct ide_board gvp_ide_rom_board, gvp_ide_controller_board; +static struct ide_board alf_board[2]; +static struct ide_board apollo_board[2]; +static struct ide_board masoboshi_board[2]; static struct ide_hdf *idecontroller_drive[TOTAL_IDE * 2]; static struct ide_thread_state idecontroller_its; -static void init_ide(struct ide_board *board, struct ide_hdf **idetable) +static struct ide_board *ide_boards[] = +{ + &gvp_ide_rom_board, + &alf_board[0], + &alf_board[1], + &apollo_board[0], + &apollo_board[1], + &masoboshi_board[0], + &masoboshi_board[1], + NULL +}; + +static void init_ide(struct ide_board *board, int ide_num, bool byteswap) { + struct ide_hdf **idetable = &idecontroller_drive[ide_num * 2]; alloc_ide_mem (idetable, 2, &idecontroller_its); board->ide = idetable[0]; idetable[0]->board = board; idetable[1]->board = board; - idetable[0]->byteswap = true; - idetable[1]->byteswap = true; - ide_initialize(idetable, 0); + idetable[0]->byteswap = byteswap; + idetable[1]->byteswap = byteswap; + ide_initialize(idecontroller_drive, ide_num); idecontroller_its.idetable = idecontroller_drive; idecontroller_its.idetotal = TOTAL_IDE * 2; start_ide_thread(&idecontroller_its); } -static bool ide_irq_check(void) +static bool ide_irq_check(struct ide_board *board) { - bool irq = ide_interrupt_check(idecontroller_drive, 2); - gvp_ide_controller_board.irq = irq; + if (!board->configured) + return false; + bool irq = ide_interrupt_check(board->ide); + board->irq = irq; + return irq; +} + +static bool ide_rethink(struct ide_board *board) +{ + bool irq = false; + if (board->configured) { + if (board->intena && ide_irq_check(board)) { + irq = true; + } + } return irq; } void idecontroller_rethink(void) { - if (!gvp_ide_controller_board.configured) - return; - if (gvp_ide_controller_board.intena && ide_irq_check() && !(intreq & 0x0008)) { + bool irq = false; + for (int i = 0; ide_boards[i]; i++) { + irq |= ide_rethink(ide_boards[i]); + } + if (irq && !(intreq & 0x0008)) { INTREQ_0(0x8000 | 0x0008); } } void idecontroller_hsync(void) { - if (!gvp_ide_controller_board.configured) - return; - if (ide_irq_check()) - idecontroller_rethink(); + for (int i = 0; ide_boards[i]; i++) { + if (ide_irq_check(ide_boards[i])) { + idecontroller_rethink(); + } + } } void idecontroller_free_units(void) @@ -81,26 +156,23 @@ void idecontroller_free_units(void) } } -int gvp_add_ide_unit(int ch, struct uaedev_config_info *ci) +static void reset_ide(struct ide_board *board) { - struct ide_hdf *ide; - - ide = add_ide_unit (idecontroller_drive, 2, ch, ci); - if (ide == NULL) - return 0; - return 1; + board->configured = 0; + board->intena = false; + board->enabled = false; } - -void idecontroller_free(void) +void idecontroller_reset(void) { - stop_ide_thread(&idecontroller_its); + for (int i = 0; ide_boards[i]; i++) { + reset_ide(ide_boards[i]); + } } -void idecontroller_reset(void) +void idecontroller_free(void) { - gvp_ide_controller_board.configured = 0; - gvp_ide_controller_board.intena = false; + stop_ide_thread(&idecontroller_its); } static bool is_gvp2_intreq(uaecptr addr) @@ -138,64 +210,198 @@ static int get_gvp_reg(uaecptr addr, struct ide_board *board, struct ide_hdf **i reg &= IDE_SECONDARY | 7; ide = board->ide; - if (idecontroller_drive[GVP_IDE]->ide_drv) + if (idecontroller_drive[GVP_IDE * 2]->ide_drv) + ide = ide->pair; + *idep = ide; + return reg; +} + +static int get_apollo_reg(uaecptr addr, struct ide_board *board, struct ide_hdf **idep) +{ + struct ide_hdf *ide; + if (addr & 0x4000) + return -1; + int reg = addr & 0x1fff; + reg >>= 10; + if (addr & 0x2000) + reg |= IDE_SECONDARY; + ide = board->ide; + if (idecontroller_drive[APOLLO_IDE * 2]->ide_drv) + ide = ide->pair; + *idep = ide; + if (reg != 0 && !(addr & 1)) + reg = -1; + write_log(_T("APOLLO %04x = %d\n"), addr, reg); + return reg; +} + +static int get_alf_reg(uaecptr addr, struct ide_board *board, struct ide_hdf **idep) +{ + struct ide_hdf *ide; + if (addr & 0x8000) + return -1; + ide = board->ide; + if (idecontroller_drive[ALF_IDE * 2]->ide_drv) ide = ide->pair; *idep = ide; + if (addr & 0x4000) { + ; + } else if (addr & 0x1000) { + addr &= 0xfff; + addr >>= 9; + } else if (addr & 0x2000) { + addr &= 0xfff; + addr >>= 9; + addr |= IDE_SECONDARY; + } + return addr; +} + +static int get_masoboshi_reg(uaecptr addr, struct ide_board *board, struct ide_hdf **idep) +{ + int reg; + struct ide_hdf *ide; + if (addr < 0xfc00) + return -1; + ide = board->ide; + if (idecontroller_drive[MASOBOSHI_IDE * 2]->ide_drv) + ide = ide->pair; + *idep = ide; + reg = 7 - ((addr >> 6) & 7); + if (addr < 0xfe00) + reg |= IDE_SECONDARY; return reg; } static uae_u32 ide_read_byte(struct ide_board *board, uaecptr addr) { - uae_u8 v = 0; + uae_u8 v = 0xff; addr &= 0xffff; + +#ifdef JIT + special_mem |= S_READ; +#endif + + addr &= board->mask; + +#if DEBUG_IDE + write_log(_T("IDE IO BYTE READ %08x %08x\n"), addr, M68K_GETPC); +#endif + if (addr < 0x40) return board->acmemory[addr]; - if (addr >= GVP_IDE_ROM_OFFSET) { - if (board->rom) { - if (addr & 1) - v = 0xe8; // board id - else - v = board->rom[((addr - GVP_IDE_ROM_OFFSET) / 2) & board->rom_mask]; + if (board->type == ALF_IDE) { + + if (addr < 0x1100 || (addr & 1)) { + if (board->rom) + v = board->rom[addr & board->rom_mask]; return v; } - v = 0xe8; -#if DEBUG_IDE - write_log(_T("GVP BOOT GET %08x %02x %08x\n"), addr, v, M68K_GETPC); + struct ide_hdf *ide; + int regnum = get_alf_reg(addr, board, &ide); + if (regnum >= 0) { + v = ide_read_reg(ide, regnum); + } +#if DEBUG_IDE_ALF + write_log(_T("ALF GET %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC); #endif - return v; - } - if (board->configured) { - if (board == &gvp_ide_rom_board && currprefs.cpuboard_type == BOARD_A3001_II) { - if (addr == 0x42) { - v = 0xff; + + } else if (board->type == MASOBOSHI_IDE) { + int regnum = -1; + bool rom = false; + if (addr >= MASOBOSHI_ROM_OFFSET && addr < MASOBOSHI_ROM_OFFSET_END) { + if (board->rom) { + v = board->rom[addr & board->rom_mask]; + rom = true; } -#if DEBUG_IDE - write_log(_T("GVP BOOT GET %08x %02x %08x\n"), addr, v, M68K_GETPC); -#endif + } else if (addr >= 0xf000 && addr <= 0xf007) { + v = masoboshi_ncr9x_scsi_get(addr, board == &masoboshi_board[0] ? 0 : 1); + } else if (addr == 0xf040) { + v = board->irq ? 2 : 0; + v |= masoboshi_ncr9x_scsi_get(addr, board == &masoboshi_board[0] ? 0 : 1); + } else if (addr == 0xf047) { + v = board->state; } else { struct ide_hdf *ide; - int regnum = get_gvp_reg(addr, board, &ide); -#if DEBUG_IDE - write_log(_T("GVP IDE GET %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC); -#endif + regnum = get_masoboshi_reg(addr, board, &ide); if (regnum >= 0) { v = ide_read_reg(ide, regnum); - } else if (is_gvp2_intreq(addr)) { - v = board->irq ? 0x40 : 0x00; -#if DEBUG_IDE - write_log(_T("GVP IRQ %02x\n"), v); + } else if (addr >= MASOBOSHI_SCSI_OFFSET && addr < MASOBOSHI_SCSI_OFFSET_END) { + v = masoboshi_ncr9x_scsi_get(addr, board == &masoboshi_board[0] ? 0 : 1); + } + } +#if DEBUG_IDE_MASOBOSHI + if (!rom) + write_log(_T("MASOBOSHI BYTE GET %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC); #endif - ide_irq_check(); - } else if (is_gvp1_intreq(addr)) { - v = gvp_ide_controller_board.irq ? 0x80 : 0x00; -#if DEBUG_IDE - write_log(_T("GVP IRQ %02x\n"), v); + } else if (board->type == APOLLO_IDE) { + + if (addr >= APOLLO_ROM_OFFSET) { + if (board->rom) + v = board->rom[(addr - APOLLO_ROM_OFFSET) & board->rom_mask]; + } else if (board->configured) { + if ((addr & 0xc000) == 0x4000) { + v = apollo_scsi_bget(addr); + } else if (addr < 0x4000) { + struct ide_hdf *ide; + int regnum = get_apollo_reg(addr, board, &ide); + if (regnum >= 0) { + v = ide_read_reg(ide, regnum); + } else { + v = 0; + } + } + } + + } else if (board->type == GVP_IDE) { + + if (addr >= GVP_IDE_ROM_OFFSET) { + if (board->rom) { + if (addr & 1) + v = 0xe8; // board id + else + v = board->rom[((addr - GVP_IDE_ROM_OFFSET) / 2) & board->rom_mask]; + return v; + } + v = 0xe8; +#if DEBUG_IDE_GVP + write_log(_T("GVP BOOT GET %08x %02x %08x\n"), addr, v, M68K_GETPC); +#endif + return v; + } + if (board->configured) { + if (board == &gvp_ide_rom_board && currprefs.cpuboard_type == BOARD_A3001_II) { + if (addr == 0x42) { + v = 0xff; + } +#if DEBUG_IDE_GVP + write_log(_T("GVP BOOT GET %08x %02x %08x\n"), addr, v, M68K_GETPC); #endif - ide_irq_check(); + } else { + struct ide_hdf *ide; + int regnum = get_gvp_reg(addr, board, &ide); +#if DEBUG_IDE_GVP + write_log(_T("GVP IDE GET %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC); +#endif + if (regnum >= 0) { + v = ide_read_reg(ide, regnum); + } else if (is_gvp2_intreq(addr)) { + v = board->irq ? 0x40 : 0x00; +#if DEBUG_IDE_GVP + write_log(_T("GVP IRQ %02x\n"), v); +#endif + ide_irq_check(board); + } else if (is_gvp1_intreq(addr)) { + v = gvp_ide_controller_board.irq ? 0x80 : 0x00; +#if DEBUG_IDE_GVP + write_log(_T("GVP IRQ %02x\n"), v); +#endif + ide_irq_check(board); + } } + } else { + v = 0xff; } - } else { - v = 0xff; } return v; } @@ -204,42 +410,128 @@ static uae_u32 ide_read_word(struct ide_board *board, uaecptr addr) { uae_u32 v = 0xffff; - addr &= 65535; - if (board->configured && (board == &gvp_ide_controller_board || currprefs.cpuboard_type == BOARD_A3001_I)) { - if (addr < 0x60) { - if (is_gvp1_intreq(addr)) - v = gvp_ide_controller_board.irq ? 0x8000 : 0x0000; - else if (addr == 0x40) { - if (currprefs.cpuboard_type == BOARD_A3001_II) - v = board->intena ? 8 : 0; +#ifdef JIT + special_mem |= S_READ; +#endif + + addr &= board->mask; + + if (board->type == APOLLO_IDE) { + + if (addr >= APOLLO_ROM_OFFSET) { + if (board->rom) { + v = board->rom[(addr + 0 - APOLLO_ROM_OFFSET) & board->rom_mask]; + v <<= 8; + v |= board->rom[(addr + 1 - APOLLO_ROM_OFFSET) & board->rom_mask]; } -#if DEBUG_IDE - write_log(_T("GVP IO WORD READ %08x %08x\n"), addr, M68K_GETPC); + } + } + + + if (board->configured) { + + if (board->type == ALF_IDE) { + + struct ide_hdf *ide; + int regnum = get_alf_reg(addr, board, &ide); + if (regnum == IDE_DATA) { + v = ide_get_data(ide); + } else { + v = 0; + if (addr == 0x4000 && board->intena) + v = board->irq ? 0x8000 : 0x0000; +#if DEBUG_IDE_ALF + write_log(_T("ALF IO WORD READ %08x %08x\n"), addr, M68K_GETPC); #endif + } + + } else if (board->type == MASOBOSHI_IDE) { + + if (addr >= MASOBOSHI_ROM_OFFSET && addr < MASOBOSHI_ROM_OFFSET_END) { + if (board->rom) { + v = board->rom[addr & board->rom_mask] << 8; + v |= board->rom[(addr + 1) & board->rom_mask]; + } } else { struct ide_hdf *ide; - int regnum = get_gvp_reg(addr, board, &ide); + int regnum = get_masoboshi_reg(addr, board, &ide); if (regnum == IDE_DATA) { v = ide_get_data(ide); -#if DEBUG_IDE > 2 - write_log(_T("IDE WORD READ %04x\n"), v); -#endif } else { v = ide_read_byte(board, addr) << 8; v |= ide_read_byte(board, addr + 1); } } + + } else if (board->type == APOLLO_IDE) { + + if ((addr & 0xc000) == 0x4000) { + v = apollo_scsi_bget(addr); + v <<= 8; + v |= apollo_scsi_bget(addr + 1); + } else if (addr < 0x4000) { + struct ide_hdf *ide; + int regnum = get_apollo_reg(addr, board, &ide); + if (regnum == IDE_DATA) { + v = ide_get_data(ide); + } else { + v = 0; + } + } + + } else if (board->type == GVP_IDE) { + + if (board == &gvp_ide_controller_board || currprefs.cpuboard_type == BOARD_A3001_I) { + if (addr < 0x60) { + if (is_gvp1_intreq(addr)) + v = gvp_ide_controller_board.irq ? 0x8000 : 0x0000; + else if (addr == 0x40) { + if (currprefs.cpuboard_type == BOARD_A3001_II) + v = board->intena ? 8 : 0; + } +#if DEBUG_IDE_GVP + write_log(_T("GVP IO WORD READ %08x %08x\n"), addr, M68K_GETPC); +#endif + } else { + struct ide_hdf *ide; + int regnum = get_gvp_reg(addr, board, &ide); + if (regnum == IDE_DATA) { + v = ide_get_data(ide); +#if DEBUG_IDE_GVP > 2 + write_log(_T("IDE WORD READ %04x\n"), v); +#endif + } else { + v = ide_read_byte(board, addr) << 8; + v |= ide_read_byte(board, addr + 1); + } + } + } + } } + +#if DEBUG_IDE + write_log(_T("IDE IO WORD READ %08x %04x %08x\n"), addr, v, M68K_GETPC); +#endif + return v; } static void ide_write_byte(struct ide_board *board, uaecptr addr, uae_u8 v) { - addr &= 65535; + addr &= board->mask; + +#ifdef JIT + special_mem |= S_WRITE; +#endif + +#if DEBUG_IDE + write_log(_T("IDE IO BYTE WRITE %08x=%02x %08x\n"), addr, v, M68K_GETPC); +#endif + if (!board->configured) { addrbank *ab = board->bank; if (addr == 0x48) { - map_banks_z2(ab, v, 0x10000 >> 16); + map_banks_z2(ab, v, (board->mask + 1) >> 16); board->configured = 1; expamem_next(ab, NULL); return; @@ -251,96 +543,149 @@ static void ide_write_byte(struct ide_board *board, uaecptr addr, uae_u8 v) } } if (board->configured) { - if (board == &gvp_ide_rom_board && currprefs.cpuboard_type == BOARD_A3001_II) { -#if DEBUG_IDE - write_log(_T("GVP BOOT PUT %08x %02x %08x\n"), addr, v, M68K_GETPC); -#endif - } else { + if (board->type == ALF_IDE) { struct ide_hdf *ide; - int regnum = get_gvp_reg(addr, board, &ide); -#if DEBUG_IDE - write_log(_T("GVP IDE PUT %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC); -#endif + int regnum = get_alf_reg(addr, board, &ide); if (regnum >= 0) ide_write_reg(ide, regnum, v); - } - } -} +#if DEBUG_IDE_ALF + write_log(_T("ALF PUT %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC); +#endif + } else if (board->type == MASOBOSHI_IDE) { -static void ide_write_word(struct ide_board *board, uaecptr addr, uae_u16 v) -{ - addr &= 65535; - if (board->configured && (board == &gvp_ide_controller_board || currprefs.cpuboard_type == BOARD_A3001_I)) { - if (addr < 0x60) { -#if DEBUG_IDE - write_log(_T("GVP IO WORD WRITE %08x %04x %08x\n"), addr, v, M68K_GETPC); +#if DEBUG_IDE_MASOBOSHI + write_log(_T("MASOBOSHI IO BYTE PUT %08x %02x %08x\n"), addr, v, M68K_GETPC); #endif - if (addr == 0x40 && currprefs.cpuboard_type == BOARD_A3001_II) - board->intena = (v & 8) != 0; - } else { struct ide_hdf *ide; - int regnum = get_gvp_reg(addr, board, &ide); - if (regnum == IDE_DATA) { - ide_put_data(ide, v); -#if DEBUG_IDE > 2 - write_log(_T("IDE WORD WRITE %04x\n"), v); + int regnum = get_masoboshi_reg(addr, board, &ide); + if (regnum >= 0) { + ide_write_reg(ide, regnum, v); + } else if (addr >= MASOBOSHI_SCSI_OFFSET && addr < MASOBOSHI_SCSI_OFFSET_END) { + masoboshi_ncr9x_scsi_put(addr, v, board == &masoboshi_board[0] ? 0 : 1); + } else if ((addr >= 0xf000 && addr <= 0xf007) || (addr >= 0xf04a && addr <= 0xf04f)) { + masoboshi_ncr9x_scsi_put(addr, v, board == &masoboshi_board[0] ? 0 : 1); + } else if (addr >= 0xf040 && addr < 0xf048) { + masoboshi_ncr9x_scsi_put(addr, v, board == &masoboshi_board[0] ? 0 : 1); + if (addr == 0xf047) { + board->state = v; + board->intena = (v & 8) != 0; + } + if (addr == 0xf040) { + board->irq = false; + } + write_log(_T("MASOBOSHI STATUS BYTE PUT %08x %02x %08x\n"), addr, v, M68K_GETPC); + } + + } else if (board->type == APOLLO_IDE) { + + if ((addr & 0xc000) == 0x4000) { + apollo_scsi_bput(addr, v); + } else if (addr < 0x4000) { + struct ide_hdf *ide; + int regnum = get_apollo_reg(addr, board, &ide); + if (regnum >= 0) { + ide_write_reg(ide, regnum, v); + } + } + + } else if (board->type == GVP_IDE) { + if (board == &gvp_ide_rom_board && currprefs.cpuboard_type == BOARD_A3001_II) { +#if DEBUG_IDE_GVP + write_log(_T("GVP BOOT PUT %08x %02x %08x\n"), addr, v, M68K_GETPC); #endif } else { - ide_write_byte(board, addr, v >> 8); - ide_write_byte(board, addr + 1, v & 0xff); + struct ide_hdf *ide; + int regnum = get_gvp_reg(addr, board, &ide); +#if DEBUG_IDE_GVP + write_log(_T("GVP IDE PUT %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC); +#endif + if (regnum >= 0) + ide_write_reg(ide, regnum, v); } } } } -static uae_u32 REGPARAM2 ide_controller_gvp_lget (uaecptr addr) +static void ide_write_word(struct ide_board *board, uaecptr addr, uae_u16 v) { - uae_u32 v; + addr &= board->mask; + #ifdef JIT - special_mem |= S_READ; + special_mem |= S_WRITE; #endif - v = ide_read_word (&gvp_ide_controller_board, addr + 0) << 16; - v |= ide_read_word (&gvp_ide_controller_board, addr + 2) << 0; - return v; -} -static uae_u32 REGPARAM2 ide_controller_gvp_wget (uaecptr addr) -{ - uae_u32 v; -#ifdef JIT - special_mem |= S_READ; + +#if DEBUG_IDE + write_log(_T("IDE IO WORD WRITE %08x=%04x %08x\n"), addr, v, M68K_GETPC); #endif - v = ide_read_word (&gvp_ide_controller_board, addr); - return v; -} -static uae_u32 REGPARAM2 ide_controller_gvp_bget (uaecptr addr) -{ -#ifdef JIT - special_mem |= S_READ; + if (board->configured) { + if (board->type == ALF_IDE) { + + struct ide_hdf *ide; + int regnum = get_alf_reg(addr, board, &ide); + if (regnum == IDE_DATA) { + ide_put_data(ide, v); + } else { +#if DEBUG_IDE_ALF + write_log(_T("ALF IO WORD WRITE %08x %04x %08x\n"), addr, v, M68K_GETPC); #endif - return ide_read_byte (&gvp_ide_controller_board, addr); -} -static void REGPARAM2 ide_controller_gvp_lput (uaecptr addr, uae_u32 l) -{ -#ifdef JIT - special_mem |= S_WRITE; + } + + } else if (board->type == MASOBOSHI_IDE) { + + struct ide_hdf *ide; + int regnum = get_masoboshi_reg(addr, board, &ide); + if (regnum == IDE_DATA) { + ide_put_data(ide, v); + } else { + ide_write_byte(board, addr, v >> 8); + ide_write_byte(board, addr + 1, v); + } +#if DEBUG_IDE_MASOBOSHI + write_log(_T("MASOBOSHI IO WORD WRITE %08x %04x %08x\n"), addr, v, M68K_GETPC); #endif - ide_write_word (&gvp_ide_controller_board, addr + 0, l >> 16); - ide_write_word (&gvp_ide_controller_board, addr + 2, l >> 0); -} -static void REGPARAM2 ide_controller_gvp_wput (uaecptr addr, uae_u32 w) -{ -#ifdef JIT - special_mem |= S_WRITE; + + } else if (board->type == APOLLO_IDE) { + + if ((addr & 0xc000) == 0x4000) { + apollo_scsi_bput(addr, v >> 8); + apollo_scsi_bput(addr + 1, v); + } else if (addr < 0x4000) { + struct ide_hdf *ide; + int regnum = get_apollo_reg(addr, board, &ide); + if (regnum == IDE_DATA) { + ide_put_data(ide, v); + } + } + + } else if (board->type == GVP_IDE) { + + if (board == &gvp_ide_controller_board || currprefs.cpuboard_type == BOARD_A3001_I) { + if (addr < 0x60) { +#if DEBUG_IDE_GVP + write_log(_T("GVP IO WORD WRITE %08x %04x %08x\n"), addr, v, M68K_GETPC); #endif - ide_write_word (&gvp_ide_controller_board, addr + 0, w); -} -static void REGPARAM2 ide_controller_gvp_bput (uaecptr addr, uae_u32 b) -{ -#ifdef JIT - special_mem |= S_WRITE; + if (addr == 0x40 && currprefs.cpuboard_type == BOARD_A3001_II) + board->intena = (v & 8) != 0; + } else { + struct ide_hdf *ide; + int regnum = get_gvp_reg(addr, board, &ide); + if (regnum == IDE_DATA) { + ide_put_data(ide, v); +#if DEBUG_IDE_GVP > 2 + write_log(_T("IDE WORD WRITE %04x\n"), v); #endif - ide_write_byte (&gvp_ide_controller_board, addr, b); + } else { + ide_write_byte(board, addr, v >> 8); + ide_write_byte(board, addr + 1, v & 0xff); + } + } + } + } + } } + +IDE_MEMORY_FUNCTIONS(ide_controller_gvp, ide, gvp_ide_controller_board); + addrbank gvp_ide_controller_bank = { ide_controller_gvp_lget, ide_controller_gvp_wget, ide_controller_gvp_bget, ide_controller_gvp_lput, ide_controller_gvp_wput, ide_controller_gvp_bput, @@ -348,54 +693,8 @@ addrbank gvp_ide_controller_bank = { dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE }; -static uae_u32 REGPARAM2 ide_rom_gvp_lget (uaecptr addr) -{ - uae_u32 v; -#ifdef JIT - special_mem |= S_READ; -#endif - v = ide_read_word (&gvp_ide_rom_board, addr + 0) << 16; - v |= ide_read_word (&gvp_ide_rom_board, addr + 2) << 0; - return v; -} -static uae_u32 REGPARAM2 ide_rom_gvp_wget (uaecptr addr) -{ - uae_u32 v; -#ifdef JIT - special_mem |= S_READ; -#endif - v = ide_read_word (&gvp_ide_rom_board, addr); - return v; -} -static uae_u32 REGPARAM2 ide_rom_gvp_bget (uaecptr addr) -{ -#ifdef JIT - special_mem |= S_READ; -#endif - return ide_read_byte (&gvp_ide_rom_board, addr); -} -static void REGPARAM2 ide_rom_gvp_lput (uaecptr addr, uae_u32 l) -{ -#ifdef JIT - special_mem |= S_WRITE; -#endif - ide_write_word (&gvp_ide_rom_board, addr + 0, l >> 16); - ide_write_word (&gvp_ide_rom_board, addr + 2, l >> 0); -} -static void REGPARAM2 ide_rom_gvp_wput (uaecptr addr, uae_u32 w) -{ -#ifdef JIT - special_mem |= S_WRITE; -#endif - ide_write_word (&gvp_ide_rom_board, addr + 0, w); -} -static void REGPARAM2 ide_rom_gvp_bput (uaecptr addr, uae_u32 b) -{ -#ifdef JIT - special_mem |= S_WRITE; -#endif - ide_write_byte (&gvp_ide_rom_board, addr, b); -} +IDE_MEMORY_FUNCTIONS(ide_rom_gvp, ide, gvp_ide_rom_board); + addrbank gvp_ide_rom_bank = { ide_rom_gvp_lget, ide_rom_gvp_wget, ide_rom_gvp_bget, ide_rom_gvp_lput, ide_rom_gvp_wput, ide_rom_gvp_bput, @@ -403,6 +702,40 @@ addrbank gvp_ide_rom_bank = { dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE }; +IDE_MEMORY_FUNCTIONS(alf, ide, alf_board[0]); +IDE_MEMORY_FUNCTIONS(alf2, ide, alf_board[1]); + +addrbank alf_bank = { + alf_lget, alf_wget, alf_bget, + alf_lput, alf_wput, alf_bput, + default_xlate, default_check, NULL, NULL, _T("ALF"), + dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE +}; +addrbank alf_bank2 = { + alf2_lget, alf2_wget, alf2_bget, + alf2_lput, alf2_wput, alf2_bput, + default_xlate, default_check, NULL, NULL, _T("ALF #2"), + dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE +}; + +IDE_MEMORY_FUNCTIONS(apollo_ide, ide, apollo_board[0]); + +addrbank apollo_bank = { + apollo_ide_lget, apollo_ide_wget, apollo_ide_bget, + apollo_ide_lput, apollo_ide_wput, apollo_ide_bput, + default_xlate, default_check, NULL, NULL, _T("Apollo"), + dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE +}; + +IDE_MEMORY_FUNCTIONS(masoboshi_ide, ide, masoboshi_board[0]); + +addrbank masoboshi_bank = { + masoboshi_ide_lget, masoboshi_ide_wget, masoboshi_ide_bget, + masoboshi_ide_lput, masoboshi_ide_wput, masoboshi_ide_bput, + default_xlate, default_check, NULL, NULL, _T("Masoboshi"), + dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE +}; + static void ew(struct ide_board *ide, int addr, uae_u32 value) { addr &= 0xffff; @@ -429,7 +762,7 @@ addrbank *gvp_ide_rom_autoconfig_init(void) if (currprefs.cpuboard_type == BOARD_A3001_I) { ide->bank = &gvp_ide_rom_bank; autoconfig = gvp_ide1_controller_autoconfig; - init_ide(ide, &idecontroller_drive[GVP_IDE]); + init_ide(ide, GVP_IDE, true); ide->rom_size = 8192; gvp_ide_controller_board.intena = true; gvp_ide_controller_board.configured = -1; @@ -441,6 +774,8 @@ addrbank *gvp_ide_rom_autoconfig_init(void) ide->rom_size = 16384; roms[0] = -1; } + ide->mask = 65536 - 1; + ide->type = GVP_IDE; ide->configured = 0; memset(ide->acmemory, 0xff, sizeof ide->acmemory); @@ -474,7 +809,7 @@ addrbank *gvp_ide_controller_autoconfig_init(void) { struct ide_board *ide = &gvp_ide_controller_board; - init_ide(ide, &idecontroller_drive[GVP_IDE]); + init_ide(ide, GVP_IDE, true); ide->configured = 0; ide->bank = &gvp_ide_controller_bank; memset(ide->acmemory, 0xff, sizeof ide->acmemory); @@ -485,3 +820,240 @@ addrbank *gvp_ide_controller_autoconfig_init(void) return ide->bank; } +int gvp_add_ide_unit(int ch, struct uaedev_config_info *ci) +{ + struct ide_hdf *ide; + + ide = add_ide_unit (&idecontroller_drive[GVP_IDE], 2, ch, ci); + if (ide == NULL) + return 0; + return 1; +} + +static const uae_u8 alf_autoconfig[16] = { 0xd1, 6, 0x00, 0x00, 0x08, 0x2c, 0x00, 0x00, 0x00, 0x00, ALF_ROM_OFFSET >> 8, ALF_ROM_OFFSET & 0xff }; +static const uae_u8 alfplus_autoconfig[16] = { 0xd1, 38, 0x00, 0x00, 0x08, 0x2c, 0x00, 0x00, 0x00, 0x00, ALF_ROM_OFFSET >> 8, ALF_ROM_OFFSET & 0xff }; + +addrbank *alf_init(int devnum) +{ + struct ide_board *ide = &alf_board[devnum]; + int roms[2]; + struct romlist *rl; + bool alfplus = cfgfile_board_enabled(&currprefs.alfplusrom); + + if (devnum > 0 && !ide->enabled) + return &expamem_null; + + roms[0] = alfplus ? 118 : 117; + roms[1] = -1; + + init_ide(ide, ALF_IDE + devnum, false); + ide->configured = 0; + ide->bank = &alf_bank; + ide->type = ALF_IDE + devnum; + ide->rom_size = 32768 * 6; + ide->userdata = alfplus; + ide->intena = alfplus; + ide->mask = 65536 - 1; + + memset(ide->acmemory, 0xff, sizeof ide->acmemory); + + ide->rom = xcalloc(uae_u8, ide->rom_size); + memset(ide->rom, 0xff, ide->rom_size); + ide->rom_mask = ide->rom_size - 1; + const TCHAR *romname = alfplus ? currprefs.alfplusrom.roms[0].romfile : currprefs.alfrom.roms[0].romfile; + struct zfile *z = read_rom_name(romname); + if (!z) { + rl = getromlistbyids(roms, romname); + if (rl) { + z = read_rom(rl->rd); + } + } + for (int i = 0; i < 16; i++) { + uae_u8 b = alfplus ? alfplus_autoconfig[i] : alf_autoconfig[i]; + ew(ide, i * 4, b); + } + if (z) { + write_log(_T("ALF BOOT ROM '%s'\n"), zfile_getname(z)); + for (int i = 0; i < 0x1000 / 2; i++) { + uae_u8 b; + zfile_fread(&b, 1, 1, z); + ide->rom[ALF_ROM_OFFSET + i * 4 + 0] = b; + zfile_fread(&b, 1, 1, z); + ide->rom[ALF_ROM_OFFSET + i * 4 + 2] = b; + } + for (int i = 0; i < 32768 - 0x1000; i++) { + uae_u8 b; + zfile_fread(&b, 1, 1, z); + ide->rom[0x2000 + i * 4 + 1] = b; + zfile_fread(&b, 1, 1, z); + ide->rom[0x2000 + i * 4 + 3] = b; + } + zfile_fclose(z); + } else { + romwarning(roms); + } + return ide->bank; +} + +int alf_add_ide_unit(int ch, struct uaedev_config_info *ci, int devnum) +{ + struct ide_hdf *ide; + + ide = add_ide_unit (&idecontroller_drive[(ALF_IDE + devnum) * 2], 2, ch, ci); + if (ide == NULL) + return 0; + return 1; +} + +// prod 0x22 = IDE + SCSI +// prod 0x23 = SCSI only +// prod 0x33 = IDE only + +const uae_u8 apollo_autoconfig[16] = { 0xd2, 0x23, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, APOLLO_ROM_OFFSET >> 8, APOLLO_ROM_OFFSET & 0xff }; +const uae_u8 apollo_autoconfig_cpuboard[16] = { 0xd2, 0x23, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, APOLLO_ROM_OFFSET >> 8, APOLLO_ROM_OFFSET & 0xff }; +const uae_u8 apollo_autoconfig_cpuboard_060[16] = { 0xd2, 0x23, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x02, APOLLO_ROM_OFFSET >> 8, APOLLO_ROM_OFFSET & 0xff }; + +addrbank *apollo_init(int devnum) +{ + struct ide_board *ide; + int roms[2]; + struct romlist *rl; + const uae_u8 *autoconfig; + bool cpuboard = false; + + if (devnum < 0) { + cpuboard = true; + devnum = 0; + } + + ide = &apollo_board[devnum]; + if (devnum > 0 && !ide->enabled) + return &expamem_null; + + roms[0] = -1; + init_ide(ide, APOLLO_IDE + devnum, false); + ide->configured = 0; + ide->bank = &apollo_bank; + ide->type = APOLLO_IDE + devnum; + ide->rom_size = 32768; + ide->mask = 131072 - 1; + + memset(ide->acmemory, 0xff, sizeof ide->acmemory); + + ide->rom = xcalloc(uae_u8, ide->rom_size); + memset(ide->rom, 0xff, ide->rom_size); + ide->rom_mask = ide->rom_size - 1; + autoconfig = apollo_autoconfig; + if (cpuboard) { + if (currprefs.cpu_model == 68060) + autoconfig = apollo_autoconfig_cpuboard_060; + else + autoconfig = apollo_autoconfig_cpuboard; + } + const TCHAR *romname = cpuboard ? currprefs.acceleratorromfile : currprefs.apollorom.roms[0].romfile; + struct zfile *z = read_rom_name(romname); + if (!z) { + rl = getromlistbyids(roms, romname); + if (rl) { + z = read_rom(rl->rd); + } + } + for (int i = 0; i < 16; i++) { + uae_u8 b = autoconfig[i]; + ew(ide, i * 4, b); + } + if (z) { + int len = zfile_size(z); + write_log(_T("Apollo BOOT ROM '%s' %d\n"), zfile_getname(z), len); + // skip 68060 $f0 ROM block + if (len >= 65536) + zfile_fseek(z, 32768, SEEK_SET); + for (int i = 0; i < 32768; i++) { + uae_u8 b; + zfile_fread(&b, 1, 1, z); + ide->rom[i] = b; + } + zfile_fclose(z); + } else { + romwarning(roms); + } + return ide->bank; +} + +int apollo_add_ide_unit(int ch, struct uaedev_config_info *ci, int devnum) +{ + struct ide_hdf *ide; + + ide = add_ide_unit (&idecontroller_drive[(APOLLO_IDE + devnum) * 2], 2, ch, ci); + if (ide == NULL) + return 0; + return 1; +} + +static const uae_u8 masoboshi_fake_no_rom[] = { 0xcf, 0x1f, 0xff, 0xbf, 0xbf, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x9f, 0x2f }; + +addrbank *masoboshi_init(int devnum) +{ + struct ide_board *ide; + int roms[2]; + struct romlist *rl; + + ide = &masoboshi_board[devnum]; + if (devnum > 0 && !ide->enabled) + return &expamem_null; + + roms[0] = 120; + roms[1] = -1; + init_ide(ide, MASOBOSHI_IDE + devnum, true); + ide->configured = 0; + ide->bank = &masoboshi_bank; + ide->type = MASOBOSHI_IDE + devnum; + ide->rom_size = 65536; + ide->mask = 65536 - 1; + + ide->rom = xcalloc(uae_u8, ide->rom_size); + memset(ide->rom, 0xff, ide->rom_size); + memset(ide->acmemory, 0xff, sizeof ide->acmemory); + ide->rom_mask = ide->rom_size - 1; + if (_tcscmp (currprefs.masoboshirom.roms[0].romfile, _T(":NOROM"))) { + const TCHAR *romname = currprefs.masoboshirom.roms[0].romfile; + struct zfile *z = read_rom_name(romname); + if (!z) { + rl = getromlistbyids(roms, romname); + if (rl) { + z = read_rom(rl->rd); + } + } + if (z) { + int len = zfile_size(z); + write_log(_T("Masoboshi BOOT ROM '%s' %d\n"), zfile_getname(z), len); + for (int i = 0; i < 32768; i++) { + uae_u8 b; + zfile_fread(&b, 1, 1, z); + ide->rom[i * 2 + 0] = b; + ide->rom[i * 2 + 1] = 0xff; + } + zfile_fclose(z); + memcpy(ide->acmemory, ide->rom, sizeof ide->acmemory); + } else { + romwarning(roms); + } + } else { + for (int i = 0; i < sizeof masoboshi_fake_no_rom; i++) { + ide->acmemory[i * 2 + 0] = masoboshi_fake_no_rom[i]; + } + } + // init SCSI part + ncr_masoboshi_autoconfig_init(devnum); + return ide->bank; +} + +int masoboshi_add_ide_unit(int ch, struct uaedev_config_info *ci, int devnum) +{ + struct ide_hdf *ide; + + ide = add_ide_unit (&idecontroller_drive[(MASOBOSHI_IDE + devnum) * 2], 2, ch, ci); + if (ide == NULL) + return 0; + return 1; +} diff --git a/include/a2091.h b/include/a2091.h index 9f223fc9..265ce153 100644 --- a/include/a2091.h +++ b/include/a2091.h @@ -24,7 +24,8 @@ struct wd_chip_state { #define COMMODORE_DMAC 1 #define COMMODORE_SDMAC 2 -#define GVP_DMAC 3 +#define GVP_DMAC_S2 3 +#define GVP_DMAC_S1 4 struct commodore_dmac { @@ -55,6 +56,8 @@ struct gvp_dmac uae_u8 version; uae_u32 addr_mask; bool series2; + uae_u8 *buffer; + int bufoffset; }; struct wd_state { @@ -91,7 +94,7 @@ extern addrbank *a2091_init (int devnum); extern void a2091_free(void); extern void a2091_reset (void); -extern addrbank *gvp_init(int devnum); +extern addrbank *gvp_init(int devnum, bool series2); extern void gvp_free(void); extern void gvp_reset (void); diff --git a/include/cpuboard.h b/include/cpuboard.h index 6b547271..58596799 100644 --- a/include/cpuboard.h +++ b/include/cpuboard.h @@ -46,4 +46,5 @@ extern uae_u8 *REGPARAM3 cyberstorm_scsi_ram_xlate(uaecptr addr) REGPARAM; #define BOARD_FUSIONFORTY 15 #define BOARD_A3001_I 16 #define BOARD_A3001_II 17 - +#define BOARD_APOLLO 18 +#define BOARD_GVP_A530 19 diff --git a/include/filesys.h b/include/filesys.h index 7312dfd9..c15dcbfb 100644 --- a/include/filesys.h +++ b/include/filesys.h @@ -91,28 +91,38 @@ struct hd_hardfiledata { #define HD_CONTROLLER_TYPE_IDE_AUTO 1 #define HD_CONTROLLER_TYPE_IDE_MB 2 #define HD_CONTROLLER_TYPE_IDE_GVP 3 -#define HD_CONTROLLER_TYPE_SCSI_AUTO 4 -#define HD_CONTROLLER_TYPE_SCSI_A2091 5 -#define HD_CONTROLLER_TYPE_SCSI_A2091_2 6 -#define HD_CONTROLLER_TYPE_SCSI_GVP 7 -#define HD_CONTROLLER_TYPE_SCSI_GVP_2 8 -#define HD_CONTROLLER_TYPE_SCSI_A4091 9 -#define HD_CONTROLLER_TYPE_SCSI_A4091_2 10 -#define HD_CONTROLLER_TYPE_SCSI_FASTLANE 11 -#define HD_CONTROLLER_TYPE_SCSI_FASTLANE_2 12 -#define HD_CONTROLLER_TYPE_SCSI_OKTAGON 13 -#define HD_CONTROLLER_TYPE_SCSI_OKTAGON_2 14 -#define HD_CONTROLLER_TYPE_SCSI_A3000 15 -#define HD_CONTROLLER_TYPE_SCSI_A4000T 16 -#define HD_CONTROLLER_TYPE_SCSI_CDTV 17 -#define HD_CONTROLLER_TYPE_SCSI_CPUBOARD 18 -#define HD_CONTROLLER_TYPE_PCMCIA_SRAM 19 -#define HD_CONTROLLER_TYPE_PCMCIA_IDE 20 +#define HD_CONTROLLER_TYPE_IDE_ALFA 4 +#define HD_CONTROLLER_TYPE_IDE_ALFA_2 5 +#define HD_CONTROLLER_TYPE_IDE_APOLLO 6 +#define HD_CONTROLLER_TYPE_IDE_APOLLO_2 7 +#define HD_CONTROLLER_TYPE_IDE_MASOBOSHI 8 +#define HD_CONTROLLER_TYPE_IDE_MASOBOSHI_2 9 +#define HD_CONTROLLER_TYPE_SCSI_AUTO 10 +#define HD_CONTROLLER_TYPE_SCSI_A2091 11 +#define HD_CONTROLLER_TYPE_SCSI_A2091_2 12 +#define HD_CONTROLLER_TYPE_SCSI_GVP 13 +#define HD_CONTROLLER_TYPE_SCSI_GVP_2 14 +#define HD_CONTROLLER_TYPE_SCSI_A4091 15 +#define HD_CONTROLLER_TYPE_SCSI_A4091_2 16 +#define HD_CONTROLLER_TYPE_SCSI_FASTLANE 17 +#define HD_CONTROLLER_TYPE_SCSI_FASTLANE_2 18 +#define HD_CONTROLLER_TYPE_SCSI_OKTAGON 19 +#define HD_CONTROLLER_TYPE_SCSI_OKTAGON_2 20 +#define HD_CONTROLLER_TYPE_SCSI_APOLLO 21 +#define HD_CONTROLLER_TYPE_SCSI_APOLLO_2 22 +#define HD_CONTROLLER_TYPE_SCSI_MASOBOSHI 23 +#define HD_CONTROLLER_TYPE_SCSI_MASOBOSHI_2 24 +#define HD_CONTROLLER_TYPE_SCSI_A3000 25 +#define HD_CONTROLLER_TYPE_SCSI_A4000T 26 +#define HD_CONTROLLER_TYPE_SCSI_CDTV 27 +#define HD_CONTROLLER_TYPE_SCSI_CPUBOARD 28 +#define HD_CONTROLLER_TYPE_PCMCIA_SRAM 29 +#define HD_CONTROLLER_TYPE_PCMCIA_IDE 30 #define HD_CONTROLLER_TYPE_IDE_FIRST 1 -#define HD_CONTROLLER_TYPE_IDE_LAST 3 -#define HD_CONTROLLER_TYPE_SCSI_FIRST 4 -#define HD_CONTROLLER_TYPE_SCSI_LAST 18 +#define HD_CONTROLLER_TYPE_IDE_LAST 9 +#define HD_CONTROLLER_TYPE_SCSI_FIRST 10 +#define HD_CONTROLLER_TYPE_SCSI_LAST 28 #define FILESYS_VIRTUAL 0 #define FILESYS_HARDFILE 1 diff --git a/include/ide.h b/include/ide.h index c944bee5..b7a67dca 100644 --- a/include/ide.h +++ b/include/ide.h @@ -30,10 +30,15 @@ struct ide_board int rom_size; int rom_mask; int configured; + int mask; addrbank *bank; struct ide_hdf *ide; bool irq; bool intena; + bool enabled; + int state; + int type; + int userdata; }; struct ide_hdf @@ -87,7 +92,7 @@ void ide_write_reg (struct ide_hdf *ide, int ide_reg, uae_u32 val); void ide_put_data (struct ide_hdf *ide, uae_u16 v); uae_u16 ide_get_data (struct ide_hdf *ide); -bool ide_interrupt_check(struct ide_hdf **ide, int num); +bool ide_interrupt_check(struct ide_hdf *ide); bool ide_isdrive(struct ide_hdf *ide); void ide_initialize(struct ide_hdf **idetable, int chpair); struct ide_hdf *add_ide_unit (struct ide_hdf **idetable, int max, int ch, struct uaedev_config_info *ci); @@ -100,3 +105,31 @@ void stop_ide_thread(struct ide_thread_state *its); uae_u8 *ide_save_state(uae_u8 *dst, struct ide_hdf *ide); uae_u8 *ide_restore_state(uae_u8 *src, struct ide_hdf *ide); +#define IDE_MEMORY_FUNCTIONS(x, y, z) \ +static void REGPARAM2 x ## _bput(uaecptr addr, uae_u32 b) \ +{ \ + y ## _write_byte(& ## z, addr, b); \ +} \ +static void REGPARAM2 x ## _wput(uaecptr addr, uae_u32 b) \ +{ \ + y ## _write_word(& ## z, addr, b); \ +} \ +static void REGPARAM2 x ## _lput(uaecptr addr, uae_u32 b) \ +{ \ + y ## _write_word(& ## z, addr, b >> 16); \ + y ## _write_word(& ## z, addr + 2, b); \ +} \ +static uae_u32 REGPARAM2 x ## _bget(uaecptr addr) \ +{ \ +return y ## _read_byte(& ## z, addr); \ +} \ +static uae_u32 REGPARAM2 x ## _wget(uaecptr addr) \ +{ \ +return y ## _read_word(& ## z, addr); \ +} \ +static uae_u32 REGPARAM2 x ## _lget(uaecptr addr) \ +{ \ + uae_u32 v = y ## _read_word(& ## z, addr) << 16; \ + v |= y ## _read_word(& ## z, addr + 2); \ + return v; \ +} diff --git a/include/idecontrollers.h b/include/idecontrollers.h index f46e93cb..a2eade4e 100644 --- a/include/idecontrollers.h +++ b/include/idecontrollers.h @@ -9,3 +9,21 @@ void idecontroller_hsync(void); int gvp_add_ide_unit(int ch, struct uaedev_config_info *ci); addrbank *gvp_ide_rom_autoconfig_init(void); addrbank *gvp_ide_controller_autoconfig_init(void); + +int alf_add_ide_unit(int ch, struct uaedev_config_info *ci, int devnum); +addrbank *alf_init(int); + +int apollo_add_ide_unit(int ch, struct uaedev_config_info *ci, int devnum); +addrbank *apollo_init(int); + +int masoboshi_add_ide_unit(int ch, struct uaedev_config_info *ci, int devnum); +addrbank *masoboshi_init(int); + +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; +void REGPARAM3 apollo_ide_lput (uaecptr addr, uae_u32 l) REGPARAM; +void REGPARAM3 apollo_ide_wput (uaecptr addr, uae_u32 w) REGPARAM; +void REGPARAM3 apollo_ide_bput (uaecptr addr, uae_u32 b) REGPARAM; +extern const uae_u8 apollo_autoconfig[16]; +extern const uae_u8 apollo_autoconfig_060[16]; diff --git a/include/ncr9x_scsi.h b/include/ncr9x_scsi.h index 58ea600f..c2c28264 100644 --- a/include/ncr9x_scsi.h +++ b/include/ncr9x_scsi.h @@ -9,6 +9,7 @@ extern int cpuboard_ncr9x_add_scsi_unit(int ch, struct uaedev_config_info *ci); extern int cpuboard_dkb_add_scsi_unit(int ch, struct uaedev_config_info *ci); extern int fastlane_add_scsi_unit(int ch, struct uaedev_config_info *ci, int devnum); extern int oktagon_add_scsi_unit(int ch, struct uaedev_config_info *ci, int devnum); +extern int masoboshi_add_scsi_unit(int ch, struct uaedev_config_info *ci, int devnum); extern addrbank *ncr_fastlane_autoconfig_init(int devnum); extern addrbank *ncr_oktagon_autoconfig_init(int devnum); @@ -17,6 +18,10 @@ extern addrbank *ncr_dkb_autoconfig_init(void); extern void cpuboard_ncr9x_scsi_put(uaecptr, uae_u32); extern uae_u32 cpuboard_ncr9x_scsi_get(uaecptr); +uae_u32 masoboshi_ncr9x_scsi_get(uaecptr addr, int devnum); +void masoboshi_ncr9x_scsi_put(uaecptr addr, uae_u32 v, int devnum); +void ncr_masoboshi_autoconfig_init(int devnum); + #define BLIZZARD_2060_SCSI_OFFSET 0x1ff00 #define BLIZZARD_2060_DMA_OFFSET 0x1fff0 #define BLIZZARD_2060_LED_OFFSET 0x1ffe0 diff --git a/include/options.h b/include/options.h index d87e19fe..35c999e6 100644 --- a/include/options.h +++ b/include/options.h @@ -484,7 +484,12 @@ struct uae_prefs { struct boardromconfig a4091rom; struct boardromconfig fastlanerom; struct boardromconfig oktagonrom; - struct boardromconfig gvprom; + struct boardromconfig gvps1rom; + struct boardromconfig gvps2rom; + struct boardromconfig alfrom; + struct boardromconfig alfplusrom; + struct boardromconfig apollorom; + struct boardromconfig masoboshirom; TCHAR romfile[MAX_DPATH]; TCHAR romident[256]; diff --git a/include/rommgr.h b/include/rommgr.h index 31aaa9af..ff3239e6 100644 --- a/include/rommgr.h +++ b/include/rommgr.h @@ -30,8 +30,13 @@ extern int decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size); #define ROMTYPE_CPUBOARDEXT 0x00100003 #define ROMTYPE_FASTLANE 0x00100004 #define ROMTYPE_OKTAGON 0x00100005 -#define ROMTYPE_GVP 0x00100006 -#define ROMTYPE_AMAX 0x00100007 +#define ROMTYPE_GVPS1 0x00100006 +#define ROMTYPE_GVPS2 0x00100007 +#define ROMTYPE_AMAX 0x00100008 +#define ROMTYPE_ALFA 0x00100009 +#define ROMTYPE_ALFAPLUS 0x0010000a +#define ROMTYPE_APOLLO 0x0010000b +#define ROMTYPE_MASOBOSHI 0x0010000c #define ROMTYPE_QUAD 0x01000000 #define ROMTYPE_EVEN 0x02000000 diff --git a/include/scsi.h b/include/scsi.h index bb96a165..bb9c8382 100644 --- a/include/scsi.h +++ b/include/scsi.h @@ -71,6 +71,14 @@ extern struct scsi_data_tape *tape_alloc (int unitnum, const TCHAR *tape_directo extern void tape_free (struct scsi_data_tape*); extern void tape_media_change (int unitnum, struct uaedev_config_info*); +int add_scsi_hd (struct scsi_data **sd, int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci, int scsi_level); +int add_scsi_cd (struct scsi_data **sd, int ch, int unitnum); +int add_scsi_tape (struct scsi_data **sd, int ch, const TCHAR *tape_directory, bool readonly); +void free_scsi (struct scsi_data *sd); + +void scsi_freenative(struct scsi_data **sd); +void scsi_addnative(struct scsi_data **sd); + #define SCSI_NO_SENSE_DATA 0x00 #define SCSI_NOT_READY 0x04 #define SCSI_NOT_LOADED 0x09 @@ -137,3 +145,10 @@ static uae_u32 REGPARAM2 x ## _lget(uaecptr addr) \ { \ return y ## _lget(& ## z, addr); \ } + + +void apollo_scsi_bput(uaecptr addr, uae_u8 v); +uae_u8 apollo_scsi_bget(uaecptr addr); +int apollo_add_scsi_unit(int ch, struct uaedev_config_info *ci, int devnum); +void apolloscsi_free(void); +void apolloscsi_reset(void); diff --git a/ncr9x_scsi.cpp b/ncr9x_scsi.cpp index 72d5bd30..a70b0359 100644 --- a/ncr9x_scsi.cpp +++ b/ncr9x_scsi.cpp @@ -65,6 +65,10 @@ #define OKTAGON_EEPROM_SDA 0x8018 #define OKTAGON_EEPROM_SIZE 512 +#define MASOBOSHI_ESP_ADDR 0xfa00 +#define MASOBOSHI_DMA_START 0xf900 +#define MASOBOSHI_DMA_END 0xfa00 + #define DKB_BOARD_SIZE 131072 #define DKB_ROM_SIZE 32768 #define DKB_ROM_OFFSET 0x8000 @@ -92,6 +96,8 @@ struct ncr9x_state uaecptr dma_ptr; int dma_cnt; int state; + int state2; + int state3; uae_u8 data; bool data_valid; @@ -100,11 +106,11 @@ struct ncr9x_state bool romisoddonly; bool romisevenonly; - uae_u8 *dkb_data_buf; - int dkb_data_size_allocated; - int dkb_data_size; - int dkb_data_offset; - uae_u8 *dkb_data_write_buffer; + uae_u8 *fakedma_data_buf; + int fakedma_data_size_allocated; + int fakedma_data_size; + int fakedma_data_offset; + uae_u8 *fakedma_data_write_buffer; }; @@ -144,9 +150,9 @@ struct ncr9x_state static struct ncr9x_state ncr_blizzard_scsi; static struct ncr9x_state ncr_fastlane_scsi[MAX_BOARD_ROMS]; static struct ncr9x_state ncr_oktagon2008_scsi[MAX_BOARD_ROMS]; +static struct ncr9x_state ncr_masoboshi_scsi[MAX_BOARD_ROMS]; static struct ncr9x_state ncr_dkb1200_scsi; - static struct ncr9x_state *ncrs[] = { &ncr_blizzard_scsi, @@ -154,6 +160,8 @@ static struct ncr9x_state *ncrs[] = &ncr_fastlane_scsi[1], &ncr_oktagon2008_scsi[0], &ncr_oktagon2008_scsi[1], + &ncr_masoboshi_scsi[0], + &ncr_masoboshi_scsi[1], &ncr_dkb1200_scsi, NULL }; @@ -161,8 +169,10 @@ static struct ncr9x_state *ncrs[] = void ncr9x_rethink(void) { for (int i = 0; ncrs[i]; i++) { - if (ncrs[i]->boardirq) + if (ncrs[i]->boardirq) { INTREQ_0(0x8000 | 0x0008); + return; + } } } @@ -211,6 +221,18 @@ static void set_irq2_fastlane(struct ncr9x_state *ncr) } } +static void set_irq2_masoboshi(struct ncr9x_state *ncr) +{ + if (ncr->chipirq && !ncr->boardirq) { + ncr->state2 |= 2; + ncr->boardirq = true; +#if NCR_DEBUG > 1 + write_log(_T("MASOBOSHI IRQ\n")); +#endif + ncr9x_rethink(); + } +} + void esp_irq_raise(qemu_irq irq) { struct ncr9x_state *ncr = (struct ncr9x_state*)irq; @@ -225,40 +247,40 @@ void esp_irq_lower(qemu_irq irq) ncr->irq_func(ncr); } -static void dkb_buffer_size(struct ncr9x_state *ncr, int size) +static void fakedma_buffer_size(struct ncr9x_state *ncr, int size) { size = (size + 1) & ~1; - if (ncr->dkb_data_size_allocated >= size) + if (ncr->fakedma_data_size_allocated >= size) return; - if (ncr->dkb_data_buf) - xfree(ncr->dkb_data_buf); - ncr->dkb_data_buf = xmalloc(uae_u8, size); - ncr->dkb_data_size_allocated = size; + if (ncr->fakedma_data_buf) + xfree(ncr->fakedma_data_buf); + ncr->fakedma_data_buf = xmalloc(uae_u8, size); + ncr->fakedma_data_size_allocated = size; } /* Fake DMA */ -static int dkb_dma_read(void *opaque, uint8_t *buf, int len) +static int fake_dma_read(void *opaque, uint8_t *buf, int len) { struct ncr9x_state *ncr = (struct ncr9x_state*)opaque; - ncr->dkb_data_offset = 0; - ncr->dkb_data_write_buffer = buf; - dkb_buffer_size(ncr, len); + ncr->fakedma_data_offset = 0; + ncr->fakedma_data_write_buffer = buf; + fakedma_buffer_size(ncr, len); return 0; } -static int dkb_dma_write(void *opaque, uint8_t *buf, int len) +static int fake_dma_write(void *opaque, uint8_t *buf, int len) { struct ncr9x_state *ncr = (struct ncr9x_state*)opaque; - ncr->dkb_data_offset = 0; - dkb_buffer_size(ncr, len); - memcpy(ncr->dkb_data_buf, buf, len); + ncr->fakedma_data_offset = 0; + fakedma_buffer_size(ncr, len); + memcpy(ncr->fakedma_data_buf, buf, len); if (len & 1) - ncr->dkb_data_buf[len] = 0; - ncr->dkb_data_size = len; + ncr->fakedma_data_buf[len] = 0; + ncr->fakedma_data_size = len; return 0; } /* Fake DMA */ -static int oktagon_dma_read(void *opaque, uint8_t *buf, int len) +static int fake2_dma_read(void *opaque, uint8_t *buf, int len) { struct ncr9x_state *ncr = (struct ncr9x_state*)opaque; esp_dma_enable(ncr->devobject.lsistate, 0); @@ -268,7 +290,7 @@ static int oktagon_dma_read(void *opaque, uint8_t *buf, int len) } return 1; } -static int oktagon_dma_write(void *opaque, uint8_t *buf, int len) +static int fake2_dma_write(void *opaque, uint8_t *buf, int len) { struct ncr9x_state *ncr = (struct ncr9x_state*)opaque; esp_dma_enable(ncr->devobject.lsistate, 0); @@ -501,7 +523,63 @@ static void ncr9x_io_bput(struct ncr9x_state *ncr, uaecptr addr, uae_u32 val) { int reg_shift = 2; addr &= ncr->board_mask; - if (ncr == &ncr_oktagon2008_scsi[0] || ncr == &ncr_oktagon2008_scsi[1]) { + if (ncr == &ncr_masoboshi_scsi[0] || ncr == &ncr_masoboshi_scsi[1]) { + + if (addr >= 0xf04c && addr < 0xf04f) { + int shift = (addr - 0xf04c) * 8; + uae_u32 mask = 0xff << shift; + ncr->dma_ptr &= ~mask; + ncr->dma_ptr |= val << shift; + ncr->dma_ptr &= 0xffffff; + return; + } + if (addr >= 0xf040 && addr <= 0xf047) { + if (addr == 0xf047) { + if (val & 0x80) + ncr->state3 = 0x80; + } + if (addr == 0xf040) { + ncr->state3 = 0; + } + return; + } + + if (addr == 0xf007) { + ncr->state = val; + } + if (addr == 0xf000) { + ncr->state2 &= ~2; + } + if (addr == 0xf004) { + ncr->state2 &= ~1; + } + if (addr >= MASOBOSHI_DMA_START && addr < MASOBOSHI_DMA_END) { + if (esp_reg_read(ncr->devobject.lsistate, ESP_RSTAT) & STAT_TC) { +#if NCR_DEBUG > 2 + write_log(_T("MASOBOSHI DMA OVERFLOW %08X PUT %02x %08x\n"), addr, val & 0xff, M68K_GETPC); +#endif + } else { + ncr->data = val; + ncr->data_valid = true; + esp_dma_enable(ncr->devobject.lsistate, 1); +#if NCR_DEBUG > 2 + write_log(_T("MASOBOSHI DMA %08X PUT %02x %08x\n"), addr, val & 0xff, M68K_GETPC); +#endif + } + return; + } + if (addr < MASOBOSHI_ESP_ADDR || addr >= MASOBOSHI_ESP_ADDR + 0x100) { +#if NCR_DEBUG + write_log(_T("MASOBOSHI IO %08X PUT %02x %08x\n"), addr, val & 0xff, M68K_GETPC); +#endif + return; + } + if (addr == MASOBOSHI_ESP_ADDR + 3 * 2 && val == 0x02) + ncr->state |= 0x80; + reg_shift = 1; + addr &= 0x3f; + + } else if (ncr == &ncr_oktagon2008_scsi[0] || ncr == &ncr_oktagon2008_scsi[1]) { if (addr == OKTAGON_EEPROM_SCL) { eeprom_i2c_set(ncr->eeprom, BITBANG_I2C_SCL, (val & 0x80) != 0); } else if (addr == OKTAGON_EEPROM_SDA) { @@ -615,10 +693,10 @@ static void ncr9x_io_bput(struct ncr9x_state *ncr, uaecptr addr, uae_u32 val) } if (addr >= 0x10080 && addr < 0x10088) { //write_log(_T("DKB PUT BYTE %02x\n"), val & 0xff); - if (ncr->dkb_data_offset < ncr->dkb_data_size) { - ncr->dkb_data_buf[ncr->dkb_data_offset++] = val; - if (ncr->dkb_data_offset == ncr->dkb_data_size) { - memcpy(ncr->dkb_data_write_buffer, ncr->dkb_data_buf, ncr->dkb_data_size); + if (ncr->fakedma_data_offset < ncr->fakedma_data_size) { + ncr->fakedma_data_buf[ncr->fakedma_data_offset++] = val; + if (ncr->fakedma_data_offset == ncr->fakedma_data_size) { + memcpy(ncr->fakedma_data_write_buffer, ncr->fakedma_data_buf, ncr->fakedma_data_size); esp_fake_dma_done(ncr->devobject.lsistate); } } @@ -638,12 +716,54 @@ static void ncr9x_io_bput(struct ncr9x_state *ncr, uaecptr addr, uae_u32 val) } +static int perse = 0; + uae_u32 ncr9x_io_bget(struct ncr9x_state *ncr, uaecptr addr) { uae_u8 v; int reg_shift = 2; addr &= ncr->board_mask; - if (ncr == &ncr_oktagon2008_scsi[0] || ncr == &ncr_oktagon2008_scsi[1]) { + if (ncr == &ncr_masoboshi_scsi[0] || ncr == &ncr_masoboshi_scsi[1]) { + + if (addr == MASOBOSHI_ESP_ADDR + 3 * 2 && (ncr->state & 0x80)) + return 2; + if (ncr->state & 0x80) + ncr->state &= ~0x80; + + if (addr == 0xf040) { + return ncr->state3; + } + + if (addr == 0xf000) { + if (esp_reg_read(ncr->devobject.lsistate, ESP_RSTAT) & STAT_TC) { + if (perse) + activate_debugger(); + ncr->state2 |= 1; // dma complete + } + return ncr->state2 & 0x7f; + } + if (addr == 0xf007) { + v = ncr->state; + } + if (addr >= MASOBOSHI_DMA_START && addr < MASOBOSHI_DMA_END) { + esp_dma_enable(ncr->devobject.lsistate, 1); + v = ncr->data; + ncr->data_valid = false; +#if NCR_DEBUG > 2 + write_log(_T("MASOBOSHI DMA %08X GET %02x %08x\n"), addr, v, M68K_GETPC); +#endif + return v; + } + if (addr < MASOBOSHI_ESP_ADDR || addr >= MASOBOSHI_ESP_ADDR + 0x100) { +#if NCR_DEBUG + write_log(_T("MASOBOSHI IO %08X GET %02x %08x\n"), addr, v, M68K_GETPC); +#endif + return v; + } + reg_shift = 1; + addr &= 0x3f; + + } else if (ncr == &ncr_oktagon2008_scsi[0] || ncr == &ncr_oktagon2008_scsi[1]) { if (addr == OKTAGON_EEPROM_SCL) { return eeprom_i2c_set(ncr->eeprom, BITBANG_I2C_SCL, -1) ? 0x80 : 0x00; } else if (addr == OKTAGON_EEPROM_SDA) { @@ -697,20 +817,20 @@ uae_u32 ncr9x_io_bget(struct ncr9x_state *ncr, uaecptr addr) uae_u8 v = 0; if (ncr->chipirq) v |= 0x40; - if (ncr->dkb_data_offset < ncr->dkb_data_size) + if (ncr->fakedma_data_offset < ncr->fakedma_data_size) v |= 0x80; //write_log(_T("DKB IO GET %02x %08x\n"), v, M68K_GETPC); return v; } if (addr >= 0x10080 && addr < 0x10088) { - //write_log(_T("DKB GET BYTE %02x\n"), ncr->dkb_data_buf[ncr->dkb_data_offset]); - if (ncr->dkb_data_offset >= ncr->dkb_data_size) + //write_log(_T("DKB GET BYTE %02x\n"), ncr->fakedma_data_buf[ncr->fakedma_data_offset]); + if (ncr->fakedma_data_offset >= ncr->fakedma_data_size) return 0; - if (ncr->dkb_data_offset == ncr->dkb_data_size - 1) { + if (ncr->fakedma_data_offset == ncr->fakedma_data_size - 1) { esp_fake_dma_done(ncr->devobject.lsistate); //write_log(_T("DKB fake dma finished\n")); } - return ncr->dkb_data_buf[ncr->dkb_data_offset++]; + return ncr->fakedma_data_buf[ncr->fakedma_data_offset++]; } if (addr < 0x10000 || addr >= 0x10040) { write_log(_T("DKB IO GET %08x %08x\n"), addr, M68K_GETPC); @@ -913,6 +1033,15 @@ void cpuboard_ncr9x_scsi_put(uaecptr addr, uae_u32 v) ncr9x_io_bput(&ncr_blizzard_scsi, addr, v); } +uae_u32 masoboshi_ncr9x_scsi_get(uaecptr addr, int devnum) +{ + return ncr9x_io_bget(&ncr_masoboshi_scsi[devnum], addr); +} +void masoboshi_ncr9x_scsi_put(uaecptr addr, uae_u32 v, int devnum) +{ + ncr9x_io_bput(&ncr_masoboshi_scsi[devnum], addr, v); +} + static void ew(struct ncr9x_state *ncr, int addr, uae_u8 value) { if (addr == 00 || addr == 02 || addr == 0x40 || addr == 0x42) { @@ -1000,8 +1129,11 @@ static void ncr9x_reset_board(struct ncr9x_state *ncr) ncr->bank = &ncr_bank_dkb; ncr->board_mask = DKB_BOARD_SIZE - 1; ncr->irq_func = set_irq2_dkb1200; + } else if (ncr == &ncr_masoboshi_scsi[0] || ncr == &ncr_masoboshi_scsi[1]) { + ncr->irq_func = set_irq2_masoboshi; } - ncr->name = ncr->bank->name; + if (ncr->bank) + ncr->name = ncr->bank->name; } void ncr9x_reset(void) @@ -1220,6 +1352,20 @@ addrbank *ncr_dkb_autoconfig_init(void) } +void ncr_masoboshi_autoconfig_init(int devnum) +{ + struct ncr9x_state *ncr = &ncr_masoboshi_scsi[devnum]; + + if (!ncr->enabled && devnum > 0) + return; + + ncr->enabled = true; + + ncr9x_init (); + ncr9x_reset_board(ncr); +} + + static void freescsi_hdf(struct scsi_data *sd) { if (!sd) @@ -1260,9 +1406,11 @@ void ncr9x_init(void) esp_scsi_init(&ncr_blizzard_scsi.devobject, blizzard_dma_read, blizzard_dma_write); esp_scsi_init(&ncr_fastlane_scsi[0].devobject, fastlane_dma_read, fastlane_dma_write); esp_scsi_init(&ncr_fastlane_scsi[1].devobject, fastlane_dma_read, fastlane_dma_write); - esp_scsi_init(&ncr_oktagon2008_scsi[0].devobject, oktagon_dma_read, oktagon_dma_write); - esp_scsi_init(&ncr_oktagon2008_scsi[1].devobject, oktagon_dma_read, oktagon_dma_write); - esp_scsi_init(&ncr_dkb1200_scsi.devobject, dkb_dma_read, dkb_dma_write); + esp_scsi_init(&ncr_oktagon2008_scsi[0].devobject, fake2_dma_read, fake2_dma_write); + esp_scsi_init(&ncr_oktagon2008_scsi[1].devobject, fake2_dma_read, fake2_dma_write); + esp_scsi_init(&ncr_dkb1200_scsi.devobject, fake_dma_read, fake_dma_write); + esp_scsi_init(&ncr_masoboshi_scsi[0].devobject, fake2_dma_read, fake2_dma_write); + esp_scsi_init(&ncr_masoboshi_scsi[1].devobject, fake2_dma_read, fake2_dma_write); } } @@ -1350,4 +1498,10 @@ int oktagon_add_scsi_unit (int ch, struct uaedev_config_info *ci, int devnum) return ncr9x_add_scsi_unit(&ncr_oktagon2008_scsi[devnum], ch, ci); } +int masoboshi_add_scsi_unit (int ch, struct uaedev_config_info *ci, int devnum) +{ + return ncr9x_add_scsi_unit(&ncr_masoboshi_scsi[devnum], ch, ci); +} + + #endif diff --git a/qemuvga/esp.cpp b/qemuvga/esp.cpp index 4b9eb8b3..1e8420a1 100644 --- a/qemuvga/esp.cpp +++ b/qemuvga/esp.cpp @@ -331,7 +331,7 @@ void esp_transfer_data(SCSIRequest *req, uint32_t len) s->async_buf = scsiesp_req_get_buf(req); if (s->dma_left) { esp_do_dma(s); - } else if (s->dma_counter != 0 && s->ti_size <= 0) { + } else if (s->dma_counter != 0 && s->ti_size == 0) { /* If this was the last part of a DMA transfer then the completion interrupt is deferred to here. */ esp_dma_done(s); @@ -450,6 +450,8 @@ uint64_t esp_reg_read(void *opaque, uint32_t saddr) esp_lower_irq(s); return old_val; + case ESP_RFLAGS: + return s->rregs[saddr] | s->rregs[ESP_RSEQ] << 5; case ESP_RES4: return 0x80 | 0x20 | 0x2; default: @@ -520,6 +522,8 @@ void esp_reg_write(void *opaque, uint32_t saddr, uint64_t val) s->rregs[ESP_RINTR] = INTR_DC; s->rregs[ESP_RSEQ] = 0; s->rregs[ESP_RFLAGS] = 0; + // Masoboshi driver expects phase=0! + s->rregs[ESP_RSTAT] &= ~7; esp_raise_irq(s); break; case CMD_PAD: @@ -544,7 +548,8 @@ void esp_reg_write(void *opaque, uint32_t saddr, uint64_t val) s->rregs[ESP_RINTR] = 0; break; case CMD_DISSEL: - s->rregs[ESP_RINTR] = 0; + // Masoboshi driver expects Function Complete. + s->rregs[ESP_RINTR] = INTR_FC; esp_raise_irq(s); break; default: diff --git a/rommgr.cpp b/rommgr.cpp index d3795e4f..e2b3fcaa 100644 --- a/rommgr.cpp +++ b/rommgr.cpp @@ -94,7 +94,7 @@ struct romdata *getromdatabypath (const TCHAR *path) return NULL; } -#define NEXT_ROM_ID 117 +#define NEXT_ROM_ID 121 static struct romheader romheaders[] = { { _T("Freezer Cartridges"), 1 }, @@ -284,7 +284,6 @@ static struct romdata roms[] = { ALTROM(116, 1, 1, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x1909f7e9, 0x5abe9b9d,0xaae328c8,0x134e2b62,0x7b33b698,0xe342afc2) ALTROM(116, 1, 2, 32768, ROMTYPE_ODD | ROMTYPE_8BIT, 0xa3927c72, 0x7adc9352,0x2d112ae9,0x23b9a70d,0x951b1e7a,0xba800ea6) - { _T("Freezer: HRTMon v2.33 (built-in)"), 0, 0, 0, 0, _T("HRTMON\0"), 0, 63, 0, 0, ROMTYPE_HRTMON, 0, 1, NULL, 0xffffffff, 0, 0, 0, 0, 0, _T("HRTMon") }, @@ -343,17 +342,23 @@ static struct romdata roms[] = { ALTROMPN(113, 1, 2, 32768, ROMTYPE_QUAD | ROMTYPE_ODD | ROMTYPE_8BIT, _T("U27"), 0x38373cf6, 0xfe8aa931, 0xada6b6f3, 0x6b48ca3c, 0x9b86677d, 0xbee4da59) ALTROMPN(113, 1, 3, 32768, ROMTYPE_QUAD | ROMTYPE_EVEN | ROMTYPE_8BIT, _T("U25"), 0xc9e990d3, 0xb251ef73, 0x1374e796, 0xa87cbc7e, 0x9263320a, 0x28a71d2b) ALTROMPN(113, 1, 4, 32768, ROMTYPE_QUAD | ROMTYPE_ODD | ROMTYPE_8BIT, _T("U26"), 0x2e117fe0, 0xbb2de2da, 0x6db4e92c, 0x636fefe6, 0x13a32699, 0xcea31011) + { _T("Apollo 1240/1260 ROM"), 5, 60, 5, 60, _T("APOLLO12XX\0"), 131072, 119, 0, 0, ROMTYPE_CPUBOARD, 0, 0, NULL, + 0xcd009ad9, 0x1c3b4851,0xc5a221e3,0xa7ca24fc,0xc1df4a5b,0x9f2343ad }, + { _T("GVP A3001 Series I ROM"), 3, 3, 3, 3, _T("A3001SI\0"), 8192, 114, 0, 0, ROMTYPE_CPUBOARD, 0, 0, NULL, + 0xaaff7c65, 0x424cf3da,0xcc9da794,0x0ba74446,0x69dd1691,0x44ae87ee, NULL, NULL }, - { _T("GVP Series I ROM"), 3, 15, 3, 15, _T("GVP\0"), 16384, 111, 0, 0, ROMTYPE_GVP, 0, 0, NULL, + { _T("GVP Series II v3.15 ROM"), 3, 15, 3, 15, _T("GVPII\0"), 16384, 111, 0, 0, ROMTYPE_GVPS2, 0, 0, NULL, 0xf99c6f11, 0x77098a9e,0x35acaef2,0x11a546f0,0xc564cdac,0xf52836c4, NULL, NULL }, - { _T("GVP Series II ROM"), 4, 15, 4, 15, _T("GVPII\0"), 16384, 109, 0, 0, ROMTYPE_GVP, 0, 0, NULL, + { _T("GVP Series II v4.15 ROM"), 4, 15, 4, 15, _T("GVPII\0"), 16384, 109, 0, 0, ROMTYPE_GVPS2, 0, 0, NULL, 0xf89f44d6, 0xbf10c12c,0xc72dd040,0x549ea17c,0x24947633,0xe3773297, NULL, NULL }, - { _T("GVP Series II Guru ROM"), 6, 14, 6, 14, _T("GVPII\0"), 32768, 110, 0, 0, ROMTYPE_GVP, 0, 0, NULL, + { _T("GVP Series II Guru ROM"), 6, 14, 6, 14, _T("GVPII\0"), 32768, 110, 0, 0, ROMTYPE_GVPS2, 0, 0, NULL, 0x756103b1, 0x7f1335ea,0xf5b7ce73,0xc5231173,0x261da5aa,0xe7249645, NULL, NULL }, - - { _T("GVP A3001 Series I ROM"), 3, 3, 3, 3, _T("A3001SI\0"), 8192, 114, 0, 0, ROMTYPE_CPUBOARD, 0, 0, NULL, - 0xaaff7c65, 0x424cf3da,0xcc9da794,0x0ba74446,0x69dd1691,0x44ae87ee, NULL, NULL }, - + { _T("AlfaPower v6.10 ROM"), 6, 10, 6, 10, _T("ALFAPOWER\0"), 32768, 117, 0, 0, ROMTYPE_ALFA, 0, 0, NULL, + 0x1cfb0a0b, 0xc7275eda,0x547d6664,0x5c4eb7a0,0x3b5cef37,0xa498365a, NULL, NULL }, + { _T("AlfaPower v8.3 ROM"), 8, 3, 8, 3, _T("ALFAPOWERPLUS\0"), 32768, 118, 0, 0, ROMTYPE_ALFAPLUS, 0, 0, NULL, + 0xe8201bad, 0xdefea015,0x596fce32,0x11e84397,0x23046a31,0x5a7726dc, NULL, NULL }, + { _T("Masoboshi MC-702 ROM"), 2, 201, 2, 201, _T("MASOBOSHI\0"), 32768, 120, 0, 0, ROMTYPE_MASOBOSHI, 0, 0, NULL, + 0xcd99b98a, 0x3897e46a,0x66d5833f,0x849b8e81,0x30acb3cb,0x319a2fa0, NULL, NULL }, { _T("CyberStorm MK I 68040"), 0, 0, 0, 0, _T("CSMKI\0"), 32768, 95, 0, 0, ROMTYPE_CPUBOARD, 0, 0, NULL, 0, 0, 0, 0, 0, 0, NULL, _T("cyberstormmk1_040.rom") }, @@ -1128,6 +1133,8 @@ void romwarning (const int *ids) TCHAR tmp1[MAX_DPATH], tmp2[MAX_DPATH]; TCHAR tmp3[MAX_DPATH]; + if (ids[0] == -1) + return; exp = 0; tmp2[0] = 0; i = 0; diff --git a/scsi.cpp b/scsi.cpp index 09699517..1fbb0c8f 100644 --- a/scsi.cpp +++ b/scsi.cpp @@ -15,8 +15,10 @@ #include "filesys.h" #include "blkdev.h" #include "zfile.h" +#include "debug.h" #define SCSI_EMU_DEBUG 0 +#define RAW_SCSI_DEBUG 0 extern int log_scsiemu; @@ -371,7 +373,115 @@ int scsi_receive_data(struct scsi_data *sd, uae_u8 *b) return 0; } +void free_scsi (struct scsi_data *sd) +{ + if (!sd) + return; + hdf_hd_close (sd->hfd); + scsi_free (sd); +} + +int add_scsi_hd (struct scsi_data **sd, int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci, int scsi_level) +{ + free_scsi (sd[ch]); + sd[ch] = NULL; + if (!hfd) { + hfd = xcalloc (struct hd_hardfiledata, 1); + memcpy (&hfd->hfd.ci, ci, sizeof (struct uaedev_config_info)); + } + if (!hdf_hd_open (hfd)) + return 0; + hfd->ansi_version = scsi_level; + sd[ch] = scsi_alloc_hd (ch, hfd); + return sd[ch] ? 1 : 0; +} + +int add_scsi_cd (struct scsi_data **sd, int ch, int unitnum) +{ + device_func_init (0); + free_scsi (sd[ch]); + sd[ch] = scsi_alloc_cd (ch, unitnum, false); + return sd[ch] ? 1 : 0; +} + +int add_scsi_tape (struct scsi_data **sd, int ch, const TCHAR *tape_directory, bool readonly) +{ + free_scsi (sd[ch]); + sd[ch] = scsi_alloc_tape (ch, tape_directory, readonly); + return sd[ch] ? 1 : 0; +} + +void scsi_freenative(struct scsi_data **sd) +{ + for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) { + free_scsi (sd[i]); + sd[i] = NULL; + } +} + +void scsi_addnative(struct scsi_data **sd) +{ + int i, j; + int devices[MAX_TOTAL_SCSI_DEVICES]; + int types[MAX_TOTAL_SCSI_DEVICES]; + struct device_info dis[MAX_TOTAL_SCSI_DEVICES]; + + scsi_freenative (sd); + i = 0; + while (i < MAX_TOTAL_SCSI_DEVICES) { + types[i] = -1; + devices[i] = -1; + if (sys_command_open (i)) { + if (sys_command_info (i, &dis[i], 0)) { + devices[i] = i; + types[i] = 100 - i; + if (dis[i].type == INQ_ROMD) + types[i] = 1000 - i; + } + sys_command_close (i); + } + i++; + } + i = 0; + while (devices[i] >= 0) { + j = i + 1; + while (devices[j] >= 0) { + if (types[i] > types[j]) { + int tmp = types[i]; + types[i] = types[j]; + types[j] = tmp; + } + j++; + } + i++; + } + i = 0; j = 0; + while (devices[i] >= 0 && j < 7) { + if (sd[j] == NULL) { + sd[j] = scsi_alloc_native(j, devices[i]); + write_log (_T("SCSI: %d:'%s'\n"), j, dis[i].label); + i++; + } + j++; + } +} + + // raw scsi + +#define SCSI_IO_BUSY 0x80 +#define SCSI_IO_ATN 0x40 +#define SCSI_IO_SEL 0x20 +#define SCSI_IO_REQ 0x10 +#define SCSI_IO_DIRECTION 0x01 +#define SCSI_IO_COMMAND 0x02 +#define SCSI_IO_MESSAGE 0x04 + +#define SCSI_SIGNAL_PHASE_FREE -1 +#define SCSI_SIGNAL_PHASE_ARBIT -2 +#define SCSI_SIGNAL_PHASE_SELECT_1 -3 +#define SCSI_SIGNAL_PHASE_SELECT_2 -4 + #define SCSI_SIGNAL_PHASE_DATA_OUT 0 #define SCSI_SIGNAL_PHASE_DATA_IN 1 #define SCSI_SIGNAL_PHASE_COMMAND 2 @@ -379,90 +489,298 @@ int scsi_receive_data(struct scsi_data *sd, uae_u8 *b) #define SCSI_SIGNAL_PHASE_MESSAGE_OUT 6 #define SCSI_SIGNAL_PHASE_MESSAGE_IN 7 -#define SCSI_BUS_PHASE_FREE 0 -#define SCSI_BUS_PHASE_ARBITRATION 1 -#define SCSI_BUS_PHASE_SELECTION 2 -#define SCSI_BUS_PHASE_RESELECTION 3 -#define SCSI_BUS_PHASE_COMMAND 4 -#define SCSI_BUS_PHASE_DATA_IN 5 -#define SCSI_BUS_PHASE_DATA_OUT 6 -#define SCSI_BUS_PHASE_STATUS 7 -#define SCSI_BUS_PHASE_MESSAGE_IN 8 -#define SCSI_BUS_PHASE_MESSAGE_OUT 9 - -struct raw_scsi_device -{ - int x; - int id; -}; struct raw_scsi { - int signal_phase; - int old_signal_phase; + int io; int bus_phase; + bool atn; uae_u8 data; - int initiator; - int target; - uae_u8 cmd[16]; - int len; - struct raw_scsi_device *device[8]; + int initiator_id, target_id; + struct scsi_data *device[8]; + struct scsi_data *target; }; -struct raw_scsi *new_raw_scsi(void) +void raw_scsi_reset(struct raw_scsi *rs) { - struct raw_scsi *rs = xcalloc(struct raw_scsi, 1); - return rs; + rs->target = NULL; + rs->io = 0; + rs->bus_phase = SCSI_SIGNAL_PHASE_FREE; } -void free_raw_scsi(struct raw_scsi *rs) +void raw_scsi_busfree(struct raw_scsi *rs) { - if (!rs) - return; - for (int i = 0; i < 8; i++) - xfree(rs->device[i]); - xfree(rs); + rs->target = NULL; + rs->io = 0; + rs->bus_phase = SCSI_SIGNAL_PHASE_FREE; } -struct raw_scsi_device *new_raw_scsi_device(struct raw_scsi *rs, int id) +static void bus_free(struct raw_scsi *rs) { - rs->device[id] = xcalloc(struct raw_scsi_device, 1); - rs->device[id]->id = id; - return rs->device[id]; + rs->bus_phase = SCSI_SIGNAL_PHASE_FREE; + rs->io = 0; } -void free_raw_scsi_device(struct raw_scsi *rs, struct raw_scsi_device *dev) +static int getbit(uae_u8 v) { - if (!dev) - return; - rs->device[dev->id] = NULL; - xfree(dev); + for (int i = 0; i < 8; i++) { + if ((1 << i) & v) + return i; + } + return -1; } -int raw_scsi_get_signal_phase(struct raw_scsi *rs, struct raw_scsi_device *dev) +void raw_scsi_set_signal_phase(struct raw_scsi *rs, bool busy, bool select, bool atn) { - return rs->signal_phase; + switch (rs->bus_phase) + { + case SCSI_SIGNAL_PHASE_FREE: + if (busy && !select) { + rs->bus_phase = SCSI_SIGNAL_PHASE_ARBIT; + } + break; + case SCSI_SIGNAL_PHASE_ARBIT: + rs->target_id = -1; + rs->target = NULL; + if (busy && select) { + rs->bus_phase = SCSI_SIGNAL_PHASE_SELECT_1; + } + break; + case SCSI_SIGNAL_PHASE_SELECT_1: + rs->atn = atn; + if (!busy) { + uae_u8 data = rs->data & ~(1 << rs->initiator_id); + rs->target_id = getbit(data); + if (rs->target_id >= 0) { + rs->target = rs->device[rs->target_id]; + if (rs->target) { +#if RAW_SCSI_DEBUG + write_log(_T("raw_scsi: selected id %d\n"), rs->target_id); +#endif + rs->io |= SCSI_IO_BUSY; + } else { +#if RAW_SCSI_DEBUG + write_log(_T("raw_scsi: selected non-existing id %d\n"), rs->target_id); +#endif + rs->target_id = -1; + } + } + if (rs->target_id >= 0) { + rs->bus_phase = SCSI_SIGNAL_PHASE_SELECT_2; + } else { + if (!select) { + rs->bus_phase = SCSI_SIGNAL_PHASE_FREE; + } + } + } + break; + case SCSI_SIGNAL_PHASE_SELECT_2: + if (!select) { + scsi_start_transfer(rs->target); + rs->bus_phase = rs->atn ? SCSI_SIGNAL_PHASE_MESSAGE_IN : SCSI_SIGNAL_PHASE_COMMAND; + rs->io = SCSI_IO_BUSY | SCSI_IO_REQ; + } + break; + } } -void raw_scsi_put_signal_phase(struct raw_scsi *rs, struct raw_scsi_device *dev, uae_u8 phase) +uae_u8 raw_scsi_get_signal_phase(struct raw_scsi *rs) { - if (rs->signal_phase == phase) - return; - rs->old_signal_phase = rs->signal_phase; - rs->signal_phase = phase; - switch(rs->bus_phase) + uae_u8 v = rs->io; + if (rs->bus_phase >= 0) + v |= rs->bus_phase; + return v; +} + +uae_u8 raw_scsi_get_data(struct raw_scsi *rs) +{ + struct scsi_data *sd = rs->target; + uae_u8 v = 0; + + switch (rs->bus_phase) { - case SCSI_BUS_PHASE_FREE: + case SCSI_SIGNAL_PHASE_FREE: +#if RAW_SCSI_DEBUG + write_log(_T("raw_scsi: bus free\n")); +#endif + v = 0; + break; + case SCSI_SIGNAL_PHASE_ARBIT: +#if RAW_SCSI_DEBUG + write_log(_T("raw_scsi: arbitration\n")); +#endif + v = rs->data; + break; + case SCSI_SIGNAL_PHASE_DATA_IN: + if (scsi_receive_data(sd, & v)) { + rs->bus_phase = SCSI_SIGNAL_PHASE_STATUS; +#if RAW_SCSI_DEBUG + write_log(_T("raw_scsi: data in finished, %d bytes: status phase\n"), sd->offset); +#endif + } + break; + case SCSI_SIGNAL_PHASE_STATUS: +#if RAW_SCSI_DEBUG + write_log(_T("raw_scsi: status byte read %02x\n"), sd->status); +#endif + v = sd->status; + bus_free(rs); + break; + default: + write_log(_T("raw_scsi_get_data but bus phase is %d!\n"), rs->bus_phase); + break; + } + + return v; +} + +void raw_scsi_put_data(struct raw_scsi *rs, uae_u8 data) +{ + struct scsi_data *sd = rs->target; + int len; + rs->data = data; + switch (rs->bus_phase) + { + case SCSI_SIGNAL_PHASE_ARBIT: + rs->initiator_id = getbit(data); + write_log(_T("raw_scsi: arbitration initiator id %d\n"), rs->initiator_id); break; - + case SCSI_SIGNAL_PHASE_SELECT_1: + break; + case SCSI_SIGNAL_PHASE_COMMAND: + sd->cmd[sd->offset++] = data; + len = scsicmdsizes[sd->cmd[0] >> 5]; + if (sd->offset >= len) { +#if RAW_SCSI_DEBUG + write_log(_T("raw_scsi: got command %02x (%d bytes)\n"), sd->cmd[0], len); +#endif + scsi_emulate_analyze(rs->target); + if (sd->direction > 0) { +#if RAW_SCSI_DEBUG + write_log(_T("raw_scsi: data out %d bytes required\n"), sd->data_len); +#endif + scsi_start_transfer(sd); + rs->bus_phase = SCSI_SIGNAL_PHASE_DATA_OUT; + } else if (sd->direction <= 0) { + scsi_emulate_cmd(sd); + scsi_start_transfer(sd); + if (!sd->status && sd->data_len > 0) { +#if RAW_SCSI_DEBUG + write_log(_T("raw_scsi: data in %d bytes waiting\n"), sd->data_len); +#endif + rs->bus_phase = SCSI_SIGNAL_PHASE_DATA_IN; + } else { +#if RAW_SCSI_DEBUG + write_log(_T("raw_scsi: no data, status = %d\n"), sd->status); +#endif + rs->bus_phase = SCSI_SIGNAL_PHASE_STATUS; + } + } + } + break; + case SCSI_SIGNAL_PHASE_DATA_OUT: + if (scsi_send_data(sd, data)) { +#if RAW_SCSI_DEBUG + write_log(_T("raw_scsi: data out finished, %d bytes\n"), sd->data_len); +#endif + scsi_emulate_cmd(sd); + rs->bus_phase = SCSI_SIGNAL_PHASE_STATUS; + } + break; + default: + write_log(_T("raw_scsi_put_data but bus phase is %d!\n"), rs->bus_phase); + break; + } +} + +struct apollo_soft_scsi +{ + bool enabled; + int configured; + bool autoconfig; + bool irq; + struct raw_scsi rscsi; +}; +static struct apollo_soft_scsi apolloscsi[2]; + +void apollo_scsi_bput(uaecptr addr, uae_u8 v) +{ + int bank = addr & (0x800 | 0x400); + struct apollo_soft_scsi *as = &apolloscsi[0]; + struct raw_scsi *rs = &as->rscsi; + addr &= 0x3fff; + if (bank == 0) { + raw_scsi_put_data(rs, v); + } else if (bank == 0xc00 && !(addr & 1)) { + as->irq = (v & 64) != 0; + raw_scsi_set_signal_phase(rs, + (v & 128) != 0, + (v & 32) != 0, + false); + } else if (bank == 0x400 && (addr & 1)) { + raw_scsi_set_signal_phase(rs, true, false, false); + raw_scsi_put_data(rs, v); + } + //write_log(_T("apollo scsi put %04x = %02x\n"), addr, v); +} + +uae_u8 apollo_scsi_bget(uaecptr addr) +{ + int bank = addr & (0x800 | 0x400); + struct apollo_soft_scsi *as = &apolloscsi[0]; + struct raw_scsi *rs = &as->rscsi; + uae_u8 v = 0xff; + addr &= 0x3fff; + if (bank == 0) { + v = raw_scsi_get_data(rs); + } else if (bank == 0x800 && (addr & 1)) { + uae_u8 t = raw_scsi_get_signal_phase(rs); + v = 1; // disable switch off + if (t & SCSI_IO_BUSY) + v |= 128; + if (t & SCSI_IO_SEL) + v |= 32; + if (t & SCSI_IO_REQ) + v |= 2; + if (t & SCSI_IO_DIRECTION) + v |= 8; + if (t & SCSI_IO_COMMAND) + v |= 16; + if (t & SCSI_IO_MESSAGE) + v |= 4; + v ^= (1 | 2 | 4 | 8 | 16 | 32 | 128); + //v |= apolloscsi.irq ? 64 : 0; } + //write_log(_T("apollo scsi get %04x = %02x\n"), addr, v); + return v; } -uae_u16 raw_scsi_get_data(struct raw_scsi *rs, struct raw_scsi_device *dev) +int apollo_add_scsi_unit(int ch, struct uaedev_config_info *ci, int devnum) { - return rs->data; + struct raw_scsi *rs = &apolloscsi[devnum].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 raw_scsi_put_data(struct raw_scsi *rs, struct raw_scsi_device *dev, uae_u16 data) +void apolloscsi_free(void) { + for (int j = 0; j < 2; j++) { + struct raw_scsi *rs = &apolloscsi[j].rscsi; + for (int i = 0; i < 8; i++) { + free_scsi (rs->device[i]); + rs->device[i] = NULL; + } + } } + +void apolloscsi_reset(void) +{ + raw_scsi_reset(&apolloscsi[0].rscsi); + raw_scsi_reset(&apolloscsi[1].rscsi); +} \ No newline at end of file -- 2.47.3