mirror of
https://github.com/86Box/86Box.git
synced 2026-02-25 21:43:16 -07:00
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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 } }
|
||||
|
||||
@@ -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 },
|
||||
|
||||
Reference in New Issue
Block a user