Fixed MSR writability, fixes Error D on the IBM PCjr.

This commit is contained in:
OBattler
2023-02-16 02:43:06 +01:00
parent 3d480a6ffc
commit f6c8080bdc

View File

@@ -203,7 +203,10 @@ serial_receive_timer(void *priv)
static void static void
write_fifo(serial_t *dev, uint8_t dat) write_fifo(serial_t *dev, uint8_t dat)
{ {
serial_log("write_fifo(%08X, %02X, %i, %i)\n", dev, dat, (dev->type >= SERIAL_16550) && dev->fifo_enabled, dev->rcvr_fifo_pos % dev->rcvr_fifo_len); serial_log("write_fifo(%08X, %02X, %i, %i)\n", dev, dat,
(dev->type >= SERIAL_16550) && dev->fifo_enabled,
((dev->type >= SERIAL_16550) && dev->fifo_enabled) ?
(dev->rcvr_fifo_pos % dev->rcvr_fifo_len) : 0);
if ((dev->type >= SERIAL_16550) && dev->fifo_enabled) { if ((dev->type >= SERIAL_16550) && dev->fifo_enabled) {
/* FIFO mode. */ /* FIFO mode. */
@@ -405,7 +408,7 @@ serial_set_dsr(serial_t *dev, uint8_t enabled)
return; return;
dev->msr &= ~0x2; dev->msr &= ~0x2;
dev->msr |= !!((dev->msr & 0x20) ^ (enabled << 5)) << 1; dev->msr |= ((dev->msr & 0x20) ^ ((!!enabled) << 5)) >> 4;
dev->msr &= ~0x20; dev->msr &= ~0x20;
dev->msr |= (!!enabled) << 5; dev->msr |= (!!enabled) << 5;
dev->msr_set &= ~0x20; dev->msr_set &= ~0x20;
@@ -424,7 +427,7 @@ serial_set_cts(serial_t *dev, uint8_t enabled)
return; return;
dev->msr &= ~0x1; dev->msr &= ~0x1;
dev->msr |= !!((dev->msr & 0x10) ^ (enabled << 4)); dev->msr |= ((dev->msr & 0x10) ^ ((!!enabled) << 4)) >> 4;
dev->msr &= ~0x10; dev->msr &= ~0x10;
dev->msr |= (!!enabled) << 4; dev->msr |= (!!enabled) << 4;
dev->msr_set &= ~0x10; dev->msr_set &= ~0x10;
@@ -443,7 +446,7 @@ serial_set_dcd(serial_t *dev, uint8_t enabled)
return; return;
dev->msr &= ~0x8; dev->msr &= ~0x8;
dev->msr |= !!((dev->msr & 0x80) ^ (enabled << 7)); dev->msr |= ((dev->msr & 0x80) ^ ((!!enabled) << 7)) >> 4;
dev->msr &= ~0x80; dev->msr &= ~0x80;
dev->msr |= (!!enabled) << 7; dev->msr |= (!!enabled) << 7;
dev->msr_set &= ~0x80; dev->msr_set &= ~0x80;
@@ -470,7 +473,8 @@ serial_write(uint16_t addr, uint8_t val, void *p)
serial_t *dev = (serial_t *) p; serial_t *dev = (serial_t *) p;
uint8_t new_msr, old; uint8_t new_msr, old;
serial_log("UART: Write %02X to port %02X\n", val, addr); // serial_log("UART: Write %02X to port %02X\n", val, addr);
serial_log("UART: [%04X:%08X] Write %02X to port %02X\n", CS, cpu_state.pc, val, addr);
cycles -= ISA_CYCLES(8); cycles -= ISA_CYCLES(8);
@@ -616,7 +620,11 @@ serial_write(uint16_t addr, uint8_t val, void *p)
serial_update_ints(dev); serial_update_ints(dev);
break; break;
case 6: case 6:
dev->msr = (val & 0xf0) | (dev->msr & 0x0f); // dev->msr = (val & 0xf0) | (dev->msr & 0x0f);
// dev->msr = val;
/* The actual condition bits of the MSR are read-only, but the delta bits are
undocumentedly writable, and the PCjr BIOS uses them to raise MSR interrupts. */
dev->msr = (dev->msr & 0xf0) | (val & 0x0f);
if (dev->msr & 0x0f) if (dev->msr & 0x0f)
dev->int_status |= SERIAL_INT_MSR; dev->int_status |= SERIAL_INT_MSR;
serial_update_ints(dev); serial_update_ints(dev);
@@ -723,7 +731,8 @@ serial_read(uint16_t addr, void *p)
break; break;
} }
serial_log("UART: Read %02X from port %02X\n", ret, addr); // serial_log("UART: Read %02X from port %02X\n", ret, addr);
serial_log("UART: [%04X:%08X] Read %02X from port %02X\n", CS, cpu_state.pc, ret, addr);
return ret; return ret;
} }
@@ -873,6 +882,9 @@ serial_init(const device_t *info)
/* Default to 1200,N,7. */ /* Default to 1200,N,7. */
dev->dlab = 96; dev->dlab = 96;
dev->fcr = 0x06; dev->fcr = 0x06;
if (info->local == SERIAL_8250_PCJR)
dev->clock_src = 1789500.0;
else
dev->clock_src = 1843200.0; dev->clock_src = 1843200.0;
timer_add(&dev->transmit_timer, serial_transmit_timer, dev, 0); timer_add(&dev->transmit_timer, serial_transmit_timer, dev, 0);
timer_add(&dev->timeout_timer, serial_timeout_timer, dev, 0); timer_add(&dev->timeout_timer, serial_timeout_timer, dev, 0);