From f39073d470b38269a315984f2dcef13711c5dfe5 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Thu, 5 Nov 2015 21:03:40 +0200 Subject: [PATCH] Golem FastSCSI/IDE controller. --- expansion.cpp | 20 ++++- ide.cpp | 16 ++-- idecontrollers.cpp | 184 +++++++++++++++++++++++++++++++++++++-- include/ide.h | 1 + include/idecontrollers.h | 3 + include/ncr9x_scsi.h | 5 ++ include/rommgr.h | 1 + ncr9x_scsi.cpp | 78 +++++++++++++++-- qemuvga/esp.cpp | 19 +++- qemuvga/scsi/esp.h | 1 + 10 files changed, 307 insertions(+), 21 deletions(-) diff --git a/expansion.cpp b/expansion.cpp index 6707ae88..24702e8a 100644 --- a/expansion.cpp +++ b/expansion.cpp @@ -2814,6 +2814,15 @@ static void nexus_memory_callback(struct romconfig *rc, uae_u8 *ac, int size) else ac[1] = 8; } +static const struct expansionboardsettings golemfast_settings[] = { + { + _T("IDE"), + _T("ide") + }, + { + NULL + } +}; static const struct expansionboardsettings nexus_settings[] = { { _T("MEM TEST"), @@ -3024,12 +3033,21 @@ const struct expansionromtype expansionroms[] = { false, EXPANSIONTYPE_SCSI }, { - _T("golem"), _T("Golem"), _T("Kupke"), + _T("golem"), _T("Golem SCSI II"), _T("Kupke"), golem_init, NULL, golem_add_scsi_unit, ROMTYPE_GOLEM, 0, 0, BOARD_AUTOCONFIG_Z2, false, NULL, 0, true, EXPANSIONTYPE_SCSI, 2079, 3, 0 }, + { + _T("golemfast"), _T("Golem Fast SCSI/IDE"), _T("Kupke"), + golemfast_init, NULL, golemfast_add_idescsi_unit, ROMTYPE_GOLEMFAST, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + true, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_IDE, + 0, 0, 0, false, NULL, + true, + golemfast_settings + }, { _T("multievolution"), _T("Multi Evolution 500/2000"), _T("MacroSystem"), ncr_multievolution_init, NULL, multievolution_add_scsi_unit, ROMTYPE_MEVOLUTION, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true, diff --git a/ide.cpp b/ide.cpp index 9f4e4f63..b8a32d76 100644 --- a/ide.cpp +++ b/ide.cpp @@ -1125,12 +1125,16 @@ uae_u32 ide_read_reg (struct ide_hdf *ide, int ide_reg) if (ide->regs.ide_status & IDE_STATUS_BSY) ide_reg = IDE_STATUS; if (!ide_isdrive (ide)) { - if (ide_reg == IDE_STATUS && ide->pair->irq) - ide->pair->irq = 0; - if (ide_isdrive (ide->pair)) - v = 0x01; - else - v = 0xff; + if (ide_reg == IDE_STATUS) { + if (ide->pair->irq) + ide->pair->irq = 0; + if (ide_isdrive (ide->pair)) + v = 0x01; + else + v = 0xff; + } else { + v = 0; + } goto end; } diff --git a/idecontrollers.cpp b/idecontrollers.cpp index c38f2cb2..575fe735 100644 --- a/idecontrollers.cpp +++ b/idecontrollers.cpp @@ -43,7 +43,8 @@ #define PROTAR_IDE (MTEC_IDE + MAX_DUPLICATE_EXPANSION_BOARDS) #define ROCHARD_IDE (PROTAR_IDE + MAX_DUPLICATE_EXPANSION_BOARDS) #define x86_AT_IDE (ROCHARD_IDE + 2 * MAX_DUPLICATE_EXPANSION_BOARDS) -#define TOTAL_IDE (x86_AT_IDE + MAX_DUPLICATE_EXPANSION_BOARDS) +#define GOLEMFAST_IDE (x86_AT_IDE + 2 * MAX_DUPLICATE_EXPANSION_BOARDS) +#define TOTAL_IDE (GOLEMFAST_IDE + MAX_DUPLICATE_EXPANSION_BOARDS) #define ALF_ROM_OFFSET 0x0100 #define GVP_IDE_ROM_OFFSET 0x8000 @@ -93,6 +94,7 @@ static struct ide_board *mtec_board[MAX_DUPLICATE_EXPANSION_BOARDS]; static struct ide_board *protar_board[MAX_DUPLICATE_EXPANSION_BOARDS]; static struct ide_board *rochard_board[MAX_DUPLICATE_EXPANSION_BOARDS]; static struct ide_board *x86_at_ide_board[MAX_DUPLICATE_EXPANSION_BOARDS]; +static struct ide_board *golemfast_board[MAX_DUPLICATE_EXPANSION_BOARDS]; static struct ide_hdf *idecontroller_drive[TOTAL_IDE * 2]; static struct ide_thread_state idecontroller_its; @@ -451,6 +453,16 @@ static int get_rochard_reg(uaecptr addr, struct ide_board *board, int *portnum) return reg; } +static int get_golemfast_reg(uaecptr addr, struct ide_board *board) +{ + int reg = -1; + if ((addr & 0x8001) != 0x8000) + return -1; + reg = (addr >> 2) & 7; + if (addr & 0x2000) + reg |= IDE_SECONDARY; + return reg; +} static int getidenum(struct ide_board *board, struct ide_board **arr) { @@ -490,6 +502,30 @@ static uae_u32 ide_read_byte(struct ide_board *board, uaecptr addr) write_log(_T("ALF GET %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC); #endif + } else if (board->type == GOLEMFAST_IDE) { + + if (!(addr & 0x8000)) { + if (board->rom) { + v = board->rom[addr & board->rom_mask]; + } + } else if ((addr & 0x8700) == 0x8400 || (addr & 0x8700) == 0x8000) { + v = golemfast_ncr9x_scsi_get(oaddr, getidenum(board, golemfast_board)); + } else if ((addr & 0x8700) == 0x8100) { + int regnum = get_golemfast_reg(addr, board); + if (regnum >= 0) { + v = get_ide_reg(board, regnum); + } + } else if ((addr & 0x8700) == 0x8300) { + v = board->original_rc->device_id ^ 7; + if (!board->original_rc->autoboot_disabled) + v |= 0x20; + if (!(board->original_rc->device_settings & 1)) + v |= 0x08; + if (ide_irq_check(board->ide[0], false) || ide_drq_check(board->ide[0])) + v |= 0x80; // IDE IRQ | DRQ + //write_log(_T("READ JUMPER %08x %02x %08x\n"), addr, v, M68K_GETPC); + } + } else if (board->type == MASOBOSHI_IDE) { int regnum = -1; bool rom = false; @@ -689,6 +725,21 @@ static uae_u32 ide_read_word(struct ide_board *board, uaecptr addr) #endif } + } else if (board->type == GOLEMFAST_IDE) { + + if ((addr & 0x8700) == 0x8100) { + int regnum = get_golemfast_reg(addr, board); + if (regnum == IDE_DATA) { + v = get_ide_reg(board, IDE_DATA); + } else { + v = ide_read_byte(board, addr) << 8; + v |= ide_read_byte(board, addr + 1); + } + } else { + v = ide_read_byte(board, addr) << 8; + v |= ide_read_byte(board, addr + 1); + } + } else if (board->type == MASOBOSHI_IDE) { if (addr >= MASOBOSHI_ROM_OFFSET && addr < MASOBOSHI_ROM_OFFSET_END) { @@ -804,6 +855,8 @@ static void ide_write_byte(struct ide_board *board, uaecptr addr, uae_u8 v) rochard_scsi_init(board->original_rc, board->baseaddress); } else if (board->type == MASOBOSHI_IDE) { ncr_masoboshi_autoconfig_init(board->original_rc, board->baseaddress); + } else if (board->type == GOLEMFAST_IDE) { + ncr_golemfast_autoconfig_init(board->original_rc, board->baseaddress); } expamem_next(ab, NULL); return; @@ -822,6 +875,16 @@ static void ide_write_byte(struct ide_board *board, uaecptr addr, uae_u8 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 == GOLEMFAST_IDE) { + + if ((addr & 0x8700) == 0x8400 || (addr & 0x8700) == 0x8000) { + golemfast_ncr9x_scsi_put(oaddr, v, getidenum(board, golemfast_board)); + } else if ((addr & 0x8700) == 0x8100) { + int regnum = get_golemfast_reg(addr, board); + if (regnum >= 0) + put_ide_reg(board, regnum, v); + } + } else if (board->type == MASOBOSHI_IDE) { #if DEBUG_IDE_MASOBOSHI @@ -928,6 +991,22 @@ static void ide_write_word(struct ide_board *board, uaecptr addr, uae_u16 v) #endif } + + } else if (board->type == GOLEMFAST_IDE) { + + if ((addr & 0x8700) == 0x8100) { + int regnum = get_golemfast_reg(addr, board); + if (regnum == IDE_DATA) { + put_ide_reg(board, IDE_DATA, v); + } else { + ide_write_byte(board, addr, v >> 8); + ide_write_byte(board, addr + 1, v); + } + } else { + ide_write_byte(board, addr, v >> 8); + ide_write_byte(board, addr + 1, v); + } + } else if (board->type == MASOBOSHI_IDE) { int regnum = get_masoboshi_reg(addr, board); @@ -1006,6 +1085,28 @@ static void ide_write_word(struct ide_board *board, uaecptr addr, uae_u16 v) } } +static uae_u32 ide_read_wordi(struct ide_board *board, uaecptr addr) +{ + uae_u16 v = 0; + if (board->type == GOLEMFAST_IDE) { + + if (!(addr & 0x8000)) { + if (board->rom) { + v = board->rom[addr & board->rom_mask] << 8; + v |= board->rom[(addr + 1) & board->rom_mask]; + } + } + + } else { + + v = dummy_wgeti(addr); + + } + return v; +} + + + IDE_MEMORY_FUNCTIONS(ide_controller_gvp, ide, gvp_ide_controller_board); addrbank gvp_ide_controller_bank = { @@ -1070,11 +1171,48 @@ static uae_u32 REGPARAM2 ide_generic_lget (uaecptr addr) } return 0; } +static uae_u32 REGPARAM2 ide_generic_wgeti(uaecptr addr) +{ + struct ide_board *ide = getideboard(addr); + if (ide) + return ide_read_wordi(ide, addr); + return 0; +} +static uae_u32 REGPARAM2 ide_generic_lgeti(uaecptr addr) +{ + struct ide_board *ide = getideboard(addr); + if (ide) { + uae_u32 v = ide_read_wordi(ide, addr) << 16; + v |= ide_read_wordi(ide, addr + 2); + return v; + } + return 0; +} +static uae_u8 *REGPARAM2 ide_generic_xlate(uaecptr addr) +{ + struct ide_board *ide = getideboard(addr); + if (!ide) + return NULL; + addr &= ide->rom_mask; + return ide->rom + addr; + +} +static int REGPARAM2 ide_generic_check(uaecptr a, uae_u32 b) +{ + struct ide_board *ide = getideboard(a); + if (!ide) + return 0; + a &= ide->rom_mask; + if (a >= ide->rom_start && a + b < ide->rom_size) + return 1; + return 0; +} + static addrbank ide_bank_generic = { ide_generic_lget, ide_generic_wget, ide_generic_bget, ide_generic_lput, ide_generic_wput, ide_generic_bput, - default_xlate, default_check, NULL, NULL, _T("IDE"), - dummy_lgeti, dummy_wgeti, + ide_generic_xlate, ide_generic_check, NULL, NULL, _T("IDE"), + ide_generic_lgeti, ide_generic_wgeti, ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE }; @@ -1381,8 +1519,6 @@ addrbank *mtec_init(struct romconfig *rc) ide->rom_size = 32768; 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; @@ -1406,8 +1542,6 @@ addrbank *rochard_init(struct romconfig *rc) ide->mask = 65536 - 1; ide->subtype = rc->subtype; - 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; @@ -1434,6 +1568,42 @@ void rochard_add_idescsi_unit(int ch, struct uaedev_config_info *ci, struct romc } } +addrbank *golemfast_init(struct romconfig *rc) +{ + struct ide_board *ide = getide(rc); + + ide->configured = 0; + ide->bank = &ide_bank_generic; + ide->rom_size = 32768; + ide->mask = 65536 - 1; + + ide->rom = xcalloc(uae_u8, ide->rom_size); + memset(ide->rom, 0xff, ide->rom_size); + ide->rom_mask = ide->rom_size - 1; + load_rom_rc(rc, ROMTYPE_GOLEMFAST, 16384, 0, ide->rom, 32768, 0); + memcpy(ide->acmemory, ide->rom, sizeof ide->acmemory); + return ide->bank; +} + +static void golemfast_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc) +{ + add_ide_standard_unit(ch, ci, rc, golemfast_board, GOLEMFAST_IDE, false, false, 2); +} + +void golemfast_add_idescsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc) +{ + if (ch < 0) { + golemfast_add_ide_unit(ch, ci, rc); + golemfast_add_scsi_unit(ch, ci, rc); + } else { + if (ci->controller_type < HD_CONTROLLER_TYPE_SCSI_FIRST) + golemfast_add_ide_unit(ch, ci, rc); + else + golemfast_add_scsi_unit(ch, ci, rc); + } +} + + extern void x86_xt_ide_bios(struct zfile*, struct romconfig*); static addrbank *x86_at_hd_init(struct romconfig *rc, int type) { diff --git a/include/ide.h b/include/ide.h index e65d8ff6..d58b65c3 100644 --- a/include/ide.h +++ b/include/ide.h @@ -33,6 +33,7 @@ struct ide_board uae_u8 *rom; uae_u8 acmemory[128]; int rom_size; + int rom_start; int rom_mask; uaecptr baseaddress; int configured; diff --git a/include/idecontrollers.h b/include/idecontrollers.h index 482577d2..a6dc28c0 100644 --- a/include/idecontrollers.h +++ b/include/idecontrollers.h @@ -33,6 +33,9 @@ addrbank *mtec_init(struct romconfig *rc); addrbank *rochard_init(struct romconfig *rc); void rochard_add_idescsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc); +addrbank *golemfast_init(struct romconfig *rc); +void golemfast_add_idescsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc); + 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; diff --git a/include/ncr9x_scsi.h b/include/ncr9x_scsi.h index 3b1679ac..fc4eeb7b 100644 --- a/include/ncr9x_scsi.h +++ b/include/ncr9x_scsi.h @@ -15,6 +15,7 @@ extern void oktagon_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct extern void masoboshi_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc); extern void ematrix_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc); extern void multievolution_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc); +extern void golemfast_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc); extern addrbank *ncr_fastlane_autoconfig_init(struct romconfig*); extern addrbank *ncr_oktagon_autoconfig_init(struct romconfig*); @@ -29,6 +30,10 @@ 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(struct romconfig*, uaecptr); +uae_u32 golemfast_ncr9x_scsi_get(uaecptr addr, int devnum); +void golemfast_ncr9x_scsi_put(uaecptr addr, uae_u32 v, int devnum); +void ncr_golemfast_autoconfig_init(struct romconfig*, uaecptr); + #define BLIZZARD_2060_SCSI_OFFSET 0x1ff00 #define BLIZZARD_2060_DMA_OFFSET 0x1fff0 #define BLIZZARD_2060_LED_OFFSET 0x1ffe0 diff --git a/include/rommgr.h b/include/rommgr.h index fa7933fb..a5de57db 100644 --- a/include/rommgr.h +++ b/include/rommgr.h @@ -103,6 +103,7 @@ extern int decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size); #define ROMTYPE_x86_VGA 0x00100035 #define ROMTYPE_APOLLOHD 0x00100036 #define ROMTYPE_MEVOLUTION 0x00100037 +#define ROMTYPE_GOLEMFAST 0x00100038 #define ROMTYPE_NOT 0x00800000 #define ROMTYPE_QUAD 0x01000000 diff --git a/ncr9x_scsi.cpp b/ncr9x_scsi.cpp index 21e4c251..2582754f 100644 --- a/ncr9x_scsi.cpp +++ b/ncr9x_scsi.cpp @@ -163,6 +163,7 @@ static struct ncr9x_state *ncr_masoboshi_scsi[MAX_DUPLICATE_EXPANSION_BOARDS]; static struct ncr9x_state *ncr_dkb1200_scsi; static struct ncr9x_state *ncr_ematrix530_scsi; static struct ncr9x_state *ncr_multievolution_scsi; +static struct ncr9x_state *ncr_golemfast_scsi[MAX_DUPLICATE_EXPANSION_BOARDS]; static struct ncr9x_state *ncr_units[MAX_NCR9X_UNITS + 1]; @@ -291,6 +292,10 @@ static void set_irq2_fastlane(struct ncr9x_state *ncr) } } +static void set_irq2_golemfast(struct ncr9x_state *ncr) +{ +} + static void set_irq2_masoboshi(struct ncr9x_state *ncr) { if (ncr->chipirq) { @@ -655,6 +660,20 @@ static void ncr9x_io_bput(struct ncr9x_state *ncr, uaecptr addr, uae_u32 val) } return; } + } else if (isncr(ncr, ncr_golemfast_scsi)) { + + reg_shift = 1; + if ((addr & 0x8400) == 0x8400) { + 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); + } + } + return; + } + } else if (isncr(ncr, ncr_masoboshi_scsi)) { if (addr >= 0xf040 && addr < 0xf048) { @@ -923,15 +942,29 @@ static uae_u32 ncr9x_io_bget(struct ncr9x_state *ncr, uaecptr addr) if (addr & 0x1000) { if (ncr->fakedma_data_offset >= ncr->fakedma_data_size) return 0; - if (ncr->fakedma_data_offset == ncr->fakedma_data_size - 1) { + v = ncr->fakedma_data_buf[ncr->fakedma_data_offset++]; + if (ncr->fakedma_data_offset == ncr->fakedma_data_size) { esp_fake_dma_done(ncr->devobject.lsistate); //write_log(_T("MultiEvolution fake dma finished\n")); } - v = ncr->fakedma_data_buf[ncr->fakedma_data_offset++]; //write_log(_T("MultiEvolution fake dma %02x %d/%d\n"), v, ncr->fakedma_data_offset, ncr->fakedma_data_size); return v; } + } else if (isncr(ncr, ncr_golemfast_scsi)) { + + reg_shift = 1; + if ((addr & 0x8400) == 0x8400) { + if (ncr->fakedma_data_offset >= ncr->fakedma_data_size) + return 0; + v = ncr->fakedma_data_buf[ncr->fakedma_data_offset++]; + if (ncr->fakedma_data_offset == ncr->fakedma_data_size) { + esp_fake_dma_done(ncr->devobject.lsistate); + } + //write_log(_T("FAKEDMA READ %08x %02X %08x (%d/%d)\n"), addr, v, M68K_GETPC, ncr->fakedma_data_offset, ncr->fakedma_data_size); + return v; + } + } else if (isncr(ncr, ncr_masoboshi_scsi)) { if (addr == MASOBOSHI_ESP_ADDR + 3 * 2 && (ncr->states[0] & 0x80)) @@ -1077,11 +1110,12 @@ static uae_u32 ncr9x_io_bget(struct ncr9x_state *ncr, uaecptr addr) //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->fakedma_data_offset == ncr->fakedma_data_size - 1) { + v = ncr->fakedma_data_buf[ncr->fakedma_data_offset++]; + if (ncr->fakedma_data_offset == ncr->fakedma_data_size) { esp_fake_dma_done(ncr->devobject.lsistate); //write_log(_T("DKB fake dma finished\n")); } - return ncr->fakedma_data_buf[ncr->fakedma_data_offset++]; + return v; } if (addr < 0x10000 || addr >= 0x10040) { write_log(_T("DKB IO GET %08x %08x\n"), addr, M68K_GETPC); @@ -1094,11 +1128,12 @@ static uae_u32 ncr9x_io_bget(struct ncr9x_state *ncr, uaecptr addr) ncr->states[0] = 0; return 0; } - if (ncr->fakedma_data_offset == ncr->fakedma_data_size - 1) { + v = ncr->fakedma_data_buf[ncr->fakedma_data_offset++]; + if (ncr->fakedma_data_offset == ncr->fakedma_data_size) { esp_fake_dma_done(ncr->devobject.lsistate); ncr->states[0] = 0; } - return ncr->fakedma_data_buf[ncr->fakedma_data_offset++]; + return v; } return 0xff; } @@ -1259,6 +1294,8 @@ static void REGPARAM2 ncr9x_bput(struct ncr9x_state *ncr, uaecptr addr, uae_u32 switch (addr) { case 0x48: + if (isncr(ncr, ncr_fastlane_scsi)) + return; map_banks_z2(ncr->bank, expamem_z2_pointer >> 16, expamem_z2_size >> 16); ncr->configured = 1; ncr->baseaddress = expamem_z2_pointer; @@ -1372,6 +1409,15 @@ void masoboshi_ncr9x_scsi_put(uaecptr addr, uae_u32 v, int devnum) ncr9x_io_bput(ncr_masoboshi_scsi[devnum], addr, v); } +uae_u32 golemfast_ncr9x_scsi_get(uaecptr addr, int devnum) +{ + return ncr9x_io_bget(ncr_golemfast_scsi[devnum], addr); +} +void golemfast_ncr9x_scsi_put(uaecptr addr, uae_u32 v, int devnum) +{ + ncr9x_io_bput(ncr_golemfast_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) { @@ -1400,6 +1446,19 @@ void ncr9x_reset(void) } } +void ncr_golemfast_autoconfig_init(struct romconfig *rc, uaecptr baseaddress) +{ + struct ncr9x_state *ncr = getscsi(rc); + + if (!ncr) + return; + + ncr->enabled = true; + ncr->baseaddress = baseaddress; + + ncr9x_reset_board(ncr); +} + addrbank *ncr_multievolution_init(struct romconfig *rc) { struct ncr9x_state *ncr = getscsi(rc); @@ -1789,4 +1848,11 @@ void multievolution_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct esp_dma_enable(ncr_multievolution_scsi->devobject.lsistate, 1); } +void golemfast_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc) +{ + ncr9x_add_scsi_unit(&ncr_golemfast_scsi[ci->controller_type_unit], ch, ci, rc); + ncr9x_esp_scsi_init(ncr_golemfast_scsi[ci->controller_type_unit], fake_dma_read, fake_dma_write, set_irq2_golemfast); + esp_dma_enable(ncr_golemfast_scsi[ci->controller_type_unit]->devobject.lsistate, 1); +} + #endif diff --git a/qemuvga/esp.cpp b/qemuvga/esp.cpp index 218ecbf6..8b972dd5 100644 --- a/qemuvga/esp.cpp +++ b/qemuvga/esp.cpp @@ -277,6 +277,7 @@ static int esp_do_dma(ESPState *s) len = s->async_len; } len2 = len; + s->dma_pending = len2; if (to_device) { len = s->dma_memory_read(s->dma_opaque, s->async_buf, len2); } else { @@ -312,7 +313,22 @@ static int esp_do_dma(ESPState *s) void esp_fake_dma_done(void *opaque) { ESPState *s = (ESPState*)opaque; - scsiesp_req_continue(s->current_req); + int to_device = (s->ti_size < 0); + int len = s->dma_pending; + + s->dma_pending = 0; + s->dma_left -= len; + s->async_buf += len; + s->async_len -= len; + if (to_device) + s->ti_size += len; + else + s->ti_size -= len; + if (s->async_len == 0) { + scsiesp_req_continue(s->current_req); + } else { + esp_do_dma(s); + } } void esp_command_complete(SCSIRequest *req, uint32_t status, @@ -322,6 +338,7 @@ void esp_command_complete(SCSIRequest *req, uint32_t status, s->ti_size = 0; s->dma_left = 0; + s->dma_pending = 0; s->async_len = 0; s->status = status; s->rregs[ESP_RSTAT] = STAT_ST; diff --git a/qemuvga/scsi/esp.h b/qemuvga/scsi/esp.h index 553ce7b6..75e1a90d 100644 --- a/qemuvga/scsi/esp.h +++ b/qemuvga/scsi/esp.h @@ -34,6 +34,7 @@ struct ESPState { /* The amount of data left in the current DMA transfer. */ uint32_t dma_left; + uint32_t dma_pending; // fakedma pending count /* The size of the current DMA transfer. Zero if no transfer is in progress. */ uint32_t dma_counter; -- 2.47.3