]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
ICD Trifecta emulation.
authorToni Wilen <twilen@winuae.net>
Sat, 26 Jan 2019 15:03:08 +0000 (17:03 +0200)
committerToni Wilen <twilen@winuae.net>
Sat, 26 Jan 2019 15:03:08 +0000 (17:03 +0200)
expansion.cpp
idecontrollers.cpp
include/idecontrollers.h
include/ncr9x_scsi.h
include/rommgr.h
include/scsi.h
ncr9x_scsi.cpp
qemuvga/esp.cpp

index c1259fa2c01f017d5fea97dca4471e096dc9ae48..fde87c3693958cddc6ff57752eb9f0ce18ba92fd 100644 (file)
@@ -3997,6 +3997,21 @@ static const struct expansionsubromtype rochard_sub[] = {
                NULL
        }
 };
+static const struct expansionsubromtype trifecta_sub[] = {
+       {
+               _T("EC"), _T("ec"), 0, // IDE-only
+               2071, 32, 0, false,
+               { 0 }
+       },
+       {
+               _T("LX"), _T("lx"), 0, // IDE+SCSI
+               2071, 32, 0, false,
+               { 0 }
+       },
+       {
+               NULL
+       }
+};
 static const struct expansionsubromtype supra_sub[] = {
        {
                _T("A500 ByteSync/XP"), _T("bytesync"), ROMTYPE_NONE | ROMTYPE_SUPRA,
@@ -5037,6 +5052,14 @@ const struct expansionromtype expansionroms[] = {
                2071, 4, 0, false, NULL,
                true, 0, adscsi2000_settings
        },
+       {
+               _T("trifecta"), _T("Trifecta"), _T("ICD"),
+               NULL, trifecta_init, NULL, trifecta_add_idescsi_unit, ROMTYPE_TRIFECTA | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, false,
+               trifecta_sub, 0,
+               false, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_IDE,
+               2071, 32, 0, false, NULL,
+               true, 0, NULL,
+       },
        {
                _T("buddha"), _T("Buddha"), _T("Individual Computers"),
                NULL, buddha_init, NULL, buddha_add_ide_unit, ROMTYPE_BUDDHA, 0, 0, BOARD_AUTOCONFIG_Z2, false,
index 60f0a5d4c892f4c94d9edb2b5187aa45bfdba49b..321c5ec9481e7d2a26f2140a081743225acfee2f 100644 (file)
@@ -53,7 +53,8 @@
 #define ELSATHD_IDE (FASTATA4K_IDE + 2 * MAX_DUPLICATE_EXPANSION_BOARDS)
 #define ACCESSX_IDE (ELSATHD_IDE + MAX_DUPLICATE_EXPANSION_BOARDS)
 #define IVST500AT_IDE (ACCESSX_IDE + 2 * MAX_DUPLICATE_EXPANSION_BOARDS)
-#define TOTAL_IDE (IVST500AT_IDE + MAX_DUPLICATE_EXPANSION_BOARDS)
+#define TRIFECTA_IDE (IVST500AT_IDE + MAX_DUPLICATE_EXPANSION_BOARDS)
+#define TOTAL_IDE (TRIFECTA_IDE + MAX_DUPLICATE_EXPANSION_BOARDS)
 
 #define ALF_ROM_OFFSET 0x0100
 #define GVP_IDE_ROM_OFFSET 0x8000
@@ -64,6 +65,9 @@
 #define MASOBOSHI_SCSI_OFFSET 0xf800
 #define MASOBOSHI_SCSI_OFFSET_END 0xfc00
 
+#define TRIFECTA_SCSI_OFFSET 0x0000
+#define TRIFECTA_SCSI_OFFSET_END 0x0100
+
 /* masoboshi:
 
 IDE 
@@ -112,6 +116,7 @@ static struct ide_board *fastata4k_board[MAX_DUPLICATE_EXPANSION_BOARDS];
 static struct ide_board *elsathd_board[MAX_DUPLICATE_EXPANSION_BOARDS];
 static struct ide_board *accessx_board[MAX_DUPLICATE_EXPANSION_BOARDS];
 static struct ide_board *ivst500at_board[MAX_DUPLICATE_EXPANSION_BOARDS];
+static struct ide_board *trifecta_board[MAX_DUPLICATE_EXPANSION_BOARDS];
 
 static struct ide_hdf *idecontroller_drive[TOTAL_IDE * 2];
 static struct ide_thread_state idecontroller_its;
@@ -454,6 +459,17 @@ static void masoboshi_ide_dma(struct ide_board *board)
        board->state2[0] |= 0x80;
 }
 
+static int get_trifecta_reg(uaecptr addr, struct ide_board *board)
+{
+       int reg;
+       if (!(addr & 0x800))
+               return -1;
+       reg = (addr >> 6) & 7;
+       if (addr & 0x200)
+               reg |= IDE_SECONDARY;
+       return reg;
+}
+
 static int get_adide_reg(uaecptr addr, struct ide_board *board)
 {
        int reg;
@@ -713,6 +729,35 @@ static uae_u32 ide_read_byte(struct ide_board *board, uaecptr addr)
                if (!rom)
                        write_log(_T("MASOBOSHI BYTE GET %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC);
 #endif
+
+       } else if (board->type == TRIFECTA_IDE) {
+
+               if (addr & 1) {
+                       int regnum = get_trifecta_reg(addr, board);
+                       if (regnum >= 0) {
+                               v = get_ide_reg(board, regnum);
+                       }
+               }
+               if (addr >= TRIFECTA_SCSI_OFFSET && addr < TRIFECTA_SCSI_OFFSET_END) {
+                       if (board->subtype)
+                               v = trifecta_ncr9x_scsi_get(oaddr, getidenum(board, trifecta_board));
+                       else
+                               v = 0xff;
+               }
+               if (addr == 0x401) {
+                       if (board->subtype)
+                               v = (board->aci->rc->device_id ^ 7) & 7; // inverted SCSI ID
+                       else
+                               v = 0xff;
+               } else if (addr & 0x8000) {
+                       if (board->rom)
+                               v = board->rom[addr & board->rom_mask];
+               }
+               if (addr >= 0x400 && addr <= 0x7ff) {
+                       write_log(_T("trifecta get %08x\n"), addr);
+               }
+
+
        } else if (board->type == APOLLO_IDE) {
 
                if (addr >= APOLLO_ROM_OFFSET) {
@@ -1035,6 +1080,23 @@ static uae_u32 ide_read_word(struct ide_board *board, uaecptr addr)
                                }
                        }
 
+               } else if (board->type == TRIFECTA_IDE) {
+
+                       if (addr & 0x8000) {
+                               if (board->rom) {
+                                       v = board->rom[addr & board->rom_mask] << 8;
+                                       v |= board->rom[(addr + 1) & board->rom_mask];
+                               }
+                       } else {
+                               int regnum = get_trifecta_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 if (board->type == APOLLO_IDE) {
 
                        if ((addr & 0xc000) == 0x4000) {
@@ -1222,6 +1284,8 @@ static void ide_write_byte(struct ide_board *board, uaecptr addr, uae_u8 v)
                                        ncr_golemfast_autoconfig_init(board->original_rc, board->baseaddress);
                                } else if (board->type == DATAFLYERPLUS_IDE) {
                                        dataflyerplus_scsi_init(board->original_rc, board->baseaddress);
+                               } else if (board->type == TRIFECTA_IDE) {
+                                       ncr_trifecta_autoconfig_init(board->original_rc, board->baseaddress);
                                }
                                expamem_next(ab, NULL);
                        }
@@ -1334,6 +1398,22 @@ static void ide_write_byte(struct ide_board *board, uaecptr addr, uae_u8 v)
                                }
                        }
 
+               } else if (board->type == TRIFECTA_IDE) {
+
+                       if (addr & 1) {
+                               int regnum = get_trifecta_reg(addr, board);
+                               if (regnum >= 0) {
+                                       put_ide_reg(board, regnum, v);
+                               }
+                       }
+                       if (addr >= TRIFECTA_SCSI_OFFSET && addr < TRIFECTA_SCSI_OFFSET_END) {
+                               if (board->subtype)
+                                       trifecta_ncr9x_scsi_put(oaddr, v, getidenum(board, trifecta_board));
+                       }
+                       if (addr >= 0x400 && addr <= 0x407) {
+                               trifecta_ncr9x_scsi_put(oaddr, v, getidenum(board, trifecta_board));
+                       }
+                       
                } else if (board->type == APOLLO_IDE) {
 
                        if ((addr & 0xc000) == 0x4000) {
@@ -1524,7 +1604,16 @@ static void ide_write_word(struct ide_board *board, uaecptr addr, uae_u16 v)
 #if DEBUG_IDE_MASOBOSHI
                        write_log(_T("MASOBOSHI IO WORD WRITE %08x %04x %08x\n"), addr, v, M68K_GETPC);
 #endif
-       
+               } else if (board->type == TRIFECTA_IDE) {
+
+                       int regnum = get_trifecta_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 if (board->type == APOLLO_IDE) {
 
                        if ((addr & 0xc000) == 0x4000) {
@@ -2061,6 +2150,64 @@ void masoboshi_add_idescsi_unit (int ch, struct uaedev_config_info *ci, struct r
        }
 }
 
+static const uae_u8 trifecta_autoconfig[16] = { 0xc1, 0x23, 0x00, 0x00, 0x08, 0x17, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 };
+
+bool trifecta_init(struct autoconfig_info *aci)
+{
+       int rom_size = 65536;
+       uae_u8 *rom = xcalloc(uae_u8, rom_size);
+       memset(rom, 0xff, rom_size);
+
+       if (!aci->doinit) {
+               aci->autoconfigp = trifecta_autoconfig;
+               return true;
+       }
+
+       struct ide_board *ide = getide(aci);
+
+       if (!ide)
+               return false;
+
+       ide->configured = 0;
+       ide->bank = &ide_bank_generic;
+       ide->type = TRIFECTA_IDE;
+       ide->rom_size = rom_size;
+       ide->rom_mask = ide->mask = rom_size - 1;
+       ide->rom = rom;
+       ide->subtype = aci->rc->subtype;
+       ide->keepautoconfig = false;
+       ide->intena = true;
+
+       load_rom_rc(aci->rc, ROMTYPE_TRIFECTA, 32768, 0, rom, 65536, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
+
+       for (int i = 0; i < 16; i++) {
+               uae_u8 b = trifecta_autoconfig[i];
+               ew(ide, i * 4, b);
+       }
+
+       aci->addrbank = ide->bank;
+       return true;
+}
+
+static void trifecta_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
+{
+       add_ide_standard_unit(ch, ci, rc, trifecta_board, TRIFECTA_IDE, true, false, 2);
+}
+
+void trifecta_add_idescsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
+{
+       if (ch < 0) {
+               trifecta_add_ide_unit(ch, ci, rc);
+               trifecta_add_scsi_unit(ch, ci, rc);
+       } else {
+               if (ci->controller_type < HD_CONTROLLER_TYPE_SCSI_FIRST)
+                       trifecta_add_ide_unit(ch, ci, rc);
+               else
+                       trifecta_add_scsi_unit(ch, ci, rc);
+       }
+}
+
+
 static const uae_u8 adide_autoconfig[16] = { 0xd1, 0x02, 0x00, 0x00, 0x08, 0x17, 0x00, 0x00, 0x00, 0x00, ADIDE_ROM_OFFSET >> 8, ADIDE_ROM_OFFSET & 0xff };
 
 bool adide_init(struct autoconfig_info *aci)
index 6313e5e1d542e203d0e786952eabad6c84fadc25..194785c2e89c1bccd709a8bf5d931f3c2e39b327 100644 (file)
@@ -24,6 +24,9 @@ bool apollo_init_cpu(struct autoconfig_info *aci);
 void masoboshi_add_idescsi_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 bool masoboshi_init(struct autoconfig_info *aci);
 
+void trifecta_add_idescsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+bool trifecta_init(struct autoconfig_info *aci);
+
 void adide_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 bool adide_init(struct autoconfig_info *aci);
 
index ee4c823d15b62736c54ed499aa0e9e77e2f14b85..7b05d9d0868c71251cb6f09086ebd05ce44b2f5e 100644 (file)
@@ -13,6 +13,7 @@ extern void cpuboard_dkb_add_scsi_unit(int ch, struct uaedev_config_info *ci, st
 extern void fastlane_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 extern void oktagon_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 extern void masoboshi_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+extern void trifecta_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);
@@ -38,6 +39,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 trifecta_ncr9x_scsi_get(uaecptr addr, int devnum);
+void trifecta_ncr9x_scsi_put(uaecptr addr, uae_u32 v, int devnum);
+void ncr_trifecta_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);
index 17a2dbb92711d1840d7df266fa7388e9e37118ad..da45c7d75a43f0fcbbb0e6449314db92547666e4 100644 (file)
@@ -183,6 +183,7 @@ extern int decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size);
 #define ROMTYPE_OVERDRIVE      0x00100078
 #define ROMTYPE_IVSTC          0x00100079
 #define ROMTYPE_IVST500AT      0x0010007a
+#define ROMTYPE_TRIFECTA       0x0010007b
 
 #define ROMTYPE_NOT                    0x00800000
 #define ROMTYPE_QUAD           0x01000000
index 9e346911dc1698c43f77bc010ee8f6c8fe149306..bdf07dcb4478adfb91fe28146a7f8c7b1894f7ba 100644 (file)
@@ -213,6 +213,9 @@ void kronos_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfi
 bool adscsi_init(struct autoconfig_info *aci);
 void adscsi_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
+bool trifecta_init(struct autoconfig_info *aci);
+void trifecta_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+
 void rochard_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 bool rochard_scsi_init(struct romconfig *rc, uaecptr baseaddress);
 
index 2e1f3780f0d1c336d7e78456ff8ade64b8a062d1..6b085a6800194d4260c2303a6dc8b0cfdb37bc95 100644 (file)
@@ -170,6 +170,7 @@ static struct ncr9x_state *ncr_typhoon2_scsi;
 static struct ncr9x_state *ncr_golemfast_scsi[MAX_DUPLICATE_EXPANSION_BOARDS];
 static struct ncr9x_state *ncr_scram5394_scsi[MAX_DUPLICATE_EXPANSION_BOARDS];
 static struct ncr9x_state *ncr_rapidfire_scsi[MAX_DUPLICATE_EXPANSION_BOARDS];
+static struct ncr9x_state *ncr_trifecta_scsi[MAX_DUPLICATE_EXPANSION_BOARDS];
 
 static struct ncr9x_state *ncr_units[MAX_NCR9X_UNITS + 1];
 
@@ -334,6 +335,24 @@ static void set_irq2_masoboshi(struct ncr9x_state *ncr)
        }
 }
 
+static void set_irq2_trifecta(struct ncr9x_state *ncr)
+{
+       if (ncr->chipirq) {
+               ncr->boardirqlatch = true;
+               if (ncr->intena) {
+                       ncr->boardirq = true;
+                       devices_rethink_all(ncr9x_rethink);
+#if NCR_DEBUG > 1
+                       write_log(_T("TRIFECTA IRQ\n"));
+#endif
+               } else {
+                       ncr->boardirq = false;
+               }
+       } else {
+               ncr->boardirq = false;
+       }
+}
+
 void esp_irq_raise(qemu_irq irq)
 {
        struct ncr9x_state *ncr = (struct ncr9x_state*)irq;
@@ -497,6 +516,51 @@ static int masoboshi_dma_write(void *opaque, uint8_t *buf, int len)
        }
 }
 
+/* Trifecta is true DMA only to/from its onboard Fast RAM expansion */
+
+static int trifecta_dma_read(void *opaque, uint8_t *buf, int len)
+{
+       struct ncr9x_state *ncr = (struct ncr9x_state*)opaque;
+       if (ncr->dma_on) {
+               write_log(_T("Trifecta DMA from %08x, %d bytes\n"), ncr->dma_ptr, len);
+               m68k_cancel_idle();
+               while (len > 0) {
+                       uae_u16 v = get_word(ncr->dma_ptr & ~1);
+                       *buf++ = v >> 8;
+                       len--;
+                       if (len > 0) {
+                               *buf++ = v;
+                               len--;
+                       }
+                       ncr->dma_ptr += 2;
+               }
+               return -1;
+       }
+       return 0;
+}
+static int trifecta_dma_write(void *opaque, uint8_t *buf, int len)
+{
+       struct ncr9x_state *ncr = (struct ncr9x_state*)opaque;
+       if (ncr->dma_on) {
+               write_log(_T("Trifecta DMA to %08x, %d bytes\n"), ncr->dma_ptr, len);
+               m68k_cancel_idle();
+               while (len > 0) {
+                       uae_u16 v;
+                       v = *buf++;
+                       len--;
+                       v <<= 8;
+                       if (len > 0) {
+                               v |= *buf++;
+                               len--;
+                       }
+                       put_word(ncr->dma_ptr & ~1, v);
+                       ncr->dma_ptr += 2;
+               }
+               return -1;
+       }
+       return 0;
+}
+
 
 static int fastlane_dma_read(void *opaque, uint8_t *buf, int len)
 {
@@ -864,6 +928,37 @@ static void ncr9x_io_bput3(struct ncr9x_state *ncr, uaecptr addr, uae_u32 val, i
                reg_shift = 1;
                addr &= 0x3f;
 
+       } else if (isncr(ncr, ncr_trifecta_scsi)) {
+
+               if (addr == 0x400) {
+                       ncr->intena = (val & 8) != 0;
+                       ncr->dma_on = (val & 4) != 0;
+                       esp_dma_enable(ncr->devobject.lsistate, ncr->dma_on);
+                       ncr->states[0] = val;
+                       ncr->dma_cnt = 0;
+                       if (ncr->dma_on) {
+                               write_log(_T("Trifecta DMA %08x %c\n"), ncr->dma_ptr, (val & 1) ? 'R' : 'W');
+                       }
+               } else if (addr == 0x402) {
+                       ncr->dma_ptr &= 0xffff00;
+                       ncr->dma_ptr |= val;
+               } else if (addr == 0x404) {
+                       ncr->dma_ptr &= 0xff00ff;
+                       ncr->dma_ptr |= val << 8;
+               } else if (addr == 0x406) {
+                       ncr->dma_ptr &= 0x00ffff;
+                       ncr->dma_ptr |= val << 16;
+               }
+
+               if (addr >= 0x200)
+                       return;
+
+               if (!(addr & 1))
+                       return;
+
+               reg_shift = 1;
+               addr &= 0x3f;
+
        } else if (isncr(ncr, ncr_oktagon2008_scsi)) {
                if (addr == OKTAGON_EEPROM_SCL) {
                        eeprom_i2c_set(ncr->eeprom, BITBANG_I2C_SCL, (val & 0x80) != 0);
@@ -1247,6 +1342,17 @@ static uae_u32 ncr9x_io_bget3(struct ncr9x_state *ncr, uaecptr addr, int *reg)
                reg_shift = 1;
                addr &= 0x3f;
 
+       } else if (isncr(ncr, ncr_trifecta_scsi)) {
+
+               if (addr >= 0x200)
+                       return v;
+
+               if (!(addr & 1))
+                       return v;
+
+               reg_shift = 1;
+               addr &= 0x3f;
+
        } else if (isncr(ncr, ncr_oktagon2008_scsi)) {
                if (addr == OKTAGON_EEPROM_SCL) {
                        return eeprom_i2c_set(ncr->eeprom, BITBANG_I2C_SCL, -1) ? 0x80 : 0x00;
@@ -1727,6 +1833,15 @@ void masoboshi_ncr9x_scsi_put(uaecptr addr, uae_u32 v, int devnum)
        ncr9x_io_bput(ncr_masoboshi_scsi[devnum], addr, v);
 }
 
+uae_u32 trifecta_ncr9x_scsi_get(uaecptr addr, int devnum)
+{
+       return ncr9x_io_bget(ncr_trifecta_scsi[devnum], addr);
+}
+void trifecta_ncr9x_scsi_put(uaecptr addr, uae_u32 v, int devnum)
+{
+       ncr9x_io_bput(ncr_trifecta_scsi[devnum], addr, v);
+}
+
 uae_u32 golemfast_ncr9x_scsi_get(uaecptr addr, int devnum)
 {
        return ncr9x_io_bget(ncr_golemfast_scsi[devnum], addr);
@@ -2133,6 +2248,20 @@ void ncr_masoboshi_autoconfig_init(struct romconfig *rc, uaecptr baseaddress)
        ncr9x_reset_board(ncr);
 }
 
+void ncr_trifecta_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);
+}
+
+
 bool ncr_scram5394_init(struct autoconfig_info *aci)
 {
        const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_SCRAM5394);
@@ -2333,6 +2462,12 @@ void masoboshi_add_scsi_unit (int ch, struct uaedev_config_info *ci, struct romc
        ncr9x_esp_scsi_init(ncr_masoboshi_scsi[ci->controller_type_unit], masoboshi_dma_read, masoboshi_dma_write, set_irq2_masoboshi, 0);
 }
 
+void trifecta_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
+{
+       ncr9x_add_scsi_unit(&ncr_trifecta_scsi[ci->controller_type_unit], ch, ci, rc);
+       ncr9x_esp_scsi_init(ncr_trifecta_scsi[ci->controller_type_unit], trifecta_dma_read, trifecta_dma_write, set_irq2_trifecta, 0);
+}
+
 void ematrix_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
        ncr9x_add_scsi_unit(&ncr_ematrix530_scsi, ch, ci, rc);
index 63c027db4324a217d6c664fd9d3e5239b1317023..b32bbdae68e422064406d11eac947d43d982abf0 100644 (file)
@@ -659,7 +659,8 @@ static uint64_t esp_reg_read2(void *opaque, uint32_t saddr)
                                        }
                                } else {
                                        s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++];
-                                       esp_raise_irq(s);
+                                       if (s->pio_on)
+                                               esp_raise_irq(s);
                                }
                        }
                        if (s->ti_size == 0) {
@@ -670,7 +671,7 @@ static uint64_t esp_reg_read2(void *opaque, uint32_t saddr)
                        }
                }
 #if    ESPLOG
-               write_log("<FIFO %02x %d %d %d\n", s->rregs[ESP_FIFO], s->pio_on, s->ti_size, s->ti_rptr);
+               write_log("<-FIFO %02x %d %d %d\n", s->rregs[ESP_FIFO], s->pio_on, s->ti_size, s->ti_rptr);
 #endif         
                break;
     case ESP_RINTR:
@@ -768,6 +769,8 @@ void esp_reg_write(void *opaque, uint32_t saddr, uint64_t val)
     case ESP_TCMID:
     case ESP_TCHI:
         s->rregs[ESP_RSTAT] &= ~STAT_TC;
+               if (!(s->wregs[ESP_CFG2] & 0x40))
+                       val = 0;
         break;
     case ESP_FIFO:
 #if    ESPLOG
@@ -837,15 +840,21 @@ 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;
+                       // Features enable
+                       if (!(s->wregs[ESP_CFG2] & 0x40)) {
+                               // Masoboshi driver expects phase=0!
+                               s->rregs[ESP_RSTAT] &= ~7;
+                       }
             esp_raise_irq(s);
             break;
         case CMD_PAD:
             s->rregs[ESP_RSTAT] = STAT_TC;
             s->rregs[ESP_RINTR] = INTR_FC;
             s->rregs[ESP_RSEQ] = 0;
-            break;
+                       if (s->current_req) {
+                               scsiesp_req_continue(s->current_req);
+                       }
+                       break;
         case CMD_SATN:
             break;
         case CMD_RSTATN: