The Pro Audio Spectrum SCSI controller is now based on the Trantor T128 (which it is considerable closer to), rather than on the 53c400.

This commit is contained in:
OBattler
2024-05-06 13:09:08 +02:00
parent ccc788ff98
commit 4c84cccae7
11 changed files with 165 additions and 262 deletions

View File

@@ -1677,8 +1677,8 @@ mo_command(scsi_common_t *sc, uint8_t *cdb)
size_idx = 4; size_idx = 4;
memset(dev->buffer, 0, 8); memset(dev->buffer, 0, 8);
if (cdb[1] & 0xe0) if ((cdb[1] & 0xe0) || ((dev->cur_lun > 0x00) && (dev->cur_lun < 0xff)))
dev->buffer[0] = 0x60; /*No physical device on this LUN*/ dev->buffer[0] = 0x7f; /*No physical device on this LUN*/
else else
dev->buffer[0] = 0x07; /*Optical disk*/ dev->buffer[0] = 0x07; /*Optical disk*/
dev->buffer[1] = 0x80; /*Removable*/ dev->buffer[1] = 0x80; /*Removable*/

View File

@@ -1865,8 +1865,8 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
size_idx = 4; size_idx = 4;
memset(dev->buffer, 0, 8); memset(dev->buffer, 0, 8);
if (cdb[1] & 0xe0) if ((cdb[1] & 0xe0) || ((dev->cur_lun > 0x00) && (dev->cur_lun < 0xff)))
dev->buffer[0] = 0x60; /*No physical device on this LUN*/ dev->buffer[0] = 0x7f; /*No physical device on this LUN*/
else else
dev->buffer[0] = 0x00; /*Hard disk*/ dev->buffer[0] = 0x00; /*Hard disk*/
dev->buffer[1] = 0x80; /*Removable*/ dev->buffer[1] = 0x80; /*Removable*/

View File

@@ -309,6 +309,7 @@
#define BUS_BSY 0x40 #define BUS_BSY 0x40
#define BUS_RST 0x80 #define BUS_RST 0x80
#define BUS_ACK 0x200 #define BUS_ACK 0x200
/* TODO: Why is this defined to the same value as BUS_ACK?! */
#define BUS_ATN 0x200 #define BUS_ATN 0x200
#define BUS_ARB 0x8000 #define BUS_ARB 0x8000
#define BUS_SETDATA(val) ((uint32_t) val << 16) #define BUS_SETDATA(val) ((uint32_t) val << 16)

View File

@@ -109,14 +109,10 @@ typedef struct ncr_t {
int data_pos; int data_pos;
int irq; int irq;
int simple_pseudo_dma;
uint32_t block_count;
double period; double period;
void *priv; void *priv;
void (*dma_init_ext)(void *priv, void *ext_priv, int send);
void (*dma_mode_ext)(void *priv, void *ext_priv); void (*dma_mode_ext)(void *priv, void *ext_priv);
int (*dma_send_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); 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_read(ncr_t *ncr);
extern void ncr5380_bus_update(ncr_t *ncr, int bus); extern void ncr5380_bus_update(ncr_t *ncr, int bus);
extern void ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr); 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); extern uint8_t ncr5380_read(uint16_t port, ncr_t *ncr);
#ifdef EMU_DEVICE_H #ifdef EMU_DEVICE_H
extern const device_t scsi_lcs6821n_device; 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_rt1000b_device;
extern const device_t scsi_rt1000mc_device; extern const device_t scsi_rt1000mc_device;
extern const device_t scsi_t128_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) #if defined(DEV_BRANCH) && defined(USE_SUMO)
extern const device_t scsi_scsiat_device; extern const device_t scsi_scsiat_device;
#endif #endif
extern const device_t scsi_pas_device;
#endif #endif
#endif /*SCSI_NCR5380_H*/ #endif /*SCSI_NCR5380_H*/

View File

@@ -18,45 +18,34 @@
* Copyright 2017-2024 TheCollector1995. * Copyright 2017-2024 TheCollector1995.
*/ */
#ifndef SCSI_NCR53C400_H #ifndef SCSI_T128_H
#define SCSI_NCR53C400_H #define SCSI_T128_H
typedef struct ncr53c400_t { typedef struct t128_t {
ncr_t ncr;
rom_t bios_rom; rom_t bios_rom;
mem_mapping_t mapping; mem_mapping_t mapping;
ncr_t ncr;
uint8_t ctrl;
uint8_t status;
uint8_t buffer[512]; uint8_t buffer[512];
uint8_t int_ram[0x40]; uint8_t ext_ram[0x80];
uint8_t ext_ram[0x600]; uint8_t block_count;
int block_loaded;
int pos, host_pos;
uint32_t rom_addr; uint32_t rom_addr;
uint16_t base;
int8_t type; int bios_enabled;
uint8_t block_count;
uint8_t status_ctrl;
int simple_ctrl;
int block_count_loaded;
int buffer_pos;
int buffer_host_pos;
int busy;
uint8_t pos_regs[8]; uint8_t pos_regs[8];
pc_timer_t timer; pc_timer_t timer;
} ncr53c400_t; } t128_t;
#define CTRL_DATA_DIR 0x40 extern void t128_write(uint32_t addr, uint8_t val, void *priv);
#define STATUS_BUFFER_NOT_READY 0x04 extern uint8_t t128_read(uint32_t addr, void *priv);
#define STATUS_5380_ACCESSIBLE 0x80
extern void ncr53c400_simple_write(uint8_t val, void *priv); extern void t128_callback(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);
#endif /*SCSI_NCR53C400_H*/ #endif /*SCSI_T128_H*/

View File

@@ -2794,6 +2794,15 @@ begin:
return; 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)) if (!(cdb[2] & 0x40))
alloc_length = 4; alloc_length = 4;
else else
@@ -3189,6 +3198,9 @@ begin:
size_idx = 4; size_idx = 4;
memset(dev->buffer, 0, 8); memset(dev->buffer, 0, 8);
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[0] = 5; /*CD-ROM*/
dev->buffer[1] = 0x80; /*Removable*/ dev->buffer[1] = 0x80; /*Removable*/

View File

@@ -1328,6 +1328,9 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb)
size_idx = 4; size_idx = 4;
memset(dev->temp_buffer, 0, 8); memset(dev->temp_buffer, 0, 8);
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[0] = 0; /*SCSI HD*/
dev->temp_buffer[1] = 0; /*Fixed*/ dev->temp_buffer[1] = 0; /*Fixed*/
dev->temp_buffer[2] = (dev->drv->bus == HDD_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ dev->temp_buffer[2] = (dev->drv->bus == HDD_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/

View File

@@ -161,8 +161,28 @@ ncr5380_get_bus_host(ncr_t *ncr)
if (ncr->icr & ICR_BSY) if (ncr->icr & ICR_BSY)
bus_host |= BUS_BSY; bus_host |= BUS_BSY;
/*
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) if (ncr->icr & ICR_ATN)
bus_host |= BUS_ATN; bus_host |= BUS_ATN;
}
if (ncr->icr & ICR_ACK) if (ncr->icr & ICR_ACK)
bus_host |= BUS_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); 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; ncr->new_phase = dev->phase;
} }
} }
@@ -358,9 +365,6 @@ 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*/ if (ncr->dma_mode == DMA_IDLE) { /*If a data in command that is not read 6/10 has been issued*/
ncr->data_wait |= 1; ncr->data_wait |= 1;
ncr5380_log("DMA mode idle in\n"); 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 { } else {
ncr5380_log("DMA mode IN.\n"); ncr5380_log("DMA mode IN.\n");
@@ -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*/ if (ncr->dma_mode == DMA_IDLE) { /*If a data out command that is not write 6/10 has been issued*/
ncr->data_wait |= 1; ncr->data_wait |= 1;
ncr5380_log("DMA mode idle out\n"); ncr5380_log("DMA mode idle out\n");
if (!ncr->simple_pseudo_dma)
ncr->timer(ncr->priv, ncr->period); ncr->timer(ncr->priv, ncr->period);
if (ncr->simple_pseudo_dma)
ncr->dma_init_ext(ncr, ncr->priv, 0);
} else } else
ncr->clear_req = 3; 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); 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 uint8_t
ncr5380_read(uint16_t port, ncr_t *ncr) ncr5380_read(uint16_t port, ncr_t *ncr)
{ {
@@ -579,6 +565,8 @@ ncr5380_read(uint16_t port, ncr_t *ncr)
ret |= BUS_SEL; ret |= BUS_SEL;
if (ncr->icr & ICR_BSY) if (ncr->icr & ICR_BSY)
ret |= BUS_BSY; ret |= BUS_BSY;
// if ((ret & SCSI_PHASE_MESSAGE_IN) == SCSI_PHASE_MESSAGE_IN)
// ret &= ~BUS_REQ;
break; break;
case 5: /* Bus and Status register */ case 5: /* Bus and Status register */

View File

@@ -41,7 +41,6 @@
#include <86box/scsi.h> #include <86box/scsi.h>
#include <86box/scsi_device.h> #include <86box/scsi_device.h>
#include <86box/scsi_ncr5380.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 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" #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 RT1000B_820R_ROM "roms/scsi/ncr5380/RTBIOS82.ROM"
#define T130B_ROM "roms/scsi/ncr5380/trantor_t130b_bios_v2.14.bin" #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 { enum {
ROM_LCS6821N = 0, ROM_LCS6821N = 0,
ROM_LS2000, ROM_LS2000,
ROM_RT1000B, ROM_RT1000B,
ROM_T130B, ROM_T130B
ROM_PAS
}; };
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 #ifdef ENABLE_NCR53C400_LOG
int ncr53c400_do_log = ENABLE_NCR53C400_LOG; int ncr53c400_do_log = ENABLE_NCR53C400_LOG;
@@ -75,29 +103,8 @@ ncr53c400_log(const char *fmt, ...)
# define ncr53c400_log(fmt, ...) # define ncr53c400_log(fmt, ...)
#endif #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. */ /* Memory-mapped I/O WRITE handler. */
void static void
ncr53c400_write(uint32_t addr, uint8_t val, void *priv) ncr53c400_write(uint32_t addr, uint8_t val, void *priv)
{ {
ncr53c400_t *ncr400 = (ncr53c400_t *) 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. */ /* Memory-mapped I/O READ handler. */
uint8_t static uint8_t
ncr53c400_read(uint32_t addr, void *priv) ncr53c400_read(uint32_t addr, void *priv)
{ {
ncr53c400_t *ncr400 = (ncr53c400_t *) priv; ncr53c400_t *ncr400 = (ncr53c400_t *) priv;
@@ -400,34 +385,6 @@ t130b_in(uint16_t port, void *priv)
return ret; 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 static void
ncr53c400_dma_mode_ext(void *priv, void *ext_priv) 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); timer_on_auto(&ncr400->timer, period);
} }
void static void
ncr53c400_callback(void *priv) ncr53c400_callback(void *priv)
{ {
ncr53c400_t *ncr400 = (void *) priv; ncr53c400_t *ncr400 = (void *) priv;
ncr_t *ncr = &ncr400->ncr; ncr_t *ncr = &ncr400->ncr;
scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id];
int bus; int bus;
int blocks_left;
uint8_t c; uint8_t c;
uint8_t temp; uint8_t temp;
const int buf_len = ncr400->simple_ctrl ? 512 : 128;
ncr53c400_log("DMA mode = %i\n", ncr->dma_mode); if (ncr->dma_mode != DMA_IDLE)
if (!ncr400->simple_ctrl && (ncr->dma_mode != DMA_IDLE))
timer_on_auto(&ncr400->timer, 1.0); timer_on_auto(&ncr400->timer, 1.0);
if (ncr->data_wait & 1) { if (ncr->data_wait & 1) {
@@ -488,7 +441,7 @@ ncr53c400_callback(void *priv)
switch (ncr->dma_mode) { switch (ncr->dma_mode) {
case DMA_SEND: 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"); ncr53c400_log("DMA_SEND with DMA direction set wrong\n");
break; break;
} }
@@ -522,20 +475,14 @@ ncr53c400_callback(void *priv)
ncr400->buffer_pos++; ncr400->buffer_pos++;
ncr53c400_log("NCR 53c400 Buffer pos for writing = %d\n", 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->status_ctrl &= ~STATUS_BUFFER_NOT_READY;
ncr400->buffer_pos = 0; ncr400->buffer_pos = 0;
ncr400->buffer_host_pos = 0; ncr400->buffer_host_pos = 0;
ncr400->busy = 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; ncr400->block_count = (ncr400->block_count - 1) & 0xff;
blocks_left = ncr400->block_count; ncr53c400_log("NCR 53c400 Remaining blocks to be written=%d\n", ncr400->block_count);
} if (!ncr400->block_count) {
ncr53c400_log("NCR 53c400 Remaining blocks to be written=%d\n", blocks_left);
if (blocks_left == 0) {
ncr400->block_count_loaded = 0; ncr400->block_count_loaded = 0;
ncr53c400_log("IO End of write transfer\n"); ncr53c400_log("IO End of write transfer\n");
ncr->tcr |= TCR_LAST_BYTE_SENT; ncr->tcr |= TCR_LAST_BYTE_SENT;
@@ -552,7 +499,7 @@ ncr53c400_callback(void *priv)
break; break;
case DMA_INITIATOR_RECEIVE: 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"); ncr53c400_log("DMA_INITIATOR_RECEIVE with DMA direction set wrong\n");
break; break;
} }
@@ -568,11 +515,9 @@ ncr53c400_callback(void *priv)
while (1) { while (1) {
for (c = 0; c < 10; c++) { for (c = 0; c < 10; c++) {
ncr5380_bus_read(ncr); ncr5380_bus_read(ncr);
if (ncr->cur_bus & BUS_REQ) { if (ncr->cur_bus & BUS_REQ)
ncr53c400_log("ncr->cur_bus & BUS_REQ\n");
break; break;
} }
}
/* Data ready. */ /* Data ready. */
ncr5380_bus_read(ncr); ncr5380_bus_read(ncr);
@@ -586,19 +531,13 @@ ncr53c400_callback(void *priv)
ncr400->buffer[ncr400->buffer_pos++] = temp; ncr400->buffer[ncr400->buffer_pos++] = temp;
ncr53c400_log("NCR 53c400 Buffer pos for reading = %d\n", ncr400->buffer_pos); 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->status_ctrl &= ~STATUS_BUFFER_NOT_READY;
ncr400->buffer_pos = 0; ncr400->buffer_pos = 0;
ncr400->buffer_host_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; ncr400->block_count = (ncr400->block_count - 1) & 0xff;
blocks_left = ncr400->block_count; ncr53c400_log("NCR 53c400 Remaining blocks to be read=%d\n", ncr400->block_count);
} if (!ncr400->block_count) {
ncr53c400_log("NCR 53c400 Remaining blocks to be read=%d\n", blocks_left);
if (blocks_left == 0) {
ncr400->block_count_loaded = 0; ncr400->block_count_loaded = 0;
ncr53c400_log("IO End of read transfer\n"); ncr53c400_log("IO End of read transfer\n");
ncr->isr |= STATUS_END_OF_DMA; ncr->isr |= STATUS_END_OF_DMA;
@@ -623,8 +562,6 @@ ncr53c400_callback(void *priv)
ncr53c400_log("Updating DMA\n"); ncr53c400_log("Updating DMA\n");
ncr->mode &= ~MODE_DMA; ncr->mode &= ~MODE_DMA;
ncr->dma_mode = DMA_IDLE; 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); ncr400->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr400);
break; break;
case ROM_LS2000: /* Corel LS2000 */ case ROM_LS2000: /* Corel LS2000 */
ncr400->rom_addr = device_get_config_hex20("bios_addr"); ncr400->rom_addr = device_get_config_hex20("bios_addr");
ncr->irq = device_get_config_int("irq"); 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); t130b_in, NULL, NULL, t130b_out, NULL, NULL, ncr400);
break; 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: default:
break; break;
} }
@@ -1076,17 +1007,3 @@ const device_t scsi_ls2000_device = {
.force_redraw = NULL, .force_redraw = NULL,
.config = ncr53c400_mmio_config .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
};

View File

@@ -41,31 +41,10 @@
#include <86box/scsi.h> #include <86box/scsi.h>
#include <86box/scsi_device.h> #include <86box/scsi_device.h>
#include <86box/scsi_ncr5380.h> #include <86box/scsi_ncr5380.h>
#include <86box/scsi_t128.h>
#define T128_ROM "roms/scsi/ncr5380/trantor_t128_bios_v1.12.bin" #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 #ifdef ENABLE_T128_LOG
int t128_do_log = ENABLE_T128_LOG; int t128_do_log = ENABLE_T128_LOG;
@@ -85,7 +64,7 @@ t128_log(const char *fmt, ...)
#endif #endif
/* Memory-mapped I/O WRITE handler. */ /* Memory-mapped I/O WRITE handler. */
static void void
t128_write(uint32_t addr, uint8_t val, void *priv) t128_write(uint32_t addr, uint8_t val, void *priv)
{ {
t128_t *t128 = (t128_t *) 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. */ /* Memory-mapped I/O READ handler. */
static uint8_t uint8_t
t128_read(uint32_t addr, void *priv) t128_read(uint32_t addr, void *priv)
{ {
t128_t *t128 = (t128_t *) 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); timer_on_auto(&t128->timer, period);
} }
static void void
t128_callback(void *priv) t128_callback(void *priv)
{ {
t128_t *t128 = (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[0] = 0x8c;
t128->pos_regs[1] = 0x50; t128->pos_regs[1] = 0x50;
mca_add(t228_read, t228_write, t228_feedb, NULL, t128); mca_add(t228_read, t228_write, t228_feedb, NULL, t128);
} else { } else if (info->local == 0) {
ncr->irq = device_get_config_int("irq"); ncr->irq = device_get_config_int("irq");
t128->rom_addr = device_get_config_hex20("bios_addr"); t128->rom_addr = device_get_config_hex20("bios_addr");
t128->bios_enabled = device_get_config_int("boot"); t128->bios_enabled = device_get_config_int("boot");
@@ -525,11 +504,12 @@ t128_init(const device_t *info)
ncr->dma_send_ext = t128_dma_send_ext; ncr->dma_send_ext = t128_dma_send_ext;
ncr->dma_initiator_receive_ext = t128_dma_initiator_receive_ext; ncr->dma_initiator_receive_ext = t128_dma_initiator_receive_ext;
ncr->timer = t128_timer_on_auto; ncr->timer = t128_timer_on_auto;
t128->status = 0x04; t128->status = 0x00 /*0x04*/;
t128->host_pos = 512; t128->host_pos = 512;
if (!t128->bios_enabled && !(info->flags & DEVICE_MCA)) if (!t128->bios_enabled && !(info->flags & DEVICE_MCA))
t128->status |= 0x80; t128->status |= 0x80;
if (info->local == 0)
timer_add(&t128->timer, t128_callback, t128, 0); timer_add(&t128->timer, t128_callback, t128, 0);
scsi_bus_set_speed(ncr->bus, 5000000.0); scsi_bus_set_speed(ncr->bus, 5000000.0);
@@ -616,6 +596,7 @@ const device_t scsi_t128_device = {
.config = t128_config .config = t128_config
}; };
const device_t scsi_t228_device = { const device_t scsi_t228_device = {
.name = "Trantor T228", .name = "Trantor T228",
.internal_name = "t228", .internal_name = "t228",
@@ -629,3 +610,17 @@ const device_t scsi_t228_device = {
.force_redraw = NULL, .force_redraw = NULL,
.config = 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
};

View File

@@ -108,8 +108,9 @@
#include <86box/pit.h> #include <86box/pit.h>
#include <86box/pit_fast.h> #include <86box/pit_fast.h>
#include <86box/rom.h> #include <86box/rom.h>
#include <86box/scsi_device.h>
#include <86box/scsi_ncr5380.h> #include <86box/scsi_ncr5380.h>
#include <86box/scsi_ncr53c400.h> #include <86box/scsi_t128.h>
#include <86box/snd_mpu401.h> #include <86box/snd_mpu401.h>
#include <86box/sound.h> #include <86box/sound.h>
#include <86box/snd_opl.h> #include <86box/snd_opl.h>
@@ -247,7 +248,7 @@ typedef struct pas16_t {
pitf_t * pit; pitf_t * pit;
ncr53c400_t *scsi; t128_t * scsi;
pc_timer_t scsi_timer; pc_timer_t scsi_timer;
} pas16_t; } pas16_t;
@@ -705,7 +706,6 @@ pas16_in(uint16_t port, void *priv)
{ {
pas16_t *pas16 = (pas16_t *) priv; pas16_t *pas16 = (pas16_t *) priv;
uint8_t ret = 0xff; uint8_t ret = 0xff;
ncr53c400_t *dev = (ncr53c400_t *) pas16->scsi;
port -= pas16->base; port -= pas16->base;
@@ -763,10 +763,8 @@ pas16_in(uint16_t port, void *priv)
case 0x1c00 ... 0x1c03: /* NCR5380 ports 0 to 3. */ case 0x1c00 ... 0x1c03: /* NCR5380 ports 0 to 3. */
case 0x3c00 ... 0x3c03: /* NCR5380 ports 4 to 7. */ case 0x3c00 ... 0x3c03: /* NCR5380 ports 4 to 7. */
if (pas16->has_scsi) { if (pas16->has_scsi)
port = (port & 0x0003) | ((port & 0x2000) >> 11); ret = ncr5380_read((port & 0x0003) | ((port & 0x2000) >> 11), &pas16->scsi->ncr);
ret = ncr5380_read(port, &pas16->scsi->ncr);
}
break; break;
case 0x2401: /* Board revision */ case 0x2401: /* Board revision */
@@ -782,20 +780,12 @@ pas16_in(uint16_t port, void *priv)
case 0x5c00: case 0x5c00:
if (pas16->has_scsi) if (pas16->has_scsi)
ret = ncr53c400_simple_read(pas16->scsi); ret = t128_read(0x1e00, pas16->scsi);
break; break;
case 0x5c01: case 0x5c01:
if (pas16->has_scsi) { if (pas16->has_scsi)
ret = ((dev->ncr.dma_mode != DMA_IDLE) && !(dev->status_ctrl & STATUS_BUFFER_NOT_READY)) << 7; /* Bits 0-6 must absolutely be set for SCSI hard disk drivers to work. */
if (!(ret & 0x80)) { ret = (((pas16->scsi->ncr.dma_mode != DMA_IDLE) && (pas16->scsi->status & 0x04)) << 7) | 0x7f;
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;
}
}
}
break; break;
case 0x5c03: case 0x5c03:
if (pas16->has_scsi) if (pas16->has_scsi)
@@ -1187,6 +1177,20 @@ lmc835_update_reg(nsc_mixer_t *mixer)
lmc835_recalc(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 static void
pas16_timeout_callback(void *priv) 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 0x1c00 ... 0x1c03: /* NCR5380 ports 0 to 3. */
case 0x3c00 ... 0x3c03: /* NCR5380 ports 4 to 7. */ case 0x3c00 ... 0x3c03: /* NCR5380 ports 4 to 7. */
if (pas16->has_scsi) { if (pas16->has_scsi)
port = (port & 0x0003) | ((port & 0x2000) >> 11); ncr5380_write((port & 0x0003) | ((port & 0x2000) >> 11), val, &pas16->scsi->ncr);
ncr5380_write(port, val, &pas16->scsi->ncr);
}
break; break;
case 0x4000: case 0x4000:
@@ -1516,7 +1518,7 @@ pas16_out(uint16_t port, uint8_t val, void *priv)
case 0x5c00: case 0x5c00:
if (pas16->has_scsi) if (pas16->has_scsi)
ncr53c400_simple_write(val, pas16->scsi); t128_write(0x1e00, val, pas16->scsi);
break; break;
case 0x5c03: case 0x5c03:
if (pas16->has_scsi) { if (pas16->has_scsi) {
@@ -2324,6 +2326,7 @@ pas16_init(const device_t *info)
if (pas16->has_scsi) { if (pas16->has_scsi) {
pas16->scsi = device_add(&scsi_pas_device); 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); timer_add(&pas16->scsi_timer, pas16_timeout_callback, pas16, 0);
other_scsi_present++; other_scsi_present++;
} }