Trantor T128/MediaVision SCSI changes of the day (March 8th, 2025)
1. Made as best as possible implementation of the status bits 1-2 of the Trantor 128 so to make a more accurate speed for SCSI devices (CD-ROM and HDD) without stalls. 2. Slightly reorganized the timer of the T128.
This commit is contained in:
@@ -77,11 +77,8 @@ 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)) {
|
||||
if ((val & 0x02) && !(t128->ctrl & 0x02))
|
||||
t128->status |= 0x02;
|
||||
|
||||
t128_log("T128 ctrl write=%02x, mode=%02x.\n", val, ncr->mode & MODE_DMA);
|
||||
t128->ctrl = val;
|
||||
t128_log("T128 ctrl write=%02x\n", val);
|
||||
} else if ((addr >= 0x1d00) && (addr < 0x1e00))
|
||||
ncr5380_write((addr - 0x1d00) >> 5, val, ncr);
|
||||
else if ((addr >= 0x1e00) && (addr < 0x2000)) {
|
||||
@@ -90,13 +87,15 @@ t128_write(uint32_t addr, uint8_t val, void *priv)
|
||||
t128->buffer[t128->host_pos] = val;
|
||||
t128->host_pos++;
|
||||
|
||||
t128_log("T128 Write transfer, addr = %i, pos = %i, val = %02x\n",
|
||||
addr & 0x1ff, t128->host_pos, val);
|
||||
t128_log("T128 Write transfer: pos=%i, addr=%x.\n",
|
||||
t128->host_pos, addr & 0x1ff);
|
||||
|
||||
if (t128->host_pos == MIN(512, dev->buffer_length)) {
|
||||
t128_log("T128 Transfer busy write, status=%02x, period=%lf, enabled=%d, loaded=%d.\n",
|
||||
t128->status, scsi_bus->period, timer_is_enabled(&t128->timer), t128->block_loaded);
|
||||
|
||||
t128->status &= ~0x04;
|
||||
t128_log("Transfer busy write, status = %02x\n", t128->status);
|
||||
timer_on_auto(&t128->timer, 0.02);
|
||||
timer_on_auto(&t128->timer, 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,31 +118,45 @@ t128_read(uint32_t addr, void *priv)
|
||||
ret = t128->ext_ram[addr & 0x7f];
|
||||
else if ((addr >= 0x1c00) && (addr < 0x1c20)) {
|
||||
ret = t128->ctrl;
|
||||
t128_log("T128 ctrl read=%02x, dma=%02x\n", ret, ncr->mode & MODE_DMA);
|
||||
t128_log("T128 ctrl read=%02x, dma=%02x, load=%d, cnt=%d.\n", ret, ncr->mode & MODE_DMA, t128->block_loaded, t128->block_count);
|
||||
} else if ((addr >= 0x1c20) && (addr < 0x1c40)) {
|
||||
ret = t128->status;
|
||||
t128_log("T128 status read=%02x, dma=%02x\n", ret, ncr->mode & MODE_DMA);
|
||||
t128_log("T128 status read=%02x, dma=%02x, blockload=%d, timer=%d.\n", ret, ncr->mode & MODE_DMA, t128->block_loaded, timer_is_enabled(&t128->timer));
|
||||
} else if ((addr >= 0x1d00) && (addr < 0x1e00))
|
||||
ret = ncr5380_read((addr - 0x1d00) >> 5, ncr);
|
||||
else if (addr >= 0x1e00 && addr < 0x2000) {
|
||||
if ((t128->host_pos >= MIN(512, dev->buffer_length)) ||
|
||||
(scsi_bus->tx_mode != DMA_IN_TX_BUS))
|
||||
ret = 0xff;
|
||||
else {
|
||||
if ((scsi_bus->tx_mode == DMA_IN_TX_BUS) &&
|
||||
(t128->host_pos < MIN(512, dev->buffer_length))) {
|
||||
ret = t128->buffer[t128->host_pos++];
|
||||
|
||||
t128_log("T128 Read transfer, addr = %i, pos = %i\n", addr & 0x1ff,
|
||||
t128->host_pos);
|
||||
t128_log("T128 Read transfer: pos=%i, addr=%x.\n",
|
||||
t128->host_pos, addr & 0x1ff);
|
||||
|
||||
if (t128->host_pos == MIN(512, dev->buffer_length)) {
|
||||
t128->status &= ~0x04;
|
||||
t128_log("T128 Transfer busy read, status = %02x, period = %lf\n",
|
||||
t128->status, scsi_bus->period);
|
||||
if ((scsi_bus->period == 0.2) || (scsi_bus->period == 0.02))
|
||||
timer_on_auto(&t128->timer, 40.2);
|
||||
} else if ((t128->host_pos < MIN(512, dev->buffer_length)) &&
|
||||
(scsi_device_get_callback(dev) > 100.0))
|
||||
cycles += 100; /*Needed to avoid timer de-syncing with transfers.*/
|
||||
t128_log("T128 Transfer busy read, status=%02x, period=%lf, enabled=%d.\n",
|
||||
t128->status, scsi_bus->period, timer_is_enabled(&t128->timer));
|
||||
|
||||
if (!t128->block_loaded) {
|
||||
ncr->isr |= STATUS_END_OF_DMA;
|
||||
if (ncr->mode & MODE_ENA_EOP_INT) {
|
||||
t128_log("T128 read irq\n");
|
||||
ncr5380_irq(ncr, 1);
|
||||
}
|
||||
t128->status &= ~0x04;
|
||||
scsi_bus->bus_out |= BUS_CD;
|
||||
scsi_bus->tx_mode = PIO_TX_BUS;
|
||||
timer_stop(&t128->timer);
|
||||
} else if (!timer_is_enabled(&t128->timer))
|
||||
timer_on_auto(&t128->timer, 1.0);
|
||||
else
|
||||
t128->status &= ~0x04;
|
||||
}
|
||||
} else {
|
||||
/*According to the WinNT DDK sources, just get the status timeout bit from here.*/
|
||||
if (!(t128->status & 0x02))
|
||||
t128->status |= 0x02;
|
||||
|
||||
t128_log("Read not allowed.\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,24 +164,20 @@ t128_read(uint32_t addr, void *priv)
|
||||
}
|
||||
|
||||
static void
|
||||
t128_dma_mode_ext(void *priv, void *ext_priv, UNUSED(uint8_t val))
|
||||
t128_dma_mode_ext(void *priv, void *ext_priv, uint8_t val)
|
||||
{
|
||||
t128_t *t128 = (t128_t *) ext_priv;
|
||||
ncr_t *ncr = (ncr_t *) priv;
|
||||
scsi_bus_t *scsi_bus = &ncr->scsibus;
|
||||
|
||||
/*Don't stop the timer until it finishes the transfer*/
|
||||
if (t128->block_loaded && (ncr->mode & MODE_DMA)) {
|
||||
t128_log("Continuing DMA mode\n");
|
||||
timer_on_auto(&t128->timer, scsi_bus->period + 1.0);
|
||||
}
|
||||
|
||||
/*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/
|
||||
if (!t128->block_loaded && !(ncr->mode & MODE_DMA)) {
|
||||
t128_log("No DMA mode\n");
|
||||
ncr->tcr &= ~TCR_LAST_BYTE_SENT;
|
||||
ncr->isr &= ~STATUS_END_OF_DMA;
|
||||
scsi_bus->tx_mode = PIO_TX_BUS;
|
||||
if (!t128->block_loaded) {
|
||||
if (!(val & MODE_DMA)) {
|
||||
ncr->tcr &= ~TCR_LAST_BYTE_SENT;
|
||||
ncr->isr &= ~STATUS_END_OF_DMA;
|
||||
scsi_bus->tx_mode = PIO_TX_BUS;
|
||||
t128_log("End of DMA.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,9 +189,9 @@ t128_dma_send_ext(void *priv, void *ext_priv)
|
||||
scsi_bus_t *scsi_bus = &ncr->scsibus;
|
||||
scsi_device_t *dev = &scsi_devices[ncr->bus][scsi_bus->target_id];
|
||||
|
||||
if ((ncr->mode & MODE_DMA) && !timer_is_on(&t128->timer) && (dev->buffer_length > 0)) {
|
||||
if ((ncr->mode & MODE_DMA) && (dev->buffer_length > 0)) {
|
||||
t128_log("T128 DMA OUT, len=%d.\n", dev->buffer_length);
|
||||
memset(t128->buffer, 0, MIN(512, dev->buffer_length));
|
||||
t128->status |= 0x04;
|
||||
t128->host_pos = 0;
|
||||
t128->block_count = dev->buffer_length >> 9;
|
||||
|
||||
@@ -190,6 +199,7 @@ t128_dma_send_ext(void *priv, void *ext_priv)
|
||||
t128->block_count = 1;
|
||||
|
||||
t128->block_loaded = 1;
|
||||
t128->status |= 0x04;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -202,9 +212,9 @@ t128_dma_initiator_receive_ext(void *priv, void *ext_priv)
|
||||
scsi_bus_t *scsi_bus = &ncr->scsibus;
|
||||
scsi_device_t *dev = &scsi_devices[ncr->bus][scsi_bus->target_id];
|
||||
|
||||
if ((ncr->mode & MODE_DMA) && !timer_is_on(&t128->timer) && (dev->buffer_length > 0)) {
|
||||
if ((ncr->mode & MODE_DMA) && (dev->buffer_length > 0)) {
|
||||
t128_log("T128 DMA IN, len=%d.\n", dev->buffer_length);
|
||||
memset(t128->buffer, 0, MIN(512, dev->buffer_length));
|
||||
t128->status |= 0x04;
|
||||
t128->host_pos = MIN(512, dev->buffer_length);
|
||||
t128->block_count = dev->buffer_length >> 9;
|
||||
|
||||
@@ -212,7 +222,8 @@ t128_dma_initiator_receive_ext(void *priv, void *ext_priv)
|
||||
t128->block_count = 1;
|
||||
|
||||
t128->block_loaded = 1;
|
||||
timer_on_auto(&t128->timer, 0.02);
|
||||
t128->status &= ~0x04;
|
||||
timer_on_auto(&t128->timer, 1.0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -222,16 +233,16 @@ t128_timer_on_auto(void *ext_priv, double period)
|
||||
{
|
||||
t128_t *t128 = (t128_t *) ext_priv;
|
||||
|
||||
if (period == 0.0)
|
||||
if (period <= 0.0)
|
||||
timer_stop(&t128->timer);
|
||||
else
|
||||
else if ((period > 0.0) && !timer_is_enabled(&t128->timer))
|
||||
timer_on_auto(&t128->timer, period);
|
||||
}
|
||||
|
||||
void
|
||||
t128_callback(void *priv)
|
||||
{
|
||||
t128_t *t128 = (void *) priv;
|
||||
t128_t *t128 = (t128_t *) priv;
|
||||
ncr_t *ncr = &t128->ncr;
|
||||
scsi_bus_t *scsi_bus = &ncr->scsibus;
|
||||
scsi_device_t *dev = &scsi_devices[ncr->bus][scsi_bus->target_id];
|
||||
@@ -240,128 +251,110 @@ t128_callback(void *priv)
|
||||
uint8_t temp;
|
||||
uint8_t status;
|
||||
|
||||
if ((scsi_bus->tx_mode != PIO_TX_BUS) && (ncr->mode & MODE_DMA) && t128->block_loaded) {
|
||||
if ((t128->host_pos == MIN(512, dev->buffer_length)) && t128->block_count)
|
||||
t128->status |= 0x04;
|
||||
|
||||
timer_on_auto(&t128->timer, scsi_bus->period / 55.0);
|
||||
}
|
||||
if (scsi_bus->tx_mode != PIO_TX_BUS)
|
||||
timer_on_auto(&t128->timer, scsi_bus->period / 65.0);
|
||||
|
||||
if (scsi_bus->data_wait & 1) {
|
||||
scsi_bus->clear_req = 3;
|
||||
scsi_bus->data_wait &= ~1;
|
||||
if (scsi_bus->tx_mode == PIO_TX_BUS)
|
||||
return;
|
||||
}
|
||||
|
||||
if (scsi_bus->tx_mode == PIO_TX_BUS) {
|
||||
t128_log("Timer CMD=%02x.\n", scsi_bus->command[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (scsi_bus->tx_mode) {
|
||||
case DMA_OUT_TX_BUS:
|
||||
if (!(t128->status & 0x04)) {
|
||||
t128_log("Write status busy, block count = %i, host pos = %i\n", t128->block_count, t128->host_pos);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!t128->block_loaded) {
|
||||
t128_log("Write block not loaded\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (t128->host_pos < MIN(512, dev->buffer_length))
|
||||
break;
|
||||
|
||||
write_again:
|
||||
for (c = 0; c < 10; c++) {
|
||||
status = scsi_bus_read(scsi_bus);
|
||||
if (status & BUS_REQ)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Data ready. */
|
||||
temp = t128->buffer[t128->pos];
|
||||
|
||||
bus = ncr5380_get_bus_host(ncr) & ~BUS_DATAMASK;
|
||||
bus |= BUS_SETDATA(temp);
|
||||
|
||||
scsi_bus_update(scsi_bus, bus | BUS_ACK);
|
||||
scsi_bus_update(scsi_bus, bus & ~BUS_ACK);
|
||||
|
||||
t128->pos++;
|
||||
t128_log("T128 Buffer pos for writing = %d\n", t128->pos);
|
||||
|
||||
if (t128->pos == MIN(512, dev->buffer_length)) {
|
||||
t128->pos = 0;
|
||||
t128->host_pos = 0;
|
||||
t128->status &= ~0x02;
|
||||
t128->block_count = (t128->block_count - 1) & 0xff;
|
||||
t128_log("T128 Remaining blocks to be written=%d\n", t128->block_count);
|
||||
if (!t128->block_count) {
|
||||
t128->block_loaded = 0;
|
||||
t128_log("IO End of write transfer\n");
|
||||
ncr->tcr |= TCR_LAST_BYTE_SENT;
|
||||
ncr->isr |= STATUS_END_OF_DMA;
|
||||
timer_stop(&t128->timer);
|
||||
if (ncr->mode & MODE_ENA_EOP_INT) {
|
||||
t128_log("T128 write irq\n");
|
||||
ncr5380_irq(ncr, 1);
|
||||
}
|
||||
}
|
||||
if (!t128->block_loaded)
|
||||
break;
|
||||
} else
|
||||
goto write_again;
|
||||
|
||||
while (1) {
|
||||
for (c = 0; c < 10; c++) {
|
||||
status = scsi_bus_read(scsi_bus);
|
||||
if (status & BUS_REQ)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Data ready. */
|
||||
temp = t128->buffer[t128->pos];
|
||||
|
||||
bus = ncr5380_get_bus_host(ncr) & ~BUS_DATAMASK;
|
||||
bus |= BUS_SETDATA(temp);
|
||||
|
||||
scsi_bus_update(scsi_bus, bus | BUS_ACK);
|
||||
scsi_bus_update(scsi_bus, bus & ~BUS_ACK);
|
||||
|
||||
t128->pos++;
|
||||
t128_log("T128 Buffer pos for writing = %d\n", t128->pos);
|
||||
|
||||
if (t128->pos == MIN(512, dev->buffer_length)) {
|
||||
t128->status |= 0x04;
|
||||
t128->status &= ~0x02;
|
||||
t128->pos = 0;
|
||||
t128->host_pos = 0;
|
||||
t128->block_count = (t128->block_count - 1) & 0xff;
|
||||
t128_log("T128 Remaining blocks to be written=%d\n", t128->block_count);
|
||||
if (!t128->block_count) {
|
||||
t128->block_loaded = 0;
|
||||
ncr->tcr |= TCR_LAST_BYTE_SENT;
|
||||
ncr->isr |= STATUS_END_OF_DMA;
|
||||
if (ncr->mode & MODE_ENA_EOP_INT) {
|
||||
t128_log("T128 write irq\n");
|
||||
ncr5380_irq(ncr, 1);
|
||||
}
|
||||
scsi_bus->tx_mode = PIO_TX_BUS;
|
||||
timer_stop(&t128->timer);
|
||||
t128_log("IO End of write transfer\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case DMA_IN_TX_BUS:
|
||||
if (!(t128->status & 0x04)) {
|
||||
t128_log("Read status busy, block count = %i, host pos = %i\n", t128->block_count, t128->host_pos);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!t128->block_loaded) {
|
||||
t128_log("Read block not loaded\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (t128->host_pos < MIN(512, dev->buffer_length))
|
||||
break;
|
||||
|
||||
read_again:
|
||||
for (c = 0; c < 10; c++) {
|
||||
status = scsi_bus_read(scsi_bus);
|
||||
if (status & BUS_REQ)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Data ready. */
|
||||
bus = scsi_bus_read(scsi_bus);
|
||||
temp = BUS_GETDATA(bus);
|
||||
|
||||
bus = ncr5380_get_bus_host(ncr);
|
||||
|
||||
scsi_bus_update(scsi_bus, bus | BUS_ACK);
|
||||
scsi_bus_update(scsi_bus, bus & ~BUS_ACK);
|
||||
|
||||
t128->buffer[t128->pos++] = temp;
|
||||
t128_log("T128 Buffer pos for reading=%d, temp=%02x, len=%d.\n", t128->pos, temp, dev->buffer_length);
|
||||
|
||||
if (t128->pos == MIN(512, dev->buffer_length)) {
|
||||
t128->pos = 0;
|
||||
t128->host_pos = 0;
|
||||
t128->status &= ~0x02;
|
||||
t128->block_count = (t128->block_count - 1) & 0xff;
|
||||
t128_log("T128 Remaining blocks to be read=%d, status=%02x, len=%i, cdb[0] = %02x\n", t128->block_count, t128->status, dev->buffer_length, ncr->command[0]);
|
||||
if (!t128->block_count) {
|
||||
t128->block_loaded = 0;
|
||||
t128_log("IO End of read transfer\n");
|
||||
ncr->isr |= STATUS_END_OF_DMA;
|
||||
timer_stop(&t128->timer);
|
||||
if (ncr->mode & MODE_ENA_EOP_INT) {
|
||||
t128_log("NCR read irq\n");
|
||||
ncr5380_irq(ncr, 1);
|
||||
}
|
||||
}
|
||||
if (!t128->block_loaded)
|
||||
break;
|
||||
} else
|
||||
goto read_again;
|
||||
|
||||
while (1) {
|
||||
for (c = 0; c < 10; c++) {
|
||||
status = scsi_bus_read(scsi_bus);
|
||||
if (status & BUS_REQ)
|
||||
break;
|
||||
}
|
||||
/* Data ready. */
|
||||
bus = scsi_bus_read(scsi_bus);
|
||||
temp = BUS_GETDATA(bus);
|
||||
|
||||
bus = ncr5380_get_bus_host(ncr);
|
||||
|
||||
scsi_bus_update(scsi_bus, bus | BUS_ACK);
|
||||
scsi_bus_update(scsi_bus, bus & ~BUS_ACK);
|
||||
|
||||
t128->buffer[t128->pos++] = temp;
|
||||
t128_log("T128 Buffer pos for reading = %d\n", t128->pos);
|
||||
|
||||
if (t128->pos == MIN(512, dev->buffer_length)) {
|
||||
t128->status |= 0x04;
|
||||
t128->status &= ~0x02;
|
||||
t128->pos = 0;
|
||||
t128->host_pos = 0;
|
||||
t128->block_count = (t128->block_count - 1) & 0xff;
|
||||
t128_log("T128 Remaining blocks to be read=%d\n", t128->block_count);
|
||||
if (!t128->block_count) {
|
||||
t128->block_loaded = 0;
|
||||
scsi_bus->bus_out |= BUS_REQ;
|
||||
t128_log("IO End of read transfer\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -374,7 +367,7 @@ read_again:
|
||||
t128_log("Updating DMA\n");
|
||||
ncr->mode &= ~MODE_DMA;
|
||||
scsi_bus->tx_mode = PIO_TX_BUS;
|
||||
timer_on_auto(&t128->timer, 10.0);
|
||||
t128->block_loaded = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -513,7 +506,7 @@ t128_init(const device_t *info)
|
||||
scsi_bus->bus_device = ncr->bus;
|
||||
scsi_bus->timer = ncr->timer;
|
||||
scsi_bus->priv = ncr->priv;
|
||||
t128->status = 0x00 /*0x04*/;
|
||||
t128->status = 0x00;
|
||||
t128->host_pos = 512;
|
||||
if (!t128->bios_enabled && !(info->flags & DEVICE_MCA))
|
||||
t128->status |= 0x80;
|
||||
@@ -528,7 +521,6 @@ t128_init(const device_t *info)
|
||||
scsi_bus->speed = 0.2;
|
||||
scsi_bus->divider = 1.0;
|
||||
scsi_bus->multi = 1.0;
|
||||
|
||||
return t128;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user