Merge pull request #1212 from 86Box/tc1995

Workaround for the Rancho RT1000B BIOSes 8.10R and 8.20R to run on an…
This commit is contained in:
Miran Grča
2021-01-07 17:33:29 +01:00
committed by GitHub

View File

@@ -184,6 +184,17 @@ ncr_log(const char *fmt, ...)
static void static void
ncr_callback(void *priv); ncr_callback(void *priv);
static void
ncr_irq(ncr5380_t *ncr_dev, ncr_t *ncr, int set_irq)
{
if (set_irq) {
ncr->isr |= STATUS_INT;
picint(1 << ncr_dev->irq);
} else {
ncr->isr &= ~STATUS_INT;
picintc(1 << ncr_dev->irq);
}
}
static int static int
get_dev_id(uint8_t data) get_dev_id(uint8_t data)
@@ -211,10 +222,17 @@ getmsglen(uint8_t *msgp, int len)
} }
static void static void
ncr_reset(ncr_t *ncr) ncr_reset(ncr5380_t *ncr_dev, ncr_t *ncr)
{ {
memset(ncr, 0x00, sizeof(ncr_t)); memset(ncr, 0x00, sizeof(ncr_t));
ncr_log("NCR reset\n"); ncr_log("NCR reset\n");
timer_stop(&ncr_dev->timer);
for (int i = 0; i < 8; i++)
scsi_device_reset(&scsi_devices[i]);
ncr_irq(ncr_dev, ncr, 0);
} }
@@ -222,14 +240,17 @@ static void
dma_timer_on(ncr5380_t *ncr_dev) dma_timer_on(ncr5380_t *ncr_dev)
{ {
ncr_t *ncr = &ncr_dev->ncr; ncr_t *ncr = &ncr_dev->ncr;
scsi_device_t *dev = &scsi_devices[ncr->target_id];
double period = ncr_dev->period; double period = ncr_dev->period;
/* DMA Timer on: 1 wait period + 64 byte periods + 64 byte periods if first time. */
if (ncr->data_wait & 2) { if (ncr->data_wait & 2) {
ncr->data_wait &= ~2; ncr->data_wait &= ~2;
}
/* DMA Timer on: 1 wait period + 128 byte periods. Hard disk timings are not emulated at the moment */
if (dev->type & 5) {
period *= 128.0; period *= 128.0;
} else }
period *= 64.0;
/* This is the 1 us wait period. */ /* This is the 1 us wait period. */
period += 1.0; period += 1.0;
@@ -407,7 +428,6 @@ ncr_bus_update(void *priv, int bus)
ncr_log("CurBus BSY|REQ=%02x\n", ncr->cur_bus); ncr_log("CurBus BSY|REQ=%02x\n", ncr->cur_bus);
ncr->command_pos = 0; ncr->command_pos = 0;
SET_BUS_STATE(ncr, SCSI_PHASE_COMMAND); SET_BUS_STATE(ncr, SCSI_PHASE_COMMAND);
picint(1 << ncr_dev->irq);
} else { } else {
ncr->state = STATE_IDLE; ncr->state = STATE_IDLE;
ncr->cur_bus = 0; ncr->cur_bus = 0;
@@ -580,7 +600,7 @@ ncr_write(uint16_t port, uint8_t val, void *priv)
ncr_log("Write: Initiator command register\n"); ncr_log("Write: Initiator command register\n");
if ((val & 0x80) && !(ncr->icr & 0x80)) { if ((val & 0x80) && !(ncr->icr & 0x80)) {
ncr_log("Resetting the 5380\n"); ncr_log("Resetting the 5380\n");
ncr_reset(&ncr_dev->ncr); ncr_reset(ncr_dev, &ncr_dev->ncr);
} }
ncr->icr = val; ncr->icr = val;
break; break;
@@ -667,7 +687,6 @@ ncr_read(uint16_t port, void *priv)
case 1: /* Initiator Command Register */ case 1: /* Initiator Command Register */
ncr_log("Read: Initiator Command register, NCR ICR Read=%02x\n", ncr->icr); ncr_log("Read: Initiator Command register, NCR ICR Read=%02x\n", ncr->icr);
ret = ncr->icr; ret = ncr->icr;
break; break;
@@ -700,8 +719,7 @@ ncr_read(uint16_t port, void *priv)
if ((bus & SCSI_PHASE_MESSAGE_IN) == (ncr->cur_bus & SCSI_PHASE_MESSAGE_IN)) { if ((bus & SCSI_PHASE_MESSAGE_IN) == (ncr->cur_bus & SCSI_PHASE_MESSAGE_IN)) {
ncr_log("Phase match\n"); ncr_log("Phase match\n");
ret |= STATUS_PHASE_MATCH; ret |= STATUS_PHASE_MATCH;
} else }
picint(1 << ncr_dev->irq);
ncr_bus_read(ncr_dev); ncr_bus_read(ncr_dev);
bus = ncr->cur_bus; bus = ncr->cur_bus;
@@ -722,7 +740,7 @@ ncr_read(uint16_t port, void *priv)
if (bus & BUS_MSG) if (bus & BUS_MSG)
bus_state |= TCR_MSG; bus_state |= TCR_MSG;
if ((ncr->tcr & 7) != bus_state) if ((ncr->tcr & 7) != bus_state)
ncr->isr |= STATUS_INT; ncr_irq(ncr_dev, ncr, 1);
} }
if (!(bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) { if (!(bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) {
ncr_log("Busy error\n"); ncr_log("Busy error\n");
@@ -731,10 +749,13 @@ ncr_read(uint16_t port, void *priv)
ret |= (ncr->isr & (STATUS_INT | STATUS_END_OF_DMA)); ret |= (ncr->isr & (STATUS_INT | STATUS_END_OF_DMA));
break; break;
case 6:
ret = ncr->tx_data;
break;
case 7: /* reset Parity/Interrupt */ case 7: /* reset Parity/Interrupt */
ncr->isr &= ~STATUS_INT; ncr->isr &= ~(STATUS_BUSY_ERROR | 0x20);
picintc(1 << ncr_dev->irq); ncr_irq(ncr_dev, ncr, 0);
ncr_log("Reset IRQ\n");
break; break;
default: default:
@@ -976,7 +997,7 @@ ncr_callback(void *priv)
{ {
ncr5380_t *ncr_dev = (ncr5380_t *)priv; ncr5380_t *ncr_dev = (ncr5380_t *)priv;
ncr_t *ncr = &ncr_dev->ncr; ncr_t *ncr = &ncr_dev->ncr;
int bus, bt = 0, c = 0; int bus, c = 0;
uint8_t temp, data; uint8_t temp, data;
ncr_log("DMA mode=%d\n", ncr->dma_mode); ncr_log("DMA mode=%d\n", ncr->dma_mode);
@@ -1010,7 +1031,8 @@ ncr_callback(void *priv)
if (!ncr_dev->block_count_loaded) if (!ncr_dev->block_count_loaded)
break; break;
while (bt < 64) { write_start:
{
for (c = 0; c < 10; c++) { for (c = 0; c < 10; c++) {
ncr_bus_read(ncr_dev); ncr_bus_read(ncr_dev);
if (ncr->cur_bus & BUS_REQ) if (ncr->cur_bus & BUS_REQ)
@@ -1028,7 +1050,6 @@ ncr_callback(void *priv)
ncr_bus_update(priv, bus | BUS_ACK); ncr_bus_update(priv, bus | BUS_ACK);
ncr_bus_update(priv, bus & ~BUS_ACK); ncr_bus_update(priv, bus & ~BUS_ACK);
bt++;
ncr_dev->buffer_pos++; ncr_dev->buffer_pos++;
ncr_log("Buffer pos for writing = %d\n", ncr_dev->buffer_pos); ncr_log("Buffer pos for writing = %d\n", ncr_dev->buffer_pos);
@@ -1048,12 +1069,12 @@ ncr_callback(void *priv)
ncr->isr |= STATUS_END_OF_DMA; ncr->isr |= STATUS_END_OF_DMA;
if (ncr->mode & MODE_ENA_EOP_INT) { if (ncr->mode & MODE_ENA_EOP_INT) {
ncr_log("NCR write irq\n"); ncr_log("NCR write irq\n");
ncr->isr |= STATUS_INT; ncr_irq(ncr_dev, ncr, 1);
picint(1 << ncr_dev->irq);
} }
} }
break; break;
} }
goto write_start;
} }
break; break;
@@ -1071,7 +1092,8 @@ ncr_callback(void *priv)
if (!ncr_dev->block_count_loaded) if (!ncr_dev->block_count_loaded)
break; break;
while (bt < 64) { read_start:
{
for (c = 0; c < 10; c++) { for (c = 0; c < 10; c++) {
ncr_bus_read(ncr_dev); ncr_bus_read(ncr_dev);
if (ncr->cur_bus & BUS_REQ) if (ncr->cur_bus & BUS_REQ)
@@ -1091,7 +1113,6 @@ ncr_callback(void *priv)
ncr_bus_update(priv, bus & ~BUS_ACK); ncr_bus_update(priv, bus & ~BUS_ACK);
ncr_dev->buffer[ncr_dev->buffer_pos++] = temp; ncr_dev->buffer[ncr_dev->buffer_pos++] = temp;
bt++;
if (ncr_dev->buffer_pos == 128) { if (ncr_dev->buffer_pos == 128) {
ncr_dev->buffer_pos = 0; ncr_dev->buffer_pos = 0;
@@ -1109,12 +1130,12 @@ ncr_callback(void *priv)
ncr->isr |= STATUS_END_OF_DMA; ncr->isr |= STATUS_END_OF_DMA;
if (ncr->mode & MODE_ENA_EOP_INT) { if (ncr->mode & MODE_ENA_EOP_INT) {
ncr_log("NCR read irq\n"); ncr_log("NCR read irq\n");
ncr->isr |= STATUS_INT; ncr_irq(ncr_dev, ncr, 1);
picint(1 << ncr_dev->irq);
} }
} }
break; break;
} }
goto read_start;
} }
break; break;
} }
@@ -1201,7 +1222,7 @@ ncr_init(const device_t *info)
sprintf(&temp[strlen(temp)], " IRQ=%d", ncr_dev->irq); sprintf(&temp[strlen(temp)], " IRQ=%d", ncr_dev->irq);
ncr_log("%s\n", temp); ncr_log("%s\n", temp);
ncr_reset(&ncr_dev->ncr); ncr_reset(ncr_dev, &ncr_dev->ncr);
ncr_dev->status_ctrl = STATUS_BUFFER_NOT_READY; ncr_dev->status_ctrl = STATUS_BUFFER_NOT_READY;
ncr_dev->buffer_host_pos = 128; ncr_dev->buffer_host_pos = 128;
@@ -1277,6 +1298,9 @@ static const device_config_t ncr5380_mmio_config[] = {
{ {
"IRQ 5", 5 "IRQ 5", 5
}, },
{
"IRQ 7", 7
},
{ {
"" ""
} }
@@ -1318,6 +1342,9 @@ static const device_config_t rancho_config[] = {
{ {
"IRQ 5", 5 "IRQ 5", 5
}, },
{
"IRQ 7", 7
},
{ {
"" ""
} }