From b607d191f4b4ba55fd4a1b1aa1260fe76483875c Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 22 Jan 2024 15:35:32 +0100 Subject: [PATCH 01/23] Fix the WD1004A-WX1 BIOS and jumpers. --- src/disk/hdc_st506_xt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/disk/hdc_st506_xt.c b/src/disk/hdc_st506_xt.c index 79a5a8eba..fc20350b0 100644 --- a/src/disk/hdc_st506_xt.c +++ b/src/disk/hdc_st506_xt.c @@ -107,7 +107,7 @@ #define ST11_BIOS_FILE_OLD "roms/hdd/st506/st11_bios_vers_1.7.bin" #define ST11_BIOS_FILE_NEW "roms/hdd/st506/st11_bios_vers_2.0.bin" #define WD1002A_WX1_BIOS_FILE "roms/hdd/st506/wd1002a_wx1-62-000094-032.bin" -#define WD1004A_WX1_BIOS_FILE "roms/hdd/st506/wd1002a_wx1-62-000094-032.bin" +#define WD1004A_WX1_BIOS_FILE "roms/hdd/st506/western_digital_WD1004A-27X.bin" /* SuperBIOS was for both the WX1 and 27X, users jumpers readout to determine if to use 26 sectors per track, 26 -> 17 sectors per track translation, or 17 sectors per track. */ @@ -1667,7 +1667,7 @@ st506_init(const device_t *info) fn = WD1004A_WX1_BIOS_FILE; /* The switches are read in reverse: 0 = closed, 1 = open. Both open means MFM, 17 sectors per track. */ - dev->switches = 0x10; /* autobios */ + dev->switches = 0x30; /* autobios */ dev->base = device_get_config_hex16("base"); dev->irq = device_get_config_int("irq"); if (dev->irq == 2) From 9844cbc2459cc33d18ae17253e431547e5504579 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Tue, 23 Jan 2024 16:02:32 +1300 Subject: [PATCH 02/23] Add 8-dot hscroll compensation to EGA graphics modes This is in lieu of whatever the correct emulation would be (as per the text modes). Somehow I forgot to add this when reworking the fine scroll implementations. --- src/video/vid_ega_render.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/video/vid_ega_render.c b/src/video/vid_ega_render.c index 98905e0c8..0cb1216ad 100644 --- a/src/video/vid_ega_render.c +++ b/src/video/vid_ega_render.c @@ -199,6 +199,7 @@ ega_render_graphics(ega_t *ega) const bool attrblink = ((ega->attrregs[0x10] & 8) != 0); const bool blinked = ega->blink & 0x10; const bool crtcreset = ((ega->crtc[0x17] & 0x80) == 0); + const bool seq9dot = ((ega->seqregs[1] & 1) == 0); const bool seqoddeven = ((ega->seqregs[1] & 4) != 0); const uint8_t blinkmask = (attrblink && blinked ? 0x8 : 0x0); uint32_t *p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; @@ -206,6 +207,15 @@ ega_render_graphics(ega_t *ega) const int dotwidth = 1 << dwshift; const int charwidth = dotwidth * 8; int secondcclk = 0; + + /* Compensate for 8dot scroll */ + if (!seq9dot) { + for (int x = 0; x < dotwidth; x++) { + p[x] = ega->overscan_color; + } + p += dotwidth; + } + for (int x = 0; x <= (ega->hdisp + ega->scrollcache); x += charwidth) { uint32_t addr = ega->remap_func(ega, ega->ma) & ega->vrammask; From e5000f7419d1020c4e657b4168f91658d3b1c746 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Tue, 23 Jan 2024 17:03:33 +1300 Subject: [PATCH 03/23] Fix fine scroll wobbling in EGA when calling `ega_recalctimings` Closes: GH-4072 --- src/video/vid_ega.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 670d88e61..282fde656 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -557,7 +557,7 @@ ega_recalctimings(ega_t *ega) overscan_x <<= 1; ega->y_add = (overscan_y >> 1); - ega->x_add = (overscan_x >> 1); + ega->x_add = (overscan_x >> 1) - ega->scrollcache; if (ega->vres) ega->y_add >>= 1; From 257cf0d1a2cb18bfd28cf5230a9a8bf27198a492 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Tue, 23 Jan 2024 17:06:39 +1300 Subject: [PATCH 04/23] Remove the "reset horizontal fine scroll on split screen" VGAism from EGA --- src/video/vid_ega.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 282fde656..7979cd958 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -804,10 +804,6 @@ ega_poll(void *priv) ega->cca = ega->ma; ega->maback <<= 2; ega->sc = 0; - if (ega->attrregs[0x10] & 0x20) { - ega->scrollcache = 0; - ega->x_add = (overscan_x >> 1); - } } if (ega->vc == ega->dispend) { ega->dispon = 0; From a21b8d865dad4cc229739ca1bf215452f6cc0a62 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 23 Jan 2024 19:15:50 +0100 Subject: [PATCH 05/23] MGA: Line draw rework/fixes by TC1995, fixes the Setup bug reported by Luennix. --- src/video/vid_mga.c | 215 +++++++++++++++++++++++++------------------- 1 file changed, 124 insertions(+), 91 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 44a33db2e..bc335fc9c 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -469,7 +469,7 @@ typedef struct mystique_t { lfb_base, ctrl_base, iload_base, ma_latch_old, maccess, mctlwtst, maccess_running, softrap_pending_val; - + atomic_uint status; atomic_bool softrap_status_read; @@ -502,7 +502,7 @@ typedef struct mystique_t { int xoff, yoff, selline, ydst, length_cur, iload_rem_count, idump_end_of_line, words, ta_key, ta_mask, lastpix_r, lastpix_g, - lastpix_b, highv_line, beta, dither; + lastpix_b, highv_line, beta, dither, err, k1, k2; int pattern[8][16]; @@ -764,13 +764,13 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) old = mystique->crtcext_regs[mystique->crtcext_idx]; if (mystique->crtcext_idx < 6) mystique->crtcext_regs[mystique->crtcext_idx] = val; - + if ((mystique->type >= MGA_1064SG) && (mystique->crtcext_idx == 0) && (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE)) { svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); - if (!(mystique->type >= MGA_2164W)) + if (!(mystique->type >= MGA_2164W)) svga->rowoffset <<= 1; svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | @@ -2394,10 +2394,10 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) break; case REG_SHIFT: - mystique->dwgreg.funcnt = val & 0xff; + mystique->dwgreg.funcnt = val & 0x7f; mystique->dwgreg.xoff = val & 7; mystique->dwgreg.yoff = (val >> 4) & 7; - mystique->dwgreg.stylelen = (val >> 16) & 0xff; + mystique->dwgreg.stylelen = (val >> 16) & 0x7f; break; case REG_PITCH: @@ -2601,7 +2601,7 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) case REG_ALPHACTRL: mystique->dwgreg.alphactrl = val; break; - + case REG_ALPHASTART: mystique->dwgreg.alphastart = val; break; @@ -2617,7 +2617,7 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) case REG_FOGCOL: mystique->dwgreg.fogcol = val; break; - + case REG_FOGSTART: mystique->dwgreg.fogstart = val; break; @@ -2678,7 +2678,7 @@ mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) wake_fifo_thread(mystique); } /* HACK: For DirectX 9.0b Direct3D testing on Windows 98 SE. - + The 4.12.013 drivers give an out-of-bounds busmastering range when dxdiag enumerates Direct3D, with exactly 16384 bytes of difference. Don't attempt busmastering in such cases. This isn't ideal, but there are no more crashes faced in this case. */ if ((mystique->dma.primend & DMA_ADDR_MASK) < (mystique->dma.primaddress & DMA_ADDR_MASK) && ((mystique->dma.primaddress & DMA_ADDR_MASK) - (mystique->dma.primend & DMA_ADDR_MASK)) == 0x4000) @@ -3229,7 +3229,7 @@ mystique_softrap_pending_timer(void *priv) mystique_update_irqs(mystique); mystique->softrap_pending--; } - + } static void @@ -4309,21 +4309,19 @@ z_check_32(uint32_t z, uint32_t old_z, uint32_t z_mode) // mystique->dwgreg.dwgc } static void -blit_line(mystique_t *mystique, int closed) +blit_line(mystique_t *mystique, int closed, int autoline) { svga_t *svga = &mystique->svga; uint32_t src = 0; uint32_t dst; uint32_t old_dst; - int x; - int len = 0; + int x = mystique->dwgreg.xdst; int z_write; switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { case DWGCTRL_ATYPE_RSTR: case DWGCTRL_ATYPE_RPL: - x = mystique->dwgreg.xdst; - while (len <= mystique->dwgreg.length) { + while (mystique->dwgreg.length >= 0) { if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { case MACCESS_PWIDTH_8: @@ -4334,7 +4332,10 @@ blit_line(mystique_t *mystique, int closed) if (closed) { svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; - } else if (!closed && (len < mystique->dwgreg.length)) { + } else if (!closed && (mystique->dwgreg.length > 0) && ((mystique->dwgreg.err > 0) || (mystique->dwgreg.err < 0)) && !autoline) { + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + } else if (!closed && (mystique->dwgreg.length > 0) && autoline) { svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; } @@ -4348,7 +4349,10 @@ blit_line(mystique_t *mystique, int closed) if (closed) { ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; - } else if (!closed && (len < mystique->dwgreg.length)) { + } else if (!closed && (mystique->dwgreg.length > 0) && ((mystique->dwgreg.err > 0) || (mystique->dwgreg.err < 0)) && !autoline) { + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + } else if (!closed && (mystique->dwgreg.length > 0) && autoline) { ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; } @@ -4362,7 +4366,10 @@ blit_line(mystique_t *mystique, int closed) if (closed) { *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; - } else if (!closed && (len < mystique->dwgreg.length)) { + } else if (!closed && (mystique->dwgreg.length > 0) && ((mystique->dwgreg.err > 0) || (mystique->dwgreg.err < 0)) && !autoline) { + *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + } else if (!closed && (mystique->dwgreg.length > 0) && autoline) { *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; } @@ -4376,7 +4383,10 @@ blit_line(mystique_t *mystique, int closed) if (closed) { ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; - } else if (!closed && (len < mystique->dwgreg.length)) { + } else if (!closed && (mystique->dwgreg.length > 0) && ((mystique->dwgreg.err > 0) || (mystique->dwgreg.err < 0)) && !autoline) { + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + } else if (!closed && (mystique->dwgreg.length > 0) && autoline) { ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; } @@ -4387,28 +4397,34 @@ blit_line(mystique_t *mystique, int closed) } } + if (!mystique->dwgreg.length) + break; + if (mystique->dwgreg.sgn.sdydxl) x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - else + else { + mystique->dwgreg.ydst += (mystique->dwgreg.sgn.sdy ? -1 : 1); + mystique->dwgreg.ydst &= 0x7fffff; mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); - - if ((int32_t) mystique->dwgreg.ar[1] >= 0) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; - if (mystique->dwgreg.sgn.sdydxl) + } + if (mystique->dwgreg.err >= 0) { + mystique->dwgreg.err += mystique->dwgreg.k2; + if (mystique->dwgreg.sgn.sdydxl) { + mystique->dwgreg.ydst += (mystique->dwgreg.sgn.sdy ? -1 : 1); + mystique->dwgreg.ydst &= 0x7fffff; mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); - else + } else x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); } else - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.err += mystique->dwgreg.k1; - len++; + mystique->dwgreg.length--; } break; case DWGCTRL_ATYPE_I: case DWGCTRL_ATYPE_ZI: z_write = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) == DWGCTRL_ATYPE_ZI); - x = mystique->dwgreg.xdst; while (mystique->dwgreg.length > 0) { if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { bool z_check_pass = false; @@ -4471,8 +4487,8 @@ blit_line(mystique_t *mystique, int closed) mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; - if ((int32_t) mystique->dwgreg.ar[1] >= 0) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + if (mystique->dwgreg.err >= 0) { + mystique->dwgreg.err += mystique->dwgreg.k2; if (mystique->dwgreg.sgn.sdydxl) mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); @@ -4490,7 +4506,7 @@ blit_line(mystique_t *mystique, int closed) mystique->dwgreg.dr[8] += mystique->dwgreg.dr[11]; mystique->dwgreg.dr[12] += mystique->dwgreg.dr[15]; } else - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.err += mystique->dwgreg.k1; mystique->dwgreg.length--; } @@ -4507,7 +4523,7 @@ blit_line(mystique_t *mystique, int closed) } static void -blit_autoline(mystique_t *mystique, int closed) +blit_line_start(mystique_t *mystique, int closed, int autoline) { int start_x = (int32_t) mystique->dwgreg.ar[5]; int start_y = (int32_t) mystique->dwgreg.ar[6]; @@ -4516,29 +4532,37 @@ blit_autoline(mystique_t *mystique, int closed) int dx = end_x - start_x; int dy = end_y - start_y; - if (ABS(dx) > ABS(dy)) { - mystique->dwgreg.sgn.sdydxl = 1; - mystique->dwgreg.ar[0] = 2 * ABS(dy); - mystique->dwgreg.ar[1] = 2 * ABS(dy) - ABS(dx) - ((start_y > end_y) ? 1 : 0); - mystique->dwgreg.ar[2] = 2 * ABS(dy) - 2 * ABS(dx); - mystique->dwgreg.length = ABS(end_x - start_x); + if (autoline) { + if (ABS(dx) > ABS(dy)) { + mystique->dwgreg.sgn.sdydxl = 1; + mystique->dwgreg.k1 = 2 * ABS(dy); + mystique->dwgreg.err = 2 * ABS(dy) - ABS(dx) - ((start_y > end_y) ? 1 : 0); + mystique->dwgreg.k2 = 2 * ABS(dy) - 2 * ABS(dx); + mystique->dwgreg.length = ABS(end_x - start_x); + } else { + mystique->dwgreg.sgn.sdydxl = 0; + mystique->dwgreg.k1 = 2 * ABS(dx); + mystique->dwgreg.err = 2 * ABS(dx) - ABS(dy) - ((start_y > end_y) ? 1 : 0); + mystique->dwgreg.k2 = 2 * ABS(dx) - 2 * ABS(dy); + mystique->dwgreg.length = ABS(end_y - start_y); + } + mystique->dwgreg.sgn.sdxl = (start_x > end_x) ? 1 : 0; + mystique->dwgreg.sgn.sdy = (start_y > end_y) ? 1 : 0; } else { - mystique->dwgreg.sgn.sdydxl = 0; - mystique->dwgreg.ar[0] = 2 * ABS(dx); - mystique->dwgreg.ar[1] = 2 * ABS(dx) - ABS(dy) - ((start_y > end_y) ? 1 : 0); - mystique->dwgreg.ar[2] = 2 * ABS(dx) - 2 * ABS(dy); - mystique->dwgreg.length = ABS(end_y - start_y); + mystique->dwgreg.k1 = (int32_t) mystique->dwgreg.ar[0]; + mystique->dwgreg.err = (int32_t) mystique->dwgreg.ar[1]; + mystique->dwgreg.k2 = (int32_t) mystique->dwgreg.ar[2]; } - mystique->dwgreg.sgn.sdxl = (start_x > end_x) ? 1 : 0; - mystique->dwgreg.sgn.sdy = (start_y > end_y) ? 1 : 0; - blit_line(mystique, closed); + blit_line(mystique, closed, autoline); - mystique->dwgreg.ar[5] = end_x; - mystique->dwgreg.xdst = end_x; - mystique->dwgreg.ar[6] = end_y; - mystique->dwgreg.ydst = end_y; - mystique->dwgreg.ydst_lin = ((int32_t) (int16_t) mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; + if (autoline) { + mystique->dwgreg.ar[5] = end_x; + mystique->dwgreg.xdst = end_x; + mystique->dwgreg.ar[6] = end_y; + mystique->dwgreg.ydst = end_y; + mystique->dwgreg.ydst_lin = ((int32_t) (int16_t) mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; + } } static void @@ -4552,6 +4576,8 @@ blit_trap(mystique_t *mystique) uint32_t b_back; int z_write; int y; + int err_l = (int32_t)mystique->dwgreg.ar[1]; + int err_r = (int32_t)mystique->dwgreg.ar[4]; const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { @@ -4562,8 +4588,14 @@ blit_trap(mystique_t *mystique) int16_t x_l = mystique->dwgreg.fxleft & 0xffff; int16_t x_r = mystique->dwgreg.fxright & 0xffff; int yoff = (mystique->dwgreg.yoff + mystique->dwgreg.ydst) & 7; + int len; - while (x_l != x_r) { + if (x_l > x_r) + len = x_l - x_r; + else + len = x_r - x_l; + + while (len > 0) { if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) { int xoff = (mystique->dwgreg.xoff + (x_l & 7)) & 15; int pattern = mystique->dwgreg.pattern[yoff][xoff]; @@ -4595,24 +4627,21 @@ blit_trap(mystique_t *mystique) fatal("TRAP BLK/RPL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); } } - if (x_l > x_r) - x_l--; - else - x_l++; - + len--; + x_l++; } - while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + while ((err_l < 0) && mystique->dwgreg.ar[0]) { + err_l += mystique->dwgreg.ar[0]; mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); } - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + err_l += mystique->dwgreg.ar[2]; - while ((int32_t) mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; + while ((err_r < 0) && mystique->dwgreg.ar[6]) { + err_r += mystique->dwgreg.ar[6]; mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); } - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + err_r += mystique->dwgreg.ar[5]; mystique->dwgreg.ydst++; mystique->dwgreg.ydst &= 0x7fffff; @@ -4628,8 +4657,14 @@ blit_trap(mystique_t *mystique) int16_t x_l = mystique->dwgreg.fxleft & 0xffff; int16_t x_r = mystique->dwgreg.fxright & 0xffff; int yoff = (mystique->dwgreg.yoff + mystique->dwgreg.ydst) & 7; + int len; - while (x_l != x_r) { + if (x_l > x_r) + len = x_l - x_r; + else + len = x_r - x_l; + + while (len > 0) { if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) { int xoff = (mystique->dwgreg.xoff + (x_l & 7)) & 15; int pattern = mystique->dwgreg.pattern[yoff][xoff]; @@ -4674,23 +4709,21 @@ blit_trap(mystique_t *mystique) fatal("TRAP RSTR PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); } } - if (x_l > x_r) - x_l--; - else - x_l++; + x_l++; + len--; } - while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + while ((err_l < 0) && mystique->dwgreg.ar[0]) { + err_l += mystique->dwgreg.ar[0]; mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); } - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + err_l += mystique->dwgreg.ar[2]; - while ((int32_t) mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; + while ((err_r < 0) && mystique->dwgreg.ar[6]) { + err_r += mystique->dwgreg.ar[6]; mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); } - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + err_r += mystique->dwgreg.ar[5]; mystique->dwgreg.ydst++; mystique->dwgreg.ydst &= 0x7fffff; @@ -5801,19 +5834,19 @@ mystique_start_blit(mystique_t *mystique) switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) { case DWGCTRL_OPCODE_LINE_OPEN: - blit_line(mystique, 0); + blit_line_start(mystique, 0, 0); break; case DWGCTRL_OPCODE_AUTOLINE_OPEN: - blit_autoline(mystique, 0); + blit_line_start(mystique, 0, 1); break; case DWGCTRL_OPCODE_LINE_CLOSE: - blit_line(mystique, 1); + blit_line_start(mystique, 1, 0); break; case DWGCTRL_OPCODE_AUTOLINE_CLOSE: - blit_autoline(mystique, 1); + blit_line_start(mystique, 1, 1); break; case DWGCTRL_OPCODE_TRAP: @@ -6046,7 +6079,7 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) case 0x33: ret = mystique->pci_regs[0x33]; break; - + case 0x34: ret = mystique->type == MGA_G100 ? 0xdc : 0x00; break; @@ -6089,7 +6122,7 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) case 0xdc: ret = 0x01; break; - + case 0xdd: ret = 0xf0; break; @@ -6097,7 +6130,7 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) case 0xde: ret = 0x21; break; - + /* No support for turning off the video adapter yet. */ case 0xe0: ret = 0x0; @@ -6106,19 +6139,19 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) case 0xf0: ret = 0x02; break; - + case 0xf1: ret = 0x00; break; - + case 0xf2: ret = 0x10; break; - + case 0xf4: ret = 0x1; break; - + case 0xf5: ret = 0x2; break; @@ -6126,15 +6159,15 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) case 0xf7: ret = 0x1; break; - + case 0xf8: ret = mystique->pci_regs[0xf8] & 0x7; break; - + case 0xf9: ret = mystique->pci_regs[0xf9] & 0x3; break; - + case 0xfb: ret = mystique->pci_regs[0xfb]; break; @@ -6277,11 +6310,11 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) case 0xf8: mystique->pci_regs[0xf8] = val & 0x7; break; - + case 0xf9: mystique->pci_regs[0xf9] = val & 0x3; break; - + case 0xfb: mystique->pci_regs[0xfb] = val; break; @@ -6455,7 +6488,7 @@ mystique_init(const device_t *info) timer_add(&mystique->softrap_pending_timer, mystique_softrap_pending_timer, (void *) mystique, 1); mystique->status = STATUS_ENDPRDMASTS; - + mystique->softrap_status_read = 1; mystique->svga.vsync_callback = mystique_vsync_callback; From 9107c2fa257df891fbc4be8c8c47c0e14096ec5c Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 24 Jan 2024 04:56:31 +0100 Subject: [PATCH 06/23] Added the AOpen AP61 and fixed floppies on the LG IBM 440 FX. --- src/chipset/intel_i450kx.c | 56 +++++++++++++++++-------------------- src/cpu/cpu.c | 56 +++++++++++-------------------------- src/cpu/cpu.h | 17 ++++------- src/include/86box/machine.h | 2 +- src/machine/m_at_socket8.c | 39 ++++++++++++++++++++++++-- src/machine/machine_table.c | 40 ++++++++++++++++++++++++++ src/sio/sio_w83787f.c | 10 ++++--- src/sio/sio_w83877f.c | 11 ++++---- 8 files changed, 139 insertions(+), 92 deletions(-) diff --git a/src/chipset/intel_i450kx.c b/src/chipset/intel_i450kx.c index 90b807a6d..2f6547309 100644 --- a/src/chipset/intel_i450kx.c +++ b/src/chipset/intel_i450kx.c @@ -8,19 +8,14 @@ * * Implementation of the Intel 450KX Mars Chipset. * + * i450GX is way more popular of an option but needs more stuff. * + * Authors: Miran Grca, + * Tiseno100, * - * Authors: Tiseno100 - * + * Copyright 2021-2024 Miran Grca. * Copyright 2021 Tiseno100. */ - -/* -Note: i450KX PB manages PCI memory access with MC manages DRAM memory access. -Due to 86Box limitations we can't manage them seperately thus it is dev branch till then. - -i450GX is way more popular of an option but needs more stuff. -*/ #include #include #include @@ -97,17 +92,18 @@ i450kx_smram_recalc(i450kx_t *dev, int bus) const uint8_t *regs = bus ? dev->pb_pci_conf : dev->mc_pci_conf; uint32_t addr; uint32_t size; + int enable = bus ? !(regs[0x57] & 0x08) : (regs[0x57] & 0x08); smram_disable(dev->smram[bus]); addr = ((uint32_t) regs[0xb8] << 16) | ((uint32_t) regs[0xb9] << 24); size = (((uint32_t) ((regs[0xbb] >> 4) & 0x0f)) << 16) + 0x00010000; - if ((addr != 0x00000000) && !!(regs[0x57] & 0x08)) { + if ((addr != 0x00000000) && enable) { if (bus) - smram_enable_ex(dev->smram[bus], addr, addr, size, 0, !!(regs[0x57] & 8), 0, 1); + smram_enable_ex(dev->smram[bus], addr, addr, size, 0, 0, 0, enable); else - smram_enable_ex(dev->smram[bus], addr, addr, size, !!(regs[0x57] & 8), 0, 1, 0); + smram_enable_ex(dev->smram[bus], addr, addr, size, 0, 0, enable, 0); } flushmmucache(); @@ -118,10 +114,8 @@ i450kx_vid_buf_recalc(i450kx_t *dev, int bus) { const uint8_t *regs = bus ? dev->pb_pci_conf : dev->mc_pci_conf; -#if 0 - // int state = (regs[0x58] & 0x02) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_DISABLED | MEM_WRITE_DISABLED); -#endif - int state = (regs[0x58] & 0x02) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + int state = (regs[0x58] & 0x02) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : + (MEM_READ_EXTANY | MEM_WRITE_EXTANY); if (bus) mem_set_mem_state_bus_both(0x000a0000, 0x00020000, state); @@ -136,10 +130,10 @@ pb_write(int func, int addr, uint8_t val, void *priv) { i450kx_t *dev = (i450kx_t *) priv; - // pclog("i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80)); - i450kx_log("i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80)); + if (func == 0) { + i450kx_log("[%04X:%08X] i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X\n", CS, cpu_state.pc, + addr, val); - if (func == 0) switch (addr) { case 0x04: dev->pb_pci_conf[addr] = (dev->pb_pci_conf[addr] & 0x04) | (val & 0x53); @@ -373,6 +367,7 @@ pb_write(int func, int addr, uint8_t val, void *priv) default: break; } + } } static uint8_t @@ -381,10 +376,12 @@ pb_read(int func, int addr, void *priv) const i450kx_t *dev = (i450kx_t *) priv; uint8_t ret = 0xff; - if (func == 0) + if (func == 0) { ret = dev->pb_pci_conf[addr]; - // pclog("i450KX-PB: [R] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, ret, inb(0x80)); + i450kx_log("[%04X:%08X] i450KX-PB: [R] dev->pb_pci_conf[%02X] = %02X\n", CS, cpu_state.pc, + addr, ret); + } return ret; } @@ -407,10 +404,10 @@ mc_write(int func, int addr, uint8_t val, void *priv) { i450kx_t *dev = (i450kx_t *) priv; - // pclog("i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80)); - i450kx_log("i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80)); + if (func == 0) { + i450kx_log("[%04X:%08X] i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X\n", CS, cpu_state.pc, + addr, val); - if (func == 0) switch (addr) { case 0x4c: dev->mc_pci_conf[addr] = val & 0xdf; @@ -600,6 +597,7 @@ mc_write(int func, int addr, uint8_t val, void *priv) default: break; } + } } static uint8_t @@ -608,10 +606,12 @@ mc_read(int func, int addr, void *priv) const i450kx_t *dev = (i450kx_t *) priv; uint8_t ret = 0xff; - if (func == 0) + if (func == 0) { ret = dev->mc_pci_conf[addr]; - // pclog("i450KX-MC: [R] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, ret, inb(0x80)); + i450kx_log("[%04X:%08X] i450KX-MC: [R] dev->mc_pci_conf[%02X] = %02X\n", CS, cpu_state.pc, + addr, ret); + } return ret; } @@ -622,10 +622,6 @@ i450kx_reset(void *priv) i450kx_t *dev = (i450kx_t *) priv; uint32_t i; -#if 0 - // pclog("i450KX: i450kx_reset()\n"); -#endif - /* Defaults PB */ dev->pb_pci_conf[0x00] = 0x86; dev->pb_pci_conf[0x01] = 0x80; diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index b6cd6f9ad..c3e3c39d4 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -2372,10 +2372,10 @@ cpu_CPUID(void) EBX = ECX = 0; EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_CMOV; } else if (EAX == 2) { - if (!strcmp(machine_get_internal_name(), "ap61")) { + /* if (!strcmp(machine_get_internal_name(), "ap61")) { EAX = 0x00000001; EDX = 0x00000000; - } else { + } else */ { EAX = 0x03020101; /* Instruction TLB: 4 KB pages, 4-way set associative, 32 entries Instruction TLB: 4 MB pages, fully associative, 2 entries Data TLB: 4 KB pages, 4-way set associative, 64 entries */ @@ -2799,7 +2799,9 @@ amd_k_invalid_rdmsr: case CPU_PENTIUM2: case CPU_PENTIUM2D: EAX = EDX = 0; - switch (ECX) { + /* Per RichardG's probing of a real Deschutes using my RDMSR tool, + we have discovered that the top 18 bits are filtered out. */ + switch (ECX & 0x00003fff) { case 0x00: case 0x01: break; @@ -2821,6 +2823,11 @@ amd_k_invalid_rdmsr: EDX = msr.apic_base >> 32; cpu_log("APIC_BASE read : %08X%08X\n", EDX, EAX); break; + /* Unknown (undocumented?) MSR used by the Hyper-V BIOS. */ + case 0x20: + EAX = msr.ecx20 & 0xffffffff; + EDX = msr.ecx20 >> 32; + break; case 0x2a: EAX = 0xc4000000; EDX = 0; @@ -3022,26 +3029,6 @@ amd_k_invalid_rdmsr: EAX = msr.ecx570 & 0xffffffff; EDX = msr.ecx570 >> 32; break; - case 0x1002ff: - EAX = msr.ecx1002ff & 0xffffffff; - EDX = msr.ecx1002ff >> 32; - break; - case 0x40000020: - EAX = msr.ecx40000020 & 0xffffffff; - EDX = msr.ecx40000020 >> 32; - break; - case 0xf0f00250: - EAX = msr.ecxf0f00250 & 0xffffffff; - EDX = msr.ecxf0f00250 >> 32; - break; - case 0xf0f00258: - EAX = msr.ecxf0f00258 & 0xffffffff; - EDX = msr.ecxf0f00258 >> 32; - break; - case 0xf0f00259: - EAX = msr.ecxf0f00259 & 0xffffffff; - EDX = msr.ecxf0f00259 >> 32; - break; default: i686_invalid_rdmsr: cpu_log("RDMSR: Invalid MSR: %08X\n", ECX); @@ -3303,7 +3290,9 @@ amd_k_invalid_wrmsr: case CPU_PENTIUMPRO: case CPU_PENTIUM2: case CPU_PENTIUM2D: - switch (ECX) { + /* Per RichardG's probing of a real Deschutes using my RDMSR tool, + we have discovered that the top 18 bits are filtered out. */ + switch (ECX & 0x00003fff) { case 0x00: case 0x01: if (EAX || EDX) @@ -3318,6 +3307,10 @@ amd_k_invalid_wrmsr: msr.apic_base = EAX | ((uint64_t) EDX << 32); #endif break; + /* Unknown (undocumented?) MSR used by the Hyper-V BIOS. */ + case 0x20: + msr.ecx20 = EAX | ((uint64_t) EDX << 32); + break; case 0x2a: break; case 0x79: @@ -3462,21 +3455,6 @@ amd_k_invalid_wrmsr: case 0x570: msr.ecx570 = EAX | ((uint64_t) EDX << 32); break; - case 0x1002ff: - msr.ecx1002ff = EAX | ((uint64_t) EDX << 32); - break; - case 0x40000020: - msr.ecx40000020 = EAX | ((uint64_t) EDX << 32); - break; - case 0xf0f00250: - msr.ecxf0f00250 = EAX | ((uint64_t) EDX << 32); - break; - case 0xf0f00258: - msr.ecxf0f00258 = EAX | ((uint64_t) EDX << 32); - break; - case 0xf0f00259: - msr.ecxf0f00259 = EAX | ((uint64_t) EDX << 32); - break; default: i686_invalid_wrmsr: cpu_log("WRMSR: Invalid MSR: %08X\n", ECX); diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 9aee59e60..e185f2e4a 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -253,6 +253,12 @@ typedef struct { /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ uint64_t apic_base; /* 0x0000001b - Should the Pentium not also have this? */ + + /* Weird long MSR's used by the Hyper-V BIOS. */ + uint64_t ecx20; /* 0x00000020, really 0x40000020, but we filter out the top 18 bits + like a real Deschutes does. */ + + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ uint64_t ecx79; /* 0x00000079 */ /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ @@ -314,9 +320,6 @@ typedef struct { /* IBM 486SLC and 486BL MSR's */ uint64_t ibm_por2; /* 0x00001002 - Processor Operation Register */ - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecx1002ff; /* 0x001002ff - MSR used by some Intel AMI boards */ - /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ uint64_t amd_efer; /* 0xc0000080 */ @@ -338,14 +341,6 @@ typedef struct { /* K6-3, K6-2P, and K6-3P MSR's */ uint64_t amd_l2aar; /* 0xc0000089 */ - - /* Weird long MSR's used by the Hyper-V BIOS. */ - uint64_t ecx40000020; /* 0x40000020 */ - - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecxf0f00250; /* 0xf0f00250 - Some weird long MSR's used by i686 AMI & some Phoenix BIOSes */ - uint64_t ecxf0f00258; /* 0xf0f00258 */ - uint64_t ecxf0f00259; /* 0xf0f00259 */ } msr_t; typedef struct { diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index faed59dae..73b27afbf 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -705,8 +705,8 @@ extern int machine_at_ficva503a_init(const machine_t *); extern int machine_at_5emapro_init(const machine_t *); /* m_at_socket8.c */ +extern int machine_at_ap61_init(const machine_t *); extern int machine_at_p6rp4_init(const machine_t *); -extern int machine_at_aurora_init(const machine_t *); extern int machine_at_686nx_init(const machine_t *); extern int machine_at_acerv60n_init(const machine_t *); diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index 6e63af732..7ce9d5095 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -39,6 +39,39 @@ #include "cpu.h" #include <86box/machine.h> +int +machine_at_ap61_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ap61/ap61r120.bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x19, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x14, PCI_CARD_NORTHBRIDGE_SEC, 0, 0, 0, 0); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_IDE, 0xFE, 0xFF, 0, 0); + pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&i450kx_device); + device_add(&sio_zb_device); + device_add(&ide_cmd646_device); + device_add(&keyboard_ps2_acer_pci_device); + device_add(&fdc37c665_device); + device_add(&sst_flash_29ee010_device); + // device_add(&intel_flash_bxt_device); + + return ret; +} + int machine_at_p6rp4_init(const machine_t *model) { @@ -183,8 +216,10 @@ machine_at_lgibm440fx_init(const machine_t *model) pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&i440fx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&w83787f_device); + // device_add(&keyboard_ps2_ami_pci_device); + device_add(&keyboard_ps2_ami_device); + // device_add(&w83787f_device); + device_add(&w83877f_president_device); device_add(&sst_flash_29ee010_device); return ret; diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 7406cce30..101052f4e 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -11655,6 +11655,46 @@ const machine_t machines[] = { /* Socket 8 machines */ /* 450KX */ /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[i450KX] AOpen AP61", + .internal_name = "ap61", + .type = MACHINE_TYPE_SOCKET8, + .chipset = MACHINE_CHIPSET_INTEL_450KX, + .init = machine_at_ap61_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET8, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2100, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ { .name = "[i450KX] ASUS P/I-P6RP4", .internal_name = "p6rp4", diff --git a/src/sio/sio_w83787f.c b/src/sio/sio_w83787f.c index 33cfc6311..2e4b82059 100644 --- a/src/sio/sio_w83787f.c +++ b/src/sio/sio_w83787f.c @@ -215,8 +215,9 @@ static void w83787f_fdc_handler(w83787f_t *dev) { fdc_remove(dev->fdc); - if (!(dev->regs[0] & 0x20) && !(dev->regs[6] & 0x08)) + if (!(dev->regs[0] & 0x20)) fdc_set_base(dev->fdc, (dev->regs[0] & 0x10) ? FDC_PRIMARY_ADDR : FDC_SECONDARY_ADDR); + fdc_set_power_down(dev->fdc, !!(dev->regs[6] & 0x08)); } static void @@ -258,10 +259,10 @@ w83787f_write(uint16_t port, uint8_t val, void *priv) return; } else { if (dev->locked) { - if (dev->rw_locked) + if (dev->rw_locked && (dev->cur_reg <= 0x0b)) return; if (dev->cur_reg == 6) - val &= 0xF3; + val &= 0xFB; valxor = val ^ dev->regs[dev->cur_reg]; dev->regs[dev->cur_reg] = val; } else @@ -363,7 +364,7 @@ w83787f_read(uint16_t port, void *priv) else if (port == 0x252) { if (dev->cur_reg == 7) ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2)); - else if (!dev->rw_locked) + else if (!dev->rw_locked || (dev->cur_reg > 0x0b)) ret = dev->regs[dev->cur_reg]; } } @@ -406,6 +407,7 @@ w83787f_reset(w83787f_t *dev) dev->regs[0x00] = 0xd0; fdc_reset(dev->fdc); + w83787f_fdc_handler(dev); dev->regs[0x01] = 0x2C; dev->regs[0x03] = 0x70; diff --git a/src/sio/sio_w83877f.c b/src/sio/sio_w83877f.c index 8cbb82876..c9a437630 100644 --- a/src/sio/sio_w83877f.c +++ b/src/sio/sio_w83877f.c @@ -78,12 +78,12 @@ w83877f_remap(w83877f_t *dev) { uint8_t hefras = HEFRAS; - io_removehandler(0x250, 0x0002, + io_removehandler(0x250, 0x0003, w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, dev); io_removehandler(FDC_PRIMARY_ADDR, 0x0002, w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, dev); dev->base_address = (hefras ? FDC_PRIMARY_ADDR : 0x250); - io_sethandler(dev->base_address, 0x0002, + io_sethandler(dev->base_address, hefras ? 0x0002 : 0x0003, w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, dev); dev->key_times = hefras + 1; dev->key = (hefras ? 0x86 : 0x88) | HEFERE; @@ -155,8 +155,9 @@ static void w83877f_fdc_handler(w83877f_t *dev) { fdc_remove(dev->fdc); - if (!(dev->regs[6] & 0x08) && (dev->regs[0x20] & 0xc0)) - fdc_set_base(dev->fdc, FDC_PRIMARY_ADDR); + if (dev->regs[0x20] & 0xc0) + fdc_set_base(dev->fdc, make_port(dev, 0x20)); + fdc_set_power_down(dev->fdc, !!(dev->regs[6] & 0x08)); } static void @@ -252,7 +253,7 @@ w83877f_write(uint16_t port, uint8_t val, void *priv) if (dev->cur_reg == 0x29) return; if (dev->cur_reg == 6) - val &= 0xF3; + val &= 0xFB; valxor = val ^ dev->regs[dev->cur_reg]; dev->regs[dev->cur_reg] = val; } else From 555cba7b8ae56a478410dc3024bffad9d63cb797 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 24 Jan 2024 05:22:22 +0100 Subject: [PATCH 07/23] RTL8139 changes: The PCI memory BAR is now 4096 bytes instead of 256 in order to fit into 86Box's memory mapping granularity, and implemented the undocumented CSCR reads discovered by RichardG when probing the real hardware. --- src/network/net_rtl8139.c | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index 74a1f90ff..a07becff0 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -308,6 +308,8 @@ enum CSCRBits { #endif enum CSCRBits { CSCR_Testfun = 1 << 15, /* 1 = Auto-neg speeds up internal timer, WO, def 0 */ + CSCR_Cable_Changed = 1 << 11, /* Undocumented: 1 = Cable status changed, 0 = No change */ + CSCR_Cable = 1 << 10, /* Undocumented: 1 = Cable connected, 0 = Cable disconnected */ CSCR_LD = 1 << 9, /* Active low TPI link disable signal. When low, TPI still transmits link pulses and TPI stays in good link state. def 1*/ CSCR_HEART_BIT = 1 << 8, /* 1 = HEART BEAT enable, 0 = HEART BEAT disable. HEART BEAT function is only valid in 10Mbps mode. def 1*/ CSCR_JBEN = 1 << 7, /* 1 = enable jabber function. 0 = disable jabber function, def 1*/ @@ -2285,7 +2287,17 @@ rtl8139_TSAD_read(RTL8139State *s) static uint16_t rtl8139_CSCR_read(RTL8139State *s) { - uint16_t ret = s->CSCR; + static uint16_t old_ret = 0xffff; + uint16_t ret = s->CSCR | + ((net_cards_conf[s->nic->card_num].link_state & NET_LINK_DOWN) ? 0 : CSCR_Cable); + + if (old_ret != 0xffff) { + ret &= ~CSCR_Cable_Changed; + if ((ret ^ old_ret) & CSCR_Cable) + ret |= CSCR_Cable_Changed; + } + + old_ret = ret; rtl8139_log("CSCR read val=0x%04x\n", ret); @@ -2736,6 +2748,13 @@ rtl8139_io_readb(uint32_t addr, void *priv) rtl8139_log("RTL8139C TxConfig at 0x43 read(b) val=0x%02x\n", ret); break; + case CSCR: + ret = rtl8139_CSCR_read(s) & 0xff; + break; + case CSCR + 1: + ret = rtl8139_CSCR_read(s) >> 8; + break; + default: rtl8139_log("not implemented read(b) addr=0x%x\n", addr); ret = 0; @@ -3105,6 +3124,10 @@ rtl8139_pci_read(UNUSED(int func), int addr, void *priv) return 1; case 0x14: return 0; +#ifndef USE_256_BYTE_BAR + case 0x15: + return s->pci_conf[addr & 0xFF] & 0xf0; +#endif case 0x2c: return 0xEC; case 0x2d: @@ -3169,10 +3192,20 @@ rtl8139_pci_write(int func, int addr, uint8_t val, void *priv) case 0x16: case 0x17: s->pci_conf[addr & 0xFF] = val; - s->mem_base = (s->pci_conf[0x15] << 8) | (s->pci_conf[0x16] << 16) | (s->pci_conf[0x17] << 24); + s->mem_base = (s->pci_conf[0x15] << 8) | (s->pci_conf[0x16] << 16) | + (s->pci_conf[0x17] << 24); +#ifndef USE_256_BYTE_BAR + s->mem_base &= 0xfffff000; +#endif rtl8139_log("New memory base: %08X\n", s->mem_base); if (s->pci_conf[0x4] & PCI_COMMAND_MEM) - mem_mapping_set_addr(&s->bar_mem, (s->pci_conf[0x15] << 8) | (s->pci_conf[0x16] << 16) | (s->pci_conf[0x17] << 24), 256); +#ifdef USE_256_BYTE_BAR + mem_mapping_set_addr(&s->bar_mem, (s->pci_conf[0x15] << 8) | (s->pci_conf[0x16] << 16) | + (s->pci_conf[0x17] << 24), 256); +#else + mem_mapping_set_addr(&s->bar_mem, ((s->pci_conf[0x15] & 0xf0) << 8) | + (s->pci_conf[0x16] << 16) | (s->pci_conf[0x17] << 24), 4096); +#endif break; case 0x3c: s->pci_conf[addr & 0xFF] = val; From ecafaa7daf4ddc2e52ce74d7efe0e55cb3ac7f59 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 24 Jan 2024 05:30:08 +0100 Subject: [PATCH 08/23] Update the GLaBIOS version to latest nightly, fixes #4074. --- src/machine/m_xt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 20a7da6ae..9a0b39a89 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -646,7 +646,7 @@ machine_xt_glabios_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/glabios/GLABIOS_0.2.5_8E.ROM", + ret = bios_load_linear("roms/machines/glabios/GLABIOS_0.2.6_8X_012324.ROM", 0x000fe000, 8192, 0); if (bios_only || !ret) @@ -655,4 +655,4 @@ machine_xt_glabios_init(const machine_t *model) machine_xt_init_ex(model); return ret; -} \ No newline at end of file +} From 13330322b491280f342f823c99e22e16626b5aa6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 24 Jan 2024 05:56:50 +0100 Subject: [PATCH 09/23] Interim mem.c/h code and a slight optimization to do_mmutranslate(). --- src/include/86box/mem.h | 2 + src/mem/mem.c | 81 +++++++++++++++++++++++++++-------------- 2 files changed, 56 insertions(+), 27 deletions(-) diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index db95d3f7b..8832ad7f9 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -449,6 +449,8 @@ extern void mem_close(void); extern void mem_reset(void); extern void mem_remap_top(int kb); +extern void umc_smram_recalc(uint32_t start, int set); + extern mem_mapping_t *read_mapping[MEM_MAPPINGS_NO]; extern mem_mapping_t *write_mapping[MEM_MAPPINGS_NO]; diff --git a/src/mem/mem.c b/src/mem/mem.c index 0b002b302..145202260 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -1585,40 +1585,38 @@ do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write) for (i = 0; i < num; i++) a64[i] = (uint64_t) addr; - for (i = 0; i < num; i++) { - if (cr0 >> 31) { - if (write && ((i == 0) || !(addr & 0xfff))) - cond = (!page_lookup[addr >> 12] || !page_lookup[addr >> 12]->write_b); + if (cr0 >> 31) for (i = 0; i < num; i++) { + if (write && ((i == 0) || !(addr & 0xfff))) + cond = (!page_lookup[addr >> 12] || !page_lookup[addr >> 12]->write_b); - if (cond) { - /* If we have encountered at least one page fault, mark all subsequent addresses as - having page faulted, prevents false negatives in readmem*l_no_mmut. */ - if ((i > 0) && cpu_state.abrt && !high_page) - a64[i] = a64[i - 1]; - /* If we are on the same page, there is no need to translate again, as we can just - reuse the previous result. */ - else if (i == 0) { - a = mmutranslatereal(addr, write); - a64[i] = (uint32_t) a; + if (cond) { + /* If we have encountered at least one page fault, mark all subsequent addresses as + having page faulted, prevents false negatives in readmem*l_no_mmut. */ + if ((i > 0) && cpu_state.abrt && !high_page) + a64[i] = a64[i - 1]; + /* If we are on the same page, there is no need to translate again, as we can just + reuse the previous result. */ + else if (i == 0) { + a = mmutranslatereal(addr, write); + a64[i] = (uint32_t) a; - high_page = high_page || (!cpu_state.abrt && (a > 0xffffffffULL)); - } else if (!(addr & 0xfff)) { - a = mmutranslatereal(last_addr, write); - a64[i] = (uint32_t) a; + high_page = high_page || (!cpu_state.abrt && (a > 0xffffffffULL)); + } else if (!(addr & 0xfff)) { + a = mmutranslatereal(last_addr, write); + a64[i] = (uint32_t) a; - high_page = high_page || (!cpu_state.abrt && (a64[i] > 0xffffffffULL)); + high_page = high_page || (!cpu_state.abrt && (a64[i] > 0xffffffffULL)); - if (!cpu_state.abrt) { - a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); - a64[i] = (uint32_t) a; - } - } else { + if (!cpu_state.abrt) { a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); a64[i] = (uint32_t) a; } - } else - mmu_perm = page_lookupp[addr >> 12]; - } + } else { + a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); + a64[i] = (uint32_t) a; + } + } else + mmu_perm = page_lookupp[addr >> 12]; addr++; } @@ -2871,6 +2869,35 @@ mem_init(void) writelookupp = malloc((1 << 20) * sizeof(uint8_t)); } +static void +umc_page_recalc(uint32_t c, int set) +{ + if (set) { + pages[c].mem = &ram[(c & 0xff) << 12]; + pages[c].write_b = mem_write_ramb_page; + pages[c].write_w = mem_write_ramw_page; + pages[c].write_l = mem_write_raml_page; + } else { + pages[c].mem = page_ff; + pages[c].write_b = NULL; + pages[c].write_w = NULL; + pages[c].write_l = NULL; + } + +#ifdef USE_NEW_DYNAREC + pages[c].evict_prev = EVICT_NOT_IN_LIST; + pages[c].byte_dirty_mask = &byte_dirty_mask[(c & 0xff) * 64]; + pages[c].byte_code_present_mask = &byte_code_present_mask[(c & 0xff) * 64]; +#endif +} + +void +umc_smram_recalc(uint32_t start, int set) +{ + for (uint32_t c = start; c < (start + 0x0020); c++) + umc_page_recalc(c, set); +} + void mem_remap_top(int kb) { From 95bb3ae33397de68ade0791e2602f56c025a815f Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 24 Jan 2024 06:00:56 +0100 Subject: [PATCH 10/23] IBM 5161: Set switches according to the total memory installed (on-board + any expansion cards), fixes #4070. --- src/device/ibm_5161.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/device/ibm_5161.c b/src/device/ibm_5161.c index 07083873e..762a379a1 100644 --- a/src/device/ibm_5161.c +++ b/src/device/ibm_5161.c @@ -73,8 +73,8 @@ ibm_5161_in(uint16_t port, void *priv) 02-03 = not used 04-07 = switch position 1 = Off - 0 =On */ - ret = dev->regs[3] & 0x01; + 0 = On */ + ret = (dev->regs[3] & 0x01) | (((~(0xf - ((mem_size + isa_mem_size) >> 6))) & 0xf) << 4); break; default: @@ -95,8 +95,7 @@ ibm_5161_close(void *priv) static void * ibm_5161_init(UNUSED(const device_t *info)) { - ibm_5161_t *dev = (ibm_5161_t *) malloc(sizeof(ibm_5161_t)); - memset(dev, 0, sizeof(ibm_5161_t)); + ibm_5161_t *dev = (ibm_5161_t *) calloc(1, sizeof(ibm_5161_t)); /* Extender Card Registers */ io_sethandler(0x0210, 0x0004, From 3e7ad13e36a006cdf4972151d78fd9edbb3f719c Mon Sep 17 00:00:00 2001 From: 640-KB <640kb@glabios.org> Date: Wed, 24 Jan 2024 10:33:04 -0500 Subject: [PATCH 11/23] Alphabetize XT machine_table list --- src/machine/machine_table.c | 78 ++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 101052f4e..860c68b61 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -709,6 +709,45 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + { + .name = "[8088] GLaBIOS", + .internal_name = "glabios", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_glabios_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_8088, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 64, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .kbc_device = &keyboard_xt_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, { .name = "[8088] Hyosung Topstar 88T", .internal_name = "top88", @@ -1804,45 +1843,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - { - .name = "[8088] GLaBIOS", - .internal_name = "glabios", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_glabios_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_8088, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PC, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 64, - .max = 640, - .step = 64 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xt_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, { .name = "[GC100A] Philips P3120", .internal_name = "p3120", From ac78275cb831d8cf4ffb3e0dc49142862e794200 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 24 Jan 2024 20:45:44 +0100 Subject: [PATCH 12/23] EGA: Correct register (non-)readability on the Compaq EGA and light pen registers. --- src/include/86box/vid_ega.h | 2 ++ src/video/vid_ega.c | 33 ++++++++++++++++++++------------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/include/86box/vid_ega.h b/src/include/86box/vid_ega.h index ec241d613..0bccd607e 100644 --- a/src/include/86box/vid_ega.h +++ b/src/include/86box/vid_ega.h @@ -56,6 +56,8 @@ typedef struct ega_t { uint8_t *vram; + uint16_t light_pen; + int vidclock; int fast; int extvram; diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 7979cd958..dd84074e6 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -295,22 +295,22 @@ ega_in(uint16_t addr, void *priv) break; case 0x3c0: - if (ega_type) + if (ega_type == 1) ret = ega->attraddr | ega->attr_palette_enable; break; case 0x3c1: - if (ega_type) + if (ega_type == 1) ret = ega->attrregs[ega->attraddr]; break; case 0x3c2: ret = (egaswitches & (8 >> egaswitchread)) ? 0x10 : 0x00; break; case 0x3c4: - if (ega_type) + if (ega_type == 1) ret = ega->seqaddr; break; case 0x3c5: - if (ega_type) + if (ega_type == 1) ret = ega->seqregs[ega->seqaddr & 0xf]; break; case 0x3c6: @@ -318,24 +318,24 @@ ega_in(uint16_t addr, void *priv) ret = ega->ctl_mode; break; case 0x3c8: - if (ega_type) + if (ega_type == 1) ret = 2; break; case 0x3cc: - if (ega_type) + if (ega_type == 1) ret = ega->miscout; break; case 0x3ce: - if (ega_type) + if (ega_type == 1) ret = ega->gdcaddr; break; case 0x3cf: - if (ega_type) + if (ega_type == 1) ret = ega->gdcreg[ega->gdcaddr & 0xf]; break; case 0x3d0: case 0x3d4: - if (ega_type) + if (ega_type == 1) ret = ega->crtcreg; break; case 0x3d1: @@ -349,14 +349,21 @@ ega_in(uint16_t addr, void *priv) break; case 0x10: - case 0x11: - /* TODO: Return light pen address once implemented. */ - if (ega_type) + if (ega_type == 1) ret = ega->crtc[ega->crtcreg]; + else + ret = ega->light_pen >> 8; + break; + + case 0x11: + if (ega_type == 1) + ret = ega->crtc[ega->crtcreg]; + else + ret = ega->light_pen & 0xff; break; default: - if (ega_type) + if (ega_type == 1) ret = ega->crtc[ega->crtcreg]; break; } From cd03b6a31c57ddbdbd2b7fd71d5058f548db208c Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 25 Jan 2024 21:47:15 +0100 Subject: [PATCH 13/23] Packard Bell machines: PS/2 mouse commands now suspend dynamic recompilation until the response byte is read, fixes #552. --- src/cpu/386_dynarec.c | 3 ++- src/cpu/cpu.h | 3 +++ src/device/kbc_at.c | 5 +++++ src/device/mouse_ps2.c | 2 ++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index e132c0300..c96e3420d 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -48,6 +48,7 @@ #define CPU_BLOCK_END() cpu_block_end = 1 +int cpu_override_dynarec = 0; int inrecomp = 0; int cpu_block_end = 0; int cpu_end_block_after_ins = 0; @@ -718,7 +719,7 @@ exec386_dynarec(int32_t cycs) cycles_old = cycles; oldtsc = tsc; tsc_old = tsc; - if (!CACHE_ON()) /*Interpret block*/ + if ((!CACHE_ON()) || cpu_override_dynarec) /*Interpret block*/ { exec386_dynarec_int(); } else { diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index e185f2e4a..95625df55 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -833,6 +833,9 @@ extern void nmi_raise(void); extern MMX_REG *MMP[8]; extern uint16_t *MMEP[8]; +extern int cpu_block_end; +extern int cpu_override_dynarec; + extern void mmx_init(void); extern void prefetch_flush(void); diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index d2e6cf364..bc4a1f366 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -1787,6 +1787,9 @@ kbc_at_process_cmd(void *priv) if (dev->ib == 0xbb) break; + if (strstr(machine_get_internal_name(), "pb") != NULL) + cpu_override_dynarec = 1; + if (dev->misc_flags & FLAG_PS2) { set_enable_aux(dev, 1); if ((dev->ports[1] != NULL) && (dev->ports[1]->priv != NULL)) { @@ -1891,6 +1894,8 @@ kbc_at_read(uint16_t port, void *priv) This also means that in AT mode, the IRQ is level-triggered. */ if (!(dev->misc_flags & FLAG_PS2)) picintclevel(1 << 1, &dev->irq_state); + if ((strstr(machine_get_internal_name(), "pb") != NULL) && (cpu_override_dynarec == 1)) + cpu_override_dynarec = 0; break; case 0x64: diff --git a/src/device/mouse_ps2.c b/src/device/mouse_ps2.c index 35f0cd9e8..c3a7310f0 100644 --- a/src/device/mouse_ps2.c +++ b/src/device/mouse_ps2.c @@ -21,6 +21,7 @@ #include #define HAVE_STDARG_H #include <86box/86box.h> +#include "cpu.h" #include <86box/device.h> #include <86box/keyboard.h> #include <86box/mouse.h> @@ -276,6 +277,7 @@ ps2_write(void *priv) break; default: + mouse_ps2_log("%s: Bad command: %02X\n", dev->name, val); kbc_at_dev_queue_add(dev, 0xfe, 0); } } From 26ea0c822504e46d47ea3332dda82bd98ca3684f Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 25 Jan 2024 22:05:31 +0100 Subject: [PATCH 14/23] XGA update/slight fixes: 1. Remove some useless parentheses and correct some identation. 2. The reversed linear mapping activation and a5 vram test are reset properly now. 3. More correct Area Fill emulation, especially in 640x480 mode, (800x600 and 1024x768 too). --- src/video/vid_xga.c | 329 +++++++++++++++++++++----------------------- 1 file changed, 156 insertions(+), 173 deletions(-) diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 44e8aa6c3..fad5e4124 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -178,8 +178,8 @@ xga_updatemapping(svga_t *svga) } } - xga_log("XGA opmode (extended) = %d, disp mode = %d, aperture = %d.\n", xga->op_mode & 7, - xga->disp_cntl_2 & 7, xga->aperture_cntl); + xga_log("XGA opmode (extended) = %d, disp mode = %d, aperture = %d, on = %d, linear endian reverse = %d.\n", xga->op_mode & 7, + xga->disp_cntl_2 & 7, xga->aperture_cntl, xga->on, xga->linear_endian_reverse); } xga_log("VGA on = %d, map = %02x.\n", vga_on, svga->gdcreg[6] & 0x0c); } @@ -198,7 +198,7 @@ xga_recalctimings(svga_t *svga) xga->h_disp = (xga->hdisp + 1) << 3; - xga->rowoffset = (xga->hdisp + 1); + xga->rowoffset = xga->hdisp + 1; xga->interlace = !!(xga->disp_cntl_1 & 0x08); xga->rowcount = (xga->disp_cntl_2 & 0xc0) >> 6; @@ -213,6 +213,11 @@ xga_recalctimings(svga_t *svga) xga->ma_latch = xga->disp_start_addr; + if ((xga->disp_cntl_2 & 7) == 2) + xga->rowoffset >>= 1; + else if ((xga->disp_cntl_2 & 7) == 4) + xga->rowoffset <<= 1; + xga_log("XGA ClkSel1 = %d, ClkSel2 = %02x.\n", (xga->clk_sel_1 >> 2) & 3, xga->clk_sel_2 & 0x80); switch ((xga->clk_sel_1 >> 2) & 3) { case 0: @@ -410,7 +415,7 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) xga->cursor_data_on = 1; else if ((xga->sprite_pos >= 1) || (((xga->disp_cntl_2 & 7) == 2) || (xga->disp_cntl_2 & 7) == 4)) xga->cursor_data_on = 1; - else if (xga->aperture_cntl == 0) { + else if (!xga->aperture_cntl) { if (xga->linear_endian_reverse && !(xga->access_mode & 8)) xga->cursor_data_on = 0; } @@ -422,10 +427,11 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) xga->cursor_data_on = 1; else xga->cursor_data_on = 0; - } else { + } else xga->cursor_data_on = 0; - } - } + } else if (!xga->sprite_pos && xga->cursor_data_on && !xga->aperture_cntl && xga->linear_endian_reverse) + xga->cursor_data_on = 0; + xga_log("Sprite POS = %d, data on = %d, idx = %d, apcntl = %d\n", xga->sprite_pos, xga->cursor_data_on, xga->sprite_pal_addr_idx, xga->aperture_cntl); @@ -998,9 +1004,9 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int addr += x; if (!skip) { READ(addr, byte); - } else { + } else byte = mem_readb_phys(addr); - } + return byte; case 4: /*16-bit*/ addr += (y * (width << 1)); @@ -1082,6 +1088,7 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui } else { byte = mem_readb_phys(addr); } + if (xga->linear_endian_reverse) mask = 0x0f << ((1 - (x & 1)) << 2); else { @@ -1259,31 +1266,17 @@ xga_line_draw_write(svga_t *svga) uint32_t plane_mask = xga->accel.plane_mask; uint32_t dstbase = xga->accel.px_map_base[xga->accel.dst_map]; uint32_t srcbase = xga->accel.px_map_base[xga->accel.src_map]; - int dminor; - int destxtmp; - int dmajor; - int err; int y = xga->accel.blt_width; int x = 0; int16_t dx; int16_t dy; - int draw_pixel; + int16_t cx; + int16_t cy; + int err = xga->accel.bres_err_term; + int draw_pixel = 0; - dminor = xga->accel.bres_k1; - if (xga->accel.bres_k1 & 0x2000) - dminor |= ~0x1fff; - - dminor >>= 1; - - destxtmp = xga->accel.bres_k2; - if (xga->accel.bres_k2 & 0x2000) - destxtmp |= ~0x1fff; - - dmajor = -(destxtmp - (dminor << 1)) >> 1; - - err = xga->accel.bres_err_term; - if (xga->accel.bres_err_term & 0x2000) - err |= ~0x1fff; + cx = xga->accel.src_map_x & 0xfff; + cy = xga->accel.src_map_y & 0xfff; dx = xga->accel.dst_map_x & 0x1fff; if (xga->accel.dst_map_x >= 0x1800) @@ -1300,75 +1293,46 @@ xga_line_draw_write(svga_t *svga) if (xga->accel.pat_src == 8) { if ((xga->accel.command & 0x30) == 0x30) { while (y >= 0) { - draw_pixel = 1; + draw_pixel = 0; + + if (xga->accel.octant & 0x01) { + if (xga->accel.octant & 0x02) { /*Bottom-to-Top*/ + if (x) + draw_pixel = 1; + } else { /*Top-to-Bottom*/ + if (y) + draw_pixel = 1; + } + } else if (!(xga->accel.octant & 0x04) && (err < (xga->accel.bres_k2 + xga->accel.bres_k1))) /*X+*/ + draw_pixel = 1; + else if ((xga->accel.octant & 0x04) && (err >= 0)) /*X-*/ + draw_pixel = 1; if (xga->accel.command & 0xc0) { if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color; + if (draw_pixel) { + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, cx, cy, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0); + + if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { + ROP(1, dest_dat, src_dat); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + } + } + } + } else { + if (draw_pixel) { + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, cx, cy, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color; dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { ROP(1, dest_dat, src_dat); - dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - if (xga->accel.octant & 0x01) { /*Y Major*/ - if (xga->accel.octant & 0x02) { /*Bottom-to-Top*/ - if (!x) - draw_pixel = 0; - } else { /*Top-to-Bottom*/ - if (!y) - draw_pixel = 0; - } - } else { - if (err >= 0) { - if (xga->accel.octant & 0x02) { /*Bottom-to-Top*/ - if (!x) - draw_pixel = 0; - } else { /*Top-to-Bottom*/ - if (!y) - draw_pixel = 0; - } - } else - draw_pixel = 0; - } - - if (draw_pixel) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); - } - } - } else { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0); - - if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { - ROP(1, dest_dat, src_dat); - dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - if (xga->accel.octant & 0x01) { /*Y Major*/ - if (xga->accel.octant & 0x02) { /*Bottom-to-Top*/ - if (!x) - draw_pixel = 0; - } else { /*Top-to-Bottom*/ - if (!y) - draw_pixel = 0; - } - } else { - if (err >= 0) { - if (xga->accel.octant & 0x02) { /*Bottom-to-Top*/ - if (!x) - draw_pixel = 0; - } else { /*Top-to-Bottom*/ - if (!y) - draw_pixel = 0; - } - } else - draw_pixel = 0; - } - - if (draw_pixel) xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + } } } - if (!y) + if (x == xga->accel.blt_width) break; if (xga->accel.octant & 0x01) { @@ -1377,34 +1341,31 @@ xga_line_draw_write(svga_t *svga) else dy++; - while (err >= 0) { - err -= (dmajor << 1); + if (err >= 0) { + err += xga->accel.bres_k2; if (xga->accel.octant & 0x04) dx--; else dx++; - } - - err += (dminor << 1); + } else + err += xga->accel.bres_k1; } else { if (xga->accel.octant & 0x04) dx--; else dx++; - while (err >= 0) { - err -= (dmajor << 1); + if (err >= 0) { + err += xga->accel.bres_k2; if (xga->accel.octant & 0x02) dy--; else dy++; - } - - err += (dminor << 1); + } else + err += xga->accel.bres_k1; } - - y--; x++; + y--; } } else { while (y >= 0) { @@ -1451,47 +1412,40 @@ xga_line_draw_write(svga_t *svga) else dy++; - while (err >= 0) { - err -= (dmajor << 1); + if (err >= 0) { + err += xga->accel.bres_k2; if (xga->accel.octant & 0x04) dx--; else dx++; - } - - err += (dminor << 1); + } else + err += xga->accel.bres_k1; } else { if (xga->accel.octant & 0x04) dx--; else dx++; - while (err >= 0) { - err -= (dmajor << 1); + if (err >= 0) { + err += xga->accel.bres_k2; if (xga->accel.octant & 0x02) dy--; else dy++; - } - - err += (dminor << 1); + } else + err += xga->accel.bres_k1; } - y--; x++; } } } - - xga->accel.dst_map_x = dx; - xga->accel.dst_map_y = dy; } static void xga_bitblt(svga_t *svga) { xga_t *xga = (xga_t *) svga->xga; - uint8_t area_state = 0; uint32_t src_dat; uint32_t dest_dat; uint32_t old_dest_dat; @@ -1530,6 +1484,7 @@ xga_bitblt(svga_t *svga) xga_log("D(%d,%d), SWH(%d,%d), BLT(%d,%d), dstwidth=%d.\n", dx, dy, xga->accel.x, xga->accel.y, srcwidth, srcheight, dstwidth); xga->accel.pattern = 0; + xga->accel.filling = 0; xga_log("XGA bitblt linear endian reverse=%d, access_mode=%x, octanty=%d, src command = %08x, " "pxsrcmap=%x, pxpatmap=%x, pxdstmap=%x, srcmap=%d, patmap=%d, dstmap=%d, " @@ -1660,70 +1615,66 @@ xga_bitblt(svga_t *svga) xga->accel.px_map_width[0], xga->accel.px_map_width[1], xga->accel.px_map_width[2], xga->accel.px_map_width[3], bkgdcol); - if (((xga->accel.command >> 24) & 0x0f) == 0x0a) { + if ((((xga->accel.command >> 24) & 0x0f) == 0x0a) && ((xga->accel.bkgd_mix & 0x1f) == 5)) { while (xga->accel.y >= 0) { mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, xga->accel.pat_src, patbase, patwidth + 1); if (mix) - area_state = !area_state; + xga->accel.filling = !xga->accel.filling; if (xga->accel.command & 0xc0) { if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { - if (area_state) - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol; - else - src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol; - - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0); - if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { - old_dest_dat = dest_dat; - ROP(area_state, dest_dat, src_dat); - dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_log("1SRCDat=%02x, DSTDat=%02x, Old=%02x, MIX=%d.\n", src_dat, dest_dat, old_dest_dat, area_state); - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol; + if (xga->accel.filling) { + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, 1024, 0); + if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { + old_dest_dat = dest_dat; + ROP(1, dest_dat, src_dat); + dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); + xga_log("1SRCDat=%02x, DSTDat=%02x, Old=%02x, MIX=%d.\n", src_dat, dest_dat, old_dest_dat, area_state); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + } } } } else { if ((dx >= 0) && (dx <= dstwidth) && (dy >= 0) && (dy <= dstheight)) { - if (area_state) - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol; - else - src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol; - - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0); - if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { - old_dest_dat = dest_dat; - ROP(area_state, dest_dat, src_dat); - dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_log("2Fill: NumXY(%d,%d): DXY(%d,%d): SRCDat=%02x, DSTDat=%02x, Old=%02x, frgdcol=%02x, bkgdcol=%02x, MIX=%d, frgdmix=%02x, bkgdmix=%02x, dstmapfmt=%02x, srcmapfmt=%02x, srcmapnum=%d.\n", x, y, dx, dy, src_dat, dest_dat, old_dest_dat, frgdcol, bkgdcol, area_state, xga->accel.frgd_mix & 0x1f, xga->accel.bkgd_mix & 0x1f, xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, xga->accel.px_map_format[xga->accel.src_map] & 0x0f, xga->accel.src_map); - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol; + if (xga->accel.filling) { + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0); + if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { + old_dest_dat = dest_dat; + ROP(1, dest_dat, src_dat); + dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); + xga_log("2Fill: NumXY(%d,%d): DXY(%d,%d): SRCDat=%02x, DSTDat=%02x, Old=%02x, frgdcol=%02x, bkgdcol=%02x, MIX=%d, frgdmix=%02x, bkgdmix=%02x, dstmapfmt=%02x, srcmapfmt=%02x, srcmapnum=%d.\n", x, y, dx, dy, src_dat, dest_dat, old_dest_dat, frgdcol, bkgdcol, area_state, xga->accel.frgd_mix & 0x1f, xga->accel.bkgd_mix & 0x1f, xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, xga->accel.px_map_format[xga->accel.src_map] & 0x0f, xga->accel.src_map); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + } } } } - xga->accel.sx = ((xga->accel.sx + 1) & srcwidth) | (xga->accel.sx & ~srcwidth); - xga->accel.px = ((xga->accel.px + 1) & patwidth) | (xga->accel.px & ~patwidth); + xga->accel.sx = ((xga->accel.sx + xdir) & srcwidth) | (xga->accel.sx & ~srcwidth); + xga->accel.px++; + dx++; xga->accel.x--; if (xga->accel.x < 0) { - area_state = 0; xga->accel.y--; xga->accel.x = xga->accel.blt_width & 0xfff; dx = xga->accel.dst_map_x & 0x1fff; if (xga->accel.dst_map_x >= 0x1800) dx |= ~0x17ff; + xga->accel.sx = xga->accel.src_map_x & 0xfff; xga->accel.px = xga->accel.pat_map_x & 0xfff; xga->accel.sy = ((xga->accel.sy + ydir) & srcheight) | (xga->accel.sy & ~srcheight); - xga->accel.py += ydir; - dy += ydir; + xga->accel.py++; - if (xga->accel.y < 0) { - xga->accel.dst_map_x = dx; - xga->accel.dst_map_y = dy; + dy++; + xga->accel.filling = 0; + + if (xga->accel.y < 0) return; - } } } } else { @@ -1777,6 +1728,7 @@ xga_bitblt(svga_t *svga) dx = xga->accel.dst_map_x & 0x1fff; if (xga->accel.dst_map_x >= 0x1800) dx |= ~0x17ff; + xga->accel.sx = xga->accel.src_map_x & 0xfff; xga->accel.px = xga->accel.pat_map_x & 0xfff; @@ -1870,7 +1822,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) if (len >= 2) { xga->accel.bres_err_term = val & 0x3fff; if (val & 0x2000) - xga->accel.bres_err_term |= ~0x3fff; + xga->accel.bres_err_term |= ~0x1fff; } else xga->accel.bres_err_term = (xga->accel.bres_err_term & 0x3f00) | val; break; @@ -1878,7 +1830,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) if (len == 1) { xga->accel.bres_err_term = (xga->accel.bres_err_term & 0xff) | ((val & 0x3f) << 8); if (val & 0x20) - xga->accel.bres_err_term |= ~0x3fff; + xga->accel.bres_err_term |= ~0x1fff; } break; @@ -1886,7 +1838,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) if (len >= 2) { xga->accel.bres_k1 = val & 0x3fff; if (val & 0x2000) - xga->accel.bres_k1 |= ~0x3fff; + xga->accel.bres_k1 |= ~0x1fff; } else xga->accel.bres_k1 = (xga->accel.bres_k1 & 0x3f00) | val; break; @@ -1894,7 +1846,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) if (len == 1) { xga->accel.bres_k1 = (xga->accel.bres_k1 & 0xff) | ((val & 0x3f) << 8); if (val & 0x20) - xga->accel.bres_k1 |= ~0x3fff; + xga->accel.bres_k1 |= ~0x1fff; } break; @@ -1902,7 +1854,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) if (len >= 2) { xga->accel.bres_k2 = val & 0x3fff; if (val & 0x2000) - xga->accel.bres_k2 |= ~0x3fff; + xga->accel.bres_k2 |= ~0x1fff; } else xga->accel.bres_k2 = (xga->accel.bres_k2 & 0x3f00) | val; break; @@ -1910,7 +1862,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) if (len == 1) { xga->accel.bres_k2 = (xga->accel.bres_k2 & 0xff) | ((val & 0x3f) << 8); if (val & 0x20) - xga->accel.bres_k2 |= ~0x3fff; + xga->accel.bres_k2 |= ~0x1fff; } break; @@ -2015,6 +1967,30 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) xga->accel.plane_mask = (xga->accel.plane_mask & 0x00ffffff) | (val << 24); break; + case 0x54: + if (len == 4) + xga->accel.carry_chain = val; + else if (len == 2) + xga->accel.carry_chain = (xga->accel.carry_chain & 0xffff0000) | val; + else + xga->accel.carry_chain = (xga->accel.carry_chain & 0xffffff00) | val; + break; + case 0x55: + if (len == 1) + xga->accel.carry_chain = (xga->accel.carry_chain & 0xffff00ff) | (val << 8); + break; + case 0x56: + if (len == 2) + xga->accel.carry_chain = (xga->accel.carry_chain & 0x0000ffff) | (val << 16); + else + xga->accel.carry_chain = (xga->accel.carry_chain & 0xff00ffff) | (val << 16); + break; + case 0x57: + if (len == 1) + xga->accel.carry_chain = (xga->accel.carry_chain & 0x00ffffff) | (val << 24); + break; + + case 0x58: if (len == 4) xga->accel.frgd_color = val; @@ -2454,7 +2430,7 @@ xga_hwcursor_draw(svga_t *svga, int displine) int y_pos; int comb = 0; uint32_t *p; - int idx = (xga->cursor_data_on) ? 32 : 0; + int idx = xga->cursor_data_on ? 32 : 0; if (xga->interlace && xga->hwcursor_oddeven) xga->hwcursor_latch.addr += 16; @@ -2549,20 +2525,24 @@ xga_render_4bpp(svga_t *svga) for (int x = 0; x <= xga->h_disp; x += 16) { dat = *(uint32_t *) (&xga->vram[xga->ma & xga->vram_mask]); - p[0] = xga->pallook[(dat >> 4) & 0x0f]; - p[1] = xga->pallook[dat & 0x0f]; - p[2] = xga->pallook[(dat >> 12) & 0x0f]; - p[3] = xga->pallook[(dat >> 8) & 0x0f]; - p[4] = xga->pallook[(dat >> 20) & 0x0f]; - p[5] = xga->pallook[(dat >> 16) & 0x0f]; - p[6] = xga->pallook[(dat >> 28) & 0x0f]; - p[7] = xga->pallook[(dat >> 24) & 0x0f]; + p[0] = xga->pallook[dat & 0x0f]; + p[1] = xga->pallook[(dat >> 4) & 0x0f]; + p[2] = xga->pallook[(dat >> 8) & 0x0f]; + p[3] = xga->pallook[(dat >> 12) & 0x0f]; + p[4] = xga->pallook[(dat >> 16) & 0x0f]; + p[5] = xga->pallook[(dat >> 20) & 0x0f]; + p[6] = xga->pallook[(dat >> 24) & 0x0f]; + p[7] = xga->pallook[(dat >> 28) & 0x0f]; dat = *(uint32_t *) (&xga->vram[(xga->ma + 4) & xga->vram_mask]); - p[9] = xga->pallook[dat & 0x0f]; - p[11] = xga->pallook[(dat >> 8) & 0x0f]; - p[13] = xga->pallook[(dat >> 16) & 0x0f]; - p[15] = xga->pallook[(dat >> 24) & 0x0f]; + p[8] = xga->pallook[dat & 0x0f]; + p[9] = xga->pallook[(dat >> 4) & 0x0f]; + p[10] = xga->pallook[(dat >> 8) & 0x0f]; + p[11] = xga->pallook[(dat >> 12) & 0x0f]; + p[12] = xga->pallook[(dat >> 16) & 0x0f]; + p[13] = xga->pallook[(dat >> 20) & 0x0f]; + p[14] = xga->pallook[(dat >> 24) & 0x0f]; + p[15] = xga->pallook[(dat >> 28) & 0x0f]; xga->ma += 8; p += 16; @@ -2626,7 +2606,7 @@ xga_render_16bpp(svga_t *svga) xga->firstline_draw = xga->displine; xga->lastline_draw = xga->displine; - for (x = 0; x <= (xga->h_disp); x += 8) { + for (x = 0; x <= xga->h_disp; x += 8) { dat = *(uint32_t *) (&xga->vram[(xga->ma + (x << 1)) & xga->vram_mask]); p[x] = video_16to32[dat & 0xffff]; p[x + 1] = video_16to32[dat >> 16]; @@ -2969,9 +2949,8 @@ xga_poll(void *priv, svga_t *svga) video_wait_for_buffer_monitor(svga->monitor_index); } - if (xga->hwcursor_on) { + if (xga->hwcursor_on) xga->changedvram[xga->ma >> 12] = xga->changedvram[(xga->ma >> 12) + 1] = xga->interlace ? 3 : 2; - } xga_do_render(svga); @@ -2993,9 +2972,10 @@ xga_poll(void *priv, svga_t *svga) if (xga->sc == xga->rowcount) { xga->sc = 0; - xga->maback += (xga->rowoffset << (xga->disp_cntl_2 & 7)); + xga->maback += (xga->rowoffset << 3); if (xga->interlace) - xga->maback += (xga->rowoffset << (xga->disp_cntl_2 & 7)); + xga->maback += (xga->rowoffset << 3); + xga->maback &= xga->vram_mask; xga->ma = xga->maback; } else { @@ -3013,6 +2993,7 @@ xga_poll(void *priv, svga_t *svga) xga->ma = xga->maback = (xga->rowoffset << 1); else xga->ma = xga->maback = 0; + xga->ma = (xga->ma << 2); xga->maback = (xga->maback << 2); @@ -3152,6 +3133,8 @@ xga_mca_reset(void *priv) xga->on = 0; vga_on = 1; xga_mca_write(0x102, 0, svga); + xga->linear_endian_reverse = 0; + xga->a5_test = 0; } static void From 40dc25466c96eef30935c374092cfa5d5e2bfd7b Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 25 Jan 2024 23:42:26 +0100 Subject: [PATCH 15/23] Updated CPU clock selection on Compaq 286/386 based machines. Per their manuals, see above and below (manuals only) --- src/cpu/cpu.h | 58 +++++++++++----------- src/cpu/cpu_table.c | 95 +++++++++++++++++++++++++++++++++++++ src/machine/machine_table.c | 10 ++-- 3 files changed, 131 insertions(+), 32 deletions(-) diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 95625df55..6a03fc328 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -86,33 +86,37 @@ enum { }; enum { - CPU_PKG_8088 = (1 << 0), - CPU_PKG_8088_EUROPC = (1 << 1), - CPU_PKG_8086 = (1 << 2), - CPU_PKG_188 = (1 << 3), - CPU_PKG_186 = (1 << 4), - CPU_PKG_286 = (1 << 5), - CPU_PKG_386SX = (1 << 6), - CPU_PKG_386DX = (1 << 7), - CPU_PKG_M6117 = (1 << 8), - CPU_PKG_386SLC_IBM = (1 << 9), - CPU_PKG_486SLC = (1 << 10), - CPU_PKG_486SLC_IBM = (1 << 11), - CPU_PKG_486BL = (1 << 12), - CPU_PKG_486DLC = (1 << 13), - CPU_PKG_SOCKET1 = (1 << 14), - CPU_PKG_SOCKET3 = (1 << 15), - CPU_PKG_SOCKET3_PC330 = (1 << 16), - CPU_PKG_STPC = (1 << 17), - CPU_PKG_SOCKET4 = (1 << 18), - CPU_PKG_SOCKET5_7 = (1 << 19), - CPU_PKG_SOCKET8 = (1 << 20), - CPU_PKG_SLOT1 = (1 << 21), - CPU_PKG_SLOT2 = (1 << 22), - CPU_PKG_SLOTA = (1 << 23), - CPU_PKG_SOCKET370 = (1 << 24), - CPU_PKG_SOCKETA = (1 << 25), - CPU_PKG_EBGA368 = (1 << 26) + CPU_PKG_8088 = (1 << 0), + CPU_PKG_8088_EUROPC = (1 << 1), + CPU_PKG_8086 = (1 << 2), + CPU_PKG_188 = (1 << 3), + CPU_PKG_186 = (1 << 4), + CPU_PKG_286 = (1 << 5), + CPU_PKG_286_CPQ_PORTABLE_II = (1 << 6), + CPU_PKG_386SX = (1 << 7), + CPU_PKG_386DX = (1 << 8), + CPU_PKG_386DX_CPQ_09_1986 = (1 << 9), + CPU_PKG_386DX_CPQ_1987 = (1 << 10), + CPU_PKG_386DX_CPQ_05_1988 = (1 << 11), + CPU_PKG_M6117 = (1 << 12), + CPU_PKG_386SLC_IBM = (1 << 13), + CPU_PKG_486SLC = (1 << 14), + CPU_PKG_486SLC_IBM = (1 << 15), + CPU_PKG_486BL = (1 << 16), + CPU_PKG_486DLC = (1 << 17), + CPU_PKG_SOCKET1 = (1 << 18), + CPU_PKG_SOCKET3 = (1 << 19), + CPU_PKG_SOCKET3_PC330 = (1 << 20), + CPU_PKG_STPC = (1 << 21), + CPU_PKG_SOCKET4 = (1 << 22), + CPU_PKG_SOCKET5_7 = (1 << 23), + CPU_PKG_SOCKET8 = (1 << 24), + CPU_PKG_SLOT1 = (1 << 25), + CPU_PKG_SLOT2 = (1 << 26), + CPU_PKG_SLOTA = (1 << 27), + CPU_PKG_SOCKET370 = (1 << 28), + CPU_PKG_SOCKETA = (1 << 29), + CPU_PKG_EBGA368 = (1 << 30) }; #define MANU_INTEL 0 diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 947804014..89b25e152 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -1004,6 +1004,65 @@ const cpu_family_t cpu_families[] = { { .name = "", 0 } } }, { + .package = CPU_PKG_286_CPQ_PORTABLE_II, + .manufacturer = "Intel", + .name = "80286", + .internal_name = "286", + .cpus = (const CPU[]) { + { + .name = "6", + .cpu_type = CPU_286, + .fpus = fpus_80286, + .rspeed = 6000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 2, + .mem_write_cycles = 2, + .cache_read_cycles = 2, + .cache_write_cycles = 2, + .atclk_div = 1 + }, + { + .name = "8", + .cpu_type = CPU_286, + .fpus = fpus_80286, + .rspeed = 8000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 2, + .mem_write_cycles = 2, + .cache_read_cycles = 2, + .cache_write_cycles = 2, + .atclk_div = 1 + }, + { + .name = "16", + .cpu_type = CPU_286, + .fpus = fpus_80286, + .rspeed = 16000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 3, + .mem_write_cycles = 3, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 2 + }, + { .name = "", 0 } + } + }, { .package = CPU_PKG_386SX, .manufacturer = "Intel", .name = "i386SX", @@ -1030,6 +1089,33 @@ const cpu_family_t cpu_families[] = { {"", 0} } }, { + .package = CPU_PKG_386DX_CPQ_09_1986, + .manufacturer = "Intel", + .name = "i386DX", + .internal_name = "i386dx", + .cpus = (const CPU[]) { + {"16", CPU_386DX, fpus_80286, 16000000, 1, 5000, 0x0308, 0, 0, 0, 3,3,3,3, 2}, + {"", 0} + } + }, { + .package = CPU_PKG_386DX_CPQ_1987, + .manufacturer = "Intel", + .name = "i386DX", + .internal_name = "i386dx", + .cpus = (const CPU[]) { + {"20", CPU_386DX, fpus_80386, 20000000, 1, 5000, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"", 0} + } + }, { + .package = CPU_PKG_386DX_CPQ_05_1988, + .manufacturer = "Intel", + .name = "i386DX", + .internal_name = "i386dx", + .cpus = (const CPU[]) { + {"25", CPU_386DX, fpus_80386, 25000000, 1, 5000, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"", 0} + } + }, { .package = CPU_PKG_386DX, .manufacturer = "Intel", .name = "i386DX", @@ -1170,6 +1256,15 @@ const cpu_family_t cpu_families[] = { {"", 0} } }, { + .package = CPU_PKG_386DX_CPQ_1987, + .manufacturer = "Cyrix", + .name = "Cx486DRx2", + .internal_name = "cx486drx2", + .cpus = (const CPU[]) { + {"40", CPU_486DLC, fpus_80386, 40000000, 2, 5000, 0x407, 0, 0x0007, 0, 8, 8,6,6, 6}, + {"", 0} + } + }, { .package = CPU_PKG_386DX, .manufacturer = "Cyrix", .name = "Cx486DRx2", diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 860c68b61..2066b125b 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -2767,7 +2767,7 @@ const machine_t machines[] = { .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_286, + .package = CPU_PKG_286_CPQ_PORTABLE_II, .block = CPU_BLOCK_NONE, .min_bus = 0, .max_bus = 0, @@ -2807,7 +2807,7 @@ const machine_t machines[] = { .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_286, + .package = CPU_PKG_286_CPQ_PORTABLE_II, .block = CPU_BLOCK_NONE, .min_bus = 0, .max_bus = 0, @@ -4875,7 +4875,7 @@ const machine_t machines[] = { .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_386DX, + .package = CPU_PKG_386DX_CPQ_09_1986, .block = CPU_BLOCK_NONE, .min_bus = 0, .max_bus = 0, @@ -4914,7 +4914,7 @@ const machine_t machines[] = { .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_386DX, + .package = CPU_PKG_386DX_CPQ_05_1988, .block = CPU_BLOCK_NONE, .min_bus = 0, .max_bus = 0, @@ -4953,7 +4953,7 @@ const machine_t machines[] = { .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_386DX, + .package = CPU_PKG_386DX_CPQ_1987, .block = CPU_BLOCK_NONE, .min_bus = 0, .max_bus = 0, From e779ea5902e4b0d40d96c42ec22cf32076c69018 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 25 Jan 2024 21:17:05 -0300 Subject: [PATCH 16/23] Fix the Compaq CPU selection mess --- src/cpu/cpu.h | 58 +++++++++++----------- src/cpu/cpu_table.c | 95 ------------------------------------- src/machine/machine_table.c | 34 ++++++------- 3 files changed, 44 insertions(+), 143 deletions(-) diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 6a03fc328..95625df55 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -86,37 +86,33 @@ enum { }; enum { - CPU_PKG_8088 = (1 << 0), - CPU_PKG_8088_EUROPC = (1 << 1), - CPU_PKG_8086 = (1 << 2), - CPU_PKG_188 = (1 << 3), - CPU_PKG_186 = (1 << 4), - CPU_PKG_286 = (1 << 5), - CPU_PKG_286_CPQ_PORTABLE_II = (1 << 6), - CPU_PKG_386SX = (1 << 7), - CPU_PKG_386DX = (1 << 8), - CPU_PKG_386DX_CPQ_09_1986 = (1 << 9), - CPU_PKG_386DX_CPQ_1987 = (1 << 10), - CPU_PKG_386DX_CPQ_05_1988 = (1 << 11), - CPU_PKG_M6117 = (1 << 12), - CPU_PKG_386SLC_IBM = (1 << 13), - CPU_PKG_486SLC = (1 << 14), - CPU_PKG_486SLC_IBM = (1 << 15), - CPU_PKG_486BL = (1 << 16), - CPU_PKG_486DLC = (1 << 17), - CPU_PKG_SOCKET1 = (1 << 18), - CPU_PKG_SOCKET3 = (1 << 19), - CPU_PKG_SOCKET3_PC330 = (1 << 20), - CPU_PKG_STPC = (1 << 21), - CPU_PKG_SOCKET4 = (1 << 22), - CPU_PKG_SOCKET5_7 = (1 << 23), - CPU_PKG_SOCKET8 = (1 << 24), - CPU_PKG_SLOT1 = (1 << 25), - CPU_PKG_SLOT2 = (1 << 26), - CPU_PKG_SLOTA = (1 << 27), - CPU_PKG_SOCKET370 = (1 << 28), - CPU_PKG_SOCKETA = (1 << 29), - CPU_PKG_EBGA368 = (1 << 30) + CPU_PKG_8088 = (1 << 0), + CPU_PKG_8088_EUROPC = (1 << 1), + CPU_PKG_8086 = (1 << 2), + CPU_PKG_188 = (1 << 3), + CPU_PKG_186 = (1 << 4), + CPU_PKG_286 = (1 << 5), + CPU_PKG_386SX = (1 << 6), + CPU_PKG_386DX = (1 << 7), + CPU_PKG_M6117 = (1 << 8), + CPU_PKG_386SLC_IBM = (1 << 9), + CPU_PKG_486SLC = (1 << 10), + CPU_PKG_486SLC_IBM = (1 << 11), + CPU_PKG_486BL = (1 << 12), + CPU_PKG_486DLC = (1 << 13), + CPU_PKG_SOCKET1 = (1 << 14), + CPU_PKG_SOCKET3 = (1 << 15), + CPU_PKG_SOCKET3_PC330 = (1 << 16), + CPU_PKG_STPC = (1 << 17), + CPU_PKG_SOCKET4 = (1 << 18), + CPU_PKG_SOCKET5_7 = (1 << 19), + CPU_PKG_SOCKET8 = (1 << 20), + CPU_PKG_SLOT1 = (1 << 21), + CPU_PKG_SLOT2 = (1 << 22), + CPU_PKG_SLOTA = (1 << 23), + CPU_PKG_SOCKET370 = (1 << 24), + CPU_PKG_SOCKETA = (1 << 25), + CPU_PKG_EBGA368 = (1 << 26) }; #define MANU_INTEL 0 diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 89b25e152..947804014 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -1004,65 +1004,6 @@ const cpu_family_t cpu_families[] = { { .name = "", 0 } } }, { - .package = CPU_PKG_286_CPQ_PORTABLE_II, - .manufacturer = "Intel", - .name = "80286", - .internal_name = "286", - .cpus = (const CPU[]) { - { - .name = "6", - .cpu_type = CPU_286, - .fpus = fpus_80286, - .rspeed = 6000000, - .multi = 1, - .voltage = 5000, - .edx_reset = 0, - .cpuid_model = 0, - .cyrix_id = 0, - .cpu_flags = 0, - .mem_read_cycles = 2, - .mem_write_cycles = 2, - .cache_read_cycles = 2, - .cache_write_cycles = 2, - .atclk_div = 1 - }, - { - .name = "8", - .cpu_type = CPU_286, - .fpus = fpus_80286, - .rspeed = 8000000, - .multi = 1, - .voltage = 5000, - .edx_reset = 0, - .cpuid_model = 0, - .cyrix_id = 0, - .cpu_flags = 0, - .mem_read_cycles = 2, - .mem_write_cycles = 2, - .cache_read_cycles = 2, - .cache_write_cycles = 2, - .atclk_div = 1 - }, - { - .name = "16", - .cpu_type = CPU_286, - .fpus = fpus_80286, - .rspeed = 16000000, - .multi = 1, - .voltage = 5000, - .edx_reset = 0, - .cpuid_model = 0, - .cyrix_id = 0, - .cpu_flags = 0, - .mem_read_cycles = 3, - .mem_write_cycles = 3, - .cache_read_cycles = 3, - .cache_write_cycles = 3, - .atclk_div = 2 - }, - { .name = "", 0 } - } - }, { .package = CPU_PKG_386SX, .manufacturer = "Intel", .name = "i386SX", @@ -1089,33 +1030,6 @@ const cpu_family_t cpu_families[] = { {"", 0} } }, { - .package = CPU_PKG_386DX_CPQ_09_1986, - .manufacturer = "Intel", - .name = "i386DX", - .internal_name = "i386dx", - .cpus = (const CPU[]) { - {"16", CPU_386DX, fpus_80286, 16000000, 1, 5000, 0x0308, 0, 0, 0, 3,3,3,3, 2}, - {"", 0} - } - }, { - .package = CPU_PKG_386DX_CPQ_1987, - .manufacturer = "Intel", - .name = "i386DX", - .internal_name = "i386dx", - .cpus = (const CPU[]) { - {"20", CPU_386DX, fpus_80386, 20000000, 1, 5000, 0x0308, 0, 0, 0, 4,4,3,3, 3}, - {"", 0} - } - }, { - .package = CPU_PKG_386DX_CPQ_05_1988, - .manufacturer = "Intel", - .name = "i386DX", - .internal_name = "i386dx", - .cpus = (const CPU[]) { - {"25", CPU_386DX, fpus_80386, 25000000, 1, 5000, 0x0308, 0, 0, 0, 4,4,3,3, 3}, - {"", 0} - } - }, { .package = CPU_PKG_386DX, .manufacturer = "Intel", .name = "i386DX", @@ -1256,15 +1170,6 @@ const cpu_family_t cpu_families[] = { {"", 0} } }, { - .package = CPU_PKG_386DX_CPQ_1987, - .manufacturer = "Cyrix", - .name = "Cx486DRx2", - .internal_name = "cx486drx2", - .cpus = (const CPU[]) { - {"40", CPU_486DLC, fpus_80386, 40000000, 2, 5000, 0x407, 0, 0x0007, 0, 8, 8,6,6, 6}, - {"", 0} - } - }, { .package = CPU_PKG_386DX, .manufacturer = "Cyrix", .name = "Cx486DRx2", diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 2066b125b..06069eed0 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -2767,10 +2767,10 @@ const machine_t machines[] = { .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_286_CPQ_PORTABLE_II, + .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, + .min_bus = 6000000, + .max_bus = 16000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -2807,10 +2807,10 @@ const machine_t machines[] = { .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_286_CPQ_PORTABLE_II, + .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, + .min_bus = 6000000, + .max_bus = 16000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -4875,10 +4875,10 @@ const machine_t machines[] = { .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_386DX_CPQ_09_1986, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, + .package = CPU_PKG_386DX, + .block = CPU_BLOCK(CPU_486DLC, CPU_RAPIDCAD), + .min_bus = 16000000, + .max_bus = 16000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -4914,10 +4914,10 @@ const machine_t machines[] = { .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_386DX_CPQ_05_1988, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, + .package = CPU_PKG_386DX, + .block = CPU_BLOCK(CPU_486DLC, CPU_RAPIDCAD), + .min_bus = 25000000, + .max_bus = 25000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -4953,10 +4953,10 @@ const machine_t machines[] = { .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_386DX_CPQ_1987, + .package = CPU_PKG_386DX, .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, + .min_bus = 20000000, + .max_bus = 20000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, From c996f69e8c8924d1d2f47a2a8af4529a6a023ed3 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 25 Jan 2024 21:27:39 -0300 Subject: [PATCH 17/23] Fix new machine names --- src/include/86box/machine.h | 10 +++++----- src/machine/m_at_slot1.c | 8 ++++---- src/machine/m_at_socket7.c | 4 ++-- src/machine/m_at_socket7_3v.c | 12 ++++++------ src/machine/m_at_socket8.c | 4 ++-- src/machine/machine_table.c | 20 ++++++++++---------- 6 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 73b27afbf..06443e101 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -638,7 +638,7 @@ extern int machine_at_8500tuc_init(const machine_t *); extern int machine_at_p55t2s_init(const machine_t *); extern int machine_at_p5vxb_init(const machine_t *); -extern int machine_at_dell_430vx_init(const machine_t *); +extern int machine_at_dellhannibalp_init(const machine_t *); extern int machine_at_gw2kte_init(const machine_t *); extern int machine_at_ap5s_init(const machine_t *); @@ -688,7 +688,7 @@ extern int machine_at_ficpa2012_init(const machine_t *); extern int machine_at_r534f_init(const machine_t *); extern int machine_at_ms5146_init(const machine_t *); -extern int machine_at_cb52x_si_init(const machine_t *); +extern int machine_at_cb52xsi_init(const machine_t *); extern int machine_at_m560_init(const machine_t *); extern int machine_at_ms5164_init(const machine_t *); @@ -710,7 +710,7 @@ extern int machine_at_p6rp4_init(const machine_t *); extern int machine_at_686nx_init(const machine_t *); extern int machine_at_acerv60n_init(const machine_t *); -extern int machine_at_lgibm440fx_init(const machine_t *); +extern int machine_at_lgibmx61_init(const machine_t *); extern int machine_at_vs440fx_init(const machine_t *); extern int machine_at_gw2kvenus_init(const machine_t *); extern int machine_at_ap440fx_init(const machine_t *); @@ -731,12 +731,12 @@ extern int machine_at_kn97_init(const machine_t *); extern int machine_at_lx6_init(const machine_t *); extern int machine_at_spitfire_init(const machine_t *); -extern int machine_at_mate_nx_ma30d_23d_init(const machine_t *); +extern int machine_at_ma30d_init(const machine_t *); extern int machine_at_p6i440e2_init(const machine_t *); extern int machine_at_p2bls_init(const machine_t *); -extern int machine_at_lgibm440bx_init(const machine_t *); +extern int machine_at_lgibmx7g_init(const machine_t *); extern int machine_at_p3bf_init(const machine_t *); extern int machine_at_bf6_init(const machine_t *); extern int machine_at_ax6bc_init(const machine_t *); diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 83e9b74a9..25cbde004 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -153,11 +153,11 @@ machine_at_spitfire_init(const machine_t *model) } int -machine_at_mate_nx_ma30d_23d_init(const machine_t *model) +machine_at_ma30d_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/mate_nx_ma30d_23d/BIOS.ROM", + ret = bios_load_linear("roms/machines/ma30d/BIOS.ROM", 0x000c0000, 262144, 0); if (bios_only || !ret) @@ -261,11 +261,11 @@ machine_at_p2bls_init(const machine_t *model) } int -machine_at_lgibm440bx_init(const machine_t *model) +machine_at_lgibmx7g_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/lgibm440bx/ms6119.331", + ret = bios_load_linear("roms/machines/lgibmx7g/ms6119.331", 0x000c0000, 262144, 0); if (bios_only || !ret) diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 46b95ce76..d06129b84 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -1211,11 +1211,11 @@ machine_at_ms5146_init(const machine_t *model) } int -machine_at_cb52x_si_init(const machine_t *model) +machine_at_cb52xsi_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/cb52x_si/CD5205S.ROM", + ret = bios_load_linear("roms/machines/cb52xsi/CD5205S.ROM", 0x000e0000, 131072, 0); if (bios_only || !ret) diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index 0e420aa3b..6b3df3c83 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -672,15 +672,15 @@ machine_at_p5vxb_init(const machine_t *model) } int -machine_at_dell_430vx_init(const machine_t *model) +machine_at_dellhannibalp_init(const machine_t *model) { int ret; - ret = bios_load_linear_combined2("roms/machines/dell_430vx/1003DY0J.BIO", - "roms/machines/dell_430vx/1003DY0J.BI1", - "roms/machines/dell_430vx/1003DY0J.BI2", - "roms/machines/dell_430vx/1003DY0J.BI3", - "roms/machines/dell_430vx/1003DY0J.RCV", + ret = bios_load_linear_combined2("roms/machines/dellhannibalp/1003DY0J.BIO", + "roms/machines/dellhannibalp/1003DY0J.BI1", + "roms/machines/dellhannibalp/1003DY0J.BI2", + "roms/machines/dellhannibalp/1003DY0J.BI3", + "roms/machines/dellhannibalp/1003DY0J.RCV", 0x3a000, 128); if (bios_only || !ret) diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index 7ce9d5095..e1dad68e7 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -195,11 +195,11 @@ machine_at_acerv60n_init(const machine_t *model) } int -machine_at_lgibm440fx_init(const machine_t *model) +machine_at_lgibmx61_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/lgibm440fx/bios.rom", + ret = bios_load_linear("roms/machines/lgibmx61/bios.rom", 0x000e0000, 131072, 0); if (bios_only || !ret) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 06069eed0..ed99ad076 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -9570,10 +9570,10 @@ const machine_t machines[] = { Command 0xA0 copyright string: (C)1994 AMI . */ { .name = "[i430VX] Dell Hannibal+", - .internal_name = "dell_430vx", + .internal_name = "dellhannibalp", .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430VX, - .init = machine_at_dell_430vx_init, + .init = machine_at_dellhannibalp_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, @@ -11122,10 +11122,10 @@ const machine_t machines[] = { /* Has the SiS 5571 chipset with on-chip KBC. */ { .name = "[SiS 5571] Daewoo CB52X-SI", - .internal_name = "cb52x_si", + .internal_name = "cb52xsi", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_SIS_5571, - .init = machine_at_cb52x_si_init, + .init = machine_at_cb52xsi_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, @@ -12024,10 +12024,10 @@ const machine_t machines[] = { /* Has the AMIKey-2 (updated 'H') KBC firmware. */ { .name = "[i440FX] LG IBM Multinet x61 (MSI MS-6106)", - .internal_name = "lgibm440fx", + .internal_name = "lgibmx61", .type = MACHINE_TYPE_SOCKET8, .chipset = MACHINE_CHIPSET_INTEL_440FX, - .init = machine_at_lgibm440fx_init, + .init = machine_at_lgibmx61_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, @@ -12357,10 +12357,10 @@ const machine_t machines[] = { AMIKey-2 KBC firmware. */ { .name = "[i440LX] NEC Mate NX MA30D/23D", - .internal_name = "mate_nx_ma30d_23d", + .internal_name = "ma30d", .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440LX, - .init = machine_at_mate_nx_ma30d_23d_init, + .init = machine_at_ma30d_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, @@ -12688,10 +12688,10 @@ const machine_t machines[] = { /* Has the AMIKey-2 (updated 'H') KBC firmware. */ { .name = "[i440BX] LG IBM Multinet i x7G (MSI MS-6119)", - .internal_name = "lgibm440bx", + .internal_name = "lgibmx7g", .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440BX, - .init = machine_at_lgibm440bx_init, + .init = machine_at_lgibmx7g_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, From aa28d7789ebbf6c79ef5fe4ad1840e1113b826e3 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 25 Jan 2024 21:43:14 -0300 Subject: [PATCH 18/23] Fix NEC MA30D parameters per a located spec sheet --- src/machine/m_at_slot1.c | 3 +-- src/machine/machine_table.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 25cbde004..12c84ffdf 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -183,8 +183,7 @@ machine_at_ma30d_init(const machine_t *model) device_add(&keyboard_ps2_ami_pci_device); device_add(&fdc37c67x_device); device_add(&intel_flash_bxt_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 256); - device_add(&lm78_device); /* no reporting in BIOS */ + spd_register(SPD_TYPE_SDRAM, 0x7, 256); return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index ed99ad076..84a55eb75 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -12379,7 +12379,7 @@ const machine_t machines[] = { .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, .ram = { .min = 8192, - .max = 1048576, + .max = 786432, .step = 8192 }, .nvrmask = 255, From ce24961846b70cb88a0ea2bd7e87c9b3077e5da0 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 25 Jan 2024 21:50:33 -0300 Subject: [PATCH 19/23] Fix parameters for the MS-6119 machine --- src/machine/machine_table.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 84a55eb75..5a799cdb4 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -12699,9 +12699,9 @@ const machine_t machines[] = { .cpu = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 112121212, - .min_voltage = 1300, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 1800, .max_voltage = 3500, .min_multi = 1.5, .max_multi = 8.0 @@ -12710,7 +12710,7 @@ const machine_t machines[] = { .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, .ram = { .min = 8192, - .max = 1048576, + .max = 786432, .step = 8192 }, .nvrmask = 255, From 0c8f03effa7f134ace159b1d562d3a1212f3ecce Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 26 Jan 2024 15:32:09 +0100 Subject: [PATCH 20/23] DEC 21140: Fix subsystem ID for the VPC Tulip, fixes #4081. --- src/network/net_tulip.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index a350d6662..00026deac 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -1375,13 +1375,23 @@ nic_init(const device_t *info) s->device_info = info; if (info->local != 3) { - /*Subsystem Vendor ID*/ - s->eeprom_data[0] = info->local ? 0x25 : 0x11; - s->eeprom_data[1] = 0x10; + if (info->local == 2) { + /*Subsystem Vendor ID*/ + s->eeprom_data[0] = 0x00; + s->eeprom_data[1] = 0x0a; - /*Subsystem ID*/ - s->eeprom_data[2] = info->local ? 0x10 : 0x0a; - s->eeprom_data[3] = info->local ? 0x03 : 0x50; + /*Subsystem ID*/ + s->eeprom_data[2] = 0x14; + s->eeprom_data[3] = 0x21; + } else { + /*Subsystem Vendor ID*/ + s->eeprom_data[0] = info->local ? 0x25 : 0x11; + s->eeprom_data[1] = 0x10; + + /*Subsystem ID*/ + s->eeprom_data[2] = info->local ? 0x10 : 0x0a; + s->eeprom_data[3] = info->local ? 0x03 : 0x50; + } /*Cardbus CIS Pointer low*/ s->eeprom_data[4] = 0x00; From 6d3e9642cecc33bdf0b995e3fe85608c047ac880 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 26 Jan 2024 16:23:53 +0100 Subject: [PATCH 21/23] SPEA Mercury P64V: Correctly caulculate the width at 1280x1024x24bpp. --- src/video/vid_s3.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 54f9047e8..d78dd03c7 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3920,6 +3920,7 @@ s3_recalctimings(svga_t *svga) case S3_VISION968: switch (s3->card_type) { case S3_MIROVIDEO40SV_ERGO_968: + case S3_SPEA_MERCURY_P64V: switch (s3->width) { case 1280: svga->hdisp = ((svga->hdisp << 1) / 3) << 1; From cfd8ec8088e85f16fb7428dda278053423e3a215 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 26 Jan 2024 19:03:43 +0100 Subject: [PATCH 22/23] Slight cleanup of the 8514/A compatible chips. Hopefully fix various modes altogether in all three chips (640x480, 800x600, 1024x768 and 1280x1024). --- src/include/86box/vid_8514a.h | 2 + src/video/vid_8514a.c | 88 ++++++++++++++++---------------- src/video/vid_ati_mach8.c | 94 ++++++++++++++++++++--------------- 3 files changed, 100 insertions(+), 84 deletions(-) diff --git a/src/include/86box/vid_8514a.h b/src/include/86box/vid_8514a.h index dcfdf6045..ce346e84d 100644 --- a/src/include/86box/vid_8514a.h +++ b/src/include/86box/vid_8514a.h @@ -152,8 +152,10 @@ typedef struct ibm8514_t { int hblank_ext; int hblank_sub; + int v_total_reg; int v_total; int dispend; + int v_sync_start; int v_syncstart; int split; int h_disp; diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 9f2b1316a..fdbd39979 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -901,8 +901,10 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) case 0x6e8: case 0x6e9: if (!(port & 1)) { - dev->hdisped = val; - dev->hdisp = (dev->hdisped + 1) << 3; + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { + dev->hdisped = val; + dev->hdisp = (dev->hdisped + 1) << 3; + } } ibm8514_log("IBM 8514/A: H_DISP write 06E8 = %d, advfunc=%x.\n", dev->hdisp, dev->accel.advfunc_cntl & 4); break; @@ -910,8 +912,10 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) case 0xae8: case 0xae9: if (!(port & 1)) { - dev->hsync_start = val; - dev->hblankstart = (dev->hsync_start & 0x07) + 1; + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { + dev->hsync_start = val; + dev->hblankstart = (dev->hsync_start & 0x07) + 1; + } } ibm8514_log("IBM 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); break; @@ -919,32 +923,44 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) case 0xee8: case 0xee9: if (!(port & 1)) { - dev->hsync_width = val; - dev->hblank_end_val = (dev->hblankstart + (dev->hsync_start & 0x1f) - 1) & 0x3f; + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { + dev->hsync_width = val; + dev->hblank_end_val = (dev->hblankstart + (dev->hsync_start & 0x1f) - 1) & 0x3f; + } } ibm8514_log("IBM 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); break; case 0x12e8: case 0x12e9: - WRITE8(port, dev->vtotal, val); - dev->vtotal &= 0x1fff; + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { + WRITE8(port, dev->v_total_reg, val); + dev->v_total_reg &= 0x1fff; + dev->vtotal = dev->v_total_reg; + dev->vtotal++; + } break; case 0x16e8: case 0x16e9: - WRITE8(port, dev->v_disp, val); - dev->v_disp &= 0x1fff; - dev->vdisp = dev->v_disp; - dev->vdisp >>= 1; - dev->vdisp++; + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { + WRITE8(port, dev->v_disp, val); + dev->v_disp &= 0x1fff; + dev->vdisp = dev->v_disp; + dev->vdisp >>= 1; + dev->vdisp++; + } ibm8514_log("IBM 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp); break; case 0x1ae8: case 0x1ae9: - WRITE8(port, dev->vsyncstart, val); - dev->vsyncstart &= 0x1fff; + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { + WRITE8(port, dev->v_sync_start, val); + dev->v_sync_start &= 0x1fff; + dev->vsyncstart = dev->v_sync_start; + dev->vsyncstart++; + } break; case 0x1ee8: @@ -988,14 +1004,6 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) dev->on[port & 1] = dev->accel.advfunc_cntl & 0x01; vga_on = !dev->on[port & 1]; dev->vendor_mode[port & 1] = 0; - if (dev->on[0] || dev->on[1]) { - if (!(dev->accel.advfunc_cntl & 4)) { - if (dev->disp_cntl & 0x60) { - dev->hdisp = 640; - dev->vdisp = 480; - } - } - } ibm8514_log("IBM 8514/A: (0x%04x): ON=%d, shadow crt=%x.\n", port, dev->on[port & 1], dev->accel.advfunc_cntl & 4); svga_recalctimings(svga); break; @@ -4208,7 +4216,6 @@ ibm8514_poll(void *priv, svga_t *svga) dev->firstline--; wx = x; - wy = dev->lastline - dev->firstline; svga_doblit(wx, wy, svga); @@ -4262,17 +4269,14 @@ ibm8514_recalctimings(svga_t *svga) dev->h_total = dev->htotal + 1; dev->h_blankstart = dev->hblankstart; dev->h_blank_end_val = dev->hblank_end_val; - dev->v_total = dev->vtotal + 1; - dev->v_syncstart = dev->vsyncstart + 1; - dev->rowcount = !!(dev->disp_cntl & 0x08); + dev->v_total = dev->vtotal; + dev->v_syncstart = dev->vsyncstart; dev->dispend = dev->vdisp; + dev->rowcount = !!(dev->disp_cntl & 0x08); if (dev->dispend == 766) dev->dispend += 2; - if (dev->dispend == 598) - dev->dispend += 2; - if (dev->accel.advfunc_cntl & 4) { dev->pitch = 1024; if (!dev->h_disp) { @@ -4289,25 +4293,18 @@ ibm8514_recalctimings(svga_t *svga) svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; } - if (dev->interlace) + if (dev->interlace) { dev->dispend >>= 1; + dev->v_syncstart >>= 2; + dev->v_total >>= 2; + } else { + dev->v_syncstart >>= 1; + dev->v_total >>= 1; + } dev->rowoffset = 0x80; svga->map8 = dev->pallook; svga->render8514 = ibm8514_render_8bpp; - - dev->hblankend = (dev->h_blankstart & ~0x3f) | dev->h_blank_end_val; - if (dev->hblankend <= dev->h_blankstart) - dev->hblankend += 0x40; - dev->hblankend += dev->hblank_ext; - - dev->hblank_sub = 0; - if (dev->hblankend > dev->h_total) { - dev->hblankend &= 0x3f; - dev->hblank_sub = dev->hblankend + 1; - - dev->h_disp -= dev->hblank_sub; - } ibm8514_log("BPP=%d, Pitch = %d, rowoffset = %d, crtc13 = %02x, highres bit = %02x, has_vga? = %d.\n", dev->bpp, dev->pitch, dev->rowoffset, svga->crtc[0x13], dev->accel.advfunc_cntl & 4, !ibm8514_standalone_enabled); } } @@ -4440,10 +4437,13 @@ ibm8514_close(void *priv) { svga_t *svga = (svga_t *) priv; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + +#ifdef ATI_8514_ULTRA mach_t *mach = (mach_t *) svga->ext8514; if (mach) free(mach); +#endif if (dev) { free(dev->vram); diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index d710b2bcf..de40dc24e 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -59,7 +59,17 @@ static uint8_t mach_accel_inb(uint16_t port, void *priv); static uint16_t mach_accel_inw(uint16_t port, void *priv); static uint8_t mach_in(uint16_t addr, void *priv); -static void mach32_updatemapping(mach_t *mach, svga_t *svga); +#ifdef ATI_8514_ULTRA +static void ati8514_accel_outb(uint16_t port, uint8_t val, void *priv); +static void ati8514_accel_outw(uint16_t port, uint16_t val, void *priv); +static void ati8514_accel_outl(uint16_t port, uint32_t val, void *priv); +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); +#endif + + +static void mach32_updatemapping(mach_t *mach, svga_t *svga); #ifdef ENABLE_MACH_LOG int mach_do_log = ENABLE_MACH_LOG; @@ -113,9 +123,9 @@ mach_log(const char *fmt, ...) #define READ_PIXTRANS_WORD(cx, n) \ if ((cmd == 0) || (cmd == 1) || (cmd == 5) || (mach->accel.cmd_type == -1)) { \ - if (dev->bpp) { \ + if (dev->bpp) \ temp = vram_w[((dev->accel.cy * dev->pitch) + (cx) + (n)) & (dev->vram_mask >> 1)]; \ - } else { \ + else { \ temp = dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n)) & dev->vram_mask]; \ temp |= (dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ } \ @@ -2482,8 +2492,8 @@ ati8514_recalctimings(svga_t *svga) dev->h_total = dev->htotal + 1; dev->h_blankstart = dev->hblankstart; dev->h_blank_end_val = dev->hblank_end_val; - dev->v_total = dev->vtotal + 1; - dev->v_syncstart = dev->vsyncstart + 1; + dev->v_total = dev->vtotal; + dev->v_syncstart = dev->vsyncstart; dev->rowcount = !!(dev->disp_cntl & 0x08); dev->dispend = dev->vdisp; @@ -2604,8 +2614,8 @@ mach_recalctimings(svga_t *svga) dev->h_total = dev->htotal + 1; dev->h_blankstart = dev->hblankstart; dev->h_blank_end_val = dev->hblank_end_val; - dev->v_total = dev->vtotal + 1; - dev->v_syncstart = dev->vsyncstart + 1; + dev->v_total = dev->vtotal; + dev->v_syncstart = dev->vsyncstart; dev->dispend = dev->vdisp; dev->rowcount = !!(dev->disp_cntl & 0x08); @@ -2615,6 +2625,9 @@ mach_recalctimings(svga_t *svga) if (dev->dispend == 598) dev->dispend += 2; + if (dev->dispend == 478) + dev->dispend += 2; + if ((dev->local & 0xff) >= 0x02) { if ((dev->accel.advfunc_cntl ^ dev->modechange) & 0x04) { if ((mach->shadow_set ^ mach->compat_mode) & 0x03) @@ -2710,8 +2723,11 @@ mach_recalctimings(svga_t *svga) svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; if (((mach->shadow_set & 0x03) != 0x02) || !(dev->accel.advfunc_cntl & 0x04)) { /*Shadow set of 2 and bit 2 of port 0x4ae8 mean 1024x768+*/ - dev->h_disp = 640; - dev->dispend = 480; + if (!(mach->accel.clock_sel & 0x01)) { + dev->h_disp = 640; + dev->dispend = 480; + } + dev->interlace = 0; } } @@ -2726,26 +2742,12 @@ mach_recalctimings(svga_t *svga) dev->pitch = dev->ext_pitch; dev->rowoffset = dev->ext_crt_pitch; - mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, shadow=%x.\n", dev->accel.advfunc_cntl & 4, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0, mach->shadow_set & 3); + mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, shadow=%x interlace=%d.\n", dev->accel.advfunc_cntl & 4, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0, mach->shadow_set & 3, dev->interlace); svga->map8 = dev->pallook; svga->render8514 = ibm8514_render_8bpp; if (mach->regs[0xb8] & 0x40) svga->clock *= 2; } - - dev->hblankend = (dev->h_blankstart & ~0x3f) | dev->h_blank_end_val; - if (dev->hblankend <= dev->h_blankstart) - dev->hblankend += 0x40; - - dev->hblankend += dev->hblank_ext; - - dev->hblank_sub = 0; - if (dev->hblankend > dev->h_total) { - dev->hblankend &= 0x3f; - dev->hblank_sub = dev->hblankend + 1; - - dev->h_disp -= dev->hblank_sub; - } } if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { @@ -3636,7 +3638,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0x6e8: case 0x6e9: if (!(port & 1)) { - if (((dev->disp_cntl & 0x60) == 0x20) || (mach->accel.clock_sel & 0x01)) { + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { dev->hdisped = val; dev->hdisp = (dev->hdisped + 1) << 3; } @@ -3647,8 +3649,10 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0xae8: case 0xae9: if (!(port & 1)) { - dev->hsync_start = val; - dev->hblankstart = (dev->hsync_start & 0x07) + 1; + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { + dev->hsync_start = val; + dev->hblankstart = (dev->hsync_start & 0x07) + 1; + } } mach_log("ATI 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); break; @@ -3656,36 +3660,46 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0xee8: case 0xee9: if (!(port & 1)) { - dev->hsync_width = val; - dev->hblank_end_val = (dev->hblankstart + (dev->hsync_start & 0x1f) - 1) & 0x3f; + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { + dev->hsync_width = val; + dev->hblank_end_val = (dev->hblankstart + (dev->hsync_start & 0x1f) - 1) & 0x3f; + } } mach_log("ATI 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); break; case 0x12e8: case 0x12e9: - WRITE8(port, dev->vtotal, val); - dev->vtotal &= 0x1fff; + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { + WRITE8(port, dev->v_total_reg, val); + dev->v_total_reg &= 0x1fff; + dev->vtotal = dev->v_total_reg; + dev->vtotal++; + } break; case 0x16e8: case 0x16e9: - if (((dev->disp_cntl & 0x60) == 0x20) || (mach->accel.clock_sel & 0x01)) { + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { WRITE8(port, dev->v_disp, val); dev->v_disp &= 0x1fff; dev->vdisp = dev->v_disp; dev->vdisp >>= 1; dev->vdisp++; } - dev->modechange = dev->accel.advfunc_cntl & 4; - mach->compat_mode = mach->shadow_set & 3; + dev->modechange = dev->accel.advfunc_cntl & 0x04; + mach->compat_mode = mach->shadow_set & 0x03; mach_log("ATI 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp); break; case 0x1ae8: case 0x1ae9: - WRITE8(port, dev->vsyncstart, val); - dev->vsyncstart &= 0x1fff; + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { + WRITE8(port, dev->v_sync_start, val); + dev->v_sync_start &= 0x1fff; + dev->vsyncstart = dev->v_sync_start; + dev->vsyncstart++; + } break; case 0x1ee8: @@ -3694,7 +3708,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 break; case 0x22e8: - dev->disp_cntl = val & 0x7e; + dev->disp_cntl = val; dev->interlace = !!(val & 0x10); mach_log("ATI 8514/A: DISP_CNTL write 22E8 = %02x, interlace = %d\n", dev->disp_cntl, dev->interlace); break; @@ -4314,13 +4328,13 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in case 0xcaee: if (len == 1) - temp = dev->vsyncstart & 0xff; + temp = dev->v_sync_start & 0xff; else - temp = dev->vsyncstart; + temp = dev->v_sync_start; break; case 0xcaef: if (len == 1) - temp = dev->vsyncstart >> 8; + temp = dev->v_sync_start >> 8; break; case 0xceee: From 3f2a61ae70617e442d4f14a290ddfb25d8462828 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 27 Jan 2024 02:15:59 +0100 Subject: [PATCH 23/23] DEC Tulip: Make the memory BAR 4096 bytes in order to fit within 86Box's memory mapping granularity. --- src/network/net_rtl8139.c | 6 ++++- src/network/net_tulip.c | 52 +++++++++++++++++++++++++++++++++------ 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index a07becff0..8afb7b4b8 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -3124,8 +3124,10 @@ rtl8139_pci_read(UNUSED(int func), int addr, void *priv) return 1; case 0x14: return 0; -#ifndef USE_256_BYTE_BAR case 0x15: +#ifdef USE_256_BYTE_BAR + return s->pci_conf[addr & 0xFF]; +#else return s->pci_conf[addr & 0xFF] & 0xf0; #endif case 0x2c: @@ -3187,7 +3189,9 @@ rtl8139_pci_write(int func, int addr, uint8_t val, void *priv) rtl8139_io_writeb_ioport, rtl8139_io_writew_ioport, rtl8139_io_writel_ioport, priv); break; +#ifndef USE_256_BYTE_BAR case 0x14: +#endif case 0x15: case 0x16: case 0x17: diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index 00026deac..5fed7f1d1 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -1038,37 +1038,55 @@ tulip_writel_io(uint16_t addr, uint32_t data, void *opaque) static void tulip_mem_writeb(uint32_t addr, uint8_t data, void *opaque) { - return tulip_write(addr, data, opaque); + if ((addr & 0xfff) < 0x100) + tulip_write(addr, data, opaque); } static void tulip_mem_writew(uint32_t addr, uint16_t data, void *opaque) { - return tulip_write(addr, data, opaque); + if ((addr & 0xfff) < 0x100) + tulip_write(addr, data, opaque); } static void tulip_mem_writel(uint32_t addr, uint32_t data, void *opaque) { - return tulip_write(addr, data, opaque); + if ((addr & 0xfff) < 0x100) + tulip_write(addr, data, opaque); } static uint8_t tulip_mem_readb(uint32_t addr, void *opaque) { - return tulip_read(addr, opaque); + uint8_t ret = 0xff; + + if ((addr & 0xfff) < 0x100) + ret = tulip_read(addr, opaque); + + return ret; } static uint16_t tulip_mem_readw(uint32_t addr, void *opaque) { - return tulip_read(addr, opaque); + uint16_t ret = 0xffff; + + if ((addr & 0xfff) < 0x100) + ret = tulip_read(addr, opaque); + + return ret; } static uint32_t tulip_mem_readl(uint32_t addr, void *opaque) { - return tulip_read(addr, opaque); + uint32_t ret = 0xffffffff; + + if ((addr & 0xfff) < 0x100) + ret = tulip_read(addr, opaque); + + return ret; } static uint8_t @@ -1208,11 +1226,17 @@ tulip_pci_read(UNUSED(int func), int addr, void *priv) case 0x13: ret = tulip_pci_bar[0].addr_regs[3]; break; +#ifdef USE_128_BYTE_BAR case 0x14: ret = (tulip_pci_bar[1].addr_regs[0] & 0x80); break; +#endif case 0x15: +#ifdef USE_128_BYTE_BAR ret = tulip_pci_bar[1].addr_regs[1]; +#else + ret = tulip_pci_bar[1].addr_regs[1] & 0xf0; +#endif break; case 0x16: ret = tulip_pci_bar[1].addr_regs[2]; @@ -1283,7 +1307,7 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) //pclog("PCI write cmd: IOBase=%04x, MMIOBase=%08x, val=%02x.\n", s->PCIBase, s->MMIOBase, s->pci_conf[0x04]); mem_mapping_disable(&s->memory); if ((s->MMIOBase != 0) && (val & PCI_COMMAND_MEM)) - mem_mapping_set_addr(&s->memory, s->MMIOBase, 128); + mem_mapping_enable(&s->memory); break; case 0x05: s->pci_conf[0x05] = val & 1; @@ -1308,18 +1332,28 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) priv); } break; +#ifndef USE_128_BYTE_BAR case 0x14: +#endif case 0x15: case 0x16: case 0x17: mem_mapping_disable(&s->memory); tulip_pci_bar[1].addr_regs[addr & 3] = val; +#ifdef USE_128_BYTE_BAR tulip_pci_bar[1].addr &= 0xffffff80; +#else + tulip_pci_bar[1].addr &= 0xfffff000; +#endif s->MMIOBase = tulip_pci_bar[1].addr; if (s->pci_conf[0x4] & PCI_COMMAND_MEM) { //pclog("PCI write=%02x, mmiobase=%08x, mmio?=%x.\n", addr, s->PCIBase, s->pci_conf[0x4] & PCI_COMMAND_MEM); if (s->MMIOBase != 0) +#ifdef USE_128_BYTE_BAR mem_mapping_set_addr(&s->memory, s->MMIOBase, 128); +#else + mem_mapping_set_addr(&s->memory, s->MMIOBase, 4096); +#endif } break; case 0x30: /* PCI_ROMBAR */ @@ -1369,7 +1403,11 @@ nic_init(const device_t *info) s->has_bios = 0; } +#ifdef USE_128_BYTE_BAR mem_mapping_add(&s->memory, 0x0fffff00, 128, tulip_mem_readb, tulip_mem_readw, tulip_mem_readl, tulip_mem_writeb, tulip_mem_writew, tulip_mem_writel, NULL, MEM_MAPPING_EXTERNAL, s); +#else + mem_mapping_add(&s->memory, 0x0ffff000, 4096, tulip_mem_readb, tulip_mem_readw, tulip_mem_readl, tulip_mem_writeb, tulip_mem_writew, tulip_mem_writel, NULL, MEM_MAPPING_EXTERNAL, s); +#endif mem_mapping_disable(&s->memory); s->device_info = info;