From 3956032b94e20d47175b940c19c2830228f55357 Mon Sep 17 00:00:00 2001 From: Emlyn Corrin Date: Tue, 1 Apr 2025 20:05:08 +0100 Subject: [PATCH 01/13] Display ISABugger status in monospace font with colour for the LED bits --- src/device/bugger.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/device/bugger.c b/src/device/bugger.c index b56937a43..6b9ed43cc 100644 --- a/src/device/bugger.c +++ b/src/device/bugger.c @@ -84,7 +84,7 @@ static uint8_t bug_spcfg; /* serial port configuration */ #define FIFO_LEN 256 static uint8_t bug_buff[FIFO_LEN]; /* serial port data buffer */ static uint8_t *bug_bptr; -#define UISTR_LEN 24 +#define UISTR_LEN 91 static char bug_str[UISTR_LEN]; /* UI output string */ extern void ui_sb_bugui(char *__str); @@ -112,7 +112,7 @@ static void bug_setui(void) { /* Format all current info in a string. */ - sprintf(bug_str, "%02X:%02X %c%c%c%c%c%c%c%c-%c%c%c%c%c%c%c%c", + sprintf(bug_str, "%02X:%02X %c%c%c%c%c%c%c%c-%c%c%c%c%c%c%c%c", bug_seg2, bug_seg1, (bug_ledg & 0x80) ? 'G' : 'g', (bug_ledg & 0x40) ? 'G' : 'g', (bug_ledg & 0x20) ? 'G' : 'g', (bug_ledg & 0x10) ? 'G' : 'g', From dd5a25aad39830c9c674b26b5c3beaba8a405f11 Mon Sep 17 00:00:00 2001 From: Emlyn Corrin Date: Tue, 1 Apr 2025 21:56:41 +0100 Subject: [PATCH 02/13] Only set LED colour when it is lit --- src/device/bugger.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/device/bugger.c b/src/device/bugger.c index 6b9ed43cc..6a30df7be 100644 --- a/src/device/bugger.c +++ b/src/device/bugger.c @@ -84,7 +84,10 @@ static uint8_t bug_spcfg; /* serial port configuration */ #define FIFO_LEN 256 static uint8_t bug_buff[FIFO_LEN]; /* serial port data buffer */ static uint8_t *bug_bptr; -#define UISTR_LEN 91 + +static char LED_R[] = "R"; +static char LED_G[] = "G"; +#define UISTR_LEN (17 + 8 * sizeof(LED_G) + 8 * sizeof(LED_R)) static char bug_str[UISTR_LEN]; /* UI output string */ extern void ui_sb_bugui(char *__str); @@ -112,16 +115,16 @@ static void bug_setui(void) { /* Format all current info in a string. */ - sprintf(bug_str, "%02X:%02X %c%c%c%c%c%c%c%c-%c%c%c%c%c%c%c%c", + sprintf(bug_str, "%02X:%02X %s%s%s%s%s%s%s%s-%s%s%s%s%s%s%s%s", bug_seg2, bug_seg1, - (bug_ledg & 0x80) ? 'G' : 'g', (bug_ledg & 0x40) ? 'G' : 'g', - (bug_ledg & 0x20) ? 'G' : 'g', (bug_ledg & 0x10) ? 'G' : 'g', - (bug_ledg & 0x08) ? 'G' : 'g', (bug_ledg & 0x04) ? 'G' : 'g', - (bug_ledg & 0x02) ? 'G' : 'g', (bug_ledg & 0x01) ? 'G' : 'g', - (bug_ledr & 0x80) ? 'R' : 'r', (bug_ledr & 0x40) ? 'R' : 'r', - (bug_ledr & 0x20) ? 'R' : 'r', (bug_ledr & 0x10) ? 'R' : 'r', - (bug_ledr & 0x08) ? 'R' : 'r', (bug_ledr & 0x04) ? 'R' : 'r', - (bug_ledr & 0x02) ? 'R' : 'r', (bug_ledr & 0x01) ? 'R' : 'r'); + (bug_ledg & 0x80) ? LED_G : "g", (bug_ledg & 0x40) ? LED_G : "g", + (bug_ledg & 0x20) ? LED_G : "g", (bug_ledg & 0x10) ? LED_G : "g", + (bug_ledg & 0x08) ? LED_G : "g", (bug_ledg & 0x04) ? LED_G : "g", + (bug_ledg & 0x02) ? LED_G : "g", (bug_ledg & 0x01) ? LED_G : "g", + (bug_ledr & 0x80) ? LED_R : "r", (bug_ledr & 0x40) ? LED_R : "r", + (bug_ledr & 0x20) ? LED_R : "r", (bug_ledr & 0x10) ? LED_R : "r", + (bug_ledr & 0x08) ? LED_R : "r", (bug_ledr & 0x04) ? LED_R : "r", + (bug_ledr & 0x02) ? LED_R : "r", (bug_ledr & 0x01) ? LED_R : "r"); /* Send formatted string to the UI. */ ui_sb_bugui(bug_str); From 420a08ee2c8755dc1ba6785cbd5e31247aac1c1f Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 2 Apr 2025 17:18:44 +0200 Subject: [PATCH 03/13] mem.c: Do not initialize the > 1 GB mapping on 64-bit binaries where it is not necessary. --- src/mem/mem.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mem/mem.c b/src/mem/mem.c index c4d11300b..8c2cfd6cc 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -2976,6 +2976,7 @@ mem_reset(void) else if (cpu_16bitbus && is6117 && mem_size > 65408) mem_init_ram_mapping(&ram_high_mapping, 0x100000, (65408 - 1024) * 1024); else { +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) if (mem_size > 1048576) { mem_init_ram_mapping(&ram_high_mapping, 0x100000, (1048576 - 1024) * 1024); @@ -2988,6 +2989,9 @@ mem_reset(void) ram2, MEM_MAPPING_INTERNAL, NULL); } else mem_init_ram_mapping(&ram_high_mapping, 0x100000, (mem_size - 1024) * 1024); +#else + mem_init_ram_mapping(&ram_high_mapping, 0x100000, (mem_size - 1024) * 1024); +#endif } } From 98efd05ddaa32823028c2130ffeb26ea40bbc6a2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 2 Apr 2025 18:45:27 +0200 Subject: [PATCH 04/13] Alfredo, Batman's Renvenge, and Plato: Pre-initialize NVR to 0x00 instead of 0xFF and give them the correct Phoenix keyboard controller, fixes hang after the first soft reset. --- src/machine/m_at_386dx_486.c | 4 +++- src/machine/m_at_socket4.c | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 0ee353f53..572cebc2e 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1249,6 +1249,8 @@ machine_at_alfredo_init(const machine_t *model) return ret; machine_at_common_init(model); + + device_add(&amstrad_megapc_nvr_device); device_add(&ide_pci_device); pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); @@ -1258,7 +1260,7 @@ machine_at_alfredo_init(const machine_t *model) pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&keyboard_ps2_pci_device); + device_add(&keyboard_ps2_phoenix_device); device_add(&sio_device); device_add(&fdc37c663_device); device_add(&intel_flash_bxt_ami_device); diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index 78df5b0cb..072d52e01 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -44,7 +44,9 @@ void machine_at_premiere_common_init(const machine_t *model, int pci_switch) { - machine_at_common_init(model); + machine_at_common_init_ex(model); + + device_add(&amstrad_megapc_nvr_device); device_add(&ide_pci_device); pci_init(PCI_CONFIG_TYPE_2 | pci_switch); @@ -54,7 +56,7 @@ machine_at_premiere_common_init(const machine_t *model, int pci_switch) pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&keyboard_ps2_phoenix_device); device_add(&sio_zb_device); device_add(&fdc37c665_device); device_add(&intel_flash_bxt_ami_device); From babac318944a5aa80daedd99d76f3abaf651f915 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 2 Apr 2025 18:46:35 +0200 Subject: [PATCH 05/13] Fixed a compile-breaking mistake. --- src/machine/m_at_386dx_486.c | 2 +- src/machine/m_at_socket4.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 572cebc2e..7f285af65 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1248,7 +1248,7 @@ machine_at_alfredo_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); device_add(&amstrad_megapc_nvr_device); device_add(&ide_pci_device); diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index 072d52e01..0d78c6de3 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -44,7 +44,7 @@ void machine_at_premiere_common_init(const machine_t *model, int pci_switch) { - machine_at_common_init_ex(model); + machine_at_common_init_ex(model, 2); device_add(&amstrad_megapc_nvr_device); device_add(&ide_pci_device); From 57851e7606d02ed15fb470641158d2b1dfb98c66 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 2 Apr 2025 16:21:50 -0300 Subject: [PATCH 06/13] AD1848: Logging and clean-ups I forgot to commit --- src/sound/snd_ad1848.c | 78 +++++++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 20 deletions(-) diff --git a/src/sound/snd_ad1848.c b/src/sound/snd_ad1848.c index 87755a96c..202fd891a 100644 --- a/src/sound/snd_ad1848.c +++ b/src/sound/snd_ad1848.c @@ -19,11 +19,12 @@ * Copyright 2021-2025 RichardG. */ #include +#include #include #include #include #include - +#define HAVE_STDARG_H #include <86box/86box.h> #include <86box/dma.h> #include <86box/pic.h> @@ -36,6 +37,24 @@ #define CS4232 0x02 #define CS4236 0x03 +#ifdef ENABLE_AD1848_LOG +int ad1848_do_log = ENABLE_AD1848_LOG; + +static void +ad1848_log(const char *fmt, ...) +{ + va_list ap; + + if (ad1848_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define ad1848_log(fmt, ...) +#endif + static int ad1848_vols_7bits[128]; static double ad1848_vols_5bits_aux_gain[32]; @@ -46,12 +65,14 @@ extern uint8_t adjustMap4[64]; void ad1848_setirq(ad1848_t *ad1848, int irq) { + ad1848_log("AD1848: setirq(%d)\n", irq); ad1848->irq = irq; } void ad1848_setdma(ad1848_t *ad1848, int newdma) { + ad1848_log("AD1848: setdma(%d)\n", newdma); ad1848->dma = newdma; } @@ -62,6 +83,7 @@ ad1848_updatevolmask(ad1848_t *ad1848) ad1848->wave_vol_mask = 0x7f; else ad1848->wave_vol_mask = 0x3f; + ad1848_log("AD1848: updatevolmask(%02X)\n", ad1848->wave_vol_mask); } static double @@ -99,6 +121,8 @@ ad1848_get_default_freq(ad1848_t *ad1848) break; } + ad1848_log("AD1848: Frequency %f through default path\n", freq); + return freq; } @@ -136,6 +160,8 @@ ad1848_updatefreq(ad1848_t *ad1848) freq /= 2558.0; break; } + + ad1848_log("AD1848: Frequency %f through CS4236B+ path\n", freq); } else if (ad1848->regs[22] & 0x80) { const uint8_t set = (ad1848->regs[22] >> 1) & 0x3f; freq = (ad1848->regs[22] & 1) ? 33868800.0 : 49152000.0; @@ -153,6 +179,8 @@ ad1848_updatefreq(ad1848_t *ad1848) freq /= 256 * set; break; } + + ad1848_log("AD1848: Frequency %f through CS4232+ path\n", freq); } else freq = ad1848_get_default_freq(ad1848); } else @@ -182,18 +210,16 @@ ad1848_read(uint16_t addr, void *priv) ad1848->regs[ad1848->index] = ret; break; - case 18: - case 19: + case 18 ... 19: if (ad1848->type >= AD1848_TYPE_CS4236B) { if ((ad1848->xregs[4] & 0x14) == 0x14) /* FM remapping */ - ret = ad1848->xregs[ad1848->index - 12]; /* real FM volume on registers 6 and 7 */ + ret = ad1848->xregs[6 | (ad1848->index & 1)]; /* real FM volume on registers 6 and 7 */ else if (ad1848->wten && !(ad1848->xregs[4] & 0x08)) /* wavetable remapping */ - ret = ad1848->xregs[ad1848->index - 2]; /* real wavetable volume on registers 16 and 17 */ + ret = ad1848->xregs[16 | (ad1848->index & 1)]; /* real wavetable volume on registers 16 and 17 */ } break; - case 20: - case 21: + case 20 ... 21: /* Backdoor to the Control/RAM registers on CS4235+. */ if ((ad1848->type >= AD1848_TYPE_CS4235) && (ad1848->xregs[18] & 0x80)) ret = ad1848->cram_read(ad1848->index - 15, ad1848->cram_priv); @@ -229,13 +255,16 @@ ad1848_read(uint16_t addr, void *priv) default: break; } + ad1848_log("AD1848: read(X%d) = %02X\n", ad1848->xindex, ret); + return ret; } break; default: break; } - break; + ad1848_log("AD1848: read(I%d) = %02X\n", ad1848->index, ret); + return ret; case 2: ret = ad1848->status; @@ -245,6 +274,8 @@ ad1848_read(uint16_t addr, void *priv) break; } + ad1848_log("AD1848: read(%04X) = %02X\n", addr, ret); + return ret; } @@ -295,7 +326,7 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) break; case 11: - return; + goto readonly_i; case 12: if (ad1848->type >= AD1848_TYPE_CS4248) { @@ -307,19 +338,19 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) ad1848->fmt_mask &= ~0x80; } } - return; + goto readonly_i; case 14: ad1848->count = ad1848->regs[15] | (val << 8); break; - case 18: - case 19: + case 18 ... 19: if (ad1848->type >= AD1848_TYPE_CS4236B) { if (ad1848->type >= AD1848_TYPE_CS4235) { if (ad1848->xregs[18] & 0x20) /* AUX1 remapping */ ad1848->regs[ad1848->index & 3] = val; /* also controls AUX1 on registers 2 and 3 */ } else { + temp = 0; if ((ad1848->xregs[4] & 0x14) == 0x14) { /* FM remapping */ ad1848->xregs[6 | (ad1848->index & 1)] = val; /* real FM volume on extended registers 6 and 7 */ temp = 1; @@ -343,7 +374,7 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) /* Stop here if any remapping is enabled. */ if (temp) - return; + goto readonly_i; } /* HACK: the Windows 9x driver's "Synth" control writes to this @@ -362,8 +393,7 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) } break; - case 20: - case 21: + case 20 ... 21: /* Backdoor to the Control/RAM registers on CS4235+. */ if ((ad1848->type >= AD1848_TYPE_CS4235) && (ad1848->xregs[18] & 0x80)) { ad1848->cram_write(ad1848->index - 15, val, ad1848->cram_priv); @@ -421,7 +451,7 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) break; case 25: - return; + goto readonly_x; case 26 ... 28: case 30: @@ -438,6 +468,8 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) if (updatefreq) ad1848_updatefreq(ad1848); +readonly_x: + ad1848_log("AD1848: write(X%d, %02X)\n", ad1848->xindex, val); return; } break; @@ -451,14 +483,14 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) break; case 25: - return; + goto readonly_i; case 27: if ((ad1848->type != AD1848_TYPE_CS4232) && (ad1848->type != AD1848_TYPE_CS4236)) - return; + goto readonly_i; break; case 29: if ((ad1848->type != AD1848_TYPE_CS4232) && (ad1848->type != AD1848_TYPE_CS4236)) - return; + goto readonly_i; break; default: @@ -480,7 +512,9 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) else ad1848->cd_vol_r = ad1848_vols_5bits_aux_gain[ad1848->regs[temp] & 0x1f]; - break; +readonly_i: + ad1848_log("AD1848: write(I%d, %02X)\n", ad1848->index, val); + return; case 2: ad1848->status &= 0xfe; @@ -490,6 +524,8 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) default: break; } + + ad1848_log("AD1848: write(%04X, %02X)\n", addr, val); } void @@ -743,6 +779,8 @@ ad1848_init(ad1848_t *ad1848, uint8_t type) uint8_t c; double attenuation; + ad1848_log("AD1848: init(%02X)\n", type); + ad1848->status = 0xcc; ad1848->index = ad1848->trd = 0; ad1848->mce = 0x40; From f56f636248aea56ce4dafabbf0a18597d167ce02 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 2 Apr 2025 16:27:10 -0300 Subject: [PATCH 07/13] Report 4 GB cacheable memory on Deschutes CPUs, fixes modern Linux limiting itself to 512 MB on some machines --- src/cpu/cpu.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 910d40765..61bd8bf36 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -2649,6 +2649,11 @@ cpu_ven_reset(void) case CPU_PENTIUM2: case CPU_PENTIUM2D: msr.mtrr_cap = 0x00000508ULL; + + /* 4 GB cacheable space on Deschutes 651h and later (including the 1632h + Overdrive) according to the Pentium II Processor Specification Update. */ + if (cpu_s->cpuid_model >= 0x651) + msr.bbl_cr_ctl3 |= 0x00300000; break; case CPU_CYRIX3S: @@ -4103,7 +4108,7 @@ pentium_invalid_wrmsr: break; /* BBL_CR_CTL3 - L2 Cache Control Register 3 */ case 0x11e: - msr.bbl_cr_ctl3 = EAX | ((uint64_t) EDX << 32); + msr.bbl_cr_ctl3 = (msr.bbl_cr_ctl3 & 0x02f00000) | (EAX & ~0x02f00000) | ((uint64_t) EDX << 32); break; /* Unknown */ case 0x131: From 5432c1dd1382331b94985283b5034daafef4c37d Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 2 Apr 2025 21:33:26 +0200 Subject: [PATCH 08/13] 8514/A compatible changes of the day (April 2nd, 2025) 1. Aliases are aliases, period. 2. Actually make the ports using bit 15 of their range use the command FIFO. 3. Improved the special ATI command 0xc2b5 in the IBM bitblt side, fixes cursor issues in 24bpp mode using OS/2. 4. When the FIFO is empty, clear the busy and available flags. 5. Also reapply a workaround for 24bpp foreground color patterns in ATI command Scan To X command, fixes patterns in OS/2 and possibly elsewhere. 6. Accelerated HiColor mode, in the IBM passthrough mode, should always be enabled, for now, as well as the Extended ATI Mach32 8bpp mode when prompted, fixes OS/2 booting into the GUI in HiColor mode. 7. Dummy data path configuration values on direct linedraw should not trigger a pixtrans read when it's not needed, fixes possible hang ups in IBM/ATI mode when the busy flag remains enabled. --- src/video/vid_8514a.c | 171 +++++++++------ src/video/vid_ati_mach8.c | 438 +++++++++++++++++++++++--------------- 2 files changed, 375 insertions(+), 234 deletions(-) diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 7c0bf9702..8925f01da 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -334,6 +334,13 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) { ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + if (port & 0x8000) { + if ((port != 0xe2e8) && (port != 0xe2e9) && (port != 0xe6e8) && (port != 0xe6e9)) { + if (port & 0x4000) + port &= ~0x4000; + } + } + switch (port) { case 0x2e8: WRITE8(port, dev->htotal, val); @@ -499,19 +506,16 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) break; case 0x82e8: - case 0xc2e8: if (len == 2) dev->accel.cur_y = val & 0x7ff; break; case 0x86e8: - case 0xc6e8: if (len == 2) dev->accel.cur_x = val & 0x7ff; break; case 0x8ae8: - case 0xcae8: if (len == 2) { dev->accel.desty = val & 0x7ff; dev->accel.desty_axstp = val & 0x3fff; @@ -521,7 +525,6 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) break; case 0x8ee8: - case 0xcee8: if (len == 2) { dev->accel.destx = val & 0x7ff; dev->accel.destx_distp = val & 0x3fff; @@ -531,12 +534,8 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) break; case 0x92e8: - if (len == 2) - dev->test = val; - fallthrough; - - case 0xd2e8: if (len == 2) { + dev->test = val; dev->accel.err_term = val & 0x3fff; if (val & 0x2000) dev->accel.err_term |= ~0x1fff; @@ -544,7 +543,6 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) break; case 0x96e8: - case 0xd6e8: if (len == 2) { dev->accel.maj_axis_pcnt = val & 0x7ff; dev->accel.maj_axis_pcnt_no_limit = val; @@ -552,7 +550,6 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) break; case 0x9ae8: - case 0xdae8: dev->accel.ssv_state = 0; if (len == 2) { dev->data_available = 0; @@ -562,13 +559,12 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) if (dev->accel.cmd & 0x100) dev->accel.cmd_back = 0; - ibm8514_log("8514/A CMD=%04x, back=%d, frgd color=%04x, frgdmix=%02x, pixcntl=%02x.\n", dev->accel.cmd, dev->accel.cmd_back, dev->accel.frgd_color, dev->accel.frgd_mix, dev->accel.multifunc[0x0a]); + ibm8514_log("8514/A CMD=%04x, frgd color=%04x, frgdmix=%02x, pixcntl=%02x.\n", dev->accel.cmd, dev->accel.frgd_color, dev->accel.frgd_mix, dev->accel.multifunc[0x0a]); ibm8514_accel_start(-1, 0, -1, 0, svga, len); } break; case 0x9ee8: - case 0xdee8: dev->accel.ssv_state = 1; if (len == 2) { dev->accel.short_stroke = val; @@ -628,35 +624,29 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) break; case 0xaae8: - case 0xeae8: if (len == 2) dev->accel.wrt_mask = val; break; case 0xaee8: - case 0xeee8: if (len == 2) dev->accel.rd_mask = val; break; case 0xb2e8: - case 0xf2e8: if (len == 2) dev->accel.color_cmp = val; break; case 0xb6e8: - case 0xf6e8: dev->accel.bkgd_mix = val & 0xff; break; case 0xbae8: - case 0xfae8: dev->accel.frgd_mix = val & 0xff; break; case 0xbee8: - case 0xfee8: if (len == 2) { dev->accel.multifunc_cntl = val; dev->accel.multifunc[dev->accel.multifunc_cntl >> 12] = dev->accel.multifunc_cntl & 0xfff; @@ -765,10 +755,12 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) { ibm8514_t *dev = (ibm8514_t *) svga->dev8514; - if (dev->accel.cmd_back) { - dev->fifo_idx++; - if (dev->fifo_idx > 8) - dev->fifo_idx = 8; + if (port & 0x8000) { + if (dev->accel.cmd_back) { + dev->fifo_idx++; + if (dev->fifo_idx > 8) + dev->fifo_idx = 8; + } } ibm8514_accel_out_fifo(svga, port, val, len); @@ -799,13 +791,11 @@ ibm8514_accel_in_fifo(svga_t *svga, uint16_t port, int len) switch (port) { case 0x82e8: - case 0xc2e8: if (len == 2) temp = dev->accel.cur_y; break; case 0x86e8: - case 0xc6e8: if (len == 2) temp = dev->accel.cur_x; break; @@ -821,7 +811,6 @@ ibm8514_accel_in_fifo(svga_t *svga, uint16_t port, int len) break; case 0x9ae8: - case 0xdae8: if (len == 2) { if (dev->fifo_idx <= 8) { for (int i = 1; i <= dev->fifo_idx; i++) @@ -835,9 +824,6 @@ ibm8514_accel_in_fifo(svga_t *svga, uint16_t port, int len) if (dev->force_busy) temp |= 0x0200; /*Hardware busy*/ - if (dev->accel.cmd_back) - dev->force_busy = 0; - if (dev->data_available) { temp |= 0x0100; /*Read Data available*/ switch (dev->accel.cmd >> 13) { @@ -857,7 +843,6 @@ ibm8514_accel_in_fifo(svga_t *svga, uint16_t port, int len) } break; case 0x9ae9: - case 0xdae9: if (len == 1) { dev->fifo_idx = 0; @@ -974,7 +959,7 @@ ibm8514_accel_in(uint16_t port, svga_t *svga) temp |= INT_GE_BSY; } - if (dev->accel.cmd_back) { + if (!dev->fifo_idx) { dev->force_busy = 0; dev->force_busy2 = 0; dev->data_available = 0; @@ -1033,6 +1018,8 @@ ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t dev->accel.ssv_len_back = dev->accel.ssv_len; if (ibm8514_cpu_src(svga)) { + dev->force_busy = 1; + dev->force_busy2 = 1; dev->data_available = 0; dev->data_available2 = 0; return; /*Wait for data from CPU*/ @@ -1079,11 +1066,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat rd_mask_polygon &= 0xff; } - if (!dev->accel.cmd_back) { - dev->force_busy = 1; - dev->force_busy2 = 1; - } - frgd_mix = (dev->accel.frgd_mix >> 5) & 3; bkgd_mix = (dev->accel.bkgd_mix >> 5) & 3; @@ -1251,8 +1233,12 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat cpu_dat >>= 8; if (!dev->accel.ssv_len) { - dev->accel.cmd_back = 1; + if (cpu_input) { + dev->force_busy = 0; + dev->force_busy2 = 0; + } dev->fifo_idx = 0; + dev->accel.cmd_back = 1; break; } @@ -1348,8 +1334,12 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat cpu_dat >>= 8; if (!dev->accel.ssv_len) { - dev->accel.cmd_back = 1; + if (cpu_input) { + dev->force_busy = 0; + dev->force_busy2 = 0; + } dev->fifo_idx = 0; + dev->accel.cmd_back = 1; break; } @@ -1413,10 +1403,14 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.output = 1; } } + dev->force_busy = 1; + dev->force_busy2 = 1; dev->data_available = 0; dev->data_available2 = 0; return; /*Wait for data from CPU*/ } else if (ibm8514_cpu_dest(svga)) { + dev->force_busy = 1; + dev->force_busy2 = 1; dev->data_available = 1; dev->data_available2 = 1; return; @@ -1524,8 +1518,12 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } if (!dev->accel.sy) { - dev->accel.cmd_back = 1; + if (cpu_input) { + dev->force_busy = 0; + dev->force_busy2 = 0; + } dev->fifo_idx = 0; + dev->accel.cmd_back = 1; if (!cpu_input) { dev->accel.cur_x = dev->accel.cx; dev->accel.cur_y = dev->accel.cy; @@ -1645,8 +1643,12 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat cpu_dat >>= 8; if (!dev->accel.sy) { - dev->accel.cmd_back = 1; + if (cpu_input) { + dev->force_busy = 0; + dev->force_busy2 = 0; + } dev->fifo_idx = 0; + dev->accel.cmd_back = 1; break; } @@ -1749,8 +1751,12 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat cpu_dat >>= 8; if (!dev->accel.sy) { - dev->accel.cmd_back = 1; + if (cpu_input) { + dev->force_busy = 0; + dev->force_busy2 = 0; + } dev->fifo_idx = 0; + dev->accel.cmd_back = 1; if (!cpu_input) { dev->accel.cur_x = dev->accel.cx; dev->accel.cur_y = dev->accel.cy; @@ -1855,6 +1861,8 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } } } + dev->force_busy = 1; + dev->force_busy2 = 1; dev->data_available = 0; dev->data_available2 = 0; return; /*Wait for data from CPU*/ @@ -1872,6 +1880,8 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } } ibm8514_log("INPUT=%d.\n", dev->accel.input); + dev->force_busy = 1; + dev->force_busy2 = 1; dev->data_available = 1; dev->data_available2 = 1; return; /*Wait for data from CPU*/ @@ -2031,8 +2041,10 @@ skip_vector_rect_write: dev->accel.x_count = 0; if (dev->accel.sy < 0) { - dev->accel.cmd_back = 1; + dev->force_busy = 0; + dev->force_busy2 = 0; dev->fifo_idx = 0; + dev->accel.cmd_back = 1; } return; } @@ -2043,6 +2055,7 @@ skip_vector_rect_write: ibm8514_log("Vectored Rectangle with normal processing (TODO).\n"); } else { /*Normal Rectangle*/ if (cpu_input) { + ibm8514_log("Normal Pixel Rectangle Fill Transfer SY=%d.\n", dev->accel.sy); while (count-- && (dev->accel.sy >= 0)) { if ((dev->accel.cx >= clip_l) && (dev->accel.cx <= clip_r) && @@ -2192,9 +2205,11 @@ skip_nibble_rect_write: dev->accel.x_count = 0; if (dev->accel.sy < 0) { - dev->accel.cmd_back = 1; dev->fifo_idx = 0; + dev->accel.cmd_back = 1; } + dev->force_busy = 0; + dev->force_busy2 = 0; return; } } @@ -2280,8 +2295,8 @@ skip_nibble_rect_write: dev->accel.sy--; if (dev->accel.sy < 0) { - dev->accel.cmd_back = 1; dev->fifo_idx = 0; + dev->accel.cmd_back = 1; } return; } @@ -2366,8 +2381,8 @@ skip_nibble_rect_write: dev->accel.cur_x = dev->accel.cx; dev->accel.cur_y = dev->accel.cy; } - dev->accel.cmd_back = 1; dev->fifo_idx = 0; + dev->accel.cmd_back = 1; return; } } @@ -2478,10 +2493,10 @@ skip_nibble_rect_write: if (dev->accel.sy < 0) { ibm8514_log(".\n"); - dev->accel.cmd_back = 1; dev->fifo_idx = 0; dev->accel.cur_x = dev->accel.cx; dev->accel.cur_y = dev->accel.cy; + dev->accel.cmd_back = 1; return; } } @@ -2568,8 +2583,8 @@ skip_nibble_rect_write: dev->accel.cur_x = dev->accel.cx; dev->accel.cur_y = dev->accel.cy; } - dev->accel.cmd_back = 1; dev->fifo_idx = 0; + dev->accel.cmd_back = 1; return; } } @@ -2599,10 +2614,14 @@ skip_nibble_rect_write: ibm8514_log("Polygon Boundary activated=%04x, len=%d, cur(%d,%d), frgdmix=%02x, err=%d, clipping: l=%d, r=%d, t=%d, b=%d, pixcntl=%02x.\n", dev->accel.cmd, dev->accel.sy, dev->accel.cx, dev->accel.cy, dev->accel.frgd_mix & 0x1f, dev->accel.err_term, clip_l, clip_r, clip_t, clip_b, dev->accel.multifunc[0x0a]); if (ibm8514_cpu_src(svga)) { + dev->force_busy = 1; + dev->force_busy2 = 1; dev->data_available = 0; dev->data_available2 = 0; return; /*Wait for data from CPU*/ } else if (ibm8514_cpu_dest(svga)) { + dev->force_busy = 1; + dev->force_busy2 = 1; dev->data_available = 1; dev->data_available2 = 1; return; @@ -2671,8 +2690,12 @@ skip_nibble_rect_write: cpu_dat >>= 8; if (!dev->accel.sy) { - dev->accel.cmd_back = 1; + if (cpu_input) { + dev->force_busy = 0; + dev->force_busy2 = 0; + } dev->fifo_idx = 0; + dev->accel.cmd_back = 1; break; } @@ -2776,8 +2799,12 @@ skip_nibble_rect_write: cpu_dat >>= 8; if (!dev->accel.sy) { - dev->accel.cmd_back = 1; + if (cpu_input) { + dev->force_busy = 0; + dev->force_busy2 = 0; + } dev->fifo_idx = 0; + dev->accel.cmd_back = 1; break; } @@ -2869,10 +2896,14 @@ skip_nibble_rect_write: } } } + dev->force_busy = 1; + dev->force_busy2 = 1; dev->data_available = 0; dev->data_available2 = 0; return; /*Wait for data from CPU*/ } else if (ibm8514_cpu_dest(svga)) { + dev->force_busy = 1; + dev->force_busy2 = 1; dev->data_available = 1; dev->data_available2 = 1; return; /*Wait for data from CPU*/ @@ -3036,6 +3067,8 @@ skip_nibble_bitblt_write: if (dev->accel.sy < 0) { dev->accel.cmd_back = 1; + dev->force_busy = 0; + dev->force_busy2 = 0; dev->fifo_idx = 0; } return; @@ -3234,8 +3267,8 @@ skip_nibble_bitblt_write: if (dev->accel.sy < 0) { dev->accel.destx = dev->accel.dx; dev->accel.desty = dev->accel.dy; - dev->accel.cmd_back = 1; dev->fifo_idx = 0; + dev->accel.cmd_back = 1; return; } } @@ -3254,9 +3287,29 @@ skip_nibble_bitblt_write: (dx <= (((uint64_t)clip_r) * 3)) && (dev->accel.dy >= (clip_t << 1)) && (dev->accel.dy <= (clip_b << 1))) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = 0; + break; + case 3: + READ(dev->accel.src + cx, src_dat); + break; + + default: + break; + } + READ(dev->accel.src + cx, src_dat); READ(dev->accel.dest + dx, dest_dat); - dest_dat = (src_dat & wrt_mask) | (dest_dat & ~wrt_mask); + old_dest_dat = dest_dat; + MIX(mix_dat & mix_mask, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); WRITE(dev->accel.dest + dx, dest_dat); } @@ -3265,8 +3318,8 @@ skip_nibble_bitblt_write: dev->accel.sx--; if (dev->accel.sx < 0) { - dev->accel.cmd_back = 1; dev->fifo_idx = 0; + dev->accel.cmd_back = 1; return; } } @@ -3321,15 +3374,8 @@ skip_nibble_bitblt_write: old_dest_dat = dest_dat; MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - - if (dev->accel.cmd & 0x04) { - if (dev->accel.sx) { - WRITE(dev->accel.dest + dev->accel.dx, dest_dat); - } - } else { - WRITE(dev->accel.dest + dev->accel.dx, dest_dat); - ibm8514_log("BitBLT DX=%d, DY=%d, data=%02x, old=%02x, src=%02x, frmix=%02x, bkmix=%02x, pixcntl=%d.\n", dev->accel.dx, dev->accel.dy, dest_dat, old_dest_dat, src_dat, dev->accel.frgd_mix & 0x1f, dev->accel.bkgd_mix & 0x1f, pixcntl); - } + WRITE(dev->accel.dest + dev->accel.dx, dest_dat); + ibm8514_log("BitBLT DX=%d, DY=%d, data=%02x, old=%02x, src=%02x, frmix=%02x, bkmix=%02x, pixcntl=%d.\n", dev->accel.dx, dev->accel.dy, dest_dat, old_dest_dat, src_dat, dev->accel.frgd_mix & 0x1f, dev->accel.bkgd_mix & 0x1f, pixcntl); } } @@ -3380,8 +3426,8 @@ skip_nibble_bitblt_write: if (dev->accel.sy < 0) { dev->accel.destx = dev->accel.dx; dev->accel.desty = dev->accel.dy; - dev->accel.cmd_back = 1; dev->fifo_idx = 0; + dev->accel.cmd_back = 1; return; } } @@ -4020,6 +4066,7 @@ ibm8514_init(const device_t *info) default: dev->extensions = 0; ibm8514_io_set(svga); + dev->accel.cmd_back = 1; if (dev->type & DEVICE_MCA) { dev->pos_regs[0] = 0x7f; diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 474ae5660..9f92ebde1 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -69,6 +69,7 @@ static uint8_t ati8514_accel_inb(uint16_t port, void *priv); static uint16_t ati8514_accel_inw(uint16_t port, void *priv); static uint32_t ati8514_accel_inl(uint16_t port, void *priv); +static void mach_set_resolution(mach_t *mach, svga_t *svga); static void mach32_updatemapping(mach_t *mach, svga_t *svga); static __inline void mach32_writew_linear(uint32_t addr, uint16_t val, mach_t *mach); static __inline void mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach, svga_t *svga); @@ -326,12 +327,6 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 bkgd_sel = (mach->accel.dp_config >> 7) & 3; mono_src = (mach->accel.dp_config >> 5) & 3; - if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) { - mach->force_busy = 1; - dev->force_busy = 1; - dev->force_busy2 = 1; - } - if (cpu_input) { if (dev->bpp) { if ((mach->accel.dp_config & 0x200) && (count == 2)) @@ -339,12 +334,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } } - if ((dev->accel_bpp == 8) || (dev->accel_bpp == 15) || (dev->accel_bpp == 16) || (dev->accel_bpp == 24)) - mach_log("RdMask=%04x, DPCONFIG=%04x, Clipping: l=%d, r=%d, t=%d, b=%d, LineDrawOpt=%04x, BPP=%d, CMDType = %d, offs=%08x, cnt = %d, input = %d, mono_src = %d, frgdsel = %d, d(%d,%d), dstxend = %d, pitch = %d, extcrt = %d, rw = %x, monopattern = %x.\n", - dev->accel.rd_mask, mach->accel.dp_config, clip_l, clip_r, clip_t, clip_b, mach->accel.linedraw_opt, dev->accel_bpp, cmd_type, mach->accel.ge_offset, count, cpu_input, mono_src, frgd_sel, dev->accel.cur_x, dev->accel.cur_y, - mach->accel.dest_x_end, dev->ext_pitch, dev->ext_crt_pitch, mach->accel.dp_config & 1, mach->accel.mono_pattern_enable); - - mach_log("cmd_type = %i, frgd_sel = %i, bkgd_sel = %i, mono_src = %i, dpconfig = %04x.\n", cmd_type, frgd_sel, bkgd_sel, mono_src, mach->accel.dp_config); + mach_log("cmd_type = %i, frgd_sel = %i, bkgd_sel = %i, mono_src = %i, dpconfig = %04x, cur_x = %d, cur_y = %d.\n", cmd_type, frgd_sel, bkgd_sel, mono_src, mach->accel.dp_config, dev->accel.cur_x, dev->accel.cur_y); switch (cmd_type) { case 1: /*Extended Raw Linedraw from bres_count register (0x96ee)*/ @@ -376,12 +366,18 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 dev->accel.dx, dev->accel.dy, dev->accel.cx, dev->accel.cy, mach->accel.width, mach->accel.linedraw_opt, mach->accel.dp_config, mach->accel.max_waitstates & 0x100); - if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) { + if (!dev->accel.cmd_back) { if (mach_pixel_write(mach)) { + dev->force_busy = 1; + dev->force_busy2 = 1; + mach->force_busy = 1; dev->data_available = 0; dev->data_available2 = 0; return; } else if (mach_pixel_read(mach)) { + dev->force_busy = 1; + dev->force_busy2 = 1; + mach->force_busy = 1; dev->data_available = 1; dev->data_available2 = 1; return; @@ -550,12 +546,22 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } if ((mono_src == 1) && !count) { - dev->accel.cmd_back = 1; + if (cpu_input) { + mach->force_busy = 0; + dev->force_busy = 0; + dev->force_busy2 = 0; + } dev->fifo_idx = 0; + dev->accel.cmd_back = 1; break; } else if ((mono_src != 1) && (dev->accel.sx >= mach->accel.width)) { - dev->accel.cmd_back = 1; + if (cpu_input) { + mach->force_busy = 0; + dev->force_busy = 0; + dev->force_busy2 = 0; + } dev->fifo_idx = 0; + dev->accel.cmd_back = 1; break; } @@ -777,12 +783,22 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } if ((mono_src == 1) && !count) { - dev->accel.cmd_back = 1; + if (cpu_input) { + dev->force_busy = 0; + dev->force_busy2 = 0; + mach->force_busy = 0; + } dev->fifo_idx = 0; + dev->accel.cmd_back = 1; break; } else if ((mono_src != 1) && (dev->accel.sx >= mach->accel.width)) { - dev->accel.cmd_back = 1; + if (cpu_input) { + dev->force_busy = 0; + dev->force_busy2 = 0; + mach->force_busy = 0; + } dev->fifo_idx = 0; + dev->accel.cmd_back = 1; break; } @@ -976,12 +992,18 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } } - if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) { + if (!dev->accel.cmd_back) { if (mach_pixel_write(mach)) { + dev->force_busy = 1; + dev->force_busy2 = 1; + mach->force_busy = 1; dev->data_available = 0; dev->data_available2 = 0; return; } else if (mach_pixel_read(mach)) { + dev->force_busy = 1; + dev->force_busy2 = 1; + mach->force_busy = 1; dev->data_available = 1; dev->data_available2 = 1; return; @@ -1000,16 +1022,26 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (mach->accel.dy_end == mach->accel.dy_start) { mach_log("No DEST.\n"); - dev->accel.cmd_back = 1; + if (cpu_input) { + dev->force_busy = 0; + dev->force_busy2 = 0; + mach->force_busy = 0; + } dev->fifo_idx = 0; + dev->accel.cmd_back = 1; return; } if ((mono_src == 3) || (bkgd_sel == 3) || (frgd_sel == 3)) { if (mach->accel.sx_end == mach->accel.sx_start) { + if (cpu_input) { + dev->force_busy = 0; + dev->force_busy2 = 0; + mach->force_busy = 0; + } mach_log("No SRC.\n"); - dev->accel.cmd_back = 1; dev->fifo_idx = 0; + dev->accel.cmd_back = 1; return; } } @@ -1020,8 +1052,11 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mono_src, frgd_sel, bkgd_sel, dev->pitch); if (dev->accel.sy == mach->accel.height) { mach_log("No Blit on DPCONFIG=3251.\n"); - dev->accel.cmd_back = 1; + dev->force_busy = 0; + dev->force_busy2 = 0; + mach->force_busy = 0; dev->fifo_idx = 0; + dev->accel.cmd_back = 1; return; } } @@ -1238,8 +1273,13 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } if (dev->accel.sy >= mach->accel.height) { - dev->accel.cmd_back = 1; + if (cpu_input) { + dev->force_busy = 0; + dev->force_busy2 = 0; + mach->force_busy = 0; + } dev->fifo_idx = 0; + dev->accel.cmd_back = 1; if ((mono_src == 2) || (mono_src == 3) || (frgd_sel == 3) || (bkgd_sel == 3) || (mach->accel.dp_config & 0x02)) return; if ((mono_src == 1) && (frgd_sel == 5) && (dev->accel_bpp == 24)) @@ -1279,14 +1319,20 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 dev->accel.cur_x, dev->accel.cur_y, dev->accel.dx, dev->accel.dy, mach->accel.cx_end_line, mach->accel.cy_end_line, mach->accel.bleft, mach->accel.bright, mach->accel.btop, mach->accel.bbottom); - if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) { + if (!dev->accel.cmd_back) { if (mach_pixel_write(mach)) { mach_log("Write PIXTRANS.\n"); + dev->force_busy = 1; + dev->force_busy2 = 1; + mach->force_busy = 1; dev->data_available = 0; dev->data_available2 = 0; return; } else if (mach_pixel_read(mach)) { mach_log("Read PIXTRANS.\n"); + dev->force_busy = 1; + dev->force_busy2 = 1; + mach->force_busy = 1; dev->data_available = 1; dev->data_available2 = 1; return; @@ -1398,8 +1444,13 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mach->accel.clip_overrun = ((mach->accel.clip_overrun + 1) & 0x0f); if (!count) { - dev->accel.cmd_back = 1; + if (cpu_input) { + dev->force_busy = 0; + dev->force_busy2 = 0; + mach->force_busy = 0; + } dev->fifo_idx = 0; + dev->accel.cmd_back = 1; break; } @@ -1569,8 +1620,13 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mach->accel.clip_overrun = ((mach->accel.clip_overrun + 1) & 0x0f); if (dev->accel.sx >= mach->accel.width) { - dev->accel.cmd_back = 1; + if (cpu_input) { + dev->force_busy = 0; + dev->force_busy2 = 0; + mach->force_busy = 0; + } dev->fifo_idx = 0; + dev->accel.cmd_back = 1; break; } @@ -1694,8 +1750,13 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mach->accel.clip_overrun = ((mach->accel.clip_overrun + 1) & 0x0f); if (!count) { - dev->accel.cmd_back = 1; + if (cpu_input) { + dev->force_busy = 0; + dev->force_busy2 = 0; + mach->force_busy = 0; + } dev->fifo_idx = 0; + dev->accel.cmd_back = 1; break; } @@ -1853,8 +1914,13 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mach->accel.clip_overrun = ((mach->accel.clip_overrun + 1) & 0x0f); if (dev->accel.sx >= mach->accel.width) { - dev->accel.cmd_back = 1; + if (cpu_input) { + dev->force_busy = 0; + dev->force_busy2 = 0; + mach->force_busy = 0; + } dev->fifo_idx = 0; + dev->accel.cmd_back = 1; break; } @@ -1986,14 +2052,38 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 else dev->accel.src = (mach->accel.ge_offset << 2) + (dev->accel.cy * (dev->pitch)); - mach_log("ScanToX: Parameters=%04x: DX=%d, DY=%d, CX=%d, CY=%d, dstwidth=%d, srcwidth=%d, height=%d, clipl=%d, clipr=%d, clipt=%d, clipb=%d, frmix=%02x.\n", mach->accel.dp_config, dev->accel.dx, dev->accel.dy, dev->accel.cx, dev->accel.cy, mach->accel.width, mach->accel.src_width, dev->accel.sy, clip_l, clip_r, clip_t, clip_b, dev->accel.frgd_mix & 0x1f); + if ((dev->accel_bpp >= 24) && (frgd_sel == 5)) { + if (mach->accel.patt_len == 0x17) + mach->accel.color_pattern_idx = 0; - if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) { + dev->accel.x1 = dev->accel.dx + mach->accel.width; + if (dev->accel.x1 == dev->pitch) + dev->accel.x2 = mach->accel.width & 1; + else if ((dev->accel.x1 == mach->accel.width) && (dev->accel.dy & 1) && !dev->accel.y1 && dev->accel.x2) { + if (mach->accel.patt_len == 0x17) + mach->accel.color_pattern_idx = 3; + + dev->accel.x3 = 1; + } else + dev->accel.x3 = 0; + } + dev->accel.y1 = 0; + + mach_log("ScanToX: Parameters=%04x: xbit=%d, ybit=%d, widthbit=%d, DX=%d, DY=%d, CX=%d, CY=%d, dstwidth=%d, srcwidth=%d, height=%d, frmix=%02x.\n", + mach->accel.dp_config, dev->accel.dx & 1, dev->accel.dy & 1, mach->accel.width & 1, dev->accel.dx, dev->accel.dy, dev->accel.cx, dev->accel.cy, mach->accel.width, mach->accel.src_width, dev->accel.sy, dev->accel.frgd_mix & 0x1f); + + if (!dev->accel.cmd_back) { if (mach_pixel_write(mach)) { + dev->force_busy = 1; + dev->force_busy2 = 1; + mach->force_busy = 1; dev->data_available = 0; dev->data_available2 = 0; return; } else if (mach_pixel_read(mach)) { + dev->force_busy = 1; + dev->force_busy2 = 1; + mach->force_busy = 1; dev->data_available = 1; dev->data_available2 = 1; return; @@ -2132,10 +2222,11 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mach->accel.sx++; if (mach->accel.sx >= mach->accel.src_width) { mach->accel.sx = 0; - if (mach->accel.src_stepx == -1) { + if (mach->accel.src_stepx == -1) dev->accel.cx += mach->accel.src_width; - } else + else dev->accel.cx -= mach->accel.src_width; + dev->accel.cy += (mach->accel.src_y_dir ? 1 : -1); if (dev->bpp) dev->accel.src = (mach->accel.ge_offset << 1) + (dev->accel.cy * (dev->pitch)); @@ -2143,13 +2234,24 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 dev->accel.src = (mach->accel.ge_offset << 2) + (dev->accel.cy * (dev->pitch)); } + mach_log("ColorIdx=%d, data=%02x, DestX=%d, DestY=%d.\n", mach->accel.color_pattern_idx, mach->accel.color_pattern[mach->accel.color_pattern_idx], dev->accel.dx, dev->accel.dy & 1); if (dev->bpp) mach->accel.color_pattern_idx += 2; else mach->accel.color_pattern_idx++; - if (mach->accel.color_pattern_idx > mach->accel.patt_len) - mach->accel.color_pattern_idx = 0; + if ((dev->accel_bpp >= 24) && (frgd_sel == 5) && (mach->accel.patt_len == 0x17)) { + if (dev->accel.x3) { + if (mach->accel.color_pattern_idx == 9) + mach->accel.color_pattern_idx = 3; + } else { + if (mach->accel.color_pattern_idx == 6) + mach->accel.color_pattern_idx = 0; + } + } else { + if (mach->accel.color_pattern_idx > mach->accel.patt_len) + mach->accel.color_pattern_idx = 0; + } dev->accel.dx += mach->accel.stepx; dev->accel.sx++; @@ -2167,11 +2269,11 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (dev->accel.sy >= 0) dev->accel.sy--; - dev->accel.cmd_back = 1; dev->fifo_idx = 0; dev->force_busy = 0; dev->force_busy2 = 0; mach->force_busy = 0; + dev->accel.cmd_back = 1; return; } } @@ -2368,7 +2470,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv) mach_log("Extended 8514/A mode.\n"); dev->vendor_mode = 1; dev->on |= 0x01; - svga_recalctimings(svga); + mach_set_resolution(mach, svga); mach32_updatemapping(mach, svga); } if (dev->on) @@ -2395,7 +2497,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv) mach_log("VGA mode.\n"); dev->vendor_mode = 0; dev->on &= ~0x01; - svga_recalctimings(svga); + mach_set_resolution(mach, svga); mach32_updatemapping(mach, svga); } if (dev->on) @@ -2688,30 +2790,11 @@ mach_set_resolution(mach_t *mach, svga_t *svga) dev->v_syncstart >>= 1; mach_log("Shadow set ATI=%x, shadow set 8514/A=%x, resolution h=%d, v=%d, vtotal=%d, vsyncstart=%d.\n", mach->shadow_set & 0x03, dev->accel.advfunc_cntl & 0x04, dev->hdisp, dev->vdisp, dev->v_total, dev->v_syncstart); - if ((mach->accel.clock_sel & 0x01) || dev->bpp || ((mach->accel.ext_ge_config & 0x30) == 0x30)) /*ATI and 15bpp+ mode*/ - svga_recalctimings(svga); - else { /*8514/A mode*/ - switch (mach->shadow_set & 0x03) { - case 0x00: /*Primary CRT Register set*/ - if (dev->on) { - if (mach->crt_resolution == 0x01) { - if (ATI_8514A_ULTRA) { - if (dev->accel.advfunc_cntl & 0x04) { - if (dev->hdisp == 640) { - dev->hdisp = 1024; - dev->vdisp = 768; - svga_recalctimings(svga); - } - } else { - if (dev->hdisp == 1024) { - dev->hdisp = 640; - dev->vdisp = 480; - svga_recalctimings(svga); - } - } - } else - svga_recalctimings(svga); - } else if (mach->crt_resolution == 0x02) { + switch (mach->shadow_set & 0x03) { + case 0x00: /*Primary CRT Register set*/ + if (dev->on) { + if (mach->crt_resolution == 0x01) { + if (ATI_8514A_ULTRA) { if (dev->accel.advfunc_cntl & 0x04) { if (dev->hdisp == 640) { dev->hdisp = 1024; @@ -2727,33 +2810,48 @@ mach_set_resolution(mach_t *mach, svga_t *svga) } } else svga_recalctimings(svga); - } - break; - case 0x01: /*Shadow 640x480 CRT register set*/ - if (dev->on) { - if (!(dev->accel.advfunc_cntl & 0x04)) { - if (dev->hdisp == 1024) { - dev->hdisp = 640; - dev->vdisp = 480; - } - } - svga_recalctimings(svga); - } - break; - case 0x02: /*Shadow 1024x768 CRT register set*/ - if (dev->on) { + } else if (mach->crt_resolution == 0x02) { if (dev->accel.advfunc_cntl & 0x04) { if (dev->hdisp == 640) { dev->hdisp = 1024; dev->vdisp = 768; + svga_recalctimings(svga); + } + } else { + if (dev->hdisp == 1024) { + dev->hdisp = 640; + dev->vdisp = 480; + svga_recalctimings(svga); } } + } else svga_recalctimings(svga); + } + break; + case 0x01: /*Shadow 640x480 CRT register set*/ + if (dev->on) { + if (!(dev->accel.advfunc_cntl & 0x04)) { + if (dev->hdisp == 1024) { + dev->hdisp = 640; + dev->vdisp = 480; + } } - break; - default: - break; - } + svga_recalctimings(svga); + } + break; + case 0x02: /*Shadow 1024x768 CRT register set*/ + if (dev->on) { + if (dev->accel.advfunc_cntl & 0x04) { + if (dev->hdisp == 640) { + dev->hdisp = 1024; + dev->vdisp = 768; + } + } + svga_recalctimings(svga); + } + break; + default: + break; } } @@ -2855,7 +2953,7 @@ mach_recalctimings(svga_t *svga) svga->ati_4color = 0; } - mach_log("ON?=%d, override=%d, gelo=%04x, gehi=%04x, vgahdisp=%d.\n", dev->on, svga->override, mach->accel.ge_offset_lo, mach->accel.ge_offset_hi, svga->hdisp); + mach_log("ON=%d, override=%d, gelo=%04x, gehi=%04x, vgahdisp=%d.\n", dev->on, svga->override, mach->accel.ge_offset_lo, mach->accel.ge_offset_hi, svga->hdisp); if (dev->on) { dev->ma_latch = 0; /*(mach->accel.crt_offset_lo | (mach->accel.crt_offset_hi << 16)) << 2;*/ dev->pitch = dev->ext_pitch; @@ -3015,6 +3113,15 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u int bkgd_sel; int mono_src; + if (port & 0x8000) { + if ((port & 0x06) != 0x06) { + if ((port != 0xe2e8) && (port != 0xe2e9) && (port != 0xe6e8) && (port != 0xe6e9)) { + if (port & 0x4000) + port &= ~0x4000; + } + } + } + mach_log("[%04X:%08X]: Port FIFO OUT=%04x, val=%04x, len=%d.\n", CS, cpu_state.pc, port, val, len); switch (port) { @@ -3240,12 +3347,16 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0x4ae8: dev->accel.advfunc_cntl = val; - dev->on = dev->accel.advfunc_cntl & 0x01; + dev->on = val & 0x01; dev->vendor_mode = 0; - mach_log("[%04X:%08X]: ATI 8514/A: (0x%04x): ON=%d, shadow crt=%x, hdisp=%d, vdisp=%d.\n", - CS, cpu_state.pc, port, val & 0x01, dev->accel.advfunc_cntl & 0x04, dev->hdisp, dev->vdisp); + mach_log("[%04X:%08X]: ATI 8514/A: (0x%04x): ON=%d, shadow crt=%x, hdisp=%d, vdisp=%d, extmode=%02x.\n", + CS, cpu_state.pc, port, val & 0x01, dev->accel.advfunc_cntl & 0x04, dev->hdisp, dev->vdisp, mach->regs[0xb0] & 0x20); if (ATI_MACH32) { + if ((mach->regs[0xb0] & 0x20) || (dev->accel_bpp >= 15)) { /*Account for the extended ATI 8514/A mode here too*/ + dev->on |= 0x01; + dev->vendor_mode = 1; + } mach_set_resolution(mach, svga); mach32_updatemapping(mach, svga); } else { @@ -3257,14 +3368,10 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0x82e8: case 0x86e8: - case 0xc2e8: - case 0xc6e8: - case 0xf6ee: ibm8514_accel_out_fifo(svga, port, val, len); break; case 0x8ae8: - case 0xcae8: ibm8514_accel_out_fifo(svga, port, val, len); if (len == 2) { mach_log("SRCY=%d.\n", val & 0x07ff); @@ -3273,7 +3380,6 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u break; case 0x8ee8: - case 0xcee8: ibm8514_accel_out_fifo(svga, port, val, len); if (len == 2) { mach_log("SRCX=%d.\n", val & 0x07ff); @@ -3282,64 +3388,55 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u break; case 0x92e8: - case 0xd2e8: ibm8514_accel_out_fifo(svga, port, val, len); break; case 0x96e8: - case 0xd6e8: ibm8514_accel_out_fifo(svga, port, val, len); if (len == 2) mach->accel.test = val & 0x1fff; break; case 0x9ae8: - case 0xdae8: mach->accel.cmd_type = -1; ibm8514_accel_out_fifo(svga, port, val, len); break; case 0x9ee8: - case 0xdee8: ibm8514_accel_out_fifo(svga, port, val, len); break; case 0xa2e8: case 0xe2e8: if (port == 0xe2e8) { + mach_log("%04X: Background Color=%04x.\n", port, val); if (len == 2) { - if (dev->accel.cmd_back) { - if (mach->accel.cmd_type == 5) { - if (dev->accel.sy >= 0) { - if (mach_pixel_read(mach)) - break; - - mach_accel_out_pixtrans(svga, mach, dev, val); - } else - dev->accel.bkgd_color = val; - } else - dev->accel.bkgd_color = val; - - mach_log("%04X: CMDBack BKGDCOLOR, sy=%d, height=%d, val=%04x.\n", port, dev->accel.sy, mach->accel.height, val); - } else { + if (!dev->accel.cmd_back) { if (mach->accel.cmd_type >= 0) { if (mach_pixel_read(mach)) break; + mach_log("ATI transfer.\n"); mach_accel_out_pixtrans(svga, mach, dev, val); } else { if (ibm8514_cpu_dest(svga)) break; + mach_log("IBM transfer.\n"); ibm8514_accel_out_pixtrans(svga, port, val, len); } + } else { + dev->accel.bkgd_color = val; + mach_log("%04X: CMDBack BKGDCOLOR, sy=%d, height=%d, cmdtype=%d, val=%04x.\n", port, dev->accel.sy, mach->accel.height, mach->accel.cmd_type, val); } } else { - if (mach->accel.cmd_type >= 0) { - if (mach_pixel_read(mach)) - break; + if (dev->accel.cmd & 0x100) { + if (mach->accel.cmd_type >= 0) { + if (mach_pixel_read(mach)) + break; - mach->accel.pix_trans[1] = val; + mach->accel.pix_trans[1] = val; + } } } } else { @@ -3353,42 +3450,39 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0xa6e8: case 0xe6e8: if (port == 0xe6e8) { + mach_log("%04X: Foreground Color=%04x.\n", port, val); if (len == 2) { - if (dev->accel.cmd_back) { - if (mach->accel.cmd_type == 5) { - if (dev->accel.sy >= 0) { - if (mach_pixel_read(mach)) - break; - - mach_accel_out_pixtrans(svga, mach, dev, val); - } else - dev->accel.frgd_color = val; - } else - dev->accel.frgd_color = val; - } else { + if (!dev->accel.cmd_back) { if (mach->accel.cmd_type >= 0) { if (mach_pixel_read(mach)) break; + mach_log("ATI transfer.\n"); mach_accel_out_pixtrans(svga, mach, dev, val); } else { if (ibm8514_cpu_dest(svga)) break; + mach_log("IBM transfer.\n"); ibm8514_accel_out_pixtrans(svga, port, val, len); } - } + } else + dev->accel.frgd_color = val; } else { - if (mach->accel.cmd_type >= 0) { - if (mach_pixel_read(mach)) - break; + if (!dev->accel.cmd_back) { + if (mach->accel.cmd_type >= 0) { + if (mach_pixel_read(mach)) + break; - mach->accel.pix_trans[1] = val; + mach->accel.pix_trans[1] = val; + } } } } else { if (len == 2) dev->accel.frgd_color = val; + + mach_log("%04X: Foreground Color=%04x.\n", port, val); } break; @@ -3396,40 +3490,42 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0xe6e9: mach_log("Write PORT=%04x, 8514/A=%x, val=%04x, len=%d.\n", port, dev->accel.cmd_back, val, len); if (len == 1) { - if (mach->accel.cmd_type >= 0) { - if (mach_pixel_read(mach)) - break; + if (!dev->accel.cmd_back) { + if (mach->accel.cmd_type >= 0) { + if (mach_pixel_read(mach)) + break; - mach->accel.pix_trans[0] = val; - frgd_sel = (mach->accel.dp_config >> 13) & 7; - bkgd_sel = (mach->accel.dp_config >> 7) & 3; - mono_src = (mach->accel.dp_config >> 5) & 3; + mach->accel.pix_trans[0] = val; + frgd_sel = (mach->accel.dp_config >> 13) & 7; + bkgd_sel = (mach->accel.dp_config >> 7) & 3; + mono_src = (mach->accel.dp_config >> 5) & 3; - switch (mach->accel.dp_config & 0x200) { - case 0x000: /*8-bit size*/ - if (mono_src == 2) { - if ((frgd_sel != 2) && (bkgd_sel != 2)) { - mach_accel_start(mach->accel.cmd_type, 1, 8, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, svga, mach, dev); + switch (mach->accel.dp_config & 0x200) { + case 0x000: /*8-bit size*/ + if (mono_src == 2) { + if ((frgd_sel != 2) && (bkgd_sel != 2)) { + mach_accel_start(mach->accel.cmd_type, 1, 8, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, svga, mach, dev); + } else + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), svga, mach, dev); } else mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), svga, mach, dev); - } else - mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), svga, mach, dev); - break; - case 0x200: /*16-bit size*/ - if (mono_src == 2) { - if ((frgd_sel != 2) && (bkgd_sel != 2)) { - if (mach->accel.dp_config & 0x1000) - mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[1] | (mach->accel.pix_trans[0] << 8), 0, svga, mach, dev); - else - mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, svga, mach, dev); + break; + case 0x200: /*16-bit size*/ + if (mono_src == 2) { + if ((frgd_sel != 2) && (bkgd_sel != 2)) { + if (mach->accel.dp_config & 0x1000) + mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[1] | (mach->accel.pix_trans[0] << 8), 0, svga, mach, dev); + else + mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, svga, mach, dev); + } else + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), svga, mach, dev); } else mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), svga, mach, dev); - } else - mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), svga, mach, dev); - break; + break; - default: - break; + default: + break; + } } } } @@ -3441,16 +3537,10 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0xb2e8: case 0xb6e8: case 0xbae8: - case 0xeae8: - case 0xeee8: - case 0xf2e8: - case 0xf6e8: - case 0xfae8: ibm8514_accel_out_fifo(svga, port, val, len); break; case 0xbee8: - case 0xfee8: ibm8514_accel_out_fifo(svga, port, val, len); if (len == 2) { if ((dev->accel.multifunc_cntl >> 12) == 5) { @@ -3728,10 +3818,10 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u } if (ATI_MACH32) { + mach_log("Load both SRC/DST GE Offset/Pitch=%03x, offset=%08x.\n", mach->shadow_set & 0x300, dev->accel.ge_offset); if ((mach->shadow_set & 0x300) == 0x000) { - mach_log("Load both SRC/DST GE Offset/Pitch.\n"); - mach->accel.ge_offset_lo = 0; - mach->accel.ge_offset_hi = 0; + mach->accel.ge_offset_lo = 0x0000; + mach->accel.ge_offset_hi = 0x0000; } } break; @@ -3856,10 +3946,14 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0x8eee: if (len == 2) { + frgd_sel = (mach->accel.dp_config >> 13) & 7; + if (mach->accel.patt_data_idx_reg < 0x10) { mach->accel.color_pattern[mach->accel.patt_data_idx] = val & 0xff; mach->accel.color_pattern[mach->accel.patt_data_idx + 1] = (val >> 8) & 0xff; mach_log("Write Port 8eee: Color Pattern Word Data[%d]=%04x.\n", mach->accel.patt_data_idx, val); + if ((dev->accel_bpp >= 24) && (frgd_sel == 5) && (mach->accel.patt_len == 0x17)) + dev->accel.y1 = 1; } else { mach->accel.mono_pattern_normal[mach->accel.patt_data_idx - 0x10] = val & 0xff; mach->accel.mono_pattern_normal[(mach->accel.patt_data_idx + 1) - 0x10] = (val >> 8) & 0xff; @@ -4103,6 +4197,9 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) dev->accel.cmd_back = 0; + if ((mach->accel.cmd_type == 3) && !dev->accel.cmd_back && (mach->accel.dp_config == 0x0000)) /*Avoid a hang with a dummy command.*/ + dev->accel.cmd_back = 1; + mach_log("LineDraw type=%x, dpconfig=%04x.\n", mach->accel.cmd_type, mach->accel.dp_config); mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, svga, mach, dev); mach->accel.line_idx = (mach->accel.line_idx == 5) ? 4 : 2; @@ -4165,9 +4262,6 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in if (dev->force_busy) temp |= 0x0200; /*Hardware busy*/ - if (dev->accel.cmd_back) - dev->force_busy = 0; - if (dev->data_available) { temp |= 0x0100; /*Read Data available*/ if (mach->accel.cmd_type >= 0) { @@ -4623,7 +4717,7 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev) } } - if (dev->accel.cmd_back) { + if (!dev->fifo_idx) { dev->force_busy = 0; dev->force_busy2 = 0; mach->force_busy = 0; @@ -4661,7 +4755,7 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev) mach_log("FIFO Test IDX=%d, Data=%04x.\n", mach->fifo_test_idx, mach->fifo_test_data[mach->fifo_test_idx]); READ8(port, mach->fifo_test_data[mach->fifo_test_idx]); if (!mach->fifo_test_idx && ((mach->accel.dp_config == 0xaaaa) || (mach->accel.dp_config == 0x5555))) - mach->accel.dp_config = 0x2211; + mach->accel.dp_config = 0x2011; break; case 0x22ee: @@ -4761,7 +4855,6 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev) if (mach->force_busy) temp |= 0x20; - mach->force_busy = 0; if (ati_eeprom_read(&mach->eeprom)) temp |= 0x40; @@ -6076,7 +6169,8 @@ mach32_updatemapping(mach_t *mach, svga_t *svga) if (svga->attrregs[0x10] & 0x40) { dev->vendor_mode = 0; dev->on &= ~0x01; - svga_recalctimings(svga); + mach_log("No 8514/A mode on b8000.\n"); + mach_set_resolution(mach, svga); } } } @@ -6892,7 +6986,6 @@ mach8_init(const device_t *info) mach->ramdac_type = mach->pci_bus ? device_get_config_int("ramdac") : 1; dev->vram_amount = device_get_config_int("memory"); dev->vram_512k_8514 = dev->vram_amount == 512; - dev->accel.cmd_back = 1; if (ATI_MACH32) { if (mach->pci_bus) { @@ -7016,6 +7109,7 @@ mach8_init(const device_t *info) io_sethandler(0x02ea, 4, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); mach_io_set(mach); mach->accel.cmd_type = -2; + dev->accel.cmd_back = 1; if (ATI_MACH32) { svga->decode_mask = (4 << 20) - 1; @@ -7077,12 +7171,12 @@ ati8514_init(svga_t *svga, void *ext8514, void *dev8514) mach->accel.clock_sel = 0x1c; mach->shadow_set = 0x02; mach->crt_resolution = 0x02; + dev->accel.cmd_back = 1; io_sethandler(0x02ea, 4, ati8514_in, NULL, NULL, ati8514_out, NULL, NULL, svga); ati8514_io_set(svga); mach->accel.cmd_type = -2; mach->mca_bus = !!(dev->type & DEVICE_MCA); - dev->accel.cmd_back = 1; mach->config1 = 0x08 | 0x80; From 9c8c1a6f406aec432756ca19fdb4b8451bcd7260 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 2 Apr 2025 21:47:32 +0200 Subject: [PATCH 09/13] Trantor SCSI changes of the day (April 2nd, 2025) 1. The PAS SCSI controller driver mamv1.sys dislikes having bits 0-6 set when a transfer has completed, take account from this, fixes mamv1.sys incomplete CD transfers (bits 0-6 get re-enabled when the transfer is ongoing). 2. I now understand why the T128 doesn't have a block count register, it does the block count manually from the SCSI layer directly, this fixes Pseudo-DMA transfers when using, e.g.: CD transfers using a sector size of 2340 bytes. --- src/include/86box/scsi_device.h | 3 ++- src/include/86box/scsi_t128.h | 3 ++- src/scsi/scsi_t128.c | 29 +++++++++++------------------ src/sound/snd_pas16.c | 9 ++++++++- 4 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/include/86box/scsi_device.h b/src/include/86box/scsi_device.h index 62da8b7dc..289201b04 100644 --- a/src/include/86box/scsi_device.h +++ b/src/include/86box/scsi_device.h @@ -467,9 +467,10 @@ typedef struct scsi_bus_t { int msgout_pos; int is_msgout; int state; - int dma_on_pio_enabled; uint32_t bus_phase; + uint32_t total_len; + uint32_t data_repeat; double period; double speed; diff --git a/src/include/86box/scsi_t128.h b/src/include/86box/scsi_t128.h index 65148a5d1..a3bc79335 100644 --- a/src/include/86box/scsi_t128.h +++ b/src/include/86box/scsi_t128.h @@ -30,7 +30,7 @@ typedef struct t128_t { uint8_t status; uint8_t buffer[512]; uint8_t ext_ram[0x80]; - uint8_t block_count; + uint32_t block_count; int block_loaded; int pos, host_pos; @@ -39,6 +39,7 @@ typedef struct t128_t { int bios_enabled; uint8_t pos_regs[8]; + int type; pc_timer_t timer; } t128_t; diff --git a/src/scsi/scsi_t128.c b/src/scsi/scsi_t128.c index 3f273d1bb..94166054c 100644 --- a/src/scsi/scsi_t128.c +++ b/src/scsi/scsi_t128.c @@ -130,12 +130,12 @@ t128_read(uint32_t addr, void *priv) (t128->host_pos < MIN(512, dev->buffer_length))) { ret = t128->buffer[t128->host_pos++]; - t128_log("T128 Read transfer: pos=%i, addr=%x.\n", - t128->host_pos, addr & 0x1ff); + t128_log("T128 Read transfer: pos=%i, addr=%x, enabled timer=%d.\n", + t128->host_pos, addr & 0x1ff, timer_is_enabled(&t128->timer)); if (t128->host_pos == MIN(512, dev->buffer_length)) { - t128_log("T128 Transfer busy read, status=%02x, period=%lf, enabled=%d.\n", - t128->status, scsi_bus->period, timer_is_enabled(&t128->timer)); + t128_log("T128 Transfer busy read, status=%02x, period=%lf, enabled=%d, block=%d.\n", + t128->status, scsi_bus->period, timer_is_enabled(&t128->timer), scsi_bus->data_pos); t128->status &= ~0x04; if (!t128->block_loaded) { @@ -192,10 +192,6 @@ t128_dma_send_ext(void *priv, void *ext_priv) t128_log("T128 DMA OUT, len=%d.\n", dev->buffer_length); memset(t128->buffer, 0, MIN(512, dev->buffer_length)); t128->host_pos = 0; - t128->block_count = dev->buffer_length >> 9; - - if (dev->buffer_length < 512) - t128->block_count = 1; t128->block_loaded = 1; t128->status |= 0x04; @@ -215,10 +211,6 @@ t128_dma_initiator_receive_ext(void *priv, void *ext_priv) t128_log("T128 DMA IN, len=%d.\n", dev->buffer_length); memset(t128->buffer, 0, MIN(512, dev->buffer_length)); t128->host_pos = MIN(512, dev->buffer_length); - t128->block_count = dev->buffer_length >> 9; - - if (dev->buffer_length < 512) - t128->block_count = 1; t128->block_loaded = 1; t128->status &= ~0x04; @@ -295,9 +287,9 @@ t128_callback(void *priv) t128->status &= ~0x02; t128->pos = 0; t128->host_pos = 0; - t128->block_count = (t128->block_count - 1) & 0xff; + scsi_bus->data_repeat = 0; t128_log("T128 Remaining blocks to be written=%d\n", t128->block_count); - if (!t128->block_count) { + if (scsi_bus->data_pos >= dev->buffer_length) { t128->block_loaded = 0; ncr->tcr |= TCR_LAST_BYTE_SENT; ncr->isr |= STATUS_END_OF_DMA; @@ -344,11 +336,11 @@ t128_callback(void *priv) 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->data_repeat = 0; + t128_log("T128 blocks read=%d, total len=%d\n", scsi_bus->data_pos, dev->buffer_length); + if (scsi_bus->data_pos >= dev->buffer_length) { scsi_bus->bus_out |= BUS_REQ; + t128->block_loaded = 0; timer_on_auto(&t128->timer, 10.0); t128_log("IO End of read transfer\n"); } @@ -472,6 +464,7 @@ t128_init(const device_t *info) ncr->bus = scsi_get_bus(); scsi_bus = &ncr->scsibus; + t128->type = info->local; if (info->flags & DEVICE_MCA) { rom_init(&t128->bios_rom, T128_ROM, diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 675582367..dd95eac4c 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -792,7 +792,14 @@ pas16_in(uint16_t port, void *priv) if ((scsi_bus->tx_mode == PIO_TX_BUS) && !(ret & 0x80)) ret |= 0x80; - pas16_log("5C01 read ret=%02x, status=%02x, txmode=%x.\n", ret, pas16->scsi->status & 0x06, scsi_bus->tx_mode); + if (ret & 0x80) { + if (scsi_bus->data_repeat < MIN(511, scsi_bus->total_len)) + scsi_bus->data_repeat++; + } else { + if (scsi_bus->data_repeat == MIN(511, scsi_bus->total_len)) + ret = 0x00; + } + pas16_log("%04X:%08X: Port %04x read ret=%02x, status=%02x, txmode=%x, repeat=%d.\n", CS, cpu_state.pc, port + pas16->base, ret, pas16->scsi->status & 0x06, scsi_bus->tx_mode, scsi_bus->data_repeat); } break; case 0x5c03: From 4bd374a7dfcceebac5249fb01409c7395762bb6d Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 2 Apr 2025 16:55:57 -0300 Subject: [PATCH 10/13] Don't apply the Deschutes cacheability fix to Covington --- src/cpu/cpu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 61bd8bf36..ffe582604 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -2651,8 +2651,9 @@ cpu_ven_reset(void) msr.mtrr_cap = 0x00000508ULL; /* 4 GB cacheable space on Deschutes 651h and later (including the 1632h - Overdrive) according to the Pentium II Processor Specification Update. */ - if (cpu_s->cpuid_model >= 0x651) + Overdrive) according to the Pentium II Processor Specification Update. + Covington 651h (no L2 cache) reports the same 512 MB value as Klamath. */ + if (CPUID >= (!strncmp(cpu_f->internal_name, "celeron", 7) ? 0x660 : 0x651)) msr.bbl_cr_ctl3 |= 0x00300000; break; From cfc8e0dc4e6780bbdbbfb81ef6ac267730e21fb9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 3 Apr 2025 06:17:27 +0200 Subject: [PATCH 11/13] Settings Storage Devices: No longer cut off the second SCSI controller. --- src/qt/qt_settingsstoragecontrollers.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/qt/qt_settingsstoragecontrollers.cpp b/src/qt/qt_settingsstoragecontrollers.cpp index eebed79e2..002b9e1d3 100644 --- a/src/qt/qt_settingsstoragecontrollers.cpp +++ b/src/qt/qt_settingsstoragecontrollers.cpp @@ -195,12 +195,10 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId) if (scsi_card_available(c)) { if (device_is_valid(scsi_card_getdevice(c), machineId)) { for (uint8_t i = 0; i < SCSI_CARD_MAX; ++i) { - if ((c != 1) || ((i == 0) && m_has_scsi)) { - int row = Models::AddEntry(models[i], name, c); + int row = Models::AddEntry(models[i], name, c); - if (c == scsi_card_current[i]) - selectedRows[i] = row - removeRows_[i]; - } + if (c == scsi_card_current[i]) + selectedRows[i] = row - removeRows_[i]; } } } From df7acc618bccd33d504e8a5fa5d1a0e53e72ee0b Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 3 Apr 2025 06:19:36 +0200 Subject: [PATCH 12/13] Remove the now unused variable m_has_scsi. --- src/qt/qt_settingsstoragecontrollers.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/qt/qt_settingsstoragecontrollers.cpp b/src/qt/qt_settingsstoragecontrollers.cpp index 002b9e1d3..9bd1bda6f 100644 --- a/src/qt/qt_settingsstoragecontrollers.cpp +++ b/src/qt/qt_settingsstoragecontrollers.cpp @@ -176,7 +176,6 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId) QAbstractItemModel *models[SCSI_CARD_MAX] = { 0 }; int removeRows_[SCSI_CARD_MAX] = { 0 }; int selectedRows[SCSI_CARD_MAX] = { 0 }; - int m_has_scsi = machine_has_flags(machineId, MACHINE_SCSI); for (uint8_t i = 0; i < SCSI_CARD_MAX; ++i) { cbox[i] = findChild(QString("comboBoxSCSI%1").arg(i + 1)); From c63d900a9383b74fbd8a5fa7209a0b2a6364a913 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 3 Apr 2025 06:35:53 +0200 Subject: [PATCH 13/13] CMS: Divide SAA samples by 2 so that the sum remains within the -32767 to 32768 range and avoids clipping. --- src/sound/snd_cms.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sound/snd_cms.c b/src/sound/snd_cms.c index c6591b1fc..9491e3076 100644 --- a/src/sound/snd_cms.c +++ b/src/sound/snd_cms.c @@ -34,7 +34,7 @@ cms_get_buffer(int32_t *buffer, int len, void *priv) cms_update(cms); for (int c = 0; c < len * 2; c++) - buffer[c] += cms->buffer[c]; + buffer[c] += (cms->buffer[c] / 2); cms->pos = 0; } @@ -47,7 +47,7 @@ cms_get_buffer_2(int32_t *buffer, int len, void *priv) cms_update(cms); for (int c = 0; c < len * 2; c++) - buffer[c] += cms->buffer2[c]; + buffer[c] += (cms->buffer2[c] / 2); cms->pos2 = 0; }