diff --git a/src/include/86box/scsi_ncr5380.h b/src/include/86box/scsi_ncr5380.h index 6453340ae..151a9873c 100644 --- a/src/include/86box/scsi_ncr5380.h +++ b/src/include/86box/scsi_ncr5380.h @@ -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; diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index 102e637c4..2a29b070d 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -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; diff --git a/src/scsi/scsi_ncr53c400.c b/src/scsi/scsi_ncr53c400.c index 31a2de8b3..c8520d082 100644 --- a/src/scsi/scsi_ncr53c400.c +++ b/src/scsi/scsi_ncr53c400.c @@ -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 } } diff --git a/src/scsi/scsi_t128.c b/src/scsi/scsi_t128.c index 5b893dd70..2c2451cc7 100644 --- a/src/scsi/scsi_t128.c +++ b/src/scsi/scsi_t128.c @@ -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 },