Sort out the IRQ/INT enabling/disabling stuff of the 5380/53c80 chip.

Allowing proper operation of the IRQ in the 53c400 and, at the same time, recognizing the RTASPI10.SYS driver of the Rancho RT1000B.
Code based on the 53c400 manual and MAME.
TODO: Verify the Trantor T128 scheme.
This commit is contained in:
TC1995
2026-02-22 21:05:39 +01:00
parent 843b9f1708
commit 81ba889f9e
4 changed files with 86 additions and 50 deletions

View File

@@ -84,6 +84,7 @@ typedef struct ncr_t {
int (*dma_send_ext)(void *priv, void *ext_priv);
int (*dma_initiator_receive_ext)(void *priv, void *ext_priv);
void (*timer)(void *ext_priv, double period);
int (*irq_ena)(void *priv, void *ext_priv, int state);
scsi_bus_t scsibus;
} ncr_t;

View File

@@ -62,13 +62,9 @@ void
ncr5380_irq(ncr_t *ncr, int set_irq)
{
if (set_irq) {
ncr->irq_state = 1;
ncr->isr |= STATUS_INT;
if (ncr->irq != -1)
picint(1 << ncr->irq);
} else {
ncr->irq_state = 0;
ncr->isr &= ~STATUS_INT;
if (ncr->irq != 1)
picintc(1 << ncr->irq);
}
@@ -104,7 +100,12 @@ ncr5380_reset(ncr_t *ncr)
scsi_bus->data = 0;
scsi_bus->command_issued = 0;
ncr5380_irq(ncr, 0);
if (ncr->irq_ena)
ncr->irq_ena(ncr, ncr->priv, 0);
else
ncr5380_irq(ncr, 0);
ncr->isr &= ~STATUS_INT;
}
uint32_t
@@ -164,7 +165,7 @@ ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr)
if ((val & 0x80) && !(ncr->icr & 0x80)) {
ncr5380_log("Resetting the 5380\n");
ncr5380_reset(ncr);
ncr5380_irq(ncr, 1);
ncr->isr |= STATUS_INT;
}
ncr->icr = val;
ncr5380_log("ICR WaitData=%d, ClearReq=%d.\n", scsi_bus->wait_data, scsi_bus->clear_req);
@@ -301,7 +302,7 @@ ncr5380_read(uint16_t port, ncr_t *ncr)
if (bus & BUS_MSG)
bus_state |= TCR_MSG;
if ((ncr->tcr & 7) != bus_state) {
ncr5380_irq(ncr, 1);
ncr->isr |= STATUS_INT;
ncr5380_log("IRQ issued\n");
}
}
@@ -321,7 +322,12 @@ ncr5380_read(uint16_t port, ncr_t *ncr)
case 7: /* reset Parity/Interrupt */
ncr->isr &= ~(STATUS_BUSY_ERROR | 0x20);
ncr5380_irq(ncr, 0);
if (ncr->irq_ena)
ncr->irq_ena(ncr, ncr->priv, 0);
else
ncr5380_irq(ncr, 0);
ncr->isr &= ~STATUS_INT;
ncr5380_log("Reset Interrupt\n");
break;

View File

@@ -72,6 +72,7 @@ typedef struct ncr53c400_t {
int8_t type;
uint8_t block_count;
uint8_t status_ctrl;
uint8_t irq_config;
int block_count_loaded;
@@ -103,6 +104,23 @@ ncr53c400_log(const char *fmt, ...)
# define ncr53c400_log(fmt, ...)
#endif
static int
ncr53c400_irq_enable(void *priv, void *ext_priv, int state)
{
ncr53c400_t *ncr400 = (ncr53c400_t *) ext_priv;
ncr_t *ncr = (ncr_t *) priv;
if (ncr->irq_state != state) {
ncr->irq_state = state;
ncr400->status_ctrl &= ~0x01;
ncr400->status_ctrl |= (state << 0);
ncr53c400_log("Status Control bit 4=%02x.\n", ncr400->status_ctrl);
if (ncr400->status_ctrl & 0x10)
ncr5380_irq(ncr, state);
}
return 1;
}
static void
ncr53c400_timer_on_auto(void *ext_priv, double period)
{
@@ -263,7 +281,8 @@ ncr53c400_read(uint32_t addr, void *priv)
ncr->isr |= STATUS_END_OF_DMA;
if (ncr->mode & MODE_ENA_EOP_INT) {
ncr53c400_log("NCR read irq\n");
ncr5380_irq(ncr, 1);
ncr53c400_irq_enable(ncr, ncr400, 1);
ncr->isr |= STATUS_INT;
}
} else if (!timer_is_enabled(&ncr400->timer)) {
ncr53c400_log("Timer re-enabled.\n");
@@ -277,15 +296,16 @@ ncr53c400_read(uint32_t addr, void *priv)
case 0x3980:
switch (addr) {
case 0x3980: /* status */
if (ncr400->reset) {
ncr400->reset = 0;
ncr53c400_irq_enable(ncr, ncr400, 1);
}
ret = ncr400->status_ctrl;
ncr53c400_log("NCR status ctrl read=%02x.\n", ncr400->status_ctrl & STATUS_BUFFER_NOT_READY);
if (!ncr400->busy)
ret |= STATUS_5380_ACCESSIBLE;
if (ncr400->reset) {
ncr400->reset = 0;
ret |= 0x01;
}
ncr53c400_log("NCR 53c400 status=%02x.\n", ret);
break;
@@ -295,10 +315,7 @@ ncr53c400_read(uint32_t addr, void *priv)
break;
case 0x3982: /* switch register read */
if (ncr->irq != -1) {
ret = 0xf8;
ret += ncr->irq;
}
ret = ((ncr400->irq_config >> 5) & 7) | 0xf8;
ncr53c400_log("Switches read=%02x.\n", ret);
break;
@@ -519,7 +536,8 @@ ncr53c400_callback(void *priv)
ncr->isr |= STATUS_END_OF_DMA;
if (ncr->mode & MODE_ENA_EOP_INT) {
ncr53c400_log("NCR 53c400 write irq\n");
ncr5380_irq(ncr, 1);
ncr53c400_irq_enable(ncr, ncr400, 1);
ncr->isr |= STATUS_INT;
}
}
break;
@@ -573,7 +591,8 @@ ncr53c400_callback(void *priv)
ncr->isr |= STATUS_END_OF_DMA;
if (ncr->mode & MODE_ENA_EOP_INT) {
ncr53c400_log("NCR read irq\n");
ncr5380_irq(ncr, 1);
ncr53c400_irq_enable(ncr, ncr400, 1);
ncr->isr |= STATUS_INT;
}
} else
timer_on_auto(&ncr400->timer, 1.0);
@@ -675,7 +694,8 @@ ncr53c400_init(const device_t *info)
switch (ncr400->type) {
case ROM_LCS6821N: /* Longshine LCS6821N */
ncr400->rom_addr = device_get_config_hex20("bios_addr");
ncr->irq = device_get_config_int("irq");
ncr400->irq_config = device_get_config_hex16("irq");
ncr->irq = (ncr400->irq_config >> 5) & 7;
rom_init(&ncr400->bios_rom, LCS6821N_ROM,
ncr400->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
@@ -689,7 +709,8 @@ ncr53c400_init(const device_t *info)
case ROM_LS2000: /* Corel LS2000 */
ncr400->rom_addr = device_get_config_hex20("bios_addr");
ncr->irq = device_get_config_int("irq");
ncr400->irq_config = device_get_config_hex16("irq");
ncr->irq = (ncr400->irq_config >> 5) & 7;
rom_init(&ncr400->bios_rom, COREL_LS2000_ROM,
ncr400->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
@@ -702,7 +723,9 @@ ncr53c400_init(const device_t *info)
case ROM_RT1000B: /* Rancho RT1000B/MC */
ncr400->rom_addr = device_get_config_hex20("bios_addr");
ncr->irq = device_get_config_int("irq");
ncr400->irq_config = device_get_config_hex16("irq");
ncr->irq = (ncr400->irq_config >> 5) & 7;
if (info->flags & DEVICE_MCA) {
rom_init(&ncr400->bios_rom, RT1000B_820R_ROM,
0xd8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
@@ -729,7 +752,8 @@ ncr53c400_init(const device_t *info)
case ROM_T130B: /* Trantor T130B */
ncr400->rom_addr = device_get_config_hex20("bios_addr");
ncr400->base = device_get_config_hex16("base");
ncr->irq = device_get_config_int("irq");
ncr400->irq_config = device_get_config_hex16("irq");
ncr->irq = (ncr400->irq_config >> 5) & 7;
if (ncr400->rom_addr > 0x00000) {
rom_init(&ncr400->bios_rom, T130B_ROM,
@@ -754,6 +778,7 @@ ncr53c400_init(const device_t *info)
ncr->dma_send_ext = NULL;
ncr->dma_initiator_receive_ext = NULL;
ncr->timer = ncr53c400_timer_on_auto;
ncr->irq_ena = ncr53c400_irq_enable;
scsi_bus->bus_device = ncr->bus;
scsi_bus->timer = ncr->timer;
scsi_bus->priv = ncr->priv;
@@ -839,16 +864,16 @@ static const device_config_t ncr53c400_mmio_config[] = {
{
.name = "irq",
.description = "IRQ",
.type = CONFIG_SELECTION,
.type = CONFIG_HEX16,
.default_string = NULL,
.default_int = 5,
.default_int = 0xa0,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "None", .value = -1 },
{ .description = "IRQ 3", .value = 3 },
{ .description = "IRQ 5", .value = 5 },
{ .description = "IRQ 7", .value = 7 },
{ .description = "IRQ 3", .value = 0x60 },
{ .description = "IRQ 4", .value = 0x80 },
{ .description = "IRQ 5", .value = 0xa0 },
{ .description = "IRQ 7", .value = 0xe0 },
{ .description = "" }
},
.bios = { { 0 } }
@@ -910,16 +935,16 @@ static const device_config_t rt1000b_config[] = {
{
.name = "irq",
.description = "IRQ",
.type = CONFIG_SELECTION,
.type = CONFIG_HEX16,
.default_string = NULL,
.default_int = 5,
.default_int = 0xa0,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "None", .value = -1 },
{ .description = "IRQ 3", .value = 3 },
{ .description = "IRQ 5", .value = 5 },
{ .description = "IRQ 7", .value = 7 },
{ .description = "IRQ 3", .value = 0x60 },
{ .description = "IRQ 4", .value = 0x80 },
{ .description = "IRQ 5", .value = 0xa0 },
{ .description = "IRQ 7", .value = 0xe0 },
{ .description = "" }
},
.bios = { { 0 } }
@@ -931,16 +956,16 @@ static const device_config_t rt1000b_mc_config[] = {
{
.name = "irq",
.description = "IRQ",
.type = CONFIG_SELECTION,
.type = CONFIG_HEX16,
.default_string = NULL,
.default_int = 5,
.default_int = 0xa0,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "None", .value = -1 },
{ .description = "IRQ 3", .value = 3 },
{ .description = "IRQ 5", .value = 5 },
{ .description = "IRQ 7", .value = 7 },
{ .description = "IRQ 3", .value = 0x60 },
{ .description = "IRQ 4", .value = 0x80 },
{ .description = "IRQ 5", .value = 0xa0 },
{ .description = "IRQ 7", .value = 0xe0 },
{ .description = "" }
},
.bios = { { 0 } }
@@ -987,16 +1012,16 @@ static const device_config_t t130b_config[] = {
{
.name = "irq",
.description = "IRQ",
.type = CONFIG_SELECTION,
.type = CONFIG_HEX16,
.default_string = NULL,
.default_int = 5,
.default_int = 0xa0,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "None", .value = -1 },
{ .description = "IRQ 3", .value = 3 },
{ .description = "IRQ 5", .value = 5 },
{ .description = "IRQ 7", .value = 7 },
{ .description = "IRQ 3", .value = 0x60 },
{ .description = "IRQ 4", .value = 0x80 },
{ .description = "IRQ 5", .value = 0xa0 },
{ .description = "IRQ 7", .value = 0xe0 },
{ .description = "" }
},
.bios = { { 0 } }

View File

@@ -27,7 +27,6 @@
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/io.h>
#include "cpu.h"
#include <86box/timer.h>
#include <86box/dma.h>
#include <86box/pic.h>
@@ -41,6 +40,7 @@
#include <86box/scsi_device.h>
#include <86box/scsi_ncr5380.h>
#include <86box/scsi_t128.h>
#include "cpu.h"
#define T128_ROM "roms/scsi/ncr5380/trantor_t128_bios_v1.12.bin"
@@ -75,7 +75,7 @@ t128_write(uint32_t addr, uint8_t val, void *priv)
if ((addr >= 0x1800) && (addr < 0x1880))
t128->ext_ram[addr & 0x7f] = val;
else if ((addr >= 0x1c00) && (addr < 0x1c20)) {
t128_log("T128 ctrl write=%02x, mode=%02x.\n", val, ncr->mode & MODE_DMA);
t128_log("T128 ctrl write=%02x, mode=%02x.\n", val & 0x10, ncr->mode & MODE_DMA);
t128->ctrl = val;
} else if ((addr >= 0x1d00) && (addr < 0x1e00))
ncr5380_write((addr - 0x1d00) >> 5, val, ncr);
@@ -141,6 +141,7 @@ t128_read(uint32_t addr, void *priv)
if (ncr->mode & MODE_ENA_EOP_INT) {
t128_log("T128 read irq\n");
ncr5380_irq(ncr, 1);
ncr->isr |= STATUS_INT;
}
scsi_bus->bus_out |= BUS_CD;
scsi_bus->tx_mode = PIO_TX_BUS;
@@ -298,6 +299,7 @@ t128_callback(void *priv)
if (ncr->mode & MODE_ENA_EOP_INT) {
t128_log("T128 write irq\n");
ncr5380_irq(ncr, 1);
ncr->isr |= STATUS_INT;
}
scsi_bus->tx_mode = PIO_TX_BUS;
timer_stop(&t128->timer);
@@ -497,6 +499,7 @@ 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;
ncr->irq_ena = NULL;
scsi_bus->bus_device = ncr->bus;
scsi_bus->timer = ncr->timer;
scsi_bus->priv = ncr->priv;
@@ -566,12 +569,13 @@ static const device_config_t t128_config[] = {
.description = "IRQ",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 5,
.default_int = -1,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "None", .value = -1 },
{ .description = "IRQ 3", .value = 3 },
{ .description = "IRQ 4", .value = 4 },
{ .description = "IRQ 5", .value = 5 },
{ .description = "IRQ 7", .value = 7 },
{ .description = "IRQ 10", .value = 10 },