]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Golem FastSCSI/IDE controller.
authorToni Wilen <twilen@winuae.net>
Thu, 5 Nov 2015 19:03:40 +0000 (21:03 +0200)
committerToni Wilen <twilen@winuae.net>
Thu, 5 Nov 2015 19:03:40 +0000 (21:03 +0200)
expansion.cpp
ide.cpp
idecontrollers.cpp
include/ide.h
include/idecontrollers.h
include/ncr9x_scsi.h
include/rommgr.h
ncr9x_scsi.cpp
qemuvga/esp.cpp
qemuvga/scsi/esp.h

index 6707ae88048213d6ef03dbe9047dcdd3ab370af7..24702e8a3378f03bc832a24266f406ab6e9fca0b 100644 (file)
@@ -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 9f4e4f63d2d619ed7268e65dbd52aa4a415c49da..b8a32d767f7bf3594ebae9f85752c4e39a5dd563 100644 (file)
--- 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;
        }
 
index c38f2cb26d6a24318574588b49fa21ae3747a358..575fe735285ac2878d5659e2932158680466631f 100644 (file)
@@ -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)
 {
index e65d8ff6301e0d296dee60c27471bef3befdba5a..d58b65c3eb17d8da185e20e35075ca5d05fe95d8 100644 (file)
@@ -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;
index 482577d215a7599f583925a67b40e3565c9fc846..a6dc28c0624cdfdb65443e5b0e71024e73a131d8 100644 (file)
@@ -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;
index 3b1679ac0701c7686506a3968662f18bdfb8088d..fc4eeb7b8fc91ae956246cb5f9f1ed0a188e2b0c 100644 (file)
@@ -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
index fa7933fb23101725dfa8cfe1ba6a66c47a045910..a5de57db6c8e433ac72f9c00c68c69c743f48ec9 100644 (file)
@@ -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
index 21e4c2516b7a36917bc50389195820a65a9fecf5..2582754f70249e3f34de737e7dd96f35e97bbd43 100644 (file)
@@ -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
index 218ecbf68b3ac0d6e595fa738959b3f5f423c7a0..8b972dd53d6ed9d2b8b57aed42a27f70ed3796ee 100644 (file)
@@ -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;
index 553ce7b6b69865111363f884fa674ce75a821948..75e1a90df3e7152d35ef0ab82d8dfc017eee48f9 100644 (file)
@@ -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;