From 6d5fd97cda4a2703bbce7bc865993eb56085e36d Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 19 Sep 2024 19:43:38 +0200 Subject: [PATCH 01/13] UMC UM8886: Invert PCI IRQ edge/level flags. --- src/chipset/umc_8886.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/chipset/umc_8886.c b/src/chipset/umc_8886.c index f2a89aed4..2b867c000 100644 --- a/src/chipset/umc_8886.c +++ b/src/chipset/umc_8886.c @@ -180,10 +180,10 @@ umc_8886_irq_recalc(umc_8886_t *dev) irq_routing = (conf[0x46] & 0x08) ? (conf[0x44] & 0x0f) : PCI_IRQ_DISABLED; pci_set_irq_routing(PCI_INTD, irq_routing); - pci_set_irq_level(PCI_INTA, !!(conf[0x47] & 0x01)); - pci_set_irq_level(PCI_INTB, !!(conf[0x47] & 0x02)); - pci_set_irq_level(PCI_INTC, !!(conf[0x47] & 0x04)); - pci_set_irq_level(PCI_INTD, !!(conf[0x47] & 0x08)); + pci_set_irq_level(PCI_INTA, !(conf[0x47] & 0x01)); + pci_set_irq_level(PCI_INTB, !(conf[0x47] & 0x02)); + pci_set_irq_level(PCI_INTC, !(conf[0x47] & 0x04)); + pci_set_irq_level(PCI_INTD, !(conf[0x47] & 0x08)); } static void From ea878410b0ff2fc8d6ff54b641b7396aaa584006 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 20 Sep 2024 13:36:01 +0200 Subject: [PATCH 02/13] Serial mouse, microtouch, and modem: Add some more sanity checks. --- src/device/mouse_microtouch_touchscreen.c | 2 ++ src/device/mouse_serial.c | 3 ++- src/network/net_modem.c | 25 +++++++++++++++-------- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/device/mouse_microtouch_touchscreen.c b/src/device/mouse_microtouch_touchscreen.c index 0aa0ce727..ce87a4b68 100644 --- a/src/device/mouse_microtouch_touchscreen.c +++ b/src/device/mouse_microtouch_touchscreen.c @@ -322,6 +322,8 @@ void mtouch_write_to_host(void *priv) { mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; + if (dev->serial == NULL) + goto no_write_to_machine; if ((dev->serial->type >= SERIAL_16550) && dev->serial->fifo_enabled) { if (fifo_get_full(dev->serial->rcvr_fifo)) { goto no_write_to_machine; diff --git a/src/device/mouse_serial.c b/src/device/mouse_serial.c index 08aee09d8..afc662a19 100644 --- a/src/device/mouse_serial.c +++ b/src/device/mouse_serial.c @@ -142,7 +142,8 @@ sermouse_transmit_byte(mouse_t *dev, int do_next) if (dev->buf_pos == 0) dev->acc_time = 0.0; - serial_write_fifo(dev->serial, dev->buf[dev->buf_pos]); + if (dev->serial) + serial_write_fifo(dev->serial, dev->buf[dev->buf_pos]); if (do_next) { dev->buf_pos = (dev->buf_pos + 1) % dev->buf_len; diff --git a/src/network/net_modem.c b/src/network/net_modem.c index 6addec352..bb312ec31 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -434,7 +434,7 @@ host_to_modem_cb(void *priv) { modem_t *modem = (modem_t *) priv; - if (modem->in_warmup) + if (modem->in_warmup || (modem->serial == NULL)) goto no_write_to_machine; if ((modem->serial->type >= SERIAL_16550) && modem->serial->fifo_enabled) { @@ -621,10 +621,12 @@ modem_enter_idle_state(modem_t *modem) } } - serial_set_cts(modem->serial, 1); - serial_set_dsr(modem->serial, 1); - serial_set_dcd(modem->serial, (!modem->dcdmode ? 1 : 0)); - serial_set_ri(modem->serial, 0); + if (modem->serial != NULL) { + serial_set_cts(modem->serial, 1); + serial_set_dsr(modem->serial, 1); + serial_set_dcd(modem->serial, (!modem->dcdmode ? 1 : 0)); + serial_set_ri(modem->serial, 0); + } } void @@ -640,8 +642,11 @@ modem_enter_connected_state(modem_t *modem) plat_netsocket_close(modem->serversocket); modem->serversocket = -1; memset(&modem->telClient, 0, sizeof(modem->telClient)); - serial_set_dcd(modem->serial, 1); - serial_set_ri(modem->serial, 0); + + if (modem->serial != NULL) { + serial_set_dcd(modem->serial, 1); + serial_set_ri(modem->serial, 0); + } } void @@ -1391,7 +1396,8 @@ modem_cmdpause_timer_callback(void *priv) } else { modem->ringing = true; modem_send_res(modem, ResRING); - serial_set_ri(modem->serial, !serial_get_ri(modem->serial)); + if (modem->serial != NULL) + serial_set_ri(modem->serial, !serial_get_ri(modem->serial)); modem->ringtimer = 3000; modem->reg[MREG_RING_COUNT] = 0; } @@ -1405,7 +1411,8 @@ modem_cmdpause_timer_callback(void *priv) return; } modem_send_res(modem, ResRING); - serial_set_ri(modem->serial, !serial_get_ri(modem->serial)); + if (modem->serial != NULL) + serial_set_ri(modem->serial, !serial_get_ri(modem->serial)); modem->ringtimer = 3000; } From 1acafb261600bdc324d59a9258cbc98416db2958 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 21 Sep 2024 03:14:36 +0200 Subject: [PATCH 03/13] 86F: Fix the physical hole retention logic, fixes PROLOK-protected 86F images after the first run. --- src/floppy/fdd_86f.c | 53 +++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index 35ddbb1dd..0fed9bd3a 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -1098,9 +1098,9 @@ d86f_get_bit(int drive, int side) /* In some cases, misindentification occurs so we need to make sure the surface data array is not not NULL. */ if (d86f_has_surface_desc(drive) && dev->track_surface_data[side]) { - if (d86f_reverse_bytes(drive)) { + if (d86f_reverse_bytes(drive)) surface_data = dev->track_surface_data[side][track_word] & 0xFF; - } else { + else { surface_data = (dev->track_surface_data[side][track_word] & 0xFF) << 8; surface_data |= (dev->track_surface_data[side][track_word] >> 8); } @@ -1150,9 +1150,9 @@ d86f_put_bit(int drive, int side, int bit) } if (d86f_has_surface_desc(drive)) { - if (d86f_reverse_bytes(drive)) { + if (d86f_reverse_bytes(drive)) surface_data = dev->track_surface_data[side][track_word] & 0xFF; - } else { + else { surface_data = (dev->track_surface_data[side][track_word] & 0xFF) << 8; surface_data |= (dev->track_surface_data[side][track_word] >> 8); } @@ -1177,9 +1177,9 @@ d86f_put_bit(int drive, int side, int bit) surface_data &= ~(1 << track_bit); surface_data |= (surface_bit << track_bit); - if (d86f_reverse_bytes(drive)) { + if (d86f_reverse_bytes(drive)) dev->track_surface_data[side][track_word] = surface_data; - } else { + else { dev->track_surface_data[side][track_word] = (surface_data & 0xFF) << 8; dev->track_surface_data[side][track_word] |= (surface_data >> 8); } @@ -1191,9 +1191,9 @@ d86f_put_bit(int drive, int side, int bit) encoded_data &= ~(1 << track_bit); encoded_data |= (current_bit << track_bit); - if (d86f_reverse_bytes(drive)) { + if (d86f_reverse_bytes(drive)) d86f_handler[drive].encoded_data(drive, side)[track_word] = encoded_data; - } else { + else { d86f_handler[drive].encoded_data(drive, side)[track_word] = (encoded_data & 0xFF) << 8; d86f_handler[drive].encoded_data(drive, side)[track_word] |= (encoded_data >> 8); } @@ -1833,7 +1833,6 @@ d86f_write_direct_common(int drive, int side, uint16_t byte, uint8_t type, uint3 uint16_t mask_data; uint16_t mask_surface; uint16_t mask_hole; - uint16_t mask_fuzzy; decoded_t dbyte; decoded_t dpbyte; @@ -1866,13 +1865,18 @@ d86f_write_direct_common(int drive, int side, uint16_t byte, uint8_t type, uint3 dev->preceding_bit[side] = encoded_byte & 1; if (d86f_has_surface_desc(drive)) { - mask_data = dev->track_encoded_data[side][pos] ^= 0xFFFF; + /* Inverted track data, clear bits are now set. */ + mask_data = ~dev->track_encoded_data[side][pos]; + /* Surface data. */ mask_surface = dev->track_surface_data[side][pos]; - mask_hole = (mask_surface & mask_data) ^ 0xFFFF; /* This will retain bits that are both fuzzy and 0, therefore physical holes. */ - encoded_byte &= mask_hole; /* Filter out physical hole bits from the encoded data. */ - mask_data ^= 0xFFFF; /* Invert back so bits 1 are 1 again. */ - mask_fuzzy = (mask_surface & mask_data) ^ 0xFFFF; /* All fuzzy bits are 0. */ - dev->track_surface_data[side][pos] &= mask_fuzzy; /* Remove fuzzy bits (but not hole bits) from the surface mask, making them regular again. */ + + /* Hole = surface & ~data, so holes are one. */ + mask_hole = mask_surface & mask_data; + /* Hole bits are ones again, set the surface data to that. */ + dev->track_surface_data[side][pos] = mask_hole; + + /* Force the data of any hole to zero. */ + encoded_byte &= ~mask_hole; } dev->track_encoded_data[side][pos] = encoded_byte; @@ -2909,15 +2913,14 @@ d86f_decompose_encoded_buffer(int drive, int side) if (d86f_has_surface_desc(drive)) { /* Source image has surface description data, so we have some more handling to do. We need hole masks for both buffers. Holes have data bit clear and surface bit set. */ - temp = src1[i] & (src1_s[i] ^ 0xffff); - temp2 = src2[i] & (src2_s[i] ^ 0xffff); - src1[i] = dst[i] & temp; - src1_s[i] = temp ^ 0xffff; - src2[i] = dst[i] & temp2; - src2_s[i] = temp2 ^ 0xffff; - } else { + temp = ~src1[i] & src1_s[i]; + temp2 = ~src2[i] & src2_s[i]; + src1[i] = dst[i] & ~temp; + src1_s[i] = temp; + src2[i] = dst[i] & ~temp2; + src2_s[i] = temp2; + } else src1[i] = src2[i] = dst[i]; - } } } @@ -3544,9 +3547,9 @@ d86f_load(int drive, char *fn) writeprot[drive] = 1; } - if (ui_writeprot[drive]) { + if (ui_writeprot[drive]) writeprot[drive] = 1; - } + fwriteprot[drive] = writeprot[drive]; fseek(dev->fp, 0, SEEK_END); From 43d93843fac06746f26275d858630a8c49a15abb Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 21 Sep 2024 05:55:39 +0200 Subject: [PATCH 04/13] 86F: More fixes. --- src/floppy/fdd_86f.c | 49 ++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index 0fed9bd3a..5a5eec398 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -628,10 +628,12 @@ d86f_get_array_size(int drive, int side, int words) int hole; int rm; int ssd; + int mpc; rm = d86f_get_rpm_mode(drive); ssd = d86f_get_speed_shift_dir(drive); - hole = (d86f_handler[drive].disk_flags(drive) & 6) >> 1; + hole = (d86f_handler[drive].disk_flags(drive) >> 1) & 3; + mpc = (d86f_handler[drive].disk_flags(drive) >> 13) & 1; if (!rm && ssd) /* Special case - extra bit cells size specifies entire array size. */ array_size = 0; @@ -703,13 +705,20 @@ d86f_get_array_size(int drive, int side, int words) array_size <<= 4; array_size += d86f_handler[drive].extra_bit_cells(drive, side); - if (array_size & 15) - array_size = (array_size >> 4) + 1; - else - array_size = (array_size >> 4); + if (mpc && !words) { + if (array_size & 7) + array_size = (array_size >> 3) + 1; + else + array_size = (array_size >> 3); + } else { + if (array_size & 15) + array_size = (array_size >> 4) + 1; + else + array_size = (array_size >> 4); - if (!words) - array_size <<= 1; + if (!words) + array_size <<= 1; + } return array_size; } @@ -2869,22 +2878,22 @@ d86f_construct_encoded_buffer(int drive, int side) /* Source image has surface description data, so we have some more handling to do. */ src1_fuzm = src1[i] & src1_s[i]; src2_fuzm = src2[i] & src2_s[i]; - dst_fuzm = src1_fuzm | src2_fuzm; /* The bits that remain set are fuzzy in either one or - the other or both. */ - src1_holm = src1[i] | (src1_s[i] ^ 0xffff); - src2_holm = src2[i] | (src2_s[i] ^ 0xffff); - dst_holm = (src1_holm & src2_holm) ^ 0xffff; /* The bits that remain set are holes in both. */ - dst_neim = (dst_fuzm | dst_holm) ^ 0xffff; /* The bits that remain set are those that are neither - fuzzy nor are holes in both. */ + dst_fuzm = src1_fuzm | src2_fuzm; /* The bits that remain set are fuzzy in either one or + the other or both. */ + src1_holm = ~src1[i] & src1_s[i]; + src2_holm = ~src2[i] & src2_s[i]; + dst_holm = src1_holm & src2_holm; /* The bits that remain set are holes in both. */ + dst_neim = ~(dst_fuzm | dst_holm); /* The bits that remain set are those that are neither + fuzzy nor are holes in both. */ src1_d = src1[i] & dst_neim; src2_d = src2[i] & dst_neim; - dst_s[i] = (dst_neim ^ 0xffff); /* The set bits are those that are either fuzzy or are - holes in both. */ - dst[i] = (src1_d | src2_d); /* Initial data is remaining data from Source 1 and - Source 2. */ - dst[i] |= dst_fuzm; /* Add to it the fuzzy bytes (holes have surface bit set - but data bit clear). */ + dst_s[i] = ~dst_neim; /* The set bits are those that are either fuzzy or are + holes in both. */ + dst[i] = (src1_d | src2_d); /* Initial data is remaining data from Source 1 and + Source 2. */ + dst[i] |= dst_fuzm; /* Add to it the fuzzy bytes (holes have surface bit set + but data bit clear). */ } else { /* No surface data, the handling is much simpler - a simple OR. */ dst[i] = src1[i] | src2[i]; From 1c03839965b3653ec83aac4ca36b7912f94bfffe Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 21 Sep 2024 12:00:05 +0200 Subject: [PATCH 05/13] IDE: Restore RAM disk timings to how they were before the timings support was are (non-RAM disk timings are not affected), allows OS/2 Warp 3 to successfully install. --- src/disk/hdc_ide.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 3793f778b..d13c18a64 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -1252,7 +1252,10 @@ ide_write_data(ide_t *ide, const uint16_t val) const double xfer_time = ide_get_xfer_time(ide, 512); const double wait_time = seek_time + xfer_time; if (ide->command == WIN_WRITE_MULTIPLE) { - if ((ide->blockcount + 1) >= ide->blocksize || ide->tf->secount == 1) { + if (hdd[ide->hdd_num].speed_preset == 0) { + ide->pending_delay = 0; + ide_callback(ide); + } else if ((ide->blockcount + 1) >= ide->blocksize || ide->tf->secount == 1) { ide_set_callback(ide, seek_time + xfer_time + ide->pending_delay); ide->pending_delay = 0; } else { @@ -1607,9 +1610,13 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) ide->sc->callback = 100.0 * IDE_TIME; ide_set_callback(ide, 100.0 * IDE_TIME); } else { - double seek_time = hdd_seek_get_time(&hdd[ide->hdd_num], (val & 0x60) ? - ide_get_sector(ide) : 0, HDD_OP_SEEK, 0, 0.0); - ide_set_callback(ide, seek_time); + if (hdd[ide->hdd_num].speed_preset == 0) + ide_set_callback(ide, 100.0 * IDE_TIME); + else { + double seek_time = hdd_seek_get_time(&hdd[ide->hdd_num], (val & 0x60) ? + ide_get_sector(ide) : 0, HDD_OP_SEEK, 0, 0.0); + ide_set_callback(ide, seek_time); + } } break; @@ -1652,6 +1659,10 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) ide_get_sector(ide), sec_count); double xfer_time = ide_get_xfer_time(ide, 512 * sec_count); wait_time = seek_time > xfer_time ? seek_time : xfer_time; + } else if ((val == WIN_READ_MULTIPLE) && (hdd[ide->hdd_num].speed_preset == 0)) { + ide_set_callback(ide, 200.0 * IDE_TIME); + ide->do_initial_read = 1; + break; } else if ((val == WIN_READ_MULTIPLE) && (ide->blocksize > 0)) { sec_count = ide->tf->secount ? ide->tf->secount : 256; if (sec_count > ide->blocksize) @@ -1848,7 +1859,9 @@ ide_read_data(ide_t *ide) ide_next_sector(ide); ide->tf->atastat = BSY_STAT | READY_STAT | DSC_STAT; if (ide->command == WIN_READ_MULTIPLE) { - if (!ide->blockcount) { + if (hdd[ide->hdd_num].speed_preset == 0) + ide_callback(ide); + else if (!ide->blockcount) { uint32_t cnt = ide->tf->secount ? ide->tf->secount : 256; if (cnt > ide->blocksize) From 3556232c21ff4f52c3566d3f22eb39c4b5b2c147 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 22 Sep 2024 05:44:25 +0200 Subject: [PATCH 06/13] IDE: Status now once again returns 0x00 on an absent slave with a present master, fixes #4843. --- src/disk/hdc_ide.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index d13c18a64..1ec054de9 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -1901,8 +1901,7 @@ ide_status(ide_t *ide, ide_t *ide_other, int ch) /* On real hardware, a slave with a present master always returns a status of 0x00. Confirmed by the ATA-3 and ATA-4 specifications. */ - // ret = 0x00; - ret = 0x01; + ret = 0x00; } else { ret = ide->tf->atastat; if (ide->type == IDE_ATAPI) From cc67f712b05d966125faed28b6c25318488811b8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 22 Sep 2024 07:11:09 +0200 Subject: [PATCH 07/13] RTL8139C+: Return correct PCI revision 0x10, fixes #4839. --- src/network/net_rtl8139.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index bc44b3fb1..335e3297a 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -3111,7 +3111,7 @@ rtl8139_pci_read(UNUSED(int func), int addr, void *priv) case 0x05: return s->pci_conf[addr & 0xFF] & 1; case 0x08: - return 0x20; + return 0x10; case 0x09: return 0x0; case 0x0a: From 8593b175fd5807f36dd4cc6dd052ec7c155dbd49 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 22 Sep 2024 10:22:03 +0200 Subject: [PATCH 08/13] More slight fixes to the RTL8139C+. --- src/network/net_rtl8139.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index 335e3297a..0b00d589a 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -352,7 +352,8 @@ enum chip_flags { #define RTL8139_PCI_REVID_8139 0x10 #define RTL8139_PCI_REVID_8139CPLUS 0x20 -#define RTL8139_PCI_REVID RTL8139_PCI_REVID_8139CPLUS +/* Return 0x10 - the RTL8139C+ datasheet and Windows 2000 driver both confirm this. */ +#define RTL8139_PCI_REVID RTL8139_PCI_REVID_8139 #pragma pack(push, 1) typedef struct RTL8139TallyCounters { @@ -3111,7 +3112,7 @@ rtl8139_pci_read(UNUSED(int func), int addr, void *priv) case 0x05: return s->pci_conf[addr & 0xFF] & 1; case 0x08: - return 0x10; + return RTL8139_PCI_REVID; case 0x09: return 0x0; case 0x0a: From 2afa424261d28081e83d025db2e5a1e514ddf399 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 22 Sep 2024 14:39:50 +0200 Subject: [PATCH 09/13] Sound Blaster / ESS: DSP reset now properly disables DMA, fixes the OS/2 ESS ES688 driver. --- src/dma.c | 2 -- src/sound/snd_sb_dsp.c | 62 ++++++++++++++++++++++++------------------ 2 files changed, 36 insertions(+), 28 deletions(-) diff --git a/src/dma.c b/src/dma.c index 8bf60cdc8..86c29fe26 100644 --- a/src/dma.c +++ b/src/dma.c @@ -814,8 +814,6 @@ dma16_read(uint16_t addr, UNUSED(void *priv)) case 7: /*Count registers*/ dma_wp[1] ^= 1; count = dma[channel].cc/* + 1*/; - // if (count > dma[channel].cb) - // count = 0x0000; if (dma_wp[1]) ret = count & 0xff; else diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 6e9a32086..4cfd2c7bb 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -446,11 +446,47 @@ sb_dsp_set_mpu(sb_dsp_t *dsp, mpu_t *mpu) mpu401_irq_attach(mpu, sb_dsp_irq_update, sb_dsp_irq_pending, dsp); } +static void +sb_stop_dma(const sb_dsp_t *dsp) +{ + dma_set_drq(dsp->sb_8_dmanum, 0); + + if (dsp->sb_16_dmanum != 0xff) { + if (dsp->sb_16_dmanum == 4) + dma_set_drq(dsp->sb_8_dmanum, 0); + else + dma_set_drq(dsp->sb_16_dmanum, 0); + } + + if (dsp->sb_16_8_dmanum != 0xff) + dma_set_drq(dsp->sb_16_8_dmanum, 0); +} + +static void +sb_finish_dma(sb_dsp_t *dsp) +{ + if (dsp->ess_playback_mode) { + ESSreg(0xB8) &= ~0x01; + dma_set_drq(dsp->sb_8_dmanum, 0); + } else + sb_stop_dma(dsp); +} + void sb_dsp_reset(sb_dsp_t *dsp) { midi_clear_buffer(); + if (dsp->sb_8_enable) { + dsp->sb_8_enable = 0; + sb_finish_dma(dsp); + } + + if (dsp->sb_16_enable) { + dsp->sb_16_enable = 0; + sb_finish_dma(dsp); + } + timer_disable(&dsp->output_timer); timer_disable(&dsp->input_timer); @@ -565,22 +601,6 @@ sb_resume_dma(const sb_dsp_t *dsp, const int is_8) } } -static void -sb_stop_dma(const sb_dsp_t *dsp) -{ - dma_set_drq(dsp->sb_8_dmanum, 0); - - if (dsp->sb_16_dmanum != 0xff) { - if (dsp->sb_16_dmanum == 4) - dma_set_drq(dsp->sb_8_dmanum, 0); - else - dma_set_drq(dsp->sb_16_dmanum, 0); - } - - if (dsp->sb_16_8_dmanum != 0xff) - dma_set_drq(dsp->sb_16_8_dmanum, 0); -} - void sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) { @@ -2206,16 +2226,6 @@ sb_dsp_dma_attach(sb_dsp_t *dsp, dsp->dma_priv = priv; } -static void -sb_finish_dma(sb_dsp_t *dsp) -{ - if (dsp->ess_playback_mode) { - ESSreg(0xB8) &= ~0x01; - dma_set_drq(dsp->sb_8_dmanum, 0); - } else - sb_stop_dma(dsp); -} - void sb_espcm_fifoctl_run(sb_dsp_t *dsp) { From 8e84dc04c3182b91997681ba78cb103491ad3628 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 22 Sep 2024 20:31:22 +0200 Subject: [PATCH 10/13] PVGA changes of the day (September 22nd, 2024) Correct the memory size (and its bits) of said chips and reorganize them. --- src/video/vid_paradise.c | 59 ++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c index 70f90d6d8..73902345d 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -204,6 +204,14 @@ paradise_out(uint16_t addr, uint8_t val, void *priv) return; case 0x0b: svga->gdcreg[0x0b] = val; + svga->gdcreg[0x0b] &= ~0xc0; + if (paradise->memory == 1024) + svga->gdcreg[0x0b] |= 0xc0; + else if (paradise->memory == 512) + svga->gdcreg[0x0b] |= 0x80; + else + svga->gdcreg[0x0b] |= 0x40; + paradise_remap(paradise); return; case 0x0e: @@ -282,6 +290,7 @@ paradise_remap(paradise_t *paradise) paradise->write_bank[1] = paradise->write_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); } + /*There are separate drivers for 1M and 512K/256K versions of the PVGA chips.*/ if ((svga->gdcreg[0x0b] & 0xc0) < 0xc0) { paradise->read_bank[1] &= 0x7ffff; paradise->write_bank[1] &= 0x7ffff; @@ -482,7 +491,7 @@ paradise_readw(uint32_t addr, void *priv) } void * -paradise_init(const device_t *info, uint32_t memsize) +paradise_init(const device_t *info, uint32_t memory) { paradise_t *paradise = malloc(sizeof(paradise_t)); svga_t *svga = ¶dise->svga; @@ -493,35 +502,35 @@ paradise_init(const device_t *info, uint32_t memsize) else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_paradise_wd90c); - paradise->memory = memsize >> 10; + paradise->memory = memory; switch (info->local) { case PVGA1A: - svga_init(info, svga, paradise, memsize, /*256kb*/ + svga_init(info, svga, paradise, (memory << 10), /*256kb default*/ paradise_recalctimings, paradise_in, paradise_out, NULL, NULL); - paradise->vram_mask = memsize - 1; - svga->decode_mask = memsize - 1; + paradise->vram_mask = (memory << 10) - 1; + svga->decode_mask = (memory << 10) - 1; break; case WD90C11: - svga_init(info, svga, paradise, 1 << 19, /*512kb*/ + svga_init(info, svga, paradise, (memory << 10), /*512kb default*/ paradise_recalctimings, paradise_in, paradise_out, NULL, NULL); - paradise->vram_mask = (1 << 19) - 1; - svga->decode_mask = (1 << 19) - 1; + paradise->vram_mask = (memory << 10) - 1; + svga->decode_mask = (memory << 10) - 1; break; case WD90C30: - svga_init(info, svga, paradise, memsize, + svga_init(info, svga, paradise, (memory << 10), paradise_recalctimings, paradise_in, paradise_out, NULL, NULL); - paradise->vram_mask = memsize - 1; - svga->decode_mask = memsize - 1; + paradise->vram_mask = (memory << 10) - 1; + svga->decode_mask = (memory << 10) - 1; svga->ramdac = device_add(&sc11487_ramdac_device); /*Actually a Winbond W82c487-80, probably a clone.*/ break; @@ -566,7 +575,7 @@ paradise_init(const device_t *info, uint32_t memsize) static void * paradise_pvga1a_ncr3302_init(const device_t *info) { - paradise_t *paradise = paradise_init(info, 1 << 18); + paradise_t *paradise = paradise_init(info, 256); if (paradise) rom_init(¶dise->bios_rom, "roms/machines/3302/c000-wd_1987-1989-740011-003058-019c.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); @@ -577,7 +586,7 @@ paradise_pvga1a_ncr3302_init(const device_t *info) static void * paradise_pvga1a_pc2086_init(const device_t *info) { - paradise_t *paradise = paradise_init(info, 1 << 18); + paradise_t *paradise = paradise_init(info, 256); if (paradise) rom_init(¶dise->bios_rom, "roms/machines/pc2086/40186.ic171", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); @@ -588,7 +597,7 @@ paradise_pvga1a_pc2086_init(const device_t *info) static void * paradise_pvga1a_pc3086_init(const device_t *info) { - paradise_t *paradise = paradise_init(info, 1 << 18); + paradise_t *paradise = paradise_init(info, 256); if (paradise) rom_init(¶dise->bios_rom, "roms/machines/pc3086/c000.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); @@ -600,12 +609,9 @@ static void * paradise_pvga1a_standalone_init(const device_t *info) { paradise_t *paradise; - uint32_t memory = 512; + uint32_t memsize = device_get_config_int("memory"); - memory = device_get_config_int("memory"); - memory <<= 10; - - paradise = paradise_init(info, memory); + paradise = paradise_init(info, memsize); if (paradise) rom_init(¶dise->bios_rom, "roms/video/pvga1a/BIOS.BIN", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); @@ -622,7 +628,7 @@ paradise_pvga1a_standalone_available(void) static void * paradise_wd90c11_megapc_init(const device_t *info) { - paradise_t *paradise = paradise_init(info, 0); + paradise_t *paradise = paradise_init(info, 512); if (paradise) rom_init_interleaved(¶dise->bios_rom, @@ -636,7 +642,7 @@ paradise_wd90c11_megapc_init(const device_t *info) static void * paradise_wd90c11_standalone_init(const device_t *info) { - paradise_t *paradise = paradise_init(info, 0); + paradise_t *paradise = paradise_init(info, 512); if (paradise) rom_init(¶dise->bios_rom, "roms/video/wd90c11/WD90C11.VBI", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); @@ -654,12 +660,9 @@ static void * paradise_wd90c30_standalone_init(const device_t *info) { paradise_t *paradise; - uint32_t memory = 512; + uint32_t memsize = device_get_config_int("memory"); - memory = device_get_config_int("memory"); - memory <<= 10; - - paradise = paradise_init(info, memory); + paradise = paradise_init(info, memsize); if (paradise) rom_init(¶dise->bios_rom, "roms/video/wd90c30/90C30-LR.VBI", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); @@ -818,6 +821,10 @@ static const device_config_t paradise_wd90c30_config[] = { .type = CONFIG_SELECTION, .default_int = 1024, .selection = { + { + .description = "256 kB", + .value = 256 + }, { .description = "512 kB", .value = 512 From 705d29342059d14f07c65871a563d3f7f7f366c3 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 22 Sep 2024 21:05:10 +0200 Subject: [PATCH 11/13] Mach32 and clock changes of the day (September 22nd, 2024) 1. Going from screenshots of the Mach32 chips, they all have the ati18811-1 clock regardless of the bus type, whilst the Mach8 has an ati18812, which is actually a ati18811-0 2. Unbreak the NS3.1 Mach32 driver, ergo, don't block the LFB processing. --- src/video/vid_ati_mach8.c | 36 +++++++++--------------------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index b170ae205..46d884adf 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2592,6 +2592,8 @@ mach_recalctimings(svga_t *svga) } svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + if (mach->accel.clock_sel & 0x40) + svga->clock8514 *= 2; if (dev->interlace) dev->dispend >>= 1; @@ -3532,13 +3534,14 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0xaef: WRITE8(port, mach->cursor_offset_lo_reg, val); mach->cursor_offset_lo = mach->cursor_offset_lo_reg; + dev->hwcursor.addr = ((mach->cursor_offset_lo | (mach->cursor_offset_hi << 16)) << 2); break; case 0xeee: case 0xeef: WRITE8(port, mach->cursor_offset_hi_reg, val); mach->cursor_offset_hi = mach->cursor_offset_hi_reg & 0x0f; - dev->hwcursor.addr = (mach->cursor_offset_lo | (mach->cursor_offset_hi << 16)) << 2; + dev->hwcursor.addr = ((mach->cursor_offset_lo | (mach->cursor_offset_hi << 16)) << 2); dev->hwcursor.ena = !!(mach->cursor_offset_hi_reg & 0x8000); break; @@ -4633,9 +4636,6 @@ mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach, svga_t cycles -= svga->monitor->mon_video_timing_write_b; if (linear) { - addr &= svga->decode_mask; - if (addr >= dev->vram_size) - return; addr &= dev->vram_mask; dev->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; dev->vram[addr] = val; @@ -4825,9 +4825,6 @@ mach32_writew_linear(uint32_t addr, uint16_t val, mach_t *mach) cycles -= svga->monitor->mon_video_timing_write_w; - addr &= svga->decode_mask; - if (addr >= dev->vram_size) - return; addr &= dev->vram_mask; dev->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; *(uint16_t *) &dev->vram[addr] = val; @@ -4841,9 +4838,6 @@ mach32_writel_linear(uint32_t addr, uint32_t val, mach_t *mach) cycles -= svga->monitor->mon_video_timing_write_l; - addr &= svga->decode_mask; - if (addr >= dev->vram_size) - return; addr &= dev->vram_mask; dev->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; *(uint32_t *) &dev->vram[addr] = val; @@ -4862,10 +4856,6 @@ mach32_read_common(uint32_t addr, int linear, mach_t *mach, svga_t *svga) cycles -= svga->monitor->mon_video_timing_read_b; if (linear) { - addr &= svga->decode_mask; - if (addr >= dev->vram_size) - return 0xff; - return dev->vram[addr & dev->vram_mask]; } else { addr = mach32_decode_addr(svga, addr, 0); @@ -5022,10 +5012,6 @@ mach32_readw_linear(uint32_t addr, mach_t *mach) cycles -= svga->monitor->mon_video_timing_read_w; - addr &= svga->decode_mask; - if (addr >= dev->vram_size) - return 0xffff; - return *(uint16_t *) &dev->vram[addr & dev->vram_mask]; } @@ -5037,10 +5023,6 @@ mach32_readl_linear(uint32_t addr, mach_t *mach) cycles -= svga->monitor->mon_video_timing_read_l; - addr &= svga->decode_mask; - if (addr >= dev->vram_size) - return 0xffffffff; - return *(uint32_t *) &dev->vram[addr & dev->vram_mask]; } @@ -5294,7 +5276,7 @@ mach32_hwcursor_draw(svga_t *svga, int displine) int x_pos; int y_pos; - mach_log("BPP=%d.\n", dev->accel_bpp); + mach_log("BPP=%d, displine=%d.\n", dev->accel_bpp, displine); switch (dev->accel_bpp) { default: case 8: @@ -5888,7 +5870,7 @@ mach8_init(const device_t *info) else mach->config1 |= 0x0c; mach->config1 |= 0x0400; - svga->clock_gen = device_add(&ati18811_0_device); + svga->clock_gen = device_add(&ati18811_1_device); } else if (mach->mca_bus) { video_inform(VIDEO_FLAG_TYPE_8514, &timing_mach32_mca); if (is286 && !is386) @@ -5905,11 +5887,11 @@ mach8_init(const device_t *info) else mach->config1 |= 0x0a00; mach->config2 |= 0x2000; - svga->clock_gen = device_add(&ati18811_0_device); + svga->clock_gen = device_add(&ati18811_1_device); } else { video_inform(VIDEO_FLAG_TYPE_8514, &timing_gfxultra_isa); mach->config1 |= 0x0400; - svga->clock_gen = device_add(&ati18811_0_device); + svga->clock_gen = device_add(&ati18811_1_device); } mem_mapping_add(&mach->mmio_linear_mapping, 0, 0, mach32_ap_readb, mach32_ap_readw, mach32_ap_readl, mach32_ap_writeb, mach32_ap_writew, mach32_ap_writel, NULL, MEM_MAPPING_EXTERNAL, mach); mem_mapping_disable(&mach->mmio_linear_mapping); @@ -5926,7 +5908,7 @@ mach8_init(const device_t *info) video_inform(VIDEO_FLAG_TYPE_8514, &timing_gfxultra_isa); mach->config1 = 0x01 | 0x02 | 0x20 | 0x08 | 0x80; mach->config2 = 0x02; - svga->clock_gen = device_add(&ati18810_device); + svga->clock_gen = device_add(&ati18811_0_device); } dev->bpp = 0; svga->getclock = ics2494_getclock; From 9cc8f0ffd4682faa4e3be1356101f0607ceb6730 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 22 Sep 2024 21:29:00 +0200 Subject: [PATCH 12/13] Workaround the volume that is too low on the PAS Plus. And added a note about it. --- src/sound/snd_pas16.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 80a2c9a7b..5ab14d1b8 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -1020,7 +1020,7 @@ pas16_nsc_mixer_reset(nsc_mixer_t *mixer) mixer->lmc1982_regs[LMC1982_REG_ISELECT] = 0x01; mixer->lmc1982_regs[LMC1982_REG_LES] = 0x00; mixer->lmc1982_regs[LMC1982_REG_BASS] = mixer->lmc1982_regs[LMC1982_REG_TREBLE] = 0x06; - mixer->lmc1982_regs[LMC1982_REG_VOL_L] = mixer->lmc1982_regs[LMC1982_REG_VOL_R] = 0x28; + mixer->lmc1982_regs[LMC1982_REG_VOL_L] = mixer->lmc1982_regs[LMC1982_REG_VOL_R] = 0x00; /*0x28*/ /*Note by TC1995: otherwise the volume gets lowered too much*/ mixer->lmc1982_regs[LMC1982_REG_MODE] = 0x05; lmc1982_recalc(mixer); From f2eb6a01610716b39e68e9f5e5d7e1796c487feb Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 23 Sep 2024 05:54:46 +0200 Subject: [PATCH 13/13] UM8886: More IRQ-related bug fixes, including incorrect shifts to the right by 8 instead of 4 bits which was causing all PCI devices to use IRQ 0 instead of their assigned IRQ. --- src/chipset/umc_8886.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/chipset/umc_8886.c b/src/chipset/umc_8886.c index 2b867c000..3ec6885b6 100644 --- a/src/chipset/umc_8886.c +++ b/src/chipset/umc_8886.c @@ -170,20 +170,20 @@ umc_8886_irq_recalc(umc_8886_t *dev) int irq_routing; uint8_t *conf = dev->pci_conf_sb[0]; - irq_routing = (conf[0x46] & 0x01) ? (conf[0x43] >> 8) : PCI_IRQ_DISABLED; + irq_routing = (conf[0x46] & 0x01) ? (conf[0x43] >> 4) : PCI_IRQ_DISABLED; pci_set_irq_routing(PCI_INTA, irq_routing); irq_routing = (conf[0x46] & 0x02) ? (conf[0x43] & 0x0f) : PCI_IRQ_DISABLED; pci_set_irq_routing(PCI_INTB, irq_routing); - irq_routing = (conf[0x46] & 0x04) ? (conf[0x44] >> 8) : PCI_IRQ_DISABLED; + irq_routing = (conf[0x46] & 0x04) ? (conf[0x44] >> 4) : PCI_IRQ_DISABLED; pci_set_irq_routing(PCI_INTC, irq_routing); irq_routing = (conf[0x46] & 0x08) ? (conf[0x44] & 0x0f) : PCI_IRQ_DISABLED; pci_set_irq_routing(PCI_INTD, irq_routing); - pci_set_irq_level(PCI_INTA, !(conf[0x47] & 0x01)); - pci_set_irq_level(PCI_INTB, !(conf[0x47] & 0x02)); - pci_set_irq_level(PCI_INTC, !(conf[0x47] & 0x04)); - pci_set_irq_level(PCI_INTD, !(conf[0x47] & 0x08)); + pci_set_irq_level(PCI_INTA, (conf[0x47] & 0x01)); + pci_set_irq_level(PCI_INTB, (conf[0x47] & 0x02)); + pci_set_irq_level(PCI_INTC, (conf[0x47] & 0x04)); + pci_set_irq_level(PCI_INTD, (conf[0x47] & 0x08)); } static void