diff --git a/src/disk/mo.c b/src/disk/mo.c index c93f4b055..e90267b95 100644 --- a/src/disk/mo.c +++ b/src/disk/mo.c @@ -1677,8 +1677,8 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) size_idx = 4; memset(dev->buffer, 0, 8); - if (cdb[1] & 0xe0) - dev->buffer[0] = 0x60; /*No physical device on this LUN*/ + if ((cdb[1] & 0xe0) || ((dev->cur_lun > 0x00) && (dev->cur_lun < 0xff))) + dev->buffer[0] = 0x7f; /*No physical device on this LUN*/ else dev->buffer[0] = 0x07; /*Optical disk*/ dev->buffer[1] = 0x80; /*Removable*/ diff --git a/src/disk/zip.c b/src/disk/zip.c index 08d3baee3..d4cbd0b41 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -1865,8 +1865,8 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) size_idx = 4; memset(dev->buffer, 0, 8); - if (cdb[1] & 0xe0) - dev->buffer[0] = 0x60; /*No physical device on this LUN*/ + if ((cdb[1] & 0xe0) || ((dev->cur_lun > 0x00) && (dev->cur_lun < 0xff))) + dev->buffer[0] = 0x7f; /*No physical device on this LUN*/ else dev->buffer[0] = 0x00; /*Hard disk*/ dev->buffer[1] = 0x80; /*Removable*/ diff --git a/src/include/86box/scsi_device.h b/src/include/86box/scsi_device.h index 216fdb2ad..2d6d60ac7 100644 --- a/src/include/86box/scsi_device.h +++ b/src/include/86box/scsi_device.h @@ -309,6 +309,7 @@ #define BUS_BSY 0x40 #define BUS_RST 0x80 #define BUS_ACK 0x200 +/* TODO: Why is this defined to the same value as BUS_ACK?! */ #define BUS_ATN 0x200 #define BUS_ARB 0x8000 #define BUS_SETDATA(val) ((uint32_t) val << 16) diff --git a/src/include/86box/scsi_ncr5380.h b/src/include/86box/scsi_ncr5380.h index 55c3bf3c5..8baa4f9d8 100644 --- a/src/include/86box/scsi_ncr5380.h +++ b/src/include/86box/scsi_ncr5380.h @@ -109,14 +109,10 @@ typedef struct ncr_t { int data_pos; int irq; - int simple_pseudo_dma; - - uint32_t block_count; double period; void *priv; - void (*dma_init_ext)(void *priv, void *ext_priv, int send); void (*dma_mode_ext)(void *priv, void *ext_priv); int (*dma_send_ext)(void *priv, void *ext_priv); int (*dma_initiator_receive_ext)(void *priv, void *ext_priv); @@ -131,11 +127,11 @@ extern uint32_t ncr5380_get_bus_host(ncr_t *ncr); extern void ncr5380_bus_read(ncr_t *ncr); extern void ncr5380_bus_update(ncr_t *ncr, int bus); extern void ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr); -extern uint8_t ncr5380_drq(ncr_t *ncr); extern uint8_t ncr5380_read(uint16_t port, ncr_t *ncr); #ifdef EMU_DEVICE_H extern const device_t scsi_lcs6821n_device; +extern const device_t scsi_pas_device; extern const device_t scsi_rt1000b_device; extern const device_t scsi_rt1000mc_device; extern const device_t scsi_t128_device; @@ -145,7 +141,6 @@ extern const device_t scsi_ls2000_device; #if defined(DEV_BRANCH) && defined(USE_SUMO) extern const device_t scsi_scsiat_device; #endif -extern const device_t scsi_pas_device; #endif #endif /*SCSI_NCR5380_H*/ diff --git a/src/include/86box/scsi_ncr53c400.h b/src/include/86box/scsi_t128.h similarity index 55% rename from src/include/86box/scsi_ncr53c400.h rename to src/include/86box/scsi_t128.h index 9a5315990..65148a5d1 100644 --- a/src/include/86box/scsi_ncr53c400.h +++ b/src/include/86box/scsi_t128.h @@ -18,45 +18,34 @@ * Copyright 2017-2024 TheCollector1995. */ -#ifndef SCSI_NCR53C400_H -#define SCSI_NCR53C400_H +#ifndef SCSI_T128_H +#define SCSI_T128_H -typedef struct ncr53c400_t { - rom_t bios_rom; - mem_mapping_t mapping; +typedef struct t128_t { ncr_t ncr; + rom_t bios_rom; + mem_mapping_t mapping; + + uint8_t ctrl; + uint8_t status; uint8_t buffer[512]; - uint8_t int_ram[0x40]; - uint8_t ext_ram[0x600]; + uint8_t ext_ram[0x80]; + uint8_t block_count; + + int block_loaded; + int pos, host_pos; uint32_t rom_addr; - uint16_t base; - int8_t type; - uint8_t block_count; - uint8_t status_ctrl; - - int simple_ctrl; - - int block_count_loaded; - - int buffer_pos; - int buffer_host_pos; - - int busy; + int bios_enabled; uint8_t pos_regs[8]; pc_timer_t timer; -} ncr53c400_t; +} t128_t; -#define CTRL_DATA_DIR 0x40 -#define STATUS_BUFFER_NOT_READY 0x04 -#define STATUS_5380_ACCESSIBLE 0x80 +extern void t128_write(uint32_t addr, uint8_t val, void *priv); +extern uint8_t t128_read(uint32_t addr, void *priv); -extern void ncr53c400_simple_write(uint8_t val, void *priv); -extern void ncr53c400_write(uint32_t addr, uint8_t val, void *priv); -extern uint8_t ncr53c400_simple_read(void *priv); -extern uint8_t ncr53c400_read(uint32_t addr, void *priv); -extern void ncr53c400_callback(void *priv); +extern void t128_callback(void *priv); -#endif /*SCSI_NCR53C400_H*/ +#endif /*SCSI_T128_H*/ diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 8a9f72946..47ba0535e 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -2794,6 +2794,15 @@ begin: return; } + if (max_len <= 0) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + scsi_cdrom_buf_free(dev); + return; + } + if (!(cdb[2] & 0x40)) alloc_length = 4; else @@ -3189,7 +3198,10 @@ begin: size_idx = 4; memset(dev->buffer, 0, 8); - dev->buffer[0] = 5; /*CD-ROM*/ + if ((cdb[1] & 0xe0) || ((dev->cur_lun > 0x00) && (dev->cur_lun < 0xff))) + dev->buffer[0] = 0x7f; /*No physical device on this LUN*/ + else + dev->buffer[0] = 5; /*CD-ROM*/ dev->buffer[1] = 0x80; /*Removable*/ if (dev->drv->bus_type == CDROM_BUS_SCSI) { diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 39a69ea32..f29e85431 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -1328,7 +1328,10 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) size_idx = 4; memset(dev->temp_buffer, 0, 8); - dev->temp_buffer[0] = 0; /*SCSI HD*/ + if ((cdb[1] & 0xe0) || ((dev->cur_lun > 0x00) && (dev->cur_lun < 0xff))) + dev->temp_buffer[0] = 0x7f; /*No physical device on this LUN*/ + else + dev->temp_buffer[0] = 0; /*SCSI HD*/ dev->temp_buffer[1] = 0; /*Fixed*/ dev->temp_buffer[2] = (dev->drv->bus == HDD_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ dev->temp_buffer[3] = (dev->drv->bus == HDD_BUS_SCSI) ? 0x02 : 0x21; diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index d256de764..fefb7b9a2 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -161,8 +161,28 @@ ncr5380_get_bus_host(ncr_t *ncr) if (ncr->icr & ICR_BSY) bus_host |= BUS_BSY; - if (ncr->icr & ICR_ATN) - bus_host |= BUS_ATN; + /* + TODO: See which method of fixing this is the most correct. + + The #define's come from PCem and, for some reason, define + BUS_ATN to the same value as BUS_ACK (0x200). This breaks + the Corel driver for the Pro Audio Spectrum Trantor SCSI + controller, as it first asserts ATN without ACK, then ACK + without ATN, which should by definition result in ACK going + ON and OFF but because of these ambiguous #define's, it + instead manifests as ACK stuck on, therefore never clearing + BUS_REQ and progressing to the next phase. + + Since I have no idea why BUS_ATN was #define's to the same + value as BUS_ACK, and the problem appears to only occur in + the Message Out phase, where ATN is not used, I have decided + to solve this by never asserting ATN in the Message Out phase + for time being. + */ + if (ncr->state != STATE_MESSAGEOUT) { + if (ncr->icr & ICR_ATN) + bus_host |= BUS_ATN; + } if (ncr->icr & ICR_ACK) bus_host |= BUS_ACK; @@ -326,19 +346,6 @@ ncr5380_bus_update(ncr_t *ncr, int bus) ncr5380_log("SCSI ID %i: command 0x%02x for p = %lf, update = %lf, len = %i, dmamode = %x\n", ncr->target_id, ncr->command[0], scsi_device_get_callback(dev), ncr->period, dev->buffer_length, ncr->dma_mode); } } - - if (ncr->simple_pseudo_dma) { - if (dev->phase == SCSI_PHASE_DATA_IN) { - ncr->block_count = dev->buffer_length / 512; - - ncr->dma_init_ext(ncr, ncr->priv, 1); - } else if (dev->phase == SCSI_PHASE_DATA_OUT) { - ncr->block_count = dev->buffer_length / 512; - - ncr->dma_init_ext(ncr, ncr->priv, 0); - } - } - ncr->new_phase = dev->phase; } } @@ -358,10 +365,7 @@ ncr5380_bus_update(ncr_t *ncr, int bus) if (ncr->dma_mode == DMA_IDLE) { /*If a data in command that is not read 6/10 has been issued*/ ncr->data_wait |= 1; ncr5380_log("DMA mode idle in\n"); - if (ncr->simple_pseudo_dma) - ncr->dma_init_ext(ncr, ncr->priv, 1); - else - ncr->timer(ncr->priv, ncr->period); + ncr->timer(ncr->priv, ncr->period); } else { ncr5380_log("DMA mode IN.\n"); ncr->clear_req = 3; @@ -388,10 +392,7 @@ ncr5380_bus_update(ncr_t *ncr, int bus) if (ncr->dma_mode == DMA_IDLE) { /*If a data out command that is not write 6/10 has been issued*/ ncr->data_wait |= 1; ncr5380_log("DMA mode idle out\n"); - if (!ncr->simple_pseudo_dma) - ncr->timer(ncr->priv, ncr->period); - if (ncr->simple_pseudo_dma) - ncr->dma_init_ext(ncr, ncr->priv, 0); + ncr->timer(ncr->priv, ncr->period); } else ncr->clear_req = 3; @@ -517,21 +518,6 @@ ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr) ncr5380_bus_update(ncr, bus_host); } -uint8_t -ncr5380_drq(ncr_t *ncr) -{ - uint8_t ret = 0; - int bus; - - ncr5380_bus_read(ncr); - bus = ncr->cur_bus; - - if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA)) - ret = 1; - - return ret; -} - uint8_t ncr5380_read(uint16_t port, ncr_t *ncr) { @@ -579,6 +565,8 @@ ncr5380_read(uint16_t port, ncr_t *ncr) ret |= BUS_SEL; if (ncr->icr & ICR_BSY) ret |= BUS_BSY; + // if ((ret & SCSI_PHASE_MESSAGE_IN) == SCSI_PHASE_MESSAGE_IN) + // ret &= ~BUS_REQ; break; case 5: /* Bus and Status register */ diff --git a/src/scsi/scsi_ncr53c400.c b/src/scsi/scsi_ncr53c400.c index f4bd9de59..1ed8e520e 100644 --- a/src/scsi/scsi_ncr53c400.c +++ b/src/scsi/scsi_ncr53c400.c @@ -41,7 +41,6 @@ #include <86box/scsi.h> #include <86box/scsi_device.h> #include <86box/scsi_ncr5380.h> -#include <86box/scsi_ncr53c400.h> #define LCS6821N_ROM "roms/scsi/ncr5380/Longshine LCS-6821N - BIOS version 1.04.bin" #define COREL_LS2000_ROM "roms/scsi/ncr5380/Corel LS2000 - BIOS ROM - Ver 1.65.bin" @@ -49,14 +48,43 @@ #define RT1000B_820R_ROM "roms/scsi/ncr5380/RTBIOS82.ROM" #define T130B_ROM "roms/scsi/ncr5380/trantor_t130b_bios_v2.14.bin" +#define CTRL_DATA_DIR 0x40 +#define STATUS_BUFFER_NOT_READY 0x04 +#define STATUS_5380_ACCESSIBLE 0x80 + enum { ROM_LCS6821N = 0, ROM_LS2000, ROM_RT1000B, - ROM_T130B, - ROM_PAS + ROM_T130B }; +typedef struct ncr53c400_t { + rom_t bios_rom; + mem_mapping_t mapping; + ncr_t ncr; + uint8_t buffer[128]; + uint8_t int_ram[0x40]; + uint8_t ext_ram[0x600]; + + uint32_t rom_addr; + uint16_t base; + + int8_t type; + uint8_t block_count; + uint8_t status_ctrl; + + int block_count_loaded; + + int buffer_pos; + int buffer_host_pos; + + int busy; + uint8_t pos_regs[8]; + + pc_timer_t timer; +} ncr53c400_t; + #ifdef ENABLE_NCR53C400_LOG int ncr53c400_do_log = ENABLE_NCR53C400_LOG; @@ -75,29 +103,8 @@ ncr53c400_log(const char *fmt, ...) # define ncr53c400_log(fmt, ...) #endif -void -ncr53c400_simple_write(uint8_t val, void *priv) -{ - ncr53c400_t *ncr400 = (ncr53c400_t *) priv; - ncr_t *ncr = &ncr400->ncr; - scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; - - if (ncr400->buffer_host_pos < MIN(512, dev->buffer_length)) { - ncr400->buffer[ncr400->buffer_host_pos++] = val; - - ncr53c400_log("Write host pos = %i, val = %02x\n", ncr400->buffer_host_pos, val); - - if (ncr400->buffer_host_pos == MIN(512, dev->buffer_length)) { - ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; - ncr400->busy = 1; - - ncr53c400_callback(priv); - } - } -} - /* Memory-mapped I/O WRITE handler. */ -void +static void ncr53c400_write(uint32_t addr, uint8_t val, void *priv) { ncr53c400_t *ncr400 = (ncr53c400_t *) priv; @@ -185,30 +192,8 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) } } -uint8_t -ncr53c400_simple_read(void *priv) -{ - ncr53c400_t *ncr400 = (ncr53c400_t *) priv; - ncr_t *ncr = &ncr400->ncr; - scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; - uint8_t ret = 0xff; - - if (ncr400->buffer_host_pos < MIN(512, dev->buffer_length)) { - ret = ncr400->buffer[ncr400->buffer_host_pos++]; - ncr53c400_log("Read host pos = %i, ret = %02x\n", ncr400->buffer_host_pos, ret); - - if (ncr400->buffer_host_pos == MIN(512, dev->buffer_length)) { - ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; - ncr53c400_log("Transfer busy read, status = %02x\n", ncr400->status_ctrl); - ncr53c400_callback(priv); - } - } - - return ret; -} - /* Memory-mapped I/O READ handler. */ -uint8_t +static uint8_t ncr53c400_read(uint32_t addr, void *priv) { ncr53c400_t *ncr400 = (ncr53c400_t *) priv; @@ -400,34 +385,6 @@ t130b_in(uint16_t port, void *priv) return ret; } -static void -ncr53c400_dma_init_ext(void *priv, void *ext_priv, int send) -{ - ncr53c400_t *ncr400 = (ncr53c400_t *) ext_priv; - ncr_t *ncr = (ncr_t *) priv; - scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; - uint8_t val = send ? CTRL_DATA_DIR : 0x00; - - ncr53c400_log("NCR 53c400 control = %02x, mode = %02x.\n", val, ncr->mode); - ncr400->status_ctrl = (ncr400->status_ctrl & 0x87) | (val & 0x78); - - ncr400->block_count_loaded = 1; - - if (ncr400->status_ctrl & CTRL_DATA_DIR) { - ncr400->buffer_host_pos = MIN(512, dev->buffer_length); - ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; - } else { - ncr400->buffer_host_pos = 0; - ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - } - if ((ncr->mode & MODE_DMA) && (dev->buffer_length > 0)) { - memset(ncr400->buffer, 0, MIN(512, dev->buffer_length)); - ncr53c400_log("DMA buffer init\n"); - ncr->timer(ncr->priv, ncr->period); - } - ncr53c400_log("NCR DMA init\n"); -} - static void ncr53c400_dma_mode_ext(void *priv, void *ext_priv) { @@ -455,21 +412,17 @@ ncr53c400_timer_on_auto(void *ext_priv, double period) timer_on_auto(&ncr400->timer, period); } -void +static void ncr53c400_callback(void *priv) { ncr53c400_t *ncr400 = (void *) priv; ncr_t *ncr = &ncr400->ncr; scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; int bus; - int blocks_left; uint8_t c; uint8_t temp; - const int buf_len = ncr400->simple_ctrl ? 512 : 128; - ncr53c400_log("DMA mode = %i\n", ncr->dma_mode); - - if (!ncr400->simple_ctrl && (ncr->dma_mode != DMA_IDLE)) + if (ncr->dma_mode != DMA_IDLE) timer_on_auto(&ncr400->timer, 1.0); if (ncr->data_wait & 1) { @@ -488,7 +441,7 @@ ncr53c400_callback(void *priv) switch (ncr->dma_mode) { case DMA_SEND: - if (!ncr400->simple_ctrl && (ncr400->status_ctrl & CTRL_DATA_DIR)) { + if (ncr400->status_ctrl & CTRL_DATA_DIR) { ncr53c400_log("DMA_SEND with DMA direction set wrong\n"); break; } @@ -522,20 +475,14 @@ ncr53c400_callback(void *priv) ncr400->buffer_pos++; ncr53c400_log("NCR 53c400 Buffer pos for writing = %d\n", ncr400->buffer_pos); - if (ncr400->buffer_pos == MIN(buf_len, dev->buffer_length)) { + if (ncr400->buffer_pos == MIN(128, dev->buffer_length)) { ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; ncr400->buffer_pos = 0; ncr400->buffer_host_pos = 0; ncr400->busy = 0; - if (ncr400->simple_ctrl) { - ncr->block_count = (ncr->block_count - 1) & 0xffffffff; - blocks_left = ncr->block_count; - } else { - ncr400->block_count = (ncr400->block_count - 1) & 0xff; - blocks_left = ncr400->block_count; - } - ncr53c400_log("NCR 53c400 Remaining blocks to be written=%d\n", blocks_left); - if (blocks_left == 0) { + ncr400->block_count = (ncr400->block_count - 1) & 0xff; + ncr53c400_log("NCR 53c400 Remaining blocks to be written=%d\n", ncr400->block_count); + if (!ncr400->block_count) { ncr400->block_count_loaded = 0; ncr53c400_log("IO End of write transfer\n"); ncr->tcr |= TCR_LAST_BYTE_SENT; @@ -552,7 +499,7 @@ ncr53c400_callback(void *priv) break; case DMA_INITIATOR_RECEIVE: - if (!ncr400->simple_ctrl && !(ncr400->status_ctrl & CTRL_DATA_DIR)) { + if (!(ncr400->status_ctrl & CTRL_DATA_DIR)) { ncr53c400_log("DMA_INITIATOR_RECEIVE with DMA direction set wrong\n"); break; } @@ -568,10 +515,8 @@ ncr53c400_callback(void *priv) while (1) { for (c = 0; c < 10; c++) { ncr5380_bus_read(ncr); - if (ncr->cur_bus & BUS_REQ) { - ncr53c400_log("ncr->cur_bus & BUS_REQ\n"); + if (ncr->cur_bus & BUS_REQ) break; - } } /* Data ready. */ @@ -586,19 +531,13 @@ ncr53c400_callback(void *priv) ncr400->buffer[ncr400->buffer_pos++] = temp; ncr53c400_log("NCR 53c400 Buffer pos for reading = %d\n", ncr400->buffer_pos); - if (ncr400->buffer_pos == MIN(buf_len, dev->buffer_length)) { + if (ncr400->buffer_pos == MIN(128, dev->buffer_length)) { ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; ncr400->buffer_pos = 0; ncr400->buffer_host_pos = 0; - if (ncr400->simple_ctrl) { - ncr->block_count = (ncr->block_count - 1) & 0xffffffff; - blocks_left = ncr->block_count; - } else { - ncr400->block_count = (ncr400->block_count - 1) & 0xff; - blocks_left = ncr400->block_count; - } - ncr53c400_log("NCR 53c400 Remaining blocks to be read=%d\n", blocks_left); - if (blocks_left == 0) { + ncr400->block_count = (ncr400->block_count - 1) & 0xff; + ncr53c400_log("NCR 53c400 Remaining blocks to be read=%d\n", ncr400->block_count); + if (!ncr400->block_count) { ncr400->block_count_loaded = 0; ncr53c400_log("IO End of read transfer\n"); ncr->isr |= STATUS_END_OF_DMA; @@ -623,8 +562,6 @@ ncr53c400_callback(void *priv) ncr53c400_log("Updating DMA\n"); ncr->mode &= ~MODE_DMA; ncr->dma_mode = DMA_IDLE; - if (ncr400->simple_ctrl) - ncr400->block_count_loaded = 0; } } @@ -719,6 +656,7 @@ ncr53c400_init(const device_t *info) ncr400->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr400); break; + case ROM_LS2000: /* Corel LS2000 */ ncr400->rom_addr = device_get_config_hex20("bios_addr"); ncr->irq = device_get_config_int("irq"); @@ -777,13 +715,6 @@ ncr53c400_init(const device_t *info) t130b_in, NULL, NULL, t130b_out, NULL, NULL, ncr400); break; - case ROM_PAS: /* Pro Audio Spectrum Plus/16 SCSI controller */ - ncr400->simple_ctrl = 1; - ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; - ncr->simple_pseudo_dma = 1; - ncr->dma_init_ext = ncr53c400_dma_init_ext; - break; - default: break; } @@ -1076,17 +1007,3 @@ const device_t scsi_ls2000_device = { .force_redraw = NULL, .config = ncr53c400_mmio_config }; - -const device_t scsi_pas_device = { - .name = "Pro Audio Spectrum Plus/16 SCSI", - .internal_name = "scsi_pas", - .flags = DEVICE_ISA, - .local = ROM_PAS, - .init = ncr53c400_init, - .close = ncr53c400_close, - .reset = NULL, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; diff --git a/src/scsi/scsi_t128.c b/src/scsi/scsi_t128.c index b13511eac..7e42a089d 100644 --- a/src/scsi/scsi_t128.c +++ b/src/scsi/scsi_t128.c @@ -41,31 +41,10 @@ #include <86box/scsi.h> #include <86box/scsi_device.h> #include <86box/scsi_ncr5380.h> +#include <86box/scsi_t128.h> #define T128_ROM "roms/scsi/ncr5380/trantor_t128_bios_v1.12.bin" -typedef struct t128_t { - ncr_t ncr; - rom_t bios_rom; - mem_mapping_t mapping; - - uint8_t ctrl; - uint8_t status; - uint8_t buffer[512]; - uint8_t ext_ram[0x80]; - uint8_t block_count; - - int block_loaded; - int pos, host_pos; - - uint32_t rom_addr; - - int bios_enabled; - uint8_t pos_regs[8]; - - pc_timer_t timer; -} t128_t; - #ifdef ENABLE_T128_LOG int t128_do_log = ENABLE_T128_LOG; @@ -85,7 +64,7 @@ t128_log(const char *fmt, ...) #endif /* Memory-mapped I/O WRITE handler. */ -static void +void t128_write(uint32_t addr, uint8_t val, void *priv) { t128_t *t128 = (t128_t *) priv; @@ -122,7 +101,7 @@ t128_write(uint32_t addr, uint8_t val, void *priv) } /* Memory-mapped I/O READ handler. */ -static uint8_t +uint8_t t128_read(uint32_t addr, void *priv) { t128_t *t128 = (t128_t *) priv; @@ -243,7 +222,7 @@ t128_timer_on_auto(void *ext_priv, double period) timer_on_auto(&t128->timer, period); } -static void +void t128_callback(void *priv) { t128_t *t128 = (void *) priv; @@ -506,7 +485,7 @@ t128_init(const device_t *info) t128->pos_regs[0] = 0x8c; t128->pos_regs[1] = 0x50; mca_add(t228_read, t228_write, t228_feedb, NULL, t128); - } else { + } else if (info->local == 0) { ncr->irq = device_get_config_int("irq"); t128->rom_addr = device_get_config_hex20("bios_addr"); t128->bios_enabled = device_get_config_int("boot"); @@ -525,12 +504,13 @@ t128_init(const device_t *info) ncr->dma_send_ext = t128_dma_send_ext; ncr->dma_initiator_receive_ext = t128_dma_initiator_receive_ext; ncr->timer = t128_timer_on_auto; - t128->status = 0x04; + t128->status = 0x00 /*0x04*/; t128->host_pos = 512; if (!t128->bios_enabled && !(info->flags & DEVICE_MCA)) t128->status |= 0x80; - timer_add(&t128->timer, t128_callback, t128, 0); + if (info->local == 0) + timer_add(&t128->timer, t128_callback, t128, 0); scsi_bus_set_speed(ncr->bus, 5000000.0); @@ -616,6 +596,7 @@ const device_t scsi_t128_device = { .config = t128_config }; + const device_t scsi_t228_device = { .name = "Trantor T228", .internal_name = "t228", @@ -629,3 +610,17 @@ const device_t scsi_t228_device = { .force_redraw = NULL, .config = NULL }; + +const device_t scsi_pas_device = { + .name = "Pro Audio Spectrum Plus/16 SCSI", + .internal_name = "scsi_pas", + .flags = DEVICE_ISA, + .local = 1, + .init = t128_init, + .close = t128_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 859a1fd17..243332257 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -108,8 +108,9 @@ #include <86box/pit.h> #include <86box/pit_fast.h> #include <86box/rom.h> +#include <86box/scsi_device.h> #include <86box/scsi_ncr5380.h> -#include <86box/scsi_ncr53c400.h> +#include <86box/scsi_t128.h> #include <86box/snd_mpu401.h> #include <86box/sound.h> #include <86box/snd_opl.h> @@ -247,7 +248,7 @@ typedef struct pas16_t { pitf_t * pit; - ncr53c400_t *scsi; + t128_t * scsi; pc_timer_t scsi_timer; } pas16_t; @@ -705,7 +706,6 @@ pas16_in(uint16_t port, void *priv) { pas16_t *pas16 = (pas16_t *) priv; uint8_t ret = 0xff; - ncr53c400_t *dev = (ncr53c400_t *) pas16->scsi; port -= pas16->base; @@ -763,10 +763,8 @@ pas16_in(uint16_t port, void *priv) case 0x1c00 ... 0x1c03: /* NCR5380 ports 0 to 3. */ case 0x3c00 ... 0x3c03: /* NCR5380 ports 4 to 7. */ - if (pas16->has_scsi) { - port = (port & 0x0003) | ((port & 0x2000) >> 11); - ret = ncr5380_read(port, &pas16->scsi->ncr); - } + if (pas16->has_scsi) + ret = ncr5380_read((port & 0x0003) | ((port & 0x2000) >> 11), &pas16->scsi->ncr); break; case 0x2401: /* Board revision */ @@ -782,20 +780,12 @@ pas16_in(uint16_t port, void *priv) case 0x5c00: if (pas16->has_scsi) - ret = ncr53c400_simple_read(pas16->scsi); + ret = t128_read(0x1e00, pas16->scsi); break; case 0x5c01: - if (pas16->has_scsi) { - ret = ((dev->ncr.dma_mode != DMA_IDLE) && !(dev->status_ctrl & STATUS_BUFFER_NOT_READY)) << 7; - if (!(ret & 0x80)) { - ncr53c400_callback(pas16->scsi); - if ((dev->ncr.dma_mode != DMA_IDLE) && !(dev->status_ctrl & STATUS_BUFFER_NOT_READY)) { - timer_stop(&pas16->scsi_timer); - pas16->timeout_status &= 0x7f; - } - - } - } + if (pas16->has_scsi) + /* Bits 0-6 must absolutely be set for SCSI hard disk drivers to work. */ + ret = (((pas16->scsi->ncr.dma_mode != DMA_IDLE) && (pas16->scsi->status & 0x04)) << 7) | 0x7f; break; case 0x5c03: if (pas16->has_scsi) @@ -1187,6 +1177,20 @@ lmc835_update_reg(nsc_mixer_t *mixer) lmc835_recalc(mixer); } +static void +pas16_scsi_callback(void *priv) +{ + pas16_t * pas16 = (pas16_t *) priv; + t128_t * dev = pas16->scsi; + + t128_callback(pas16->scsi); + + if ((dev->ncr.dma_mode != DMA_IDLE) && (dev->status & 0x04)) { + timer_stop(&pas16->scsi_timer); + pas16->timeout_status &= 0x7f; + } +} + static void pas16_timeout_callback(void *priv) { @@ -1491,10 +1495,8 @@ pas16_out(uint16_t port, uint8_t val, void *priv) case 0x1c00 ... 0x1c03: /* NCR5380 ports 0 to 3. */ case 0x3c00 ... 0x3c03: /* NCR5380 ports 4 to 7. */ - if (pas16->has_scsi) { - port = (port & 0x0003) | ((port & 0x2000) >> 11); - ncr5380_write(port, val, &pas16->scsi->ncr); - } + if (pas16->has_scsi) + ncr5380_write((port & 0x0003) | ((port & 0x2000) >> 11), val, &pas16->scsi->ncr); break; case 0x4000: @@ -1516,7 +1518,7 @@ pas16_out(uint16_t port, uint8_t val, void *priv) case 0x5c00: if (pas16->has_scsi) - ncr53c400_simple_write(val, pas16->scsi); + t128_write(0x1e00, val, pas16->scsi); break; case 0x5c03: if (pas16->has_scsi) { @@ -2324,6 +2326,7 @@ pas16_init(const device_t *info) if (pas16->has_scsi) { pas16->scsi = device_add(&scsi_pas_device); + timer_add(&pas16->scsi->timer, pas16_scsi_callback, pas16, 0); timer_add(&pas16->scsi_timer, pas16_timeout_callback, pas16, 0); other_scsi_present++; }