From d27d15501ea70adbffbca09affd4665b8a4be086 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 26 Jun 2022 17:10:28 +0600 Subject: [PATCH 01/31] qt: attempt fixing black screen --- src/qt/qt_rendererstack.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index f8532c78e..74cfdbb37 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -244,6 +244,7 @@ RendererStack::switchRenderer(Renderer renderer) createRenderer(renderer); disconnect(this, &RendererStack::blit, this, &RendererStack::blitDummy); blitDummied = false; + QTimer::singleShot(1000, this, [this] () { this->blitDummied = false; }; ); }); rendererWindow->hasBlitFunc() ? current.reset() : current.release()->deleteLater(); From 07c76cb06e70989e8ab72708c99a5dfea61c708e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 26 Jun 2022 17:29:41 +0600 Subject: [PATCH 02/31] Update qt_rendererstack.cpp --- src/qt/qt_rendererstack.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 74cfdbb37..c7f1984a7 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -244,7 +244,7 @@ RendererStack::switchRenderer(Renderer renderer) createRenderer(renderer); disconnect(this, &RendererStack::blit, this, &RendererStack::blitDummy); blitDummied = false; - QTimer::singleShot(1000, this, [this] () { this->blitDummied = false; }; ); + QTimer::singleShot(1000, this, [this]() { this->blitDummied = false; } ); }); rendererWindow->hasBlitFunc() ? current.reset() : current.release()->deleteLater(); From 7ca64ced86531d12b2bec62a1cc5b26eb5a2baf0 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 26 Jun 2022 23:16:44 +0200 Subject: [PATCH 03/31] EGA fixes to its renderer. --- src/video/vid_ega_render.c | 208 +++++++++++++++++-------------------- 1 file changed, 94 insertions(+), 114 deletions(-) diff --git a/src/video/vid_ega_render.c b/src/video/vid_ega_render.c index 94474577f..c3ceafc6f 100644 --- a/src/video/vid_ega_render.c +++ b/src/video/vid_ega_render.c @@ -254,47 +254,42 @@ ega_render_2bpp_lowres(ega_t *ega) int x; uint8_t dat[2]; uint32_t addr, *p; - uint32_t changed_addr; if ((ega->displine + ega->y_add) < 0) return; - changed_addr = ega->remap_func(ega, ega->ma); + p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; - if (fullchange) { - p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; + if (ega->firstline_draw == 2000) + ega->firstline_draw = ega->displine; + ega->lastline_draw = ega->displine; - if (ega->firstline_draw == 2000) - ega->firstline_draw = ega->displine; - ega->lastline_draw = ega->displine; + for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 16) { + addr = ega->remap_func(ega, ega->ma); - for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 16) { - addr = ega->remap_func(ega, ega->ma); + dat[0] = ega->vram[addr]; + dat[1] = ega->vram[addr | 0x1]; + if (ega->seqregs[1] & 4) + ega->ma += 2; + else + ega->ma += 4; - dat[0] = ega->vram[addr]; - dat[1] = ega->vram[addr | 0x1]; - if (ega->seqregs[1] & 4) - ega->ma += 2; - else - ega->ma += 4; + ega->ma &= ega->vrammask; - ega->ma &= ega->vrammask; + if (ega->crtc[0x17] & 0x80) { + p[0] = p[1] = ega->pallook[ega->egapal[(dat[0] >> 6) & 3]]; + p[2] = p[3] = ega->pallook[ega->egapal[(dat[0] >> 4) & 3]]; + p[4] = p[5] = ega->pallook[ega->egapal[(dat[0] >> 2) & 3]]; + p[6] = p[7] = ega->pallook[ega->egapal[dat[0] & 3]]; + p[8] = p[9] = ega->pallook[ega->egapal[(dat[1] >> 6) & 3]]; + p[10] = p[11] = ega->pallook[ega->egapal[(dat[1] >> 4) & 3]]; + p[12] = p[13] = ega->pallook[ega->egapal[(dat[1] >> 2) & 3]]; + p[14] = p[15] = ega->pallook[ega->egapal[dat[1] & 3]]; + } else + memset(p, 0x00, 16 * sizeof(uint32_t)); - if (ega->crtc[0x17] & 0x80) { - p[0] = p[1] = ega->pallook[ega->egapal[(dat[0] >> 6) & 3]]; - p[2] = p[3] = ega->pallook[ega->egapal[(dat[0] >> 4) & 3]]; - p[4] = p[5] = ega->pallook[ega->egapal[(dat[0] >> 2) & 3]]; - p[6] = p[7] = ega->pallook[ega->egapal[dat[0] & 3]]; - p[8] = p[9] = ega->pallook[ega->egapal[(dat[1] >> 6) & 3]]; - p[10] = p[11] = ega->pallook[ega->egapal[(dat[1] >> 4) & 3]]; - p[12] = p[13] = ega->pallook[ega->egapal[(dat[1] >> 2) & 3]]; - p[14] = p[15] = ega->pallook[ega->egapal[dat[1] & 3]]; - } else - memset(p, 0x00, 16 * sizeof(uint32_t)); - - p += 16; - } - } + p += 16; + } } @@ -304,14 +299,10 @@ ega_render_2bpp_highres(ega_t *ega) int x; uint8_t dat[2]; uint32_t addr, *p; - uint32_t changed_addr; if ((ega->displine + ega->y_add) < 0) return; - changed_addr = ega->remap_func(ega, ega->ma); - - if (fullchange) { p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; if (ega->firstline_draw == 2000) @@ -344,7 +335,6 @@ ega_render_2bpp_highres(ega_t *ega) p += 8; } - } } @@ -354,54 +344,49 @@ ega_render_4bpp_lowres(ega_t *ega) int x, oddeven; uint8_t dat, edat[4]; uint32_t addr, *p; - uint32_t changed_addr; if ((ega->displine + ega->y_add) < 0) return; - changed_addr = ega->remap_func(ega, ega->ma); + p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; - if (fullchange) { - p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; + if (ega->firstline_draw == 2000) + ega->firstline_draw = ega->displine; + ega->lastline_draw = ega->displine; - if (ega->firstline_draw == 2000) - ega->firstline_draw = ega->displine; - ega->lastline_draw = ega->displine; + for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 16) { + addr = ega->remap_func(ega, ega->ma); + oddeven = 0; - for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 16) { - addr = ega->remap_func(ega, ega->ma); - oddeven = 0; + if (ega->seqregs[1] & 4) { + oddeven = (addr & 4) ? 1 : 0; + edat[0] = ega->vram[addr | oddeven]; + edat[2] = ega->vram[addr | oddeven | 0x2]; + edat[1] = edat[3] = 0; + ega->ma += 2; + } else { + *(uint32_t *)(&edat[0]) = *(uint32_t *)(&ega->vram[addr]); + ega->ma += 4; + } + ega->ma &= ega->vrammask; - if (ega->seqregs[1] & 4) { - oddeven = (addr & 4) ? 1 : 0; - edat[0] = ega->vram[addr | oddeven]; - edat[2] = ega->vram[addr | oddeven | 0x2]; - edat[1] = edat[3] = 0; - ega->ma += 2; - } else { - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&ega->vram[addr]); - ega->ma += 4; - } - ega->ma &= ega->vrammask; + if (ega->crtc[0x17] & 0x80) { + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + p[0] = p[1] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; + p[2] = p[3] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + p[4] = p[5] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; + p[6] = p[7] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + p[8] = p[9] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; + p[10] = p[11] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + p[12] = p[13] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; + p[14] = p[15] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; + } else + memset(p, 0x00, 16 * sizeof(uint32_t)); - if (ega->crtc[0x17] & 0x80) { - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = p[1] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[2] = p[3] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[4] = p[5] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[6] = p[7] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[8] = p[9] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[10] = p[11] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[12] = p[13] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[14] = p[15] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - } else - memset(p, 0x00, 16 * sizeof(uint32_t)); - - p += 16; - } + p += 16; } } @@ -412,53 +397,48 @@ ega_render_4bpp_highres(ega_t *ega) int x, oddeven; uint8_t dat, edat[4]; uint32_t addr, *p; - uint32_t changed_addr; if ((ega->displine + ega->y_add) < 0) return; - changed_addr = ega->remap_func(ega, ega->ma); + p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; - if (fullchange) { - p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; + if (ega->firstline_draw == 2000) + ega->firstline_draw = ega->displine; + ega->lastline_draw = ega->displine; - if (ega->firstline_draw == 2000) - ega->firstline_draw = ega->displine; - ega->lastline_draw = ega->displine; + for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 8) { + addr = ega->remap_func(ega, ega->ma); + oddeven = 0; - for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 8) { - addr = ega->remap_func(ega, ega->ma); - oddeven = 0; + if (ega->seqregs[1] & 4) { + oddeven = (addr & 4) ? 1 : 0; + edat[0] = ega->vram[addr | oddeven]; + edat[2] = ega->vram[addr | oddeven | 0x2]; + edat[1] = edat[3] = 0; + ega->ma += 2; + } else { + *(uint32_t *)(&edat[0]) = *(uint32_t *)(&ega->vram[addr]); + ega->ma += 4; + } + ega->ma &= ega->vrammask; - if (ega->seqregs[1] & 4) { - oddeven = (addr & 4) ? 1 : 0; - edat[0] = ega->vram[addr | oddeven]; - edat[2] = ega->vram[addr | oddeven | 0x2]; - edat[1] = edat[3] = 0; - ega->ma += 2; - } else { - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&ega->vram[addr]); - ega->ma += 4; - } - ega->ma &= ega->vrammask; + if (ega->crtc[0x17] & 0x80) { + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + p[0] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; + p[1] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + p[2] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; + p[3] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + p[4] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; + p[5] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + p[6] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; + p[7] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; + } else + memset(p, 0x00, 8 * sizeof(uint32_t)); - if (ega->crtc[0x17] & 0x80) { - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[1] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[2] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[3] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[4] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[5] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[6] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[7] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - } else - memset(p, 0x00, 8 * sizeof(uint32_t)); - - p += 8; - } + p += 8; } } From 29d9d58890af36eadfb6e42ae8bbdb4db6b87d2a Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 26 Jun 2022 23:19:48 +0200 Subject: [PATCH 04/31] Slight fixes to the 8514/A blitter in line draw, rectangle and outline modes. --- src/video/vid_8514a.c | 213 ++++++++++++++++++++++++++++++------------ 1 file changed, 151 insertions(+), 62 deletions(-) diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 07faf1c49..566cd3739 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -63,7 +63,7 @@ static void ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_da static void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, ibm8514_t *dev, int len); #define READ_PIXTRANS_WORD(cx, n) \ - if (cmd <= 1) { \ + if (cmd <= 1 || (cmd == 5)) { \ temp = dev->vram[((dev->accel.cy * dev->h_disp) + (cx) + (n)) & dev->vram_mask]; \ temp |= (dev->vram[((dev->accel.cy * dev->h_disp) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ } else { \ @@ -248,8 +248,8 @@ regular_nibble: nibble |= 0x01; } - if ((and3 == 0) || (dev->accel.cmd & 0x1000) || (dev->accel.cmd & 8)) { - if (dev->accel.cmd & 8) { + if ((and3 == 0) || (dev->accel.cmd & 0x1000) || ((dev->accel.cmd & 8) && ibm8514_cpu_src(dev))) { + if ((dev->accel.cmd & 8) && ibm8514_cpu_src(dev)) { monoxfer = val; } else monoxfer = nibble; @@ -1117,6 +1117,8 @@ ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t ibm8514_accel_start(count, cpu_input, mix_dat, cpu_dat, dev, len); } +#define SWAP(a,b) { tmpswap = a; a = b; b = tmpswap; } + static void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, ibm8514_t *dev, int len) { @@ -1137,6 +1139,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat uint32_t old_mix_dat; int and3 = dev->accel.cur_x & 3; uint8_t poly_src = 0; + int16_t tmpswap; if (dev->accel.cmd & 0x100) { dev->force_busy = 1; @@ -1242,6 +1245,11 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat /*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled. When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on the NOP command)*/ + if (dev->accel.cmd == 0x41f0) { + pclog("CMD = %d, full = %04x, pixcntl = %d, curx = %d, cury = %d, cl = %d, cr = %d, ct = %d, cb = %d, len = %d, sx = %d, sy = %d, BX = %04X, CX = %02X\n", cmd, dev->accel.cmd, pixcntl, dev->accel.cur_x, dev->accel.cur_y, dev->accel.multifunc[2], dev->accel.multifunc[4], dev->accel.multifunc[1], dev->accel.multifunc[3], dev->accel.maj_axis_pcnt, dev->accel.sx, dev->accel.sy, BX, CH); + pclog("\n"); + } + switch (cmd) { case 0: /*NOP (Short Stroke Vectors)*/ if (dev->accel.ssv_state == 0) @@ -1302,6 +1310,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat case 1: /*Draw line*/ if (!cpu_input) { + dev->accel.xx_count = 0; dev->accel.cx = dev->accel.cur_x; dev->accel.cy = dev->accel.cur_y; @@ -1315,6 +1324,35 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.sy = dev->accel.maj_axis_pcnt; if (ibm8514_cpu_src(dev)) { + if (dev->accel.cmd & 2) { + if (dev->accel.cmd & 8) { + if (and3 == 1) { + dev->accel.sy += 4; + if (dev->accel.cmd & 0x20) + dev->accel.cx += 4; + else + dev->accel.cx -= 4; + } else if (and3 == 2) { + dev->accel.sy += 5; + if (dev->accel.cmd & 0x20) + dev->accel.cx += 5; + else + dev->accel.cx -= 5; + } else if (and3 == 3) { + dev->accel.sy += 6; + if (dev->accel.cmd & 0x20) + dev->accel.cx += 6; + else + dev->accel.cx -= 6; + } else { + dev->accel.sy += 3; + if (dev->accel.cmd & 0x20) + dev->accel.cx += 3; + else + dev->accel.cx -= 3; + } + } + } dev->data_available = 0; dev->data_available2 = 0; return; /*Wait for data from CPU*/ @@ -1326,6 +1364,9 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } if (dev->accel.cmd & 8) { /*Vector Line*/ + if (ibm8514_cpu_dest(dev) && cpu_input && (dev->accel.cmd & 2)) + count >>= 1; + dev->accel.xx_count++; while (count-- && (dev->accel.sy >= 0)) { if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { @@ -1361,11 +1402,71 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat old_dest_dat = dest_dat; MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if (ibm8514_cpu_src(dev) || !cpu_input) { - if ((dev->accel.cmd & 4) && dev->accel.sy) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + if ((dev->accel.cmd & 2) && ibm8514_cpu_src(dev)) { + if (and3 == 1) { + if (dev->accel.xx_count >= 2) { + if ((dev->accel.cmd & 4) && dev->accel.sy) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } + } + } else if (and3 == 2) { + if (dev->accel.xx_count == 2) { + if (count <= 2) { + if ((dev->accel.cmd & 4) && dev->accel.sy) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } + } + } else if (dev->accel.xx_count >= 3) { + if ((dev->accel.cmd & 4) && dev->accel.sy) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } + } + } else if (and3 == 3) { + if (dev->accel.xx_count == 2) { + if (count <= 1) { + if ((dev->accel.cmd & 4) && dev->accel.sy) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } + } + } else if (dev->accel.xx_count >= 3) { + if ((dev->accel.cmd & 4) && dev->accel.sy) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } + } + } else { + if (dev->accel.xx_count == 1) { + if (!count) { + if ((dev->accel.cmd & 4) && dev->accel.sy) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } + } + } else if (dev->accel.xx_count >= 2) { + if ((dev->accel.cmd & 4) && dev->accel.sy) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } + } + } + } else { + if (ibm8514_cpu_src(dev) || !cpu_input) { + if ((dev->accel.cmd & 4) && dev->accel.sy) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } } } } @@ -1576,15 +1677,14 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.sy = dev->accel.multifunc[0] & 0x7ff; dev->accel.cx = dev->accel.cur_x & 0x3ff; - dev->accel.cy = dev->accel.cur_y & 0x3ff; - if (dev->accel.cur_x & 0x400) dev->accel.cx |= ~0x3ff; + dev->accel.cy = dev->accel.cur_y & 0x3ff; if (dev->accel.cur_y & 0x400) dev->accel.cy |= ~0x3ff; - dev->accel.fill_state = 0; dev->accel.dest = dev->accel.cy * dev->h_disp; + dev->accel.fill_state = 0; if (cmd == 4) dev->accel.cmd |= 2; @@ -1644,6 +1744,13 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.input = 1; dev->accel.newdest_in = (dev->accel.cy + 1) * dev->h_disp; } + } else if (dev->accel.cmd & 2) { + if (dev->accel.cmd & 8) { + dev->accel.sx += and3; + dev->accel.nibbleset = (uint8_t *)calloc(1, (dev->accel.sx >> 3) + 1); + dev->accel.writemono = (uint8_t *)calloc(1, (dev->accel.sx >> 3) + 1); + dev->accel.sys_cnt = (dev->accel.sx >> 3) + 1; + } } dev->data_available = 1; dev->data_available2 = 1; @@ -1654,25 +1761,12 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (dev->accel.cmd & 2) { if (cpu_input) { rect_fill_pix: - if (dev->accel.cmd & 8) { + if ((dev->accel.cmd & 8) && ibm8514_cpu_src(dev)) { dev->accel.xx_count++; while (count-- && (dev->accel.sy >= 0)) { if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { - if (ibm8514_cpu_dest(dev) && (pixcntl == 0)) { - mix_dat = mix_mask; /* Mix data = forced to foreground register. */ - } else if (ibm8514_cpu_dest(dev) && (pixcntl == 3)) { - /* Mix data = current video memory value. */ - READ(dev->accel.dest + dev->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? mix_mask : 0; - } - - if (ibm8514_cpu_dest(dev)) { - READ(dev->accel.dest + dev->accel.cx, src_dat); - if (pixcntl == 3) - src_dat = ((src_dat & rd_mask) == rd_mask); - } else switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: src_dat = bkgd_color; break; case 1: src_dat = frgd_color; break; case 2: src_dat = cpu_dat & 0xff; break; @@ -2322,7 +2416,7 @@ rect_fill: } } } else { - if (dev->accel.multifunc[0x0a] & 4) { + if (dev->accel.multifunc[0x0a] & 6) { while (count-- && dev->accel.sy >= 0) { if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { @@ -2340,8 +2434,9 @@ rect_fill: poly_src = ((poly_src & rd_mask_polygon) == rd_mask_polygon); } - if (poly_src) + if (poly_src) { dev->accel.fill_state = !dev->accel.fill_state; + } if (dev->accel.fill_state) { READ(dev->accel.dest + dev->accel.cx, dest_dat); @@ -2364,20 +2459,22 @@ rect_fill: mix_dat <<= 1; mix_dat |= 1; - if (dev->accel.cmd & 0x20) + if (dev->accel.cmd & 0x20) { dev->accel.cx++; - else + } else { dev->accel.cx--; + } dev->accel.sx--; if (dev->accel.sx < 0) { - dev->accel.fill_state = 0; dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + dev->accel.fill_state = 0; if (dev->accel.cmd & 0x20) { dev->accel.cx -= (dev->accel.sx) + 1; - } else + } else { dev->accel.cx += (dev->accel.sx) + 1; + } if (dev->accel.cmd & 0x80) dev->accel.cy++; @@ -2464,22 +2561,18 @@ rect_fill: dev->accel.cx = dev->accel.cur_x; dev->accel.cy = dev->accel.cur_y; - if (dev->accel.cur_x & 0x400) { - if (dev->accel.cx >= 1024) { - dev->accel.cx = 0; - } else - dev->accel.cx |= ~0x3ff; - } - - if (dev->accel.cur_y & 0x400) { - if (dev->accel.cy >= 1024) - dev->accel.cy = 1; - else - dev->accel.cy |= ~0x3ff; - } - dev->accel.sy = dev->accel.maj_axis_pcnt; + if (dev->accel.cx < dev->accel.clip_left) + dev->accel.cx = dev->accel.clip_left; + else if (dev->accel.cx > clip_r) + dev->accel.cx = dev->accel.clip_left; + + dev->accel.sx = dev->accel.sy; + dev->accel.dx = dev->accel.destx_distp; + dev->accel.dy = dev->accel.desty_axstp; + dev->accel.err = dev->accel.err_term; + if (ibm8514_cpu_src(dev)) { dev->data_available = 0; dev->data_available2 = 0; @@ -2527,7 +2620,6 @@ rect_fill: old_dest_dat = dest_dat; MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if ((dev->accel.cmd & 4) && dev->accel.sy) { WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); } else if (!(dev->accel.cmd & 4)) { @@ -2556,8 +2648,6 @@ rect_fill: dev->accel.sy--; } - dev->accel.cur_x = dev->accel.cx; - dev->accel.cur_y = dev->accel.cy; } else { /*Bresenham*/ if (pixcntl == 1) { dev->accel.temp_cnt = 8; @@ -2636,15 +2726,13 @@ rect_fill: } } else { while (count-- && (dev->accel.sy >= 0)) { - if (dev->accel.cur_x >= 1024) { - dev->accel.cx = 0; - } - if (dev->accel.cur_y >= 1024) { - dev->accel.cy = 1; - } + if (dev->accel.cx < dev->accel.clip_left) + dev->accel.cx = dev->accel.clip_left; + else if (dev->accel.cx > clip_r) + dev->accel.cx = dev->accel.clip_left; - if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && - dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { + if (((dev->accel.cx) >= dev->accel.clip_left && (dev->accel.cx) <= clip_r && + (dev->accel.cy) >= dev->accel.clip_top && (dev->accel.cy) <= clip_b)) { if (ibm8514_cpu_dest(dev) && (pixcntl == 0)) { mix_dat = mix_mask; /* Mix data = forced to foreground register. */ } else if (ibm8514_cpu_dest(dev) && (pixcntl == 3)) { @@ -2684,6 +2772,7 @@ rect_fill: } } } + mix_dat <<= 1; mix_dat |= 1; cpu_dat >>= 8; @@ -2692,8 +2781,8 @@ rect_fill: break; } - if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) { - dev->accel.err_term += dev->accel.destx_distp; + if (dev->accel.err >= dev->accel.sx) { + dev->accel.err += dev->accel.dx; /*Step minor axis*/ switch (dev->accel.cmd & 0xe0) { case 0x00: dev->accel.cy--; break; @@ -2706,7 +2795,7 @@ rect_fill: case 0xe0: dev->accel.cx++; break; } } else - dev->accel.err_term += dev->accel.desty_axstp; + dev->accel.err += dev->accel.dy; /*Step major axis*/ switch (dev->accel.cmd & 0xe0) { @@ -2723,9 +2812,9 @@ rect_fill: dev->accel.sy--; } } - dev->accel.cur_x = dev->accel.cx; - dev->accel.cur_y = dev->accel.cy; } + dev->accel.cur_x = dev->accel.cx; + dev->accel.cur_y = dev->accel.cy; break; case 6: /*BitBlt*/ From 061c756a18872d6c3dc8b510326c6ceefaf447e5 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 26 Jun 2022 23:22:32 +0200 Subject: [PATCH 05/31] Remove excess log. --- src/video/vid_8514a.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 566cd3739..85607f004 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -1245,11 +1245,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat /*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled. When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on the NOP command)*/ - if (dev->accel.cmd == 0x41f0) { - pclog("CMD = %d, full = %04x, pixcntl = %d, curx = %d, cury = %d, cl = %d, cr = %d, ct = %d, cb = %d, len = %d, sx = %d, sy = %d, BX = %04X, CX = %02X\n", cmd, dev->accel.cmd, pixcntl, dev->accel.cur_x, dev->accel.cur_y, dev->accel.multifunc[2], dev->accel.multifunc[4], dev->accel.multifunc[1], dev->accel.multifunc[3], dev->accel.maj_axis_pcnt, dev->accel.sx, dev->accel.sy, BX, CH); - pclog("\n"); - } - switch (cmd) { case 0: /*NOP (Short Stroke Vectors)*/ if (dev->accel.ssv_state == 0) From 10f867dce1d4f0e1cc0fbe56af15479cfe159976 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 27 Jun 2022 00:08:10 +0200 Subject: [PATCH 06/31] Fix compile. --- src/include/86box/vid_8514a.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/include/86box/vid_8514a.h b/src/include/86box/vid_8514a.h index af46b166d..0bb1e85cd 100644 --- a/src/include/86box/vid_8514a.h +++ b/src/include/86box/vid_8514a.h @@ -63,8 +63,9 @@ typedef struct ibm8514_t int sys_cnt, sys_cnt2; int temp_cnt; int16_t cx, cy; - int sx, sy; - int dx, dy; + int16_t sx, sy; + int16_t dx, dy; + int16_t err; uint32_t src, dest; uint32_t newsrc_blt, newdest_blt; uint32_t newdest_in, newdest_out; From 0898913d05e4b2110a57f35d665782d1ddb24fc0 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 27 Jun 2022 15:35:55 +0200 Subject: [PATCH 07/31] Fixed the Rancho RT1000A/B aspi manager loading (rtaspi10.sys). --- src/scsi/scsi_ncr5380.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index 1b05b1a88..f69f34276 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -749,6 +749,8 @@ ncr_read(uint16_t port, void *priv) break; case 2: /* Mode register */ + if (((ncr->mode & 0x30) == 0x30) && (ncr_dev->type <= 1)) + ncr->mode = 0; ncr_log("Read: Mode register\n"); ret = ncr->mode; break; @@ -764,6 +766,10 @@ ncr_read(uint16_t port, void *priv) ncr_bus_read(ncr_dev); ncr_log("NCR cur bus stat=%02x\n", ncr->cur_bus & 0xff); ret |= (ncr->cur_bus & 0xff); + if ((ncr->icr & ICR_SEL) && (ncr_dev->type != 3)) + ret |= 0x02; + if ((ncr->icr & ICR_BSY) && (ncr_dev->type != 3)) + ret |= 0x40; break; case 5: /* Bus and Status register */ @@ -782,9 +788,9 @@ ncr_read(uint16_t port, void *priv) ncr_bus_read(ncr_dev); bus = ncr->cur_bus; - if (bus & BUS_ACK) + if ((bus & BUS_ACK) || ((ncr->icr & ICR_ACK) && (ncr_dev->type != 3))) ret |= STATUS_ACK; - if (bus & BUS_ATN) + if ((bus & BUS_ATN) || ((ncr->icr & ICR_ATN) && (ncr_dev->type != 3))) ret |= 0x02; if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA)) { @@ -920,8 +926,6 @@ memio_write(uint32_t addr, uint8_t val, void *priv) addr &= 0x3fff; - ncr_log("memio_write(%08x,%02x) %i %02x\n", addr, val, ncr_dev->buffer_host_pos, ncr_dev->status_ctrl); - if (addr >= 0x3a00) ncr_dev->ext_ram[addr - 0x3a00] = val; else switch (addr & 0x3f80) { From 63b4209414d53d9ed831e88229ccb074a1ea5528 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 27 Jun 2022 17:01:02 +0200 Subject: [PATCH 08/31] And finally, more fixes to the XGA implementation including: Cursor and mapping on Windows 2.x' 286/808x XGA driver. Pattern and DMA bus master fixes to OS/2 2.x/Warp's XGA driver. Software reset no longer causes glitches to the screen using XGA (x86.c) --- src/cpu/x86.c | 2 +- src/include/86box/vid_xga.h | 5 +- src/video/vid_xga.c | 547 ++++++++---------------------------- 3 files changed, 122 insertions(+), 432 deletions(-) diff --git a/src/cpu/x86.c b/src/cpu/x86.c index 77dd3b139..e8370a5b5 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -343,7 +343,7 @@ softresetx86(void) if (soft_reset_mask) return; - if (ibm8514_enabled) + if (ibm8514_enabled || xga_enabled) vga_on = 1; reset_common(0); diff --git a/src/include/86box/vid_xga.h b/src/include/86box/vid_xga.h index f3bdd0a1c..aef837fba 100644 --- a/src/include/86box/vid_xga.h +++ b/src/include/86box/vid_xga.h @@ -63,6 +63,7 @@ typedef struct xga_t uint8_t pal_g, pal_g_prefetch; uint8_t pal_b, pal_b_prefetch; uint8_t sprite_data[1024]; + uint8_t scrollcache; uint8_t *vram, *changedvram; int16_t hwc_pos_x; @@ -88,11 +89,9 @@ typedef struct xga_t char_width, hwcursor_on; int pal_pos, pal_pos_prefetch; int on; - int op_mode_reset; + int op_mode_reset, linear_endian_reverse; int sprite_pos, sprite_pos_prefetch, cursor_data_on; int pal_test; - int dma_channel; - int from_to_vram; uint32_t linear_base, linear_size, banked_mask; uint32_t base_addr_1mb; diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 1560debfd..ff0cd081f 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -44,15 +44,15 @@ xga_updatemapping(svga_t *svga) { xga_t *xga = &svga->xga; - //pclog("OpMode = %x, linear base = %08x, aperture cntl = %d\n", xga->op_mode, xga->linear_base, xga->aperture_cntl); - if ((xga->op_mode & 7) == 4) { + //pclog("OpMode = %x, linear base = %08x, aperture cntl = %d, opmodereset1 = %d, access mode = %x\n", xga->op_mode, xga->linear_base, xga->aperture_cntl, xga->op_mode_reset, xga->access_mode); + if ((xga->op_mode & 7) >= 4) { if (xga->aperture_cntl == 1) { - xga->op_mode_reset = 0; mem_mapping_disable(&svga->mapping); mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000); mem_mapping_enable(&xga->video_mapping); xga->banked_mask = 0xffff; - mem_mapping_disable(&xga->linear_mapping); + if (!xga->linear_endian_reverse) + mem_mapping_disable(&xga->linear_mapping); } else if (xga->aperture_cntl == 0) { linear: mem_mapping_disable(&svga->mapping); @@ -72,7 +72,6 @@ linear: xga->on = 0; vga_on = 1; } else { - xga->op_mode_reset = 0; mem_mapping_disable(&svga->mapping); mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000); mem_mapping_enable(&xga->video_mapping); @@ -81,10 +80,8 @@ linear: } } else { if (!(xga->op_mode & 7)) { - xga->op_mode_reset = 1; goto linear; } - xga->op_mode_reset = 0; if (xga->aperture_cntl == 2) { mem_mapping_disable(&svga->mapping); mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000); @@ -309,8 +306,14 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) case 0x61: xga->sprite_pal_addr_idx = (xga->sprite_pal_addr_idx & 0xff) | ((val & 0x3f) << 8); xga->sprite_pos = xga->sprite_pal_addr_idx & 0x1ff; - if ((xga->sprite_pos >= 1) && (xga->sprite_pos <= 16)) - xga->cursor_data_on = 1; + if ((xga->sprite_pos >= 0) && (xga->sprite_pos <= 16)) { + if ((xga->op_mode & 7) >= 5) + xga->cursor_data_on = 1; + else if (xga->sprite_pos >= 1) + xga->cursor_data_on = 1; + else if (xga->aperture_cntl == 0) + xga->cursor_data_on = 0; + } if ((xga->sprite_pos > 16) && (xga->sprite_pos <= 0x1ff)) xga->cursor_data_on = 0; break; @@ -394,6 +397,9 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *p) xga->aperture_cntl = val; xga_updatemapping(svga); break; + case 4: + xga->access_mode &= ~8; + break; case 6: vga_on = 0; xga->on = 1; @@ -401,13 +407,11 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *p) case 8: xga->ap_idx = val; //pclog("Aperture CNTL = %d, val = %02x, up to bit6 = %02x\n", xga->aperture_cntl, val, val & 0x3f); - if (xga->aperture_cntl == 1) { - if ((xga->op_mode & 7) < 4) { - xga->write_bank = xga->read_bank = 0; - } else { - xga->write_bank = (xga->ap_idx & 0x3f) << 16; - xga->read_bank = xga->write_bank; - } + if ((xga->op_mode & 7) < 4) { + xga->write_bank = xga->read_bank = 0; + } else { + xga->write_bank = (xga->ap_idx & 0x3f) << 16; + xga->read_bank = xga->write_bank; } break; case 9: @@ -722,15 +726,10 @@ xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t b int skip = 0; if (xga->base_addr_1mb) { - if (!xga->linear_base) { - if (addr < xga->linear_base) - skip = 1; - } else { - if (addr < xga->base_addr_1mb) - skip = 1; - } + if (addr < xga->base_addr_1mb || (addr > (xga->base_addr_1mb + 0xfffff))) + skip = 1; } else { - if (addr < xga->linear_base) + if (addr < xga->linear_base || (addr > (xga->linear_base + 0xfffff))) skip = 1; } @@ -742,17 +741,14 @@ xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t b byte = mem_readb_phys(addr); } byte2 = byte; - if ((xga->aperture_cntl == 1) || !xga->op_mode_reset) - byte = mem_readb_phys(addr); - else if (xga->op_mode_reset) { - byte2 = mem_readb_phys(addr); - } else { - byte = mem_readb_phys(addr); - } - if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8) && !xga->op_mode_reset) - bits = (x & 7); - else + if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) + if (xga->linear_endian_reverse) + bits = 7 - (x & 7); + else + bits = (x & 7); + else { bits = 7 - (x & 7); + } px = (byte2 >> bits) & 1; return px; } @@ -769,15 +765,10 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int int skip = 0; if (xga->base_addr_1mb) { - if (!xga->linear_base) { - if (addr < xga->linear_base) - skip = 1; - } else { - if (addr < xga->base_addr_1mb) - skip = 1; - } + if (addr < xga->base_addr_1mb || (addr > (xga->base_addr_1mb + 0xfffff))) + skip = 1; } else { - if (addr < xga->linear_base) + if (addr < xga->linear_base || (addr > (xga->linear_base + 0xfffff))) skip = 1; } @@ -791,38 +782,16 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int byte = mem_readb_phys(addr); } byte2 = byte; - if ((xga->aperture_cntl == 1) || !xga->op_mode_reset) - byte = mem_readb_phys(addr); - else if (xga->op_mode_reset) { - byte2 = mem_readb_phys(addr); - } else { - byte = mem_readb_phys(addr); - } - if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8) && !xga->op_mode_reset) - bits = (x & 7); - else + if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) + if (xga->linear_endian_reverse) + bits = 7 - (x & 7); + else + bits = (x & 7); + else { bits = 7 - (x & 7); + } px = (byte2 >> bits) & 1; return px; - case 1: /*2-bit*/ - addr += (y * (width) >> 2); - addr += (x >> 2); - READ(addr, byte); - byte2 = byte; - if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) - bits = (x & 3); - else - bits = 3 - (x & 3); - return (byte2 >> (bits << 1)) & 3; - case 2: /*4-bit*/ - addr += (y * (width) >> 1); - addr += (x >> 1); - READ(addr, byte); - if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) - bits = (x & 1); - else - bits = 1 - (x & 1); - return (byte >> (bits << 2)) & 0x0f; case 3: /*8-bit*/ addr += (y * width); addr += x; @@ -832,18 +801,16 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int byte = mem_readb_phys(addr); } byte2 = byte; - if ((xga->aperture_cntl == 1) || !xga->op_mode_reset) { - byte = mem_readb_phys(addr); - } else if (xga->op_mode_reset) { - byte2 = mem_readb_phys(addr); - } else { - byte = mem_readb_phys(addr); - } return byte2; case 4: /*16-bit*/ + width >>= 1; addr += (y * (width) << 1); addr += (x << 1); - READW(addr, byte); + if (!skip) { + READW(addr, byte); + } else { + byte = mem_readw_phys(addr); + } return byte; } @@ -860,15 +827,10 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui int skip = 0; if (xga->base_addr_1mb) { - if (!xga->linear_base) { - if (addr < xga->linear_base) - skip = 1; - } else { - if (addr < xga->base_addr_1mb) - skip = 1; - } + if (addr < xga->base_addr_1mb || (addr > (xga->base_addr_1mb + 0xfffff))) + skip = 1; } else { - if (addr < xga->linear_base) + if (addr < xga->linear_base || (addr > (xga->linear_base + 0xfffff))) skip = 1; } @@ -882,45 +844,20 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui byte = mem_readb_phys(addr); } byte2 = byte; - if ((xga->aperture_cntl == 1) || !xga->op_mode_reset) { - byte = mem_readb_phys(addr); - } else if (xga->op_mode_reset) { - byte2 = mem_readb_phys(addr); + if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) { + if (xga->linear_endian_reverse) + mask = 1 << (7 - (x & 7)); + else + mask = 1 << (x & 7); } else { - byte = mem_readb_phys(addr); - } - if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8) && !xga->op_mode_reset) - mask = 1 << (x & 7); - else mask = 1 << (7 - (x & 7)); + } byte2 = (byte2 & ~mask) | ((pixel ? 0xff : 0) & mask); if (!skip) { WRITE(addr, byte2); } mem_writeb_phys(addr, byte2); break; - case 1: /*2-bit*/ - addr += (y * (width) >> 2); - addr += (x >> 2); - READ(addr, byte); - if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) - mask = 3 << ((x & 3) << 1); - else - mask = 3 << ((3 - (x & 3)) << 1); - byte = (byte & ~mask) | ((pixel ? 0xff : 0) & mask); - WRITE(addr, byte); - break; - case 2: /*4-bit*/ - addr += (y * (width) >> 1); - addr += (x >> 1); - READ(addr, byte); - if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) - mask = 0x0f << ((x & 1) << 2); - else - mask = 0x0f << ((1 - (x & 1)) << 2); - byte = (byte & ~mask) | ((pixel ? 0xff : 0) & mask); - WRITE(addr, byte); - break; case 3: /*8-bit*/ addr += (y * width); addr += x; @@ -930,9 +867,13 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui mem_writeb_phys(addr, pixel & 0xff); break; case 4: /*16-bit*/ + width >>= 1; addr += (y * (width) << 1); addr += (x << 1); - WRITEW(addr, pixel); + if (!skip) { + WRITEW(addr, pixel); + } + mem_writew_phys(addr, pixel); break; } } @@ -1241,176 +1182,6 @@ xga_line_draw_write(svga_t *svga) } } -#if 0 -static void -xga_line_draw_read(xga_t *xga) -{ - uint32_t src_dat = 0, dest_dat, old_dest_dat; - uint32_t out = 0; - int clip_t = xga->accel.mask_map_origin_y_off & 0xfff; - int clip_l = xga->accel.mask_map_origin_x_off & 0xfff; - int clip_b = xga->accel.px_map[0].height & 0xfff; - int clip_r = xga->accel.px_map[0].width & 0xfff; - int pixcnt = xga->accel.blt_width; - int count = -1; - int16_t dminor, dmajor, destxtmp, tmpswap; - int16_t cx, cy, dx, dy, err; - int16_t sx, sy, px, py; - int xdir = (xga->accel.octant & 0x04) ? -1 : 1; - int ydir = (xga->accel.octant & 0x02) ? -1 : 1; - int steep = 1; - int mix = 0; - uint8_t color_cmp = xga->accel.color_cmp & 0xff; - - - - dminor = xga->accel.bres_k1; - if (xga->accel.bres_k1 & 0x1000) - dminor |= ~0xfff; - dminor >>= 1; - - destxtmp = xga->accel.bres_k2; - if (xga->accel.bres_k2 & 0x1000) - destxtmp |= ~0xfff; - - dmajor = -(destxtmp - (dminor << 1)) >> 1; - - cx = dmajor; - cy = dminor; - - sx = xga->accel.dst_map_x & 0xfff; - sy = xga->accel.dst_map_y & 0xfff; - - dx = xga->accel.src_map_x & 0xfff; - dy = xga->accel.src_map_y & 0xfff; - - px = xga->accel.pat_map_x & 0xfff; - py = xga->accel.pat_map_y & 0xfff; - - err = xga->accel.bres_err_term; - if (xga->accel.bres_err_term & 0x1000) - err |= ~0xfff; - - if (xga->accel.octant & 0x01) { - steep = 0; - SWAP(sx, sy); - SWAP(dx, dy); - SWAP(px, py); - SWAP(xdir, ydir); - } - - xga->force_busy = 1; - - while (count--) { - if (steep) { - if (((dx >= clip_l) && (dx <= clip_r) && - (dy >= clip_t) && (dy <= clip_b)) || (xga->accel.mask_mode == 0)){ - if (xga->accel.pat_src == 8) - mix = xga_accel_read_map_pixel(xga, sx, sy, xga->accel.src_map + 1) & 0xff; - else if (xga->accel.pat_src == 7) { - mix = 1; - } else if (xga->accel.pat_src <= 2) { - mix = xga_accel_read_map_pixel(xga, px, py, xga->accel.pat_src + 1) & 0xff; - } - - if (mix) { - if (xga->accel.fore_src) - src_dat = xga_accel_read_map_pixel(xga, sx, sy, xga->accel.src_map + 1) & 0xff; - else - src_dat = xga->accel.frgd_color & 0xff; - } else { - if (xga->accel.bkgd_src) - src_dat = xga_accel_read_map_pixel(xga, sx, sy, xga->accel.src_map + 1) & 0xff; - else - src_dat = xga->accel.bkgd_color & 0xff; - } - - dest_dat = xga_accel_read_map_pixel(xga, dx, dy, xga->accel.dst_map + 1) & 0xff; - - 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; - MIX(mix, dest_dat, src_dat); - if (xga->accel.mask_mode) - dest_dat = (dest_dat & xga->accel.plane_mask) | (old_dest_dat & ~xga->accel.plane_mask); - if ((xga->accel.draw_mode == 0x20) && (pixcnt < xga->accel.blt_width)) - xga_accel_write_map_pixel(xga, dx, dy, xga->accel.dst_map + 1, dest_dat); - else if ((xga->accel.draw_mode == 0x10) && (pixcnt > 0)) - xga_accel_write_map_pixel(xga, dx, dy, xga->accel.dst_map + 1, dest_dat); - else - xga_accel_write_map_pixel(xga, dx, dy, xga->accel.dst_map + 1, dest_dat); - } - } - } else { - if (((dy >= clip_l) && (dy <= clip_r) && - (dx >= clip_t) && (dx <= clip_b)) || (xga->accel.mask_mode == 0)) { - if (xga->accel.pat_src == 8) - mix = xga_accel_read_map_pixel(xga, sy, sx, xga->accel.src_map + 1) & 0xff; - else if (xga->accel.pat_src == 7) { - mix = 1; - } else if (xga->accel.pat_src <= 2) { - mix = xga_accel_read_map_pixel(xga, py, px, xga->accel.pat_src + 1) & 0xff; - } - - if (mix) { - if (xga->accel.fore_src) - src_dat = xga_accel_read_map_pixel(xga, sy, sx, xga->accel.src_map + 1) & 0xff; - else - src_dat = xga->accel.frgd_color & 0xff; - } else { - if (xga->accel.bkgd_src) - src_dat = xga_accel_read_map_pixel(xga, sy, sx, xga->accel.src_map + 1) & 0xff; - else - src_dat = xga->accel.bkgd_color & 0xff; - } - - dest_dat = xga_accel_read_map_pixel(xga, dy, dx, xga->accel.dst_map + 1) & 0xff; - - 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; - MIX(mix, dest_dat, src_dat); - if (xga->accel.mask_mode) - dest_dat = (dest_dat & xga->accel.plane_mask) | (old_dest_dat & ~xga->accel.plane_mask); - if ((xga->accel.draw_mode == 0x20) && (pixcnt < xga->accel.blt_width)) - xga_accel_write_map_pixel(xga, dy, dx, xga->accel.dst_map + 1, dest_dat); - else if ((xga->accel.draw_mode == 0x10) && (pixcnt > 0)) - xga_accel_write_map_pixel(xga, dy, dx, xga->accel.dst_map + 1, dest_dat); - else - xga_accel_write_map_pixel(xga, dy, dx, xga->accel.dst_map + 1, dest_dat); - } - } - } - - if (pixcnt == xga->accel.blt_width) { - break; - } - - while (err > 0) { - sy += ydir; - dy += ydir; - py += ydir; - err -= (cx << 1); - } - sx += xdir; - dx += xdir; - px += xdir; - err += (cy << 1); - - pixcnt++; - } -} -#endif static int16_t xga_dst_wrap(int16_t addr) @@ -1466,11 +1237,20 @@ xga_bitblt(svga_t *svga) xga->accel.pattern = 1; else { if ((dstwidth == (xga->h_disp - 1)) && (srcwidth == 1)) { - if ((xga->accel.dst_map == 1) && (xga->accel.src_map == 2) && xga->op_mode_reset) { - if ((xga->accel.px_map_format[xga->accel.dst_map] == 0x0b) && (xga->accel.px_map_format[xga->accel.src_map] == 0x0b)) { + if ((xga->accel.dst_map == 1) && (xga->accel.src_map == 2) && xga->linear_endian_reverse) { + if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0b) && (xga->accel.px_map_format[xga->accel.src_map] >= 0x0b)) { xga->accel.pattern = 1; } } + } else if ((dstwidth == (xga->h_disp - 1)) && (srcwidth == (xga->h_disp - 1))) { + if ((xga->accel.dst_map == 1) && (xga->accel.src_map == 1) && xga->linear_endian_reverse) { + if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0b) && (xga->accel.px_map_format[xga->accel.src_map] >= 0x0b)) { + if ((xga->accel.command & 0xc0) == 0x40) + xga->accel.pattern = 0; + else + xga->accel.pattern = 1; + } + } } } @@ -1542,9 +1322,20 @@ xga_bitblt(svga_t *svga) xga->accel.pattern = 1; else { if (dstwidth == (xga->h_disp - 1)) { - if (!xga->accel.src_map && (xga->accel.dst_map == 1) && (xga->accel.pat_src == 2) && xga->op_mode_reset) { - if ((xga->accel.px_map_format[xga->accel.dst_map] == 0x0b) && (xga->accel.px <= 7) && (xga->accel.py <= 3)) { - xga->accel.pattern = 1; + if (srcwidth == (xga->h_disp - 1)) { + if ((xga->accel.src_map == 1) && (xga->accel.dst_map == 1) && (xga->accel.pat_src == 2) && xga->linear_endian_reverse) { + if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0b) && (xga->accel.px <= 7) && (xga->accel.py <= 3)) { + xga->accel.pattern = 1; + } + } + } else { + if (!xga->accel.src_map && (xga->accel.dst_map == 1) && (xga->accel.pat_src == 2) && xga->linear_endian_reverse) { + if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0b) && (xga->accel.px <= 7) && (xga->accel.py <= 3)) { + if ((patwidth >= 7) && ((xga->accel.command & 0xc0) == 0x40)) + xga->accel.pattern = 0; + else + xga->accel.pattern = 1; + } } } } @@ -1629,101 +1420,6 @@ xga_bitblt(svga_t *svga) } } -#if 0 -static void -xga_inverting_bitblt(xga_t *xga) -{ - uint32_t src_dat = 0, dest_dat, old_dest_dat; - uint32_t out = 0; - int clip_t = xga->accel.mask_map_origin_y_off & 0xfff; - int clip_l = xga->accel.mask_map_origin_x_off & 0xfff; - int clip_b = xga->accel.px_map[0].height & 0xfff; - int clip_r = xga->accel.px_map[0].width & 0xfff; - int count = -1; - int xdir = (xga->accel.octant & 0x04) ? 1 : -1; - int ydir = (xga->accel.octant & 0x02) ? 1 : -1; - int mix = 0; - int x = 0, y = 0; - int sx, sy, dx, dy, px, py; - uint8_t color_cmp = xga->accel.color_cmp & 0xff; - - sx = xga->accel.src_map_x & 0xfff; - sy = xga->accel.src_map_y & 0xfff; - - dx = xga->accel.dst_map_x & 0xfff; - dy = xga->accel.dst_map_y & 0xfff; - - px = xga->accel.pat_map_x & 0xfff; - py = xga->accel.pat_map_y & 0xfff; - - xga->force_busy = 1; - - while (count--) { - if (((dx <= clip_l) && (dx >= clip_r) && - (dy <= clip_t) && (dy >= clip_b)) || (xga->accel.mask_mode == 0)) { - if (xga->accel.pat_src == 8) - mix = xga_accel_read_map_pixel(xga, sx, sy, xga->accel.src_map + 1) & 0xff; - else if (xga->accel.pat_src == 7) { - mix = 1; - } else if (xga->accel.pat_src <= 2) { - mix = xga_accel_read_map_pixel(xga, px, py, xga->accel.pat_src + 1) & 0xff; - } - - if (mix) { - if (xga->accel.fore_src) - src_dat = xga_accel_read_map_pixel(xga, sx, sy, xga->accel.src_map + 1) & 0xff; - else - src_dat = xga->accel.frgd_color & 0xff; - } else { - if (xga->accel.bkgd_src) - src_dat = xga_accel_read_map_pixel(xga, sx, sy, xga->accel.src_map + 1) & 0xff; - else - src_dat = xga->accel.bkgd_color & 0xff; - } - - dest_dat = xga_accel_read_map_pixel(xga, dx, dy, xga->accel.dst_map + 1) & 0xff; - - 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; - MIX(mix, dest_dat, src_dat); - if (xga->accel.mask_mode) - dest_dat = (dest_dat & xga->accel.plane_mask) | (old_dest_dat & ~xga->accel.plane_mask); - xga_accel_write_map_pixel(xga, dx, dy, xga->accel.dst_map + 1, dest_dat); - } - } - - sx += xdir; - dx = xga_dstwrap(xga, dx + xdir); - px += xdir; - x++; - - if (x > xga->accel.blt_width) { - x = 0; - - px = xga->accel.pat_map_x & 0xfff; - py += ydir; - - dx = xga->accel.dst_map_x & 0xfff; - dy = xga_dstwrap(xga, dy + ydir); - - sx = xga->accel.src_map_x & 0xfff; - sy += ydir; - - y++; - - if (y > xga->accel.blt_height) - return; - } - } -} -#endif - static void xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) { @@ -1761,27 +1457,27 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) case 0x18: if (len == 4) { - xga->accel.px_map_width[xga->accel.px_map_idx] = val & 0xfff; - xga->accel.px_map_height[xga->accel.px_map_idx] = (val >> 16) & 0xfff; + xga->accel.px_map_width[xga->accel.px_map_idx] = val & 0xffff; + xga->accel.px_map_height[xga->accel.px_map_idx] = (val >> 16) & 0xffff; } else if (len == 2) { - xga->accel.px_map_width[xga->accel.px_map_idx] = val & 0xfff; + xga->accel.px_map_width[xga->accel.px_map_idx] = val & 0xffff; } else - xga->accel.px_map_width[xga->accel.px_map_idx] = (xga->accel.px_map_width[xga->accel.px_map_idx] & 0xf00) | val; + xga->accel.px_map_width[xga->accel.px_map_idx] = (xga->accel.px_map_width[xga->accel.px_map_idx] & 0xff00) | val; break; case 0x19: if (len == 1) - xga->accel.px_map_width[xga->accel.px_map_idx] = (xga->accel.px_map_width[xga->accel.px_map_idx] & 0xff) | ((val & 0x0f) << 8); + xga->accel.px_map_width[xga->accel.px_map_idx] = (xga->accel.px_map_width[xga->accel.px_map_idx] & 0xff) | (val << 8); break; case 0x1a: if (len == 2) - xga->accel.px_map_height[xga->accel.px_map_idx] = val & 0xfff; + xga->accel.px_map_height[xga->accel.px_map_idx] = val & 0xffff; else - xga->accel.px_map_height[xga->accel.px_map_idx] = (xga->accel.px_map_height[xga->accel.px_map_idx] & 0xf00) | val; + xga->accel.px_map_height[xga->accel.px_map_idx] = (xga->accel.px_map_height[xga->accel.px_map_idx] & 0xff00) | val; break; case 0x1b: if (len == 1) - xga->accel.px_map_height[xga->accel.px_map_idx] = (xga->accel.px_map_height[xga->accel.px_map_idx] & 0xff) | ((val & 0x0f) << 8); + xga->accel.px_map_height[xga->accel.px_map_idx] = (xga->accel.px_map_height[xga->accel.px_map_idx] & 0xff) | (val << 8); break; case 0x1c: @@ -2116,31 +1812,22 @@ exec_command: xga->accel.dst_map = ((xga->accel.command >> 16) & 0x0f); xga->accel.src_map = ((xga->accel.command >> 20) & 0x0f); - xga->accel.dir_cmd = xga->accel.command & 0x30000; - xga->from_to_vram = 0; - - if (xga->accel.dir_cmd == 0x20000) { - xga->from_to_vram = 2; - } else if (xga->accel.dir_cmd == 0x10000) { - xga->from_to_vram = 1; - } - - //if (xga->accel.pat_src || ((xga->accel.pat_src == 8) && (((xga->accel.command >> 28) & 3) == 2) && (((xga->accel.command >> 30) & 3) == 2))) { - //pclog("[%04X:%08X]: Accel Command = %02x, full = %08x, patwidth = %d, dstwidth = %d, srcwidth = %d, patheight = %d, dstheight = %d, srcheight = %d, px = %d, py = %d, dx = %d, dy = %d, sx = %d, sy = %d, patsrc = %d, dstmap = %d, srcmap = %d, dstbase = %08x, srcbase = %08x, patbase = %08x, dstformat = %x, srcformat = %x\n", - // CS, cpu_state.pc, ((xga->accel.command >> 24) & 0x0f), xga->accel.command, xga->accel.px_map_width[xga->accel.pat_src], - // xga->accel.px_map_width[xga->accel.dst_map], xga->accel.px_map_width[xga->accel.src_map], - // xga->accel.px_map_height[xga->accel.pat_src], xga->accel.px_map_height[xga->accel.dst_map], - // xga->accel.px_map_height[xga->accel.src_map], - // xga->accel.pat_map_x, xga->accel.pat_map_y, - // xga->accel.dst_map_x, xga->accel.dst_map_y, - // xga->accel.src_map_x, xga->accel.src_map_y, - // xga->accel.pat_src, xga->accel.dst_map, xga->accel.src_map, - // xga->accel.px_map_base[xga->accel.dst_map], xga->accel.px_map_base[xga->accel.src_map], xga->accel.px_map_base[xga->accel.pat_src], - // xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, xga->accel.px_map_format[xga->accel.src_map] & 0x0f); + //if (xga->accel.pat_src) { + // pclog("[%04X:%08X]: Accel Command = %02x, full = %08x, patwidth = %d, dstwidth = %d, srcwidth = %d, patheight = %d, dstheight = %d, srcheight = %d, px = %d, py = %d, dx = %d, dy = %d, sx = %d, sy = %d, patsrc = %d, dstmap = %d, srcmap = %d, dstbase = %08x, srcbase = %08x, patbase = %08x, dstformat = %x, srcformat = %x\n", + // CS, cpu_state.pc, ((xga->accel.command >> 24) & 0x0f), xga->accel.command, xga->accel.px_map_width[xga->accel.pat_src], + // xga->accel.px_map_width[xga->accel.dst_map], xga->accel.px_map_width[xga->accel.src_map], + // xga->accel.px_map_height[xga->accel.pat_src], xga->accel.px_map_height[xga->accel.dst_map], + // xga->accel.px_map_height[xga->accel.src_map], + // xga->accel.pat_map_x, xga->accel.pat_map_y, + // xga->accel.dst_map_x, xga->accel.dst_map_y, + // xga->accel.src_map_x, xga->accel.src_map_y, + // xga->accel.pat_src, xga->accel.dst_map, xga->accel.src_map, + // xga->accel.px_map_base[xga->accel.dst_map], xga->accel.px_map_base[xga->accel.src_map], xga->accel.px_map_base[xga->accel.pat_src], + // xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, xga->accel.px_map_format[xga->accel.src_map] & 0x0f); + // pclog("\n"); //} switch ((xga->accel.command >> 24) & 0x0f) { case 3: /*Bresenham Line Draw Read*/ - //xga_line_draw_read(xga); break; case 4: /*Short Stroke Vectors*/ break; @@ -2151,7 +1838,6 @@ exec_command: xga_bitblt(svga); break; case 9: /*Inverting BitBLT*/ - //xga_inverting_bitblt(xga); break; } } else if (len == 2) { @@ -2334,7 +2020,7 @@ xga_hwcursor_draw(svga_t *svga, int displine) int comb; uint32_t *p; uint8_t *cd; - int idx = ((xga->cursor_data_on && !xga->op_mode_reset) ? 32 : 0); + int idx = (xga->cursor_data_on) ? 32 : 0; if (xga->interlace && xga->hwcursor_oddeven) xga->hwcursor_latch.addr += 16; @@ -2457,7 +2143,7 @@ xga_render_16bpp(xga_t *xga, svga_t *svga) if ((xga->displine + svga->y_add) < 0) return; - if (xga->changedvram[svga->ma >> 12] || xga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + if (xga->changedvram[xga->ma >> 12] || xga->changedvram[(xga->ma >> 12) + 1] || svga->fullchange) { p = &buffer32->line[xga->displine + svga->y_add][svga->x_add]; if (xga->firstline_draw == 2000) @@ -2956,7 +2642,6 @@ xga_mca_write(int port, uint8_t val, void *priv) mem_mapping_disable(&xga->memio_mapping); xga->on = 0; vga_on = 1; - xga->op_mode_reset = 0; /* Save the MCA register value. */ xga->pos_regs[port & 7] = val; @@ -3022,19 +2707,21 @@ static void xga->on = 0; xga->hwcursor.xsize = 64; xga->hwcursor.ysize = 64; + xga->bios_rom.sz = 0x2000; f = rom_fopen(XGA_BIOS_PATH, "rb"); (void)fseek(f, 0L, SEEK_END); temp = ftell(f); (void)fseek(f, 0L, SEEK_SET); - rom = malloc(0x2000); - (void)fread(rom, 0x2000, 1, f); - temp -= 0x2000; + rom = malloc(xga->bios_rom.sz); + memset(rom, 0xff, xga->bios_rom.sz); + (void)fread(rom, xga->bios_rom.sz, 1, f); + temp -= xga->bios_rom.sz; (void)fclose(f); xga->bios_rom.rom = rom; - xga->bios_rom.mask = 0x1fff; + xga->bios_rom.mask = xga->bios_rom.sz - 1; if (f != NULL) { free(rom); } @@ -3044,7 +2731,11 @@ static void xga->linear_base = 0; xga->instance = 0; xga->rom_addr = 0; - rom_init(&xga->bios_rom, XGA_BIOS_PATH, 0xdc000, 0x2000, xga->bios_rom.mask, 0, MEM_MAPPING_EXTERNAL); + mem_mapping_add(&xga->bios_rom.mapping, + 0xdc000, xga->bios_rom.sz, + rom_read, rom_readw, rom_readl, + NULL, NULL, NULL, + xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, &xga->bios_rom); } else { xga->pos_regs[2] = 1 | 0x0c | 0xf0; xga->instance = (xga->pos_regs[2] & 0x0e) >> 1; From 28987befd739fea0b659b0d4f4464d04bb2a76e3 Mon Sep 17 00:00:00 2001 From: richardg867 Date: Mon, 27 Jun 2022 15:02:00 -0300 Subject: [PATCH 09/31] Jenkins: Update Discord Game SDK to add macOS ARM64 --- .ci/build.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.ci/build.sh b/.ci/build.sh index 73eb48fcd..ba5652d67 100644 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -511,7 +511,7 @@ then macports="/opt/local" [ -e "/opt/$arch/bin/port" ] && macports="/opt/$arch" [ "$arch" = "x86_64" -a -e "/opt/intel/bin/port" ] && macports="/opt/intel" - export PATH="$macports/bin:$macports/sbin:$macports/libexec/qt5/bin:$PATH" + export PATH="$macports/bin:$macports/sbin:$PATH" # Install dependencies. echo [-] Installing dependencies through MacPorts @@ -662,7 +662,7 @@ fi if [ ! -e "discord_game_sdk.zip" ] then echo [-] Downloading Discord Game SDK - wget -qO discord_game_sdk.zip "https://dl-game-sdk.discordapp.net/2.5.6/discord_game_sdk.zip" + wget -qO discord_game_sdk.zip "https://dl-game-sdk.discordapp.net/latest/discord_game_sdk.zip" status=$? if [ $status -ne 0 ] then @@ -673,9 +673,10 @@ fi # Determine Discord Game SDK architecture. case $arch in - 32) arch_discord="x86";; - 64) arch_discord="x86_64";; - *) arch_discord="$arch";; + 32) arch_discord="x86";; + 64) arch_discord="x86_64";; + arm64 | ARM64) arch_discord="aarch64";; + *) arch_discord="$arch";; esac # Create temporary directory for archival. From e6b84753c4e3f6e7bff337a6be69dc01da9375f8 Mon Sep 17 00:00:00 2001 From: richardg867 Date: Mon, 27 Jun 2022 15:03:30 -0300 Subject: [PATCH 10/31] Jenkins: Fix incorrectly reverted macOS PATH change --- .ci/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/build.sh b/.ci/build.sh index ba5652d67..eeb22c9c2 100644 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -511,7 +511,7 @@ then macports="/opt/local" [ -e "/opt/$arch/bin/port" ] && macports="/opt/$arch" [ "$arch" = "x86_64" -a -e "/opt/intel/bin/port" ] && macports="/opt/intel" - export PATH="$macports/bin:$macports/sbin:$PATH" + export PATH="$macports/bin:$macports/sbin:$macports/libexec/qt5/bin:$PATH" # Install dependencies. echo [-] Installing dependencies through MacPorts From 69480da5e75d553c76ae64ed869d87bd19b206a7 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 27 Jun 2022 15:51:10 -0300 Subject: [PATCH 11/31] Freeze EMU_VERSION_EX at 3.50 due to reported Windows redetections --- CMakeLists.txt | 3 +-- bumpversion.sh | 26 ++++++-------------------- src/include/86box/version.h.in | 2 +- src/include_make/86box/version.h | 2 +- 4 files changed, 9 insertions(+), 24 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index aa3ee449d..1ba5aa151 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -187,11 +187,10 @@ elseif(BUILD_TYPE_LOWER STREQUAL "alpha") add_compile_definitions(ALPHA_BUILD) endif() -# Variables introduced by richardg867 for versioning stuff +# Versioning variables if(NOT CMAKE_PROJECT_VERSION_PATCH) set(CMAKE_PROJECT_VERSION_PATCH 0) endif() -set(EMU_VERSION_EX "3.50") if(NOT EMU_BUILD_NUM) set(EMU_BUILD_NUM 0) endif() diff --git a/bumpversion.sh b/bumpversion.sh index 2efbeb952..5c960e6f7 100644 --- a/bumpversion.sh +++ b/bumpversion.sh @@ -30,31 +30,19 @@ newversion_min=$(echo $newversion | cut -d. -f2) newversion_patch=$(echo $newversion | cut -d. -f3) [ -z "$newversion_patch" ] && newversion_patch=0 -base36() { - if [ $1 -lt 10 ] - then - echo $1 - else - printf '%b' $(printf '\\%03o' $((55 + $1))) - fi -} -newversion_maj_base36=$(base36 $newversion_maj) -newversion_min_base36=$(base36 $newversion_min) -newversion_patch_base36=$(base36 $newversion_patch) - # Switch to the repository root directory. cd "$(dirname "$0")" get_latest_rom_release() { - # get the latest ROM release from GitHub api - curl --silent "https://api.github.com/repos/86Box/roms/releases/latest" | - grep '"tag_name":' | - sed -E 's/.*"([^"]+)".*/\1/' + # Get the latest ROM release from the GitHub API. + curl --silent "https://api.github.com/repos/86Box/roms/releases/latest" | + grep '"tag_name":' | + sed -E 's/.*"([^"]+)".*/\1/' } pretty_date() { - # Ensure we get the date in English - LANG=en_US.UTF-8 date '+%a %b %d %Y' + # Ensure we get the date in English. + LANG=en_US.UTF-8 date '+%a %b %d %Y' } # Patch files. @@ -71,10 +59,8 @@ patch_file() { fi } patch_file CMakeLists.txt VERSION 's/^(\s*VERSION ).+/\1'"$newversion"'/' -patch_file CMakeLists.txt EMU_VERSION_EX 's/(\s*set\(EMU_VERSION_EX\s+")[^"]+/\1'"$newversion_maj_base36.$newversion_min_base36$newversion_patch_base36"'/' patch_file vcpkg.json version-string 's/(^\s*"version-string"\s*:\s*")[^"]+/\1'"$newversion"'/' patch_file src/include_make/*/version.h EMU_VERSION 's/(#\s*define\s+EMU_VERSION\s+")[^"]+/\1'"$newversion"'/' -patch_file src/include_make/*/version.h EMU_VERSION_EX 's/(#\s*define\s+EMU_VERSION_EX\s+")[^"]+/\1'"$newversion_maj_base36.$newversion_min_base36$newversion_patch_base36"'/' patch_file src/include_make/*/version.h EMU_VERSION_MAJ 's/(#\s*define\s+EMU_VERSION_MAJ\s+)[0-9]+/\1'"$newversion_maj"'/' patch_file src/include_make/*/version.h EMU_VERSION_MIN 's/(#\s*define\s+EMU_VERSION_MIN\s+)[0-9]+/\1'"$newversion_min"'/' patch_file src/include_make/*/version.h EMU_VERSION_PATCH 's/(#\s*define\s+EMU_VERSION_PATCH\s+)[0-9]+/\1'"$newversion_patch"'/' diff --git a/src/include/86box/version.h.in b/src/include/86box/version.h.in index 0e6595536..b8cd9ed97 100644 --- a/src/include/86box/version.h.in +++ b/src/include/86box/version.h.in @@ -22,7 +22,7 @@ #define EMU_VERSION "@CMAKE_PROJECT_VERSION@" #define EMU_VERSION_W LSTR(EMU_VERSION) -#define EMU_VERSION_EX "@EMU_VERSION_EX@" +#define EMU_VERSION_EX "3.50" /* frozen due to IDE re-detection behavior on Windows */ #define EMU_VERSION_MAJ @CMAKE_PROJECT_VERSION_MAJOR@ #define EMU_VERSION_MIN @CMAKE_PROJECT_VERSION_MINOR@ #define EMU_VERSION_PATCH @CMAKE_PROJECT_VERSION_PATCH@ diff --git a/src/include_make/86box/version.h b/src/include_make/86box/version.h index 548ca28a6..fbf31b0b4 100644 --- a/src/include_make/86box/version.h +++ b/src/include_make/86box/version.h @@ -22,7 +22,7 @@ #define EMU_VERSION "3.5" #define EMU_VERSION_W LSTR(EMU_VERSION) -#define EMU_VERSION_EX "3.50" +#define EMU_VERSION_EX "3.50" /* frozen due to IDE re-detection behavior on Windows */ #define EMU_VERSION_MAJ 3 #define EMU_VERSION_MIN 5 #define EMU_VERSION_PATCH 0 From 1ea3634efc4bdaea67ffb46f264cb196defbcad4 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 27 Jun 2022 15:52:31 -0300 Subject: [PATCH 12/31] Bump version to 3.6 --- CMakeLists.txt | 2 +- src/include_make/86box/version.h | 6 +++--- src/unix/assets/86Box.spec | 6 +++--- src/unix/assets/net.86box.86Box.metainfo.xml | 2 +- vcpkg.json | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ba5aa151..2e0a29896 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,7 @@ if(MUNT_EXTERNAL) endif() project(86Box - VERSION 3.5 + VERSION 3.6 DESCRIPTION "Emulator of x86-based systems" HOMEPAGE_URL "https://86box.net" LANGUAGES C CXX) diff --git a/src/include_make/86box/version.h b/src/include_make/86box/version.h index fbf31b0b4..63e675c1e 100644 --- a/src/include_make/86box/version.h +++ b/src/include_make/86box/version.h @@ -20,11 +20,11 @@ #define EMU_NAME "86Box" #define EMU_NAME_W LSTR(EMU_NAME) -#define EMU_VERSION "3.5" +#define EMU_VERSION "3.6" #define EMU_VERSION_W LSTR(EMU_VERSION) #define EMU_VERSION_EX "3.50" /* frozen due to IDE re-detection behavior on Windows */ #define EMU_VERSION_MAJ 3 -#define EMU_VERSION_MIN 5 +#define EMU_VERSION_MIN 6 #define EMU_VERSION_PATCH 0 #define EMU_BUILD_NUM 0 @@ -40,7 +40,7 @@ #define EMU_ROMS_URL "https://github.com/86Box/roms/releases/latest" #define EMU_ROMS_URL_W LSTR(EMU_ROMS_URL) #ifdef RELEASE_BUILD -# define EMU_DOCS_URL "https://86box.readthedocs.io/en/v3.5/" +# define EMU_DOCS_URL "https://86box.readthedocs.io/en/v3.6/" #else # define EMU_DOCS_URL "https://86box.readthedocs.io" #endif diff --git a/src/unix/assets/86Box.spec b/src/unix/assets/86Box.spec index 1ef0aeb14..6ee9098ab 100644 --- a/src/unix/assets/86Box.spec +++ b/src/unix/assets/86Box.spec @@ -12,10 +12,10 @@ # After a successful build, you can install the RPMs as follows: # sudo dnf install RPMS/$(uname -m)/86Box-3* RPMS/noarch/86Box-roms* -%global romver 20220523 +20220523 Name: 86Box -Version: 3.5 +Version: 3.6 Release: 1%{?dist} Summary: Classic PC emulator License: GPLv2+ @@ -120,5 +120,5 @@ popd %{_bindir}/roms %changelog -* Mon May 23 2022 Robert de Rooy 3.5-1 +* Mon Jun 27 2022 Robert de Rooy 3.6-1 - Bump release diff --git a/src/unix/assets/net.86box.86Box.metainfo.xml b/src/unix/assets/net.86box.86Box.metainfo.xml index 9593da9ea..71121b708 100644 --- a/src/unix/assets/net.86box.86Box.metainfo.xml +++ b/src/unix/assets/net.86box.86Box.metainfo.xml @@ -10,7 +10,7 @@ net.86box.86Box.desktop - + diff --git a/vcpkg.json b/vcpkg.json index d64fc9108..3583bb961 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,6 +1,6 @@ { "name": "86box", - "version-string": "3.5", + "version-string": "3.6", "homepage": "https://86box.net/", "documentation": "http://86box.readthedocs.io/", "license": "GPL-2.0-or-later", From 972550048c036c4e2a88537dd9b3add4ac1090f2 Mon Sep 17 00:00:00 2001 From: richardg867 Date: Wed, 29 Jun 2022 13:32:49 -0300 Subject: [PATCH 13/31] Jenkins: Disable static Qt on Windows debug builds --- .ci/Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/Jenkinsfile b/.ci/Jenkinsfile index e8a3612a8..fbcb51c04 100644 --- a/.ci/Jenkinsfile +++ b/.ci/Jenkinsfile @@ -90,8 +90,8 @@ def presetSlugs = [ def presetFlags = [ 'Regular': '-t --preset=regular -D CMAKE_BUILD_TYPE=Release', - 'Debug': '--preset=debug -D CMAKE_BUILD_TYPE=Debug', - 'Dev': '--preset=experimental -D CMAKE_BUILD_TYPE=Debug -D VNC=OFF' + 'Debug': '--preset=debug -D CMAKE_BUILD_TYPE=Debug -D STATIC_BUILD=OFF', + 'Dev': '--preset=experimental -D CMAKE_BUILD_TYPE=Debug -D VNC=OFF -D STATIC_BUILD=OFF' ] def gitClone(repository, branch) { From ad8ea20e14c9b5d0e2c54d1d44f59a5f33572cb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Wed, 29 Jun 2022 18:55:15 +0200 Subject: [PATCH 14/31] qt: fix windeployqt with qt5 --- src/qt/CMakeLists.txt | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 6b4c7a7ca..b9d0e40e9 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -240,12 +240,24 @@ if(WIN32) # needed for static builds qt_import_plugins(plat INCLUDE Qt${QT_MAJOR}::QWindowsIntegrationPlugin Qt${QT_MAJOR}::QICOPlugin Qt${QT_MAJOR}::QWindowsVistaStylePlugin) else() - install(CODE " - get_filename_component(CMAKE_INSTALL_PREFIX_ABSOLUTE \${CMAKE_INSTALL_PREFIX} ABSOLUTE) - execute_process( - COMMAND $ - \"\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/$\") - ") + if(USE_QT6) + install(CODE " + get_filename_component(CMAKE_INSTALL_PREFIX_ABSOLUTE \${CMAKE_INSTALL_PREFIX} ABSOLUTE) + execute_process( + COMMAND $ + \"\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/$\") + ") + else() + find_program(WINDEPLOYQT_EXECUTABLE windeployqt) + if(WINDEPLOYQT_EXECUTABLE) + install(CODE " + get_filename_component(CMAKE_INSTALL_PREFIX_ABSOLUTE \${CMAKE_INSTALL_PREFIX} ABSOLUTE) + execute_process( + COMMAND ${WINDEPLOYQT_EXECUTABLE} + \"\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/$\") + ") + endif() + endif() endif() endif() From 30e020117456f4fc072cc6711069b42ca88b723f Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 1 Jul 2022 17:58:56 +0200 Subject: [PATCH 15/31] When linear framebuffer base is mapped, it's fb_only time, fixes gibberish fonts and corrupt mouse cursor on BeOS releases using the S3 Trio/Virge cards. Slight cleanup of the XGA card and fixed more possible cursor issues. --- src/video/vid_s3.c | 11 ++++++----- src/video/vid_s3_virge.c | 3 --- src/video/vid_xga.c | 13 ++++++++----- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 371d81ce4..cb968f005 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3128,6 +3128,10 @@ static void s3_recalctimings(svga_t *svga) if (s3->width == 1280 || s3->width == 1600 || (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_NUMBER9_9FX_771)) svga->hdisp <<= 1; + if (s3->card_type == S3_NUMBER9_9FX_771) { + if (svga->hdisp == 832) + svga->hdisp -= 32; + } if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_MIROCRYSTAL20SV_964 || s3->card_type == S3_MIROCRYSTAL20SD_864 || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_SPEA_MERCURY_P64V) { @@ -3378,12 +3382,9 @@ s3_updatemapping(s3_t *s3) mem_mapping_set_addr(&s3->linear_mapping, s3->linear_base, s3->linear_size); } - if (s3->chip >= S3_TRIO64V) - svga->fb_only = 1; + svga->fb_only = 1; } else { - if (s3->chip >= S3_TRIO64V) - svga->fb_only = 0; - + svga->fb_only = 0; mem_mapping_disable(&s3->linear_mapping); } diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index dd1c03fa4..662e55379 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -777,7 +777,6 @@ static void s3_virge_recalctimings(svga_t *svga) if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/ { - svga->fb_only = 0; svga->ma_latch |= (virge->ma_ext << 16); if (svga->crtc[0x51] & 0x30) svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4; else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100; @@ -820,8 +819,6 @@ static void s3_virge_recalctimings(svga_t *svga) } else /*Streams mode*/ { - svga->fb_only = 1; - if (virge->streams.buffer_ctrl & 1) svga->ma_latch = virge->streams.pri_fb1 >> 2; else diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index ff0cd081f..1dfa2e6ec 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -115,6 +115,9 @@ xga_recalctimings(svga_t *svga) xga->h_total = (xga->htotal + 1) << 3; xga->rowoffset = (xga->hdisp + 1); + if ((xga->disp_cntl_2 & 7) == 4) { + xga->rowoffset = 0x80; + } xga->interlace = !!(xga->disp_cntl_1 & 0x08); xga->rowcount = (xga->disp_cntl_2 & 0xc0) >> 6; @@ -311,8 +314,10 @@ 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->cursor_data_on = 1; - else if (xga->aperture_cntl == 0) - xga->cursor_data_on = 0; + else if (xga->aperture_cntl == 0) { + if (xga->linear_endian_reverse) + xga->cursor_data_on = 0; + } } if ((xga->sprite_pos > 16) && (xga->sprite_pos <= 0x1ff)) xga->cursor_data_on = 0; @@ -803,7 +808,6 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int byte2 = byte; return byte2; case 4: /*16-bit*/ - width >>= 1; addr += (y * (width) << 1); addr += (x << 1); if (!skip) { @@ -867,7 +871,6 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui mem_writeb_phys(addr, pixel & 0xff); break; case 4: /*16-bit*/ - width >>= 1; addr += (y * (width) << 1); addr += (x << 1); if (!skip) { @@ -2151,7 +2154,7 @@ xga_render_16bpp(xga_t *xga, svga_t *svga) xga->lastline_draw = xga->displine; for (x = 0; x <= (xga->h_disp); x += 8) { - uint32_t dat = *(uint32_t *)(&xga->vram[(xga->ma + (x << 1)) & xga->vram_mask]); + 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]; From 4bf1e512d42e5c41b29d1f013d163eb931943e96 Mon Sep 17 00:00:00 2001 From: Robert de Rooy Date: Fri, 1 Jul 2022 22:17:33 +0200 Subject: [PATCH 16/31] fix regex bug --- bumpversion.sh | 19 ++++++++++++------- src/unix/assets/86Box.spec | 4 ++-- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/bumpversion.sh b/bumpversion.sh index 5c960e6f7..73886912a 100644 --- a/bumpversion.sh +++ b/bumpversion.sh @@ -17,23 +17,28 @@ # Parse arguments. newversion="$1" -if [ -z "$(echo $newversion | grep '\.')" ] +romversion="$2" +if [ -z "$(echo "$newversion" | grep '\.')" ] then - echo '[!] Usage: bumpversion.sh x.y[.z]' + echo '[!] Usage: bumpversion.sh x.y[.z] [romversion]' exit 1 fi shift # Extract version components. -newversion_maj=$(echo $newversion | cut -d. -f1) -newversion_min=$(echo $newversion | cut -d. -f2) -newversion_patch=$(echo $newversion | cut -d. -f3) +newversion_maj=$(echo "$newversion" | cut -d. -f1) +newversion_min=$(echo "$newversion" | cut -d. -f2) +newversion_patch=$(echo "$newversion" | cut -d. -f3) [ -z "$newversion_patch" ] && newversion_patch=0 # Switch to the repository root directory. -cd "$(dirname "$0")" +cd "$(dirname "$0")" || exit get_latest_rom_release() { + if [ -n "${romversion}" ]; then + echo "${romversion}" + return + fi # Get the latest ROM release from the GitHub API. curl --silent "https://api.github.com/repos/86Box/roms/releases/latest" | grep '"tag_name":' | @@ -67,7 +72,7 @@ patch_file src/include_make/*/version.h EMU_VERSION_PATCH 's/(#\s*define\s+EMU_V patch_file src/include_make/*/version.h COPYRIGHT_YEAR 's/(#\s*define\s+COPYRIGHT_YEAR\s+)[0-9]+/\1'"$(date +%Y)"'/' patch_file src/include_make/*/version.h EMU_DOCS_URL 's/(#\s*define\s+EMU_DOCS_URL\s+"https:\/\/[^\/]+\/en\/v)[^\/]+/\1'"$newversion_maj.$newversion_min"'/' patch_file src/unix/assets/*.spec Version 's/(Version:\s+)[0-9].+/\1'"$newversion"'/' -patch_file src/unix/assets/*.spec '%global romver' 's/(^%global\ romver\s+)[0-9]{8}/'"$(get_latest_rom_release)"'/' +patch_file src/unix/assets/*.spec '%global romver' 's/(^%global\ romver\s+)[0-9]{8}/\1'"$(get_latest_rom_release)"'/' patch_file src/unix/assets/*.spec 'changelog version' 's/(^[*]\s.*>\s+)[0-9].+/\1'"$newversion"-1'/' patch_file src/unix/assets/*.spec 'changelog date' 's/(^[*]\s)[a-zA-Z]{3}\s[a-zA-Z]{3}\s[0-9]{2}\s[0-9]{4}/\1'"$(pretty_date)"'/' patch_file src/unix/assets/*.metainfo.xml release 's/( 3.6-1 +* Fri Jul 01 2022 Robert de Rooy 3.6-1 - Bump release From 15e93eaa89621781a6726385fafb1c06233ce3dc Mon Sep 17 00:00:00 2001 From: Robert de Rooy Date: Fri, 1 Jul 2022 22:29:51 +0200 Subject: [PATCH 17/31] remove function --- bumpversion.sh | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/bumpversion.sh b/bumpversion.sh index 73886912a..7fb0e96eb 100644 --- a/bumpversion.sh +++ b/bumpversion.sh @@ -31,20 +31,17 @@ newversion_min=$(echo "$newversion" | cut -d. -f2) newversion_patch=$(echo "$newversion" | cut -d. -f3) [ -z "$newversion_patch" ] && newversion_patch=0 + +if [ -z "${romversion}" ]; then + # Get the latest ROM release from the GitHub API. + romversion=$(curl --silent "https://api.github.com/repos/86Box/roms/releases/latest" | + grep '"tag_name":' | + sed -E 's/.*"([^"]+)".*/\1/') +fi + # Switch to the repository root directory. cd "$(dirname "$0")" || exit -get_latest_rom_release() { - if [ -n "${romversion}" ]; then - echo "${romversion}" - return - fi - # Get the latest ROM release from the GitHub API. - curl --silent "https://api.github.com/repos/86Box/roms/releases/latest" | - grep '"tag_name":' | - sed -E 's/.*"([^"]+)".*/\1/' -} - pretty_date() { # Ensure we get the date in English. LANG=en_US.UTF-8 date '+%a %b %d %Y' @@ -72,7 +69,7 @@ patch_file src/include_make/*/version.h EMU_VERSION_PATCH 's/(#\s*define\s+EMU_V patch_file src/include_make/*/version.h COPYRIGHT_YEAR 's/(#\s*define\s+COPYRIGHT_YEAR\s+)[0-9]+/\1'"$(date +%Y)"'/' patch_file src/include_make/*/version.h EMU_DOCS_URL 's/(#\s*define\s+EMU_DOCS_URL\s+"https:\/\/[^\/]+\/en\/v)[^\/]+/\1'"$newversion_maj.$newversion_min"'/' patch_file src/unix/assets/*.spec Version 's/(Version:\s+)[0-9].+/\1'"$newversion"'/' -patch_file src/unix/assets/*.spec '%global romver' 's/(^%global\ romver\s+)[0-9]{8}/\1'"$(get_latest_rom_release)"'/' +patch_file src/unix/assets/*.spec '%global romver' 's/(^%global\ romver\s+)[0-9]{8}/\1'"$romversion"'/' patch_file src/unix/assets/*.spec 'changelog version' 's/(^[*]\s.*>\s+)[0-9].+/\1'"$newversion"-1'/' patch_file src/unix/assets/*.spec 'changelog date' 's/(^[*]\s)[a-zA-Z]{3}\s[a-zA-Z]{3}\s[0-9]{2}\s[0-9]{4}/\1'"$(pretty_date)"'/' patch_file src/unix/assets/*.metainfo.xml release 's/( Date: Sat, 2 Jul 2022 00:33:38 +0200 Subject: [PATCH 18/31] Fix EGA/VGA display type of the Olivetti M24 --- src/machine/m_xt_olivetti.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/m_xt_olivetti.c b/src/machine/m_xt_olivetti.c index 8541fa2c3..bd4403d66 100644 --- a/src/machine/m_xt_olivetti.c +++ b/src/machine/m_xt_olivetti.c @@ -721,7 +721,7 @@ m24_read(uint16_t port, void *priv) ret |= ((fdd_count - 1) << 6); /* Switches 5, 6 - monitor type */ - if (video_is_mda()) + if (video_is_ega_vga()) ret |= 0x30; else if (video_is_cga()) ret |= 0x20; /* 0x10 would be 40x25 */ From eb0ba3d1c4e970310783f41d39104a7c736677ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Sat, 2 Jul 2022 16:17:05 +0200 Subject: [PATCH 19/31] Revert "Fix EGA/VGA display type of the Olivetti M24" This reverts commit b831b87355a8a8da285c256dec62f44b7d06217c. --- src/machine/m_xt_olivetti.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/m_xt_olivetti.c b/src/machine/m_xt_olivetti.c index bd4403d66..8541fa2c3 100644 --- a/src/machine/m_xt_olivetti.c +++ b/src/machine/m_xt_olivetti.c @@ -721,7 +721,7 @@ m24_read(uint16_t port, void *priv) ret |= ((fdd_count - 1) << 6); /* Switches 5, 6 - monitor type */ - if (video_is_ega_vga()) + if (video_is_mda()) ret |= 0x30; else if (video_is_cga()) ret |= 0x20; /* 0x10 would be 40x25 */ From f0a78c7642e3395b1432081a7855d4bd5b025ceb Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 3 Jul 2022 23:01:46 +0200 Subject: [PATCH 20/31] Initial XGA-2 implementation, (same as XGA-1 internally, but able to do 800x600 officially), selection is possible only on QT at the moment. Refactored the ROP/MIX of the XGA accelerator. Bus type variable added to make sure the device is an ISA-16 device or MCA in its dedicated register. --- src/include/86box/vid_xga.h | 2 + src/include/86box/vid_xga_device.h | 22 ++ src/qt/qt_settingsdisplay.cpp | 15 ++ src/qt/qt_settingsdisplay.hpp | 2 + src/qt/qt_settingsdisplay.ui | 7 + src/video/vid_xga.c | 358 +++++++++++++++-------------- 6 files changed, 237 insertions(+), 169 deletions(-) create mode 100644 src/include/86box/vid_xga_device.h diff --git a/src/include/86box/vid_xga.h b/src/include/86box/vid_xga.h index aef837fba..4d70c601a 100644 --- a/src/include/86box/vid_xga.h +++ b/src/include/86box/vid_xga.h @@ -64,6 +64,7 @@ typedef struct xga_t uint8_t pal_b, pal_b_prefetch; uint8_t sprite_data[1024]; uint8_t scrollcache; + uint8_t direct_color; uint8_t *vram, *changedvram; int16_t hwc_pos_x; @@ -92,6 +93,7 @@ typedef struct xga_t int op_mode_reset, linear_endian_reverse; int sprite_pos, sprite_pos_prefetch, cursor_data_on; int pal_test; + int type, bus; uint32_t linear_base, linear_size, banked_mask; uint32_t base_addr_1mb; diff --git a/src/include/86box/vid_xga_device.h b/src/include/86box/vid_xga_device.h new file mode 100644 index 000000000..37893e0d5 --- /dev/null +++ b/src/include/86box/vid_xga_device.h @@ -0,0 +1,22 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * IBM XGA emulation. + * + * + * + * Authors: TheCollector1995. + * + * Copyright 2022 TheCollector1995. + */ + +#ifndef VIDEO_XGA_DEVICE_H +# define VIDEO_XGA_DEVICE_H +extern const device_t xga_device; +extern const device_t xga_isa_device; +#endif /*VIDEO_XGA_DEVICE_H*/ diff --git a/src/qt/qt_settingsdisplay.cpp b/src/qt/qt_settingsdisplay.cpp index 8686d1ace..e3fac08ec 100644 --- a/src/qt/qt_settingsdisplay.cpp +++ b/src/qt/qt_settingsdisplay.cpp @@ -24,6 +24,7 @@ extern "C" { #include <86box/device.h> #include <86box/machine.h> #include <86box/video.h> +#include <86box/vid_xga_device.h> } #include "qt_deviceconfig.hpp" @@ -102,6 +103,14 @@ void SettingsDisplay::on_pushButtonConfigureVoodoo_clicked() { DeviceConfig::ConfigureDevice(&voodoo_device, 0, qobject_cast(Settings::settings)); } +void SettingsDisplay::on_pushButtonConfigureXga_clicked() { + if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) { + DeviceConfig::ConfigureDevice(&xga_device, 0, qobject_cast(Settings::settings)); + } else { + DeviceConfig::ConfigureDevice(&xga_isa_device, 0, qobject_cast(Settings::settings)); + } +} + void SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) { if (index < 0) { return; @@ -126,8 +135,14 @@ void SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) { ui->checkBoxXga->setEnabled(hasIsa16 || has_MCA); if (hasIsa16 || has_MCA) ui->checkBoxXga->setChecked(xga_enabled); + + ui->pushButtonConfigureXga->setEnabled((hasIsa16 || has_MCA) && ui->checkBoxXga->isChecked()); } void SettingsDisplay::on_checkBoxVoodoo_stateChanged(int state) { ui->pushButtonConfigureVoodoo->setEnabled(state == Qt::Checked); } + +void SettingsDisplay::on_checkBoxXga_stateChanged(int state) { + ui->pushButtonConfigureXga->setEnabled(state == Qt::Checked); +} diff --git a/src/qt/qt_settingsdisplay.hpp b/src/qt/qt_settingsdisplay.hpp index 768f40311..44e688d9a 100644 --- a/src/qt/qt_settingsdisplay.hpp +++ b/src/qt/qt_settingsdisplay.hpp @@ -22,8 +22,10 @@ public slots: private slots: void on_checkBoxVoodoo_stateChanged(int state); + void on_checkBoxXga_stateChanged(int state); void on_comboBoxVideo_currentIndexChanged(int index); void on_pushButtonConfigureVoodoo_clicked(); + void on_pushButtonConfigureXga_clicked(); void on_pushButtonConfigure_clicked(); private: diff --git a/src/qt/qt_settingsdisplay.ui b/src/qt/qt_settingsdisplay.ui index cb927e7c2..58032a17b 100644 --- a/src/qt/qt_settingsdisplay.ui +++ b/src/qt/qt_settingsdisplay.ui @@ -70,6 +70,13 @@ + + + + Configure + + + diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 1dfa2e6ec..9bd6e3e8b 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -32,9 +32,11 @@ #include <86box/video.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> +#include <86box/vid_xga_device.h> #include "cpu.h" #define XGA_BIOS_PATH "roms/video/xga/XGA_37F9576_Ver200.BIN" +#define XGA2_BIOS_PATH "roms/video/xga/xga2_v300.bin" static void xga_ext_outb(uint16_t addr, uint8_t val, void *p); static uint8_t xga_ext_inb(uint16_t addr, void *p); @@ -44,7 +46,7 @@ xga_updatemapping(svga_t *svga) { xga_t *xga = &svga->xga; - //pclog("OpMode = %x, linear base = %08x, aperture cntl = %d, opmodereset1 = %d, access mode = %x\n", xga->op_mode, xga->linear_base, xga->aperture_cntl, xga->op_mode_reset, xga->access_mode); + //pclog("OpMode = %x, linear base = %08x, aperture cntl = %d, opmodereset1 = %d, access mode = %x, map = %x.\n", xga->op_mode, xga->linear_base, xga->aperture_cntl, xga->op_mode_reset, xga->access_mode, svga->gdcreg[6] & 0x0c); if ((xga->op_mode & 7) >= 4) { if (xga->aperture_cntl == 1) { mem_mapping_disable(&svga->mapping); @@ -112,12 +114,8 @@ xga_recalctimings(svga_t *svga) xga->v_blankstart = xga->vblankstart + 1; xga->h_disp = (xga->hdisp + 1) << 3; - xga->h_total = (xga->htotal + 1) << 3; xga->rowoffset = (xga->hdisp + 1); - if ((xga->disp_cntl_2 & 7) == 4) { - xga->rowoffset = 0x80; - } xga->interlace = !!(xga->disp_cntl_1 & 0x08); xga->rowcount = (xga->disp_cntl_2 & 0xc0) >> 6; @@ -131,7 +129,6 @@ xga_recalctimings(svga_t *svga) } xga->ma_latch = xga->disp_start_addr; - xga->h_disp_time = xga->h_disp; switch (xga->clk_sel_1 & 0x0c) { case 0: @@ -301,6 +298,10 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) svga_recalctimings(svga); break; + case 0x59: + xga->direct_color = val; + break; + case 0x60: xga->sprite_pal_addr_idx = (xga->sprite_pal_addr_idx & 0x3f00) | val; svga->dac_pos = 0; @@ -349,8 +350,8 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) svga->dac_pos++; break; case 2: - index = svga->dac_addr & 0xff; xga->pal_b = val; + index = svga->dac_addr & 0xff; svga->vgapal[index].r = svga->dac_r; svga->vgapal[index].g = svga->dac_g; svga->vgapal[index].b = xga->pal_b; @@ -404,6 +405,8 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *p) break; case 4: xga->access_mode &= ~8; + if ((xga->disp_cntl_2 & 7) == 4) + xga->aperture_cntl = 0; break; case 6: vga_on = 0; @@ -467,7 +470,7 @@ xga_ext_inb(uint16_t addr, void *p) case 0x0f: switch (xga->regs_idx) { case 4: - ret = 1; + ret = (xga->bus & DEVICE_MCA) ? 1 : 0; break; case 0x10: ret = xga->htotal & 0xff; @@ -572,15 +575,19 @@ xga_ext_inb(uint16_t addr, void *p) ret = xga->disp_cntl_2; break; case 0x52: - ret = 0x0a; + ret = 0x0b; break; case 0x53: - ret = 0xa0; + ret = 0xb0; break; case 0x54: ret = xga->clk_sel_1; break; + case 0x59: + ret = xga->direct_color; + break; + case 0x60: ret = xga->sprite_pal_addr_idx & 0xff; break; @@ -664,61 +671,45 @@ xga_ext_inb(uint16_t addr, void *p) #define READW(addr, dat) \ dat = *(uint16_t *)&xga->vram[(addr) & (xga->vram_mask)]; +#define READW_REVERSE(addr, dat) \ + dat = xga->vram[(addr + 1) & (xga->vram_mask - 1)] & 0xff; \ + dat |= (xga->vram[(addr) & (xga->vram_mask - 1)] << 8); + #define WRITEW(addr, dat) \ *(uint16_t *)&xga->vram[((addr)) & (xga->vram_mask)] = dat; \ xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = changeframecount; -static uint32_t -xga_rop(uint32_t s, uint8_t d, uint8_t op) -{ - switch(op) { - default: - case 0: - return 0; - case 1: - return s & d; - case 2: - return s & ~d; - case 3: - return s; - case 4: - return ~s & d; - case 5: - return d; - case 6: - return s ^ d; - case 7: - return s | d; - case 8: - return ~s & ~d; - case 9: - return s ^ ~d; - case 0x0a: - return ~d; - case 0x0b: - return s | ~d; - case 0x0c: - return ~s; - case 0x0d: - return ~s | d; - case 0x0e: - return ~s | ~d; - case 0x0f: - return -1; - case 0x10: - return MAX(s, d); - case 0x11: - return MIN(s, d); - case 0x12: - return MIN(0xff, s + d); - case 0x13: - return MAX(0, d - s); - case 0x14: - return MAX(0, s - d); - case 0x15: - return (s + d) >> 1; - } -} +#define WRITEW_REVERSE(addr, dat) \ + xga->vram[((addr + 1)) & (xga->vram_mask - 1)] = dat & 0xff; \ + xga->vram[((addr)) & (xga->vram_mask - 1)] = dat >> 8; \ + xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = changeframecount; + +#define ROP(mix, d, s) { \ + switch ((mix) ? (xga->accel.frgd_mix & 0x1f) : (xga->accel.bkgd_mix & 0x1f)) { \ + case 0x00: d = 0; break; \ + case 0x01: d = s & d; break; \ + case 0x02: d = s & ~d; break; \ + case 0x03: d = s; break; \ + case 0x04: d = ~s & d; break; \ + case 0x05: d = d; break; \ + case 0x06: d = s ^ d; break; \ + case 0x07: d = s | d; break; \ + case 0x08: d = ~s & ~d; break; \ + case 0x09: d = s ^ ~d; break; \ + case 0x0a: d = ~d; break; \ + case 0x0b: d = s | ~d; break; \ + case 0x0c: d = ~s; break; \ + case 0x0d: d = ~s | d; break; \ + case 0x0e: d = ~s | ~d; break; \ + case 0x0f: d = ~0; break; \ + case 0x10: d = MAX(s, d); break; \ + case 0x11: d = MIN(s, d); break; \ + case 0x12: d = MIN(0xff, s + d); break; \ + case 0x13: d = MAX(0, d - s); break; \ + case 0x14: d = MAX(0, s - d); break; \ + case 0x15: d = (s + d) >> 1; break; \ + } \ + } static uint32_t xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int width) @@ -738,7 +729,7 @@ xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t b skip = 1; } - addr += (y * (width) >> 3); + addr += (y * (width >> 3)); addr += (x >> 3); if (!skip) { READ(addr, byte); @@ -779,7 +770,7 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int switch (xga->accel.px_map_format[map] & 7) { case 0: /*1-bit*/ - addr += (y * (width) >> 3); + addr += (y * (width >> 3)); addr += (x >> 3); if (!skip) { READ(addr, byte); @@ -805,13 +796,20 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int } else { byte = mem_readb_phys(addr); } - byte2 = byte; - return byte2; + return byte; case 4: /*16-bit*/ - addr += (y * (width) << 1); + addr += (y * (width << 1)); addr += (x << 1); if (!skip) { - READW(addr, byte); + if ((xga->accel.px_map_format[map] & 8)) { + if (xga->linear_endian_reverse) { + READW(addr, byte); + } else { + READW_REVERSE(addr, byte); + } + } else { + READW(addr, byte); + } } else { byte = mem_readw_phys(addr); } @@ -874,7 +872,15 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui addr += (y * (width) << 1); addr += (x << 1); if (!skip) { - WRITEW(addr, pixel); + if ((xga->accel.px_map_format[map] & 8)) { + if (xga->linear_endian_reverse) { + WRITEW(addr, pixel); + } else { + WRITEW_REVERSE(addr, pixel); + } + } else { + WRITEW(addr, pixel); + } } mem_writew_phys(addr, pixel); break; @@ -890,8 +896,6 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) 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 mix; - int count = -1; int y = ssv & 0x0f; int x = 0; int dx, dy, dirx, diry; @@ -954,7 +958,9 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) ((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))) { - dest_dat = (dest_dat & ~plane_mask) | (xga_rop(src_dat, dest_dat, xga->accel.frgd_mix & 0x1f) & plane_mask); + old_dest_dat = dest_dat; + ROP(1, dest_dat, src_dat); + dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) { if (ssv & 0x10) 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, xga->accel.px_map_height[xga->accel.dst_map] + 1); @@ -978,7 +984,9 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) ((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))) { - dest_dat = (dest_dat & ~plane_mask) | (xga_rop(src_dat, dest_dat, xga->accel.frgd_mix & 0x1f) & plane_mask); + old_dest_dat = dest_dat; + ROP(1, dest_dat, src_dat); + dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) { if (ssv & 0x10) 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, xga->accel.px_map_height[xga->accel.dst_map] + 1); @@ -1019,11 +1027,9 @@ 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 mix; int dminor, destxtmp, dmajor, err, tmpswap; int steep = 1; int xdir, ydir; - int count = -1; int y = xga->accel.blt_width; int x = 0; int dx, dy; @@ -1085,7 +1091,9 @@ xga_line_draw_write(svga_t *svga) ((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))) { - dest_dat = (dest_dat & ~plane_mask) | (xga_rop(src_dat, dest_dat, xga->accel.frgd_mix & 0x1f) & plane_mask); + old_dest_dat = dest_dat; + ROP(1, dest_dat, src_dat); + dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) 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, xga->accel.px_map_height[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x10) && x) @@ -1107,7 +1115,9 @@ xga_line_draw_write(svga_t *svga) ((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))) { - dest_dat = (dest_dat & ~plane_mask) | (xga_rop(src_dat, dest_dat, xga->accel.frgd_mix & 0x1f) & plane_mask); + old_dest_dat = dest_dat; + ROP(1, dest_dat, src_dat); + dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x10) && x) @@ -1129,7 +1139,9 @@ xga_line_draw_write(svga_t *svga) ((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))) { - dest_dat = (dest_dat & ~plane_mask) | (xga_rop(src_dat, dest_dat, xga->accel.frgd_mix & 0x1f) & plane_mask); + old_dest_dat = dest_dat; + ROP(1, dest_dat, src_dat); + dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) 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, xga->accel.px_map_height[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x10) && x) @@ -1148,7 +1160,9 @@ xga_line_draw_write(svga_t *svga) ((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))) { - dest_dat = (dest_dat & ~plane_mask) | (xga_rop(src_dat, dest_dat, xga->accel.frgd_mix & 0x1f) & plane_mask); + old_dest_dat = dest_dat; + ROP(1, dest_dat, src_dat); + dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x10) && x) @@ -1245,15 +1259,6 @@ xga_bitblt(svga_t *svga) xga->accel.pattern = 1; } } - } else if ((dstwidth == (xga->h_disp - 1)) && (srcwidth == (xga->h_disp - 1))) { - if ((xga->accel.dst_map == 1) && (xga->accel.src_map == 1) && xga->linear_endian_reverse) { - if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0b) && (xga->accel.px_map_format[xga->accel.src_map] >= 0x0b)) { - if ((xga->accel.command & 0xc0) == 0x40) - xga->accel.pattern = 0; - else - xga->accel.pattern = 1; - } - } } } @@ -1273,7 +1278,9 @@ xga_bitblt(svga_t *svga) ((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))) { - dest_dat = (dest_dat & ~plane_mask) | (xga_rop(src_dat, dest_dat, xga->accel.frgd_mix & 0x1f) & plane_mask); + old_dest_dat = dest_dat; + ROP(1, dest_dat, src_dat); + dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); } } @@ -1288,7 +1295,9 @@ xga_bitblt(svga_t *svga) ((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))) { - dest_dat = (dest_dat & ~plane_mask) | (xga_rop(src_dat, dest_dat, xga->accel.frgd_mix & 0x1f) & plane_mask); + old_dest_dat = dest_dat; + ROP(1, dest_dat, src_dat); + dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); } } @@ -1366,7 +1375,9 @@ xga_bitblt(svga_t *svga) ((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))) { - dest_dat = (dest_dat & ~plane_mask) | (xga_rop(src_dat, dest_dat, mix ? (xga->accel.frgd_mix & 0x1f) : (xga->accel.bkgd_mix & 0x1f)) & plane_mask); + old_dest_dat = dest_dat; + ROP(mix, dest_dat, src_dat); + dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); } } @@ -1385,7 +1396,9 @@ xga_bitblt(svga_t *svga) ((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))) { - dest_dat = (dest_dat & ~plane_mask) | (xga_rop(src_dat, dest_dat, mix ? (xga->accel.frgd_mix & 0x1f) : (xga->accel.bkgd_mix & 0x1f)) & plane_mask); + old_dest_dat = dest_dat; + ROP(mix, dest_dat, src_dat); + dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); } } @@ -1429,7 +1442,6 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) addr &= 0x1fff; if (addr >= 0x1800) { - //pclog("[%04X:%08X]: WriteMEM = %02x, val = %08x, len = %d.\n", CS, cpu_state.pc, addr & 0x7f, val, len); switch (addr & 0x7f) { case 0x12: xga->accel.px_map_idx = val & 3; @@ -1831,6 +1843,7 @@ exec_command: //} switch ((xga->accel.command >> 24) & 0x0f) { case 3: /*Bresenham Line Draw Read*/ + //pclog("Line Draw Read\n"); break; case 4: /*Short Stroke Vectors*/ break; @@ -1841,6 +1854,7 @@ exec_command: xga_bitblt(svga); break; case 9: /*Inverting BitBLT*/ + //pclog("Inverting BitBLT\n"); break; } } else if (len == 2) { @@ -2265,8 +2279,29 @@ xga_writew_linear(uint32_t addr, uint16_t val, void *p) return; } - xga_write_linear(addr, val, p); - xga_write_linear(addr + 1, val >> 8, p); + if (xga->linear_endian_reverse) { + if (xga->accel.px_map_format[xga->accel.dst_map] == 0x0c) { + xga_write_linear(addr, val, p); + xga_write_linear(addr + 1, val >> 8, p); + } else if (xga->accel.px_map_format[xga->accel.dst_map] == 4) { + xga_write_linear(addr + 1, val, p); + xga_write_linear(addr, val >> 8, p); + } else { + xga_write_linear(addr, val, p); + xga_write_linear(addr + 1, val >> 8, p); + } + } else { + if (xga->accel.px_map_format[xga->accel.dst_map] == 0x0c) { + xga_write_linear(addr + 1, val, p); + xga_write_linear(addr, val >> 8, p); + } else if (xga->accel.px_map_format[xga->accel.dst_map] == 4) { + xga_write_linear(addr, val, p); + xga_write_linear(addr + 1, val >> 8, p); + } else { + xga_write_linear(addr, val, p); + xga_write_linear(addr + 1, val >> 8, p); + } + } } static void @@ -2370,11 +2405,27 @@ xga_readw_linear(uint32_t addr, void *p) { svga_t *svga = (svga_t *)p; xga_t *xga = &svga->xga; + uint16_t ret; if (!xga->on) return svga_readw_linear(addr, svga); - return xga_read_linear(addr, p) | (xga_read_linear(addr + 1, p) << 8); + if (xga->linear_endian_reverse) { + if (xga->accel.px_map_format[xga->accel.src_map] == 0x0c) { + ret = xga_read_linear(addr, p) | (xga_read_linear(addr + 1, p) << 8); + } else if (xga->accel.px_map_format[xga->accel.src_map] == 4) { + ret = xga_read_linear(addr + 1, p) | (xga_read_linear(addr, p) << 8); + } else + ret = xga_read_linear(addr, p) | (xga_read_linear(addr + 1, p) << 8); + } else { + if (xga->accel.px_map_format[xga->accel.src_map] == 0x0c) { + ret = xga_read_linear(addr + 1, p) | (xga_read_linear(addr, p) << 8); + } else if (xga->accel.px_map_format[xga->accel.src_map] == 4) { + ret = xga_read_linear(addr, p) | (xga_read_linear(addr + 1, p) << 8); + } else + ret = xga_read_linear(addr, p) | (xga_read_linear(addr + 1, p) << 8); + } + return ret; } static uint32_t @@ -2417,72 +2468,6 @@ xga_do_render(svga_t *svga) } } -static void -xga_doblit(int wx, int wy, svga_t *svga) -{ - int y_add, x_add, y_start, x_start, bottom; - uint32_t *p; - int i, j; - int xs_temp, ys_temp; - - y_add = (enable_overscan) ? overscan_y : 0; - x_add = (enable_overscan) ? overscan_x : 0; - y_start = (enable_overscan) ? 0 : (overscan_y >> 1); - x_start = (enable_overscan) ? 0 : (overscan_x >> 1); - bottom = (overscan_y >> 1); - - if ((wx <= 0) || (wy <= 0)) - return; - - xs_temp = wx; - ys_temp = wy + 1; - if (xs_temp < 64) - xs_temp = 640; - if (ys_temp < 32) - ys_temp = 200; - - if ((svga->crtc[0x17] & 0x80) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { - /* Screen res has changed.. fix up, and let them know. */ - xsize = xs_temp; - ysize = ys_temp; - - if ((xsize > 1984) || (ysize > 2016)) { - /* 2048x2048 is the biggest safe render texture, to account for overscan, - we suppress overscan starting from x 1984 and y 2016. */ - x_add = 0; - y_add = 0; - suppress_overscan = 1; - } else - suppress_overscan = 0; - - /* Block resolution changes while in DPMS mode to avoid getting a bogus - screen width (320). We're already rendering a blank screen anyway. */ - set_screen_size(xsize + x_add, ysize + y_add); - - if (video_force_resize_get()) - video_force_resize_set(0); - } - - if ((wx >= 160) && ((wy + 1) >= 120)) { - /* Draw (overscan_size - scroll size) lines of overscan on top and bottom. */ - for (i = 0; i < svga->y_add; i++) { - p = &buffer32->line[i & 0x7ff][0]; - - for (j = 0; j < (xsize + x_add); j++) - p[j] = svga->overscan_color; - } - - for (i = 0; i < bottom; i++) { - p = &buffer32->line[(ysize + svga->y_add + i) & 0x7ff][0]; - - for (j = 0; j < (xsize + x_add); j++) - p[j] = svga->overscan_color; - } - } - - video_blit_memtoscreen(x_start, y_start, xsize + x_add, ysize + y_add); -} - void xga_poll(xga_t *xga, svga_t *svga) { @@ -2539,9 +2524,15 @@ xga_poll(xga_t *xga, svga_t *svga) if (xga->sc == xga->rowcount) { xga->sc = 0; - xga->maback += (xga->rowoffset << 3); - if (xga->interlace) + if ((xga->disp_cntl_2 & 7) == 4) { + xga->maback += (xga->rowoffset << 4); + if (xga->interlace) + xga->maback += (xga->rowoffset << 4); + } else { xga->maback += (xga->rowoffset << 3); + if (xga->interlace) + xga->maback += (xga->rowoffset << 3); + } xga->maback &= xga->vram_mask; xga->ma = xga->maback; } else { @@ -2703,6 +2694,9 @@ static void uint32_t temp; uint8_t *rom = NULL; + xga->type = device_get_config_int("type"); + xga->bus = info->flags; + xga->vram_size = (1024 << 10); xga->vram_mask = xga->vram_size - 1; xga->vram = calloc(xga->vram_size, 1); @@ -2712,7 +2706,7 @@ static void xga->hwcursor.ysize = 64; xga->bios_rom.sz = 0x2000; - f = rom_fopen(XGA_BIOS_PATH, "rb"); + f = rom_fopen(xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, "rb"); (void)fseek(f, 0L, SEEK_END); temp = ftell(f); (void)fseek(f, 0L, SEEK_SET); @@ -2761,10 +2755,10 @@ static void mem_mapping_disable(&xga->linear_mapping); mem_mapping_disable(&xga->memio_mapping); - xga->pos_regs[0] = 0xdb; + xga->pos_regs[0] = xga->type ? 0xda : 0xdb; xga->pos_regs[1] = 0x8f; - if (info->flags & DEVICE_MCA) { + if (xga->bus & DEVICE_MCA) { mca_add(xga_mca_read, xga_mca_write, xga_mca_feedb, NULL, svga); } else { io_sethandler(0x0100, 0x0008, xga_pos_in, NULL, NULL, NULL, NULL, NULL, svga); @@ -2790,7 +2784,7 @@ xga_close(void *p) static int xga_available(void) { - return rom_present(XGA_BIOS_PATH); + return rom_present(XGA_BIOS_PATH) && rom_present(XGA2_BIOS_PATH); } static void @@ -2809,6 +2803,32 @@ xga_force_redraw(void *p) svga->fullchange = changeframecount; } +static const device_config_t xga_configuration[] = { + // clang-format off + { + .name = "type", + .description = "XGA type", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "XGA-1", + .value = 0 + }, + { + .description = "XGA-2", + .value = 1 + }, + { .description = "" } + } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + const device_t xga_device = { .name = "XGA (MCA)", .internal_name = "xga_mca", @@ -2820,7 +2840,7 @@ const device_t xga_device = { { .available = xga_available }, .speed_changed = xga_speed_changed, .force_redraw = xga_force_redraw, - .config = NULL + .config = xga_configuration }; const device_t xga_isa_device = { @@ -2834,7 +2854,7 @@ const device_t xga_isa_device = { { .available = xga_available }, .speed_changed = xga_speed_changed, .force_redraw = xga_force_redraw, - .config = NULL + .config = xga_configuration }; void From 6da31a55572e504bbc814394a4dccc1b31bfa78e Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 3 Jul 2022 23:09:55 +0200 Subject: [PATCH 21/31] Make the dedicated Longshine SCSI ASPI driver work under DOS. --- src/scsi/scsi_ncr5380.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index f69f34276..ce43a9cf2 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -749,8 +749,11 @@ ncr_read(uint16_t port, void *priv) break; case 2: /* Mode register */ - if (((ncr->mode & 0x30) == 0x30) && (ncr_dev->type <= 1)) + if (((ncr->mode & 0x30) == 0x30) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1))) ncr->mode = 0; + if (((ncr->mode & 0x20) == 0x20) && (ncr_dev->type == 0)) + ncr->mode = 0; + ncr_log("Read: Mode register\n"); ret = ncr->mode; break; @@ -766,9 +769,9 @@ ncr_read(uint16_t port, void *priv) ncr_bus_read(ncr_dev); ncr_log("NCR cur bus stat=%02x\n", ncr->cur_bus & 0xff); ret |= (ncr->cur_bus & 0xff); - if ((ncr->icr & ICR_SEL) && (ncr_dev->type != 3)) + if ((ncr->icr & ICR_SEL) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1))) ret |= 0x02; - if ((ncr->icr & ICR_BSY) && (ncr_dev->type != 3)) + if ((ncr->icr & ICR_BSY) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1))) ret |= 0x40; break; @@ -788,9 +791,9 @@ ncr_read(uint16_t port, void *priv) ncr_bus_read(ncr_dev); bus = ncr->cur_bus; - if ((bus & BUS_ACK) || ((ncr->icr & ICR_ACK) && (ncr_dev->type != 3))) + if ((bus & BUS_ACK) || ((ncr->icr & ICR_ACK) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1)))) ret |= STATUS_ACK; - if ((bus & BUS_ATN) || ((ncr->icr & ICR_ATN) && (ncr_dev->type != 3))) + if ((bus & BUS_ATN) || ((ncr->icr & ICR_ATN) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1)))) ret |= 0x02; if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA)) { From 6888cd36032d32a3f6507f5e07036c7e4f8e8015 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 3 Jul 2022 23:34:49 +0200 Subject: [PATCH 22/31] Fixed the overscan setting when using the 8514/A native drivers. --- src/video/vid_8514a.c | 67 +------------------------------------------ 1 file changed, 1 insertion(+), 66 deletions(-) diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 85607f004..4731132f1 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -3438,71 +3438,6 @@ ibm8514_render_overscan_right(ibm8514_t *dev, svga_t *svga) buffer32->line[dev->displine + svga->y_add][svga->x_add + dev->h_disp + i] = svga->overscan_color; } -static void -ibm8514_doblit(int wx, int wy, ibm8514_t *dev, svga_t *svga) -{ - int y_add, x_add, y_start, x_start, bottom; - uint32_t *p; - int i, j; - int xs_temp, ys_temp; - - y_add = (enable_overscan) ? overscan_y : 0; - x_add = (enable_overscan) ? overscan_x : 0; - y_start = (enable_overscan) ? 0 : (overscan_y >> 1); - x_start = (enable_overscan) ? 0 : (overscan_x >> 1); - bottom = (overscan_y >> 1) + (svga->crtc[8] & 0x1f); - - if ((wx <= 0) || (wy <= 0)) - return; - - xs_temp = wx; - ys_temp = wy + 1; - if (xs_temp < 64) - xs_temp = 640; - if (ys_temp < 32) - ys_temp = 200; - - if ((svga->crtc[0x17] & 0x80) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { - /* Screen res has changed.. fix up, and let them know. */ - xsize = xs_temp; - ysize = ys_temp; - - if ((xsize > 1984) || (ysize > 2016)) { - /* 2048x2048 is the biggest safe render texture, to account for overscan, - we suppress overscan starting from x 1984 and y 2016. */ - x_add = 0; - y_add = 0; - suppress_overscan = 1; - } else - suppress_overscan = 0; - - /* Block resolution changes while in DPMS mode to avoid getting a bogus - screen width (320). We're already rendering a blank screen anyway. */ - set_screen_size(xsize + x_add, ysize + y_add); - - if (video_force_resize_get()) - video_force_resize_set(0); - } - - if ((wx >= 160) && ((wy + 1) >= 120)) { - /* Draw (overscan_size - scroll size) lines of overscan on top and bottom. */ - for (i = 0; i < svga->y_add; i++) { - p = &buffer32->line[i & 0x7ff][0]; - - for (j = 0; j < (xsize + x_add); j++) - p[j] = svga->overscan_color; - } - - for (i = 0; i < bottom; i++) { - p = &buffer32->line[(ysize + svga->y_add + i) & 0x7ff][0]; - - for (j = 0; j < (xsize + x_add); j++) - p[j] = svga->overscan_color; - } - } - video_blit_memtoscreen(x_start, y_start, xsize + x_add, ysize + y_add); -} - void ibm8514_poll(ibm8514_t *dev, svga_t *svga) { @@ -3588,7 +3523,7 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga) wx = x; wy = dev->lastline - dev->firstline; - ibm8514_doblit(wx, wy, dev, svga); + svga_doblit(wx, wy, svga); dev->firstline = 2000; dev->lastline = 0; From 4417532851d36a9538e11ba0205292b47ed78edc Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 4 Jul 2022 17:36:47 +0200 Subject: [PATCH 23/31] Forgot to update the svga core source file. --- src/video/vid_svga.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index a102d71f0..6c894b29a 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1076,7 +1076,7 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) if (!linear) { if (xga_enabled) { - if (((svga->xga.op_mode & 7) == 4) && (svga->xga.aperture_cntl == 1)) { + if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl == 1)) { if (val == 0xa5) { /*Memory size test of XGA*/ svga->xga.test = val; return; @@ -1086,7 +1086,7 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) } else if (val == 0x12 || val == 0x34) { addr += svga->xga.write_bank; svga->xga.vram[addr & svga->xga.vram_mask] = val; - svga->xga.op_mode_reset = 1; + svga->xga.linear_endian_reverse = 1; return; } } else @@ -1277,7 +1277,7 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p) if (!linear) { if (xga_enabled) { - if (((svga->xga.op_mode & 7) == 4) && (svga->xga.aperture_cntl == 1)) { + if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl == 1)) { if (svga->xga.test == 0xa5) { /*Memory size test of XGA*/ svga->xga.on = 1; return svga->xga.test; From 5063cf1bb4484ae4cb857094e3ebaadad724c6a1 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 8 Jul 2022 00:17:46 +0600 Subject: [PATCH 24/31] PGC: Properly draw 40x25 CGA text mode --- src/video/vid_pgc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/video/vid_pgc.c b/src/video/vid_pgc.c index e956cb12e..d810536b3 100644 --- a/src/video/vid_pgc.c +++ b/src/video/vid_pgc.c @@ -2363,7 +2363,12 @@ pgc_cga_text(pgc_t *dev, int w) val = cols[(fontdatm[chr + dev->fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ 0x0f; else val = cols[(fontdatm[chr + dev->fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0]; - buffer32->line[dev->displine][(x * cw) + c] = val; + if (cw == 8) /* 80x25 CGA text screen. */ + buffer32->line[dev->displine][(x * cw) + c] = val; + else { /* 40x25 CGA text screen. */ + buffer32->line[dev->displine][(x * cw) + (c * 2)] = val; + buffer32->line[dev->displine][(x * cw) + (c * 2) + 1] = val; + } } ma++; From fe3061ff7aa081557ea35b3b405c9024d6db6aba Mon Sep 17 00:00:00 2001 From: Adrien Moulin Date: Thu, 7 Jul 2022 23:35:34 +0200 Subject: [PATCH 25/31] Add HDD timing simulation - realistic seeking and read/write speed - read-ahead cache - write cache - preset system for performance characteristics --- src/disk/hdd.c | 352 +++++++++++++++++++++++++++++++++++++++- src/include/86box/hdd.h | 78 +++++++++ 2 files changed, 428 insertions(+), 2 deletions(-) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index c2d619062..a9c840701 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -17,15 +17,19 @@ * Copyright 2017-2019 Fred N. van Kempen. */ #include -#include +#include #include +#include +#include +#include #include #include <86box/86box.h> #include <86box/plat.h> #include <86box/ui.h> #include <86box/hdd.h> #include <86box/cdrom.h> - +#include <86box/video.h> +#include "cpu.h" hard_disk_t hdd[HDD_NUM]; @@ -150,3 +154,347 @@ hdd_is_valid(int c) return(1); } + +double +hdd_seek_get_time(hard_disk_t *hdd, uint32_t dst_addr, uint8_t operation, uint8_t continuous, double max_seek_time) +{ + hdd_zone_t *zone = NULL; + for (int i = 0; i < hdd->num_zones; i++) { + zone = &hdd->zones[i]; + if (zone->end_sector >= dst_addr) + break; + } + + uint32_t new_track = zone->start_track + ((dst_addr - zone->start_sector) / zone->sectors_per_track); + uint32_t new_cylinder = new_track / hdd->phy_heads; + uint32_t cylinder_diff = abs((int)hdd->cur_cylinder - (int)new_cylinder); + + bool sequential = dst_addr == hdd->cur_addr + 1; + continuous = continuous && sequential; + + double seek_time = 0.0; + if (continuous) { + if (new_track == hdd->cur_track) { + // Same track + seek_time = zone->sector_time_usec; + } else if (!cylinder_diff) { + // Same cylinder, sequential track + seek_time = hdd->head_switch_usec; + } else { + // Sequential cylinder + seek_time = hdd->cyl_switch_usec; + } + } else { + if (!cylinder_diff) { + if (operation != HDD_OP_SEEK) { + seek_time = hdd->avg_rotation_lat_usec; + } else { + //seek_time = hdd->cyl_switch_usec; + seek_time = 50.0; + } + } else { + seek_time = hdd->cyl_switch_usec + (hdd->full_stroke_usec * (double)cylinder_diff / (double)hdd->phy_cyl); + if (operation != HDD_OP_SEEK) { + seek_time += hdd->avg_rotation_lat_usec; + } + } + } + + if (!max_seek_time || seek_time <= max_seek_time) { + hdd->cur_addr = dst_addr; + hdd->cur_track = new_track; + hdd->cur_cylinder = new_cylinder; + } + + return seek_time; +} + +static void +hdd_readahead_update(hard_disk_t *hdd) +{ + hdd_cache_t *cache = &hdd->cache; + if (cache->ra_ongoing) { + hdd_cache_seg_t *segment = &cache->segments[cache->ra_segment]; + + uint64_t elapsed_cycles = tsc - cache->ra_start_time; + double elapsed_us = (double)elapsed_cycles / cpuclock * 1000000.0; + // Do not overwrite data not yet read by host + uint32_t max_read_ahead = (segment->host_addr + cache->segment_size) - segment->ra_addr; + + double seek_time = 0.0; + + for (uint32_t i = 0; i < max_read_ahead; i++) { + seek_time += hdd_seek_get_time(hdd, segment->ra_addr, HDD_OP_READ, 1, elapsed_us - seek_time); + if (seek_time > elapsed_us) + break; + + segment->ra_addr++; + } + + if (segment->ra_addr > segment->lba_addr + cache->segment_size) { + uint32_t space_needed = segment->ra_addr - (segment->lba_addr + cache->segment_size); + segment->lba_addr += space_needed; + } + } +} + +static double +hdd_writecache_flush(hard_disk_t *hdd) +{ + double seek_time = 0.0; + while (hdd->cache.write_pending) { + seek_time += hdd_seek_get_time(hdd, hdd->cache.write_addr, HDD_OP_WRITE, 1, 0); + hdd->cache.write_addr++; + hdd->cache.write_pending--; + } + + return seek_time; +} + +static void +hdd_writecache_update(hard_disk_t *hdd) +{ + if (hdd->cache.write_pending) { + uint64_t elapsed_cycles = tsc - hdd->cache.write_start_time; + double elapsed_us = (double)elapsed_cycles / cpuclock * 1000000.0; + double seek_time = 0.0; + + while (hdd->cache.write_pending) { + seek_time += hdd_seek_get_time(hdd, hdd->cache.write_addr, HDD_OP_WRITE, 1, elapsed_us - seek_time); + if (seek_time > elapsed_us) + break; + + hdd->cache.write_addr++; + hdd->cache.write_pending--; + } + } +} + +double +hdd_timing_write(hard_disk_t *hdd, uint32_t addr, uint32_t len) +{ + hdd_readahead_update(hdd); + hdd_writecache_update(hdd); + + hdd->cache.ra_ongoing = 0; + + double seek_time = 0.0; + + if (hdd->cache.write_pending && (addr != (hdd->cache.write_addr + hdd->cache.write_pending))) { + // New request is not sequential to existing cache, need to flush it + seek_time += hdd_writecache_flush(hdd); + } + + if (!hdd->cache.write_pending) { + // Cache is empty + hdd->cache.write_addr = addr; + } + + hdd->cache.write_pending += len; + if (hdd->cache.write_pending > hdd->cache.write_size) { + // If request is bigger than free cache, flush some data first + uint32_t flush_needed = hdd->cache.write_pending - hdd->cache.write_size; + for (uint32_t i = 0; i < flush_needed; i++) { + seek_time += hdd_seek_get_time(hdd, hdd->cache.write_addr, HDD_OP_WRITE, 1, 0); + hdd->cache.write_addr++; + } + } + + hdd->cache.write_start_time = tsc + (uint32_t)(seek_time * cpuclock / 1000000.0); + + return seek_time; +} + +double +hdd_timing_read(hard_disk_t *hdd, uint32_t addr, uint32_t len) +{ + hdd_readahead_update(hdd); + hdd_writecache_update(hdd); + + double seek_time = 0.0; + seek_time += hdd_writecache_flush(hdd); + + hdd_cache_t *cache = &hdd->cache; + hdd_cache_seg_t *active_seg = &cache->segments[0]; + + for (uint32_t i = 0; i < cache->num_segments; i++) { + hdd_cache_seg_t *segment = &cache->segments[i]; + if (!segment->valid) { + active_seg = segment; + continue; + } + + if (segment->lba_addr <= addr && (segment->lba_addr + cache->segment_size) >= addr) { + // Cache HIT + segment->host_addr = addr; + active_seg = segment; + if (addr + len > segment->ra_addr) { + uint32_t need_read = (addr + len) - segment->ra_addr; + for (uint32_t j = 0; j < need_read; j++) { + seek_time += hdd_seek_get_time(hdd, segment->ra_addr, HDD_OP_READ, 1, 0.0); + segment->ra_addr++; + } + } + if (addr + len > segment->lba_addr + cache->segment_size) { + // Need to erase some previously cached data + uint32_t space_needed = (addr + len) - (segment->lba_addr + cache->segment_size); + segment->lba_addr += space_needed; + } + hit = true; + goto update_lru; + } else { + if (segment->lru > active_seg->lru) { + active_seg = segment; + } + } + } + + // Cache MISS + active_seg->lba_addr = addr; + active_seg->valid = 1; + active_seg->host_addr = addr; + active_seg->ra_addr = addr; + + for (uint32_t i = 0; i < len; i++) { + seek_time += hdd_seek_get_time(hdd, active_seg->ra_addr, HDD_OP_READ, i != 0, 0.0); + active_seg->ra_addr++; + } + +update_lru: + for (uint32_t i = 0; i < cache->num_segments; i++) { + cache->segments[i].lru++; + } + + active_seg->lru = 0; + + cache->ra_ongoing = 1; + cache->ra_segment = active_seg->id; + cache->ra_start_time = tsc + (uint32_t)(seek_time * cpuclock / 1000000.0); + + return seek_time; +} + +static void +hdd_cache_init(hard_disk_t *hdd) +{ + hdd_cache_t *cache = &hdd->cache; + cache->ra_segment = 0; + cache->ra_ongoing = 0; + cache->ra_start_time = 0; + + for (uint32_t i = 0; i < cache->num_segments; i++) { + cache->segments[i].valid = 0; + cache->segments[i].lru = 0; + cache->segments[i].id = i; + cache->segments[i].ra_addr = 0; + cache->segments[i].host_addr = 0; + } +} + +static void +hdd_zones_init(hard_disk_t *hdd) +{ + uint32_t lba = 0; + uint32_t track = 0; + + double revolution_usec = 60.0 / (double)hdd->rpm * 1000000.0; + for (uint32_t i = 0; i < hdd->num_zones; i++) { + hdd_zone_t *zone = &hdd->zones[i]; + zone->start_sector = lba; + zone->start_track = track; + zone->sector_time_usec = revolution_usec / (double)zone->sectors_per_track; + uint32_t tracks = zone->cylinders * hdd->phy_heads; + lba += tracks * zone->sectors_per_track; + zone->end_sector = lba - 1; + track += tracks - 1; + } +} + +hdd_preset_t hdd_presets[] = { + { .target_year = 1989, .match_max_mbyte = 99, .zones = 1, .avg_spt = 35, .heads = 2, .rpm = 3500, .full_stroke_ms = 40, .track_seek_ms = 8, + .rcache_num_seg = 1, .rcache_seg_size = 16, .max_multiple = 8 }, + + { .target_year = 1992, .match_max_mbyte = 249, .zones = 1, .avg_spt = 45, .heads = 2, .rpm = 3500, .full_stroke_ms = 30, .track_seek_ms = 6, + .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 8 }, + + { .target_year = 1994, .match_max_mbyte = 999, .zones = 8, .avg_spt = 80, .heads = 4, .rpm = 4500, .full_stroke_ms = 26, .track_seek_ms = 5, + .rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 16 }, + + { .target_year = 1996, .match_max_mbyte = 1999, .zones = 16, .avg_spt = 135, .heads = 4, .rpm = 5400, .full_stroke_ms = 24, .track_seek_ms = 3, + .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 }, + + { .target_year = 1997, .match_max_mbyte = 4999, .zones = 16, .avg_spt = 185, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2.5, + .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 32 }, + + { .target_year = 1998, .match_max_mbyte = 9999, .zones = 16, .avg_spt = 300, .heads = 8, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2, + .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, + + { .target_year = 2000, .match_max_mbyte = 99999, .zones = 16, .avg_spt = 350, .heads = 6, .rpm = 7200, .full_stroke_ms = 15, .track_seek_ms = 2, + .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 }, +}; + +void +hdd_preset_apply(hard_disk_t *hdd, hdd_preset_t *preset) +{ + hdd->phy_heads = preset->heads; + hdd->rpm = preset->rpm; + + double revolution_usec = 60.0 / (double)hdd->rpm * 1000000.0; + hdd->avg_rotation_lat_usec = revolution_usec / 2; + hdd->full_stroke_usec = preset->full_stroke_ms * 1000; + hdd->head_switch_usec = preset->track_seek_ms * 1000; + hdd->cyl_switch_usec = preset->track_seek_ms * 1000; + + hdd->cache.num_segments = preset->rcache_num_seg; + hdd->cache.segment_size = preset->rcache_seg_size; + hdd->max_multiple_block = preset->max_multiple; + + hdd->cache.write_size = 64; + + hdd->num_zones = preset->zones; + + uint32_t disk_sectors = hdd->tracks * hdd->hpc * hdd->spt; + uint32_t sectors_per_surface = (uint32_t)ceil((double)disk_sectors / (double)hdd->phy_heads); + uint32_t cylinders = (uint32_t)ceil((double)sectors_per_surface / (double)preset->avg_spt); + hdd->phy_cyl = cylinders; + uint32_t cylinders_per_zone = cylinders / preset->zones; + + uint32_t total_sectors = 0; + for (uint32_t i = 0; i < preset->zones; i++) { + uint32_t spt; + double zone_percent = i * 100 / (double)preset->zones; + + if (i < preset->zones - 1) { + // Function for realistic zone sector density + double spt_percent = -0.00341684 * pow(zone_percent, 2) - 0.175811 * zone_percent + 118.48; + spt = (uint32_t)ceil((double)preset->avg_spt * spt_percent / 100); + } else { + spt = (uint32_t)ceil((double)(disk_sectors - total_sectors) / (double)(cylinders_per_zone*preset->heads)); + } + + uint32_t zone_sectors = spt * cylinders_per_zone * preset->heads; + total_sectors += zone_sectors; + + hdd->zones[i].cylinders = cylinders_per_zone; + hdd->zones[i].sectors_per_track = spt; + } + + hdd_zones_init(hdd); + hdd_cache_init(hdd); +} + +void +hdd_preset_auto(hard_disk_t *hdd) +{ + uint32_t disk_sectors = hdd->tracks * hdd->hpc * hdd->spt; + uint32_t disk_size_mb = disk_sectors * 512 / 1024 / 1024; + int i; + for (i = 0; i < (sizeof(hdd_presets) / sizeof(hdd_presets[0])); i++) { + if (hdd_presets[i].match_max_mbyte >= disk_size_mb) + break; + } + + hdd_preset_t *preset = &hdd_presets[i]; + + hdd_preset_apply(hdd, preset); +} \ No newline at end of file diff --git a/src/include/86box/hdd.h b/src/include/86box/hdd.h index 96afcdde0..2a2a16bfc 100644 --- a/src/include/86box/hdd.h +++ b/src/include/86box/hdd.h @@ -72,6 +72,62 @@ enum { }; #endif +enum { + HDD_OP_SEEK = 0, + HDD_OP_READ, + HDD_OP_WRITE +}; + +#define HDD_MAX_ZONES 16 +#define HDD_MAX_CACHE_SEG 16 + +typedef struct { + uint32_t match_max_mbyte; + uint32_t zones; + uint32_t avg_spt; + uint32_t heads; + uint32_t rpm; + uint32_t target_year; + uint32_t rcache_num_seg; + uint32_t rcache_seg_size; + uint32_t max_multiple; + double full_stroke_ms; + double track_seek_ms; +} hdd_preset_t; + +typedef struct { + uint32_t id; + uint32_t lba_addr; + uint32_t ra_addr; + uint32_t host_addr; + uint8_t lru; + uint8_t valid; +} hdd_cache_seg_t; + +typedef struct { + // Read cache + hdd_cache_seg_t segments[HDD_MAX_CACHE_SEG]; + uint32_t num_segments; + uint32_t segment_size; + uint32_t ra_segment; + uint8_t ra_ongoing; + uint64_t ra_start_time; + + // Write cache + uint32_t write_addr; + uint32_t write_pending; + uint32_t write_size; + uint64_t write_start_time; +} hdd_cache_t; + +typedef struct { + uint32_t cylinders; + uint32_t sectors_per_track; + double sector_time_usec; + uint32_t start_sector; + uint32_t end_sector; + uint32_t start_track; +} hdd_zone_t; /* Define the virtual Hard Disk. */ typedef struct { @@ -100,6 +156,23 @@ typedef struct { spt, hpc, /* Physical geometry parameters */ tracks; + + hdd_zone_t zones[HDD_MAX_ZONES]; + uint32_t num_zones; + hdd_cache_t cache; + uint32_t phy_cyl; + uint32_t phy_heads; + uint32_t rpm; + uint8_t max_multiple_block; + + uint32_t cur_cylinder; + uint32_t cur_track; + uint32_t cur_addr; + + double avg_rotation_lat_usec; + double full_stroke_usec; + double head_switch_usec; + double cyl_switch_usec; } hard_disk_t; @@ -131,5 +204,10 @@ extern int image_is_hdi(const char *s); extern int image_is_hdx(const char *s, int check_signature); extern int image_is_vhd(const char *s, int check_signature); +extern double hdd_timing_write(hard_disk_t *hdd, uint32_t addr, uint32_t len); +extern double hdd_timing_read(hard_disk_t *hdd, uint32_t addr, uint32_t len); +extern double hdd_seek_get_time(hard_disk_t *hdd, uint32_t dst_addr, uint8_t operation, uint8_t continuous, double max_seek_time); +extern void hdd_preset_apply(hard_disk_t *hdd, hdd_preset_t *preset); +extern void hdd_preset_auto(hard_disk_t *hdd); #endif /*EMU_HDD_H*/ From 27d31c4d9985e9bfba0854c3cbd076e8908b3525 Mon Sep 17 00:00:00 2001 From: Adrien Moulin Date: Thu, 7 Jul 2022 23:38:45 +0200 Subject: [PATCH 26/31] Enable HDD timing simulation with IDE --- src/disk/hdc_ide.c | 144 +++++++++++++++++++++++------------- src/include/86box/hdc_ide.h | 3 +- 2 files changed, 94 insertions(+), 53 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index f80662c82..a4a9f2ddc 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -220,7 +220,7 @@ ide_get_drive(int ch) double -ide_get_period(ide_t *ide, int size) +ide_get_xfer_time(ide_t *ide, int size) { double period = (10.0 / 3.0); @@ -313,7 +313,7 @@ ide_atapi_get_period(uint8_t channel) return -1.0; } - return ide_get_period(ide, 1); + return ide_get_xfer_time(ide, 1); } @@ -535,7 +535,7 @@ static void ide_hd_identify(ide_t *ide) ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ ide->buffer[0] = (1 << 6); /*Fixed drive*/ ide->buffer[20] = 3; /*Buffer type*/ - ide->buffer[21] = 512; /*Buffer size*/ + ide->buffer[21] = hdd[ide->hdd_num].cache.num_segments * hdd[ide->hdd_num].cache.segment_size; /*Buffer size*/ ide->buffer[50] = 0x4000; /* Capabilities */ ide->buffer[59] = ide->blocksize ? (ide->blocksize | 0x100) : 0; @@ -577,12 +577,11 @@ static void ide_hd_identify(ide_t *ide) ide_log("Current CHS translation: %i, %i, %i\n", ide->buffer[54], ide->buffer[55], ide->buffer[56]); } + ide->buffer[47] = hdd[ide->hdd_num].max_multiple_block | 0x8000; /*Max sectors on multiple transfer command*/ if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board]) { - ide->buffer[47] = 32 | 0x8000; /*Max sectors on multiple transfer command*/ ide->buffer[80] = 0x7e; /*ATA-1 to ATA-6 supported*/ ide->buffer[81] = 0x19; /*ATA-6 revision 3a supported*/ } else { - ide->buffer[47] = 16 | 0x8000; /*Max sectors on multiple transfer command*/ ide->buffer[80] = 0x0e; /*ATA-1 to ATA-3 supported*/ } } @@ -692,13 +691,15 @@ ide_get_sector(ide_t *ide) uint32_t heads, sectors; if (ide->lba) - return (off64_t)ide->lba_addr + ide->skip512; + return (off64_t)ide->lba_addr; else { heads = ide->cfg_hpc; sectors = ide->cfg_spt; + uint8_t sector = ide->sector ? ide->sector : 1; + return ((((off64_t) ide->cylinder * heads) + ide->head) * - sectors) + (ide->sector - 1) + ide->skip512; + sectors) + (sector - 1); } } @@ -733,6 +734,8 @@ loadhd(ide_t *ide, int d, const char *fn) return; } + hdd_preset_auto(&hdd[d]); + ide->spt = ide->cfg_spt = hdd[d].spt; ide->hpc = ide->cfg_hpc = hdd[d].hpc; ide->tracks = hdd[d].tracks; @@ -1226,31 +1229,41 @@ ide_write_data(ide_t *ide, uint32_t val, int length) if (ide->type == IDE_ATAPI) ide_atapi_packet_write(ide, val, length); } else { - switch(length) { - case 1: - idebufferb[ide->pos] = val & 0xff; - ide->pos++; - break; - case 2: - idebufferw[ide->pos >> 1] = val & 0xffff; - ide->pos += 2; - break; - case 4: - idebufferl[ide->pos >> 2] = val; - ide->pos += 4; - break; - default: - return; - } + switch(length) { + case 1: + idebufferb[ide->pos] = val & 0xff; + ide->pos++; + break; + case 2: + idebufferw[ide->pos >> 1] = val & 0xffff; + ide->pos += 2; + break; + case 4: + idebufferl[ide->pos >> 2] = val; + ide->pos += 4; + break; + default: + return; + } - if (ide->pos >= 512) { - ide->pos=0; - ide->atastat = BSY_STAT; - if (ide->command == WIN_WRITE_MULTIPLE) - ide_callback(ide); - else - ide_set_callback(ide, ide_get_period(ide, 512)); - } + if (ide->pos >= 512) { + ide->pos=0; + ide->atastat = BSY_STAT; + double seek_time = hdd_timing_write(&hdd[ide->hdd_num], ide_get_sector(ide), 1); + double xfer_time = ide_get_xfer_time(ide, 512); + double wait_time = seek_time + xfer_time; + if (ide->command == WIN_WRITE_MULTIPLE) { + if ((ide->blockcount+1) >= ide->blocksize || ide->secount == 1) { + ide_set_callback(ide, seek_time + xfer_time + ide->pending_delay); + ide->pending_delay = 0; + } else { + ide->pending_delay += wait_time; + ide_callback(ide); + } + } else { + ide_set_callback(ide, wait_time); + } + } } } @@ -1601,9 +1614,13 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) else ide->atastat = READY_STAT | BSY_STAT; - if (ide->type == IDE_ATAPI) + if (ide->type == IDE_ATAPI) { ide->sc->callback = 100.0 * IDE_TIME; - ide_set_callback(ide, 100.0 * IDE_TIME); + ide_set_callback(ide, 100.0 * IDE_TIME); + } else { + double seek_time = hdd_seek_get_time(&hdd[ide->hdd_num], ide_get_sector(ide), HDD_OP_SEEK, 0, 0.0); + ide_set_callback(ide, seek_time); + } return; } @@ -1641,15 +1658,26 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) ide->atastat = BSY_STAT; if (ide->type == IDE_HDD) { + uint32_t sec_count; + double wait_time; if ((val == WIN_READ_DMA) || (val == WIN_READ_DMA_ALT)) { - if (ide->secount) - ide_set_callback(ide, ide_get_period(ide, (int) ide->secount << 9)); - else - ide_set_callback(ide, ide_get_period(ide, 131072)); - } else if (val == WIN_READ_MULTIPLE) - ide_set_callback(ide, 200.0 * IDE_TIME); - else - ide_set_callback(ide, ide_get_period(ide, 512)); + // TODO make DMA timing more accurate + sec_count = ide->secount ? ide->secount : 256; + double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); + double xfer_time = ide_get_xfer_time(ide, 512 * sec_count); + wait_time = seek_time > xfer_time ? seek_time : xfer_time; + } else if (val == WIN_READ_MULTIPLE) { + sec_count = (ide->secount < ide->blocksize) ? ide->secount : ide->blocksize; + double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); + double xfer_time = ide_get_xfer_time(ide, 512 * sec_count); + wait_time = seek_time + xfer_time; + } else { + sec_count = 1; + double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); + double xfer_time = ide_get_xfer_time(ide, 512 * sec_count); + wait_time = seek_time + xfer_time; + } + ide_set_callback(ide, wait_time); } else ide_set_callback(ide, 200.0 * IDE_TIME); ide->do_initial_read = 1; @@ -1690,14 +1718,16 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) if ((ide->type == IDE_HDD) && ((val == WIN_WRITE_DMA) || (val == WIN_WRITE_DMA_ALT))) { - if (ide->secount) - ide_set_callback(ide, ide_get_period(ide, (int) ide->secount << 9)); - else - ide_set_callback(ide, ide_get_period(ide, 131072)); + uint32_t sec_count = ide->secount ? ide->secount : 256; + double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); + double xfer_time = ide_get_xfer_time(ide, 512 * sec_count); + double wait_time = seek_time > xfer_time ? seek_time : xfer_time; + ide_set_callback(ide, wait_time); } else if ((ide->type == IDE_HDD) && - ((val == WIN_VERIFY) || (val == WIN_VERIFY_ONCE))) - ide_set_callback(ide, ide_get_period(ide, 512)); - else if (val == WIN_IDENTIFY) + ((val == WIN_VERIFY) || (val == WIN_VERIFY_ONCE))) { + double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), ide->secount); + ide_set_callback(ide, seek_time + ide_get_xfer_time(ide, 2)); + } else if (val == WIN_IDENTIFY) ide_callback(ide); else ide_set_callback(ide, 200.0 * IDE_TIME); @@ -1864,10 +1894,20 @@ ide_read_data(ide_t *ide, int length) if (ide->secount) { ide_next_sector(ide); ide->atastat = BSY_STAT | READY_STAT | DSC_STAT; - if (ide->command == WIN_READ_MULTIPLE) - ide_callback(ide); - else - ide_set_callback(ide, ide_get_period(ide, 512)); + if (ide->command == WIN_READ_MULTIPLE) { + if (!ide->blockcount) { + uint32_t sec_count = (ide->secount < ide->blocksize) ? ide->secount : ide->blocksize; + double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); + double xfer_time = ide_get_xfer_time(ide, 512 * sec_count); + ide_set_callback(ide, seek_time + xfer_time); + } else { + ide_callback(ide); + } + } else { + double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), 1); + double xfer_time = ide_get_xfer_time(ide, 512); + ide_set_callback(ide, seek_time + xfer_time); + } } else if (ide->command != WIN_READ_MULTIPLE) ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); } diff --git a/src/include/86box/hdc_ide.h b/src/include/86box/hdc_ide.h index 8f1b3551a..840e5daad 100644 --- a/src/include/86box/hdc_ide.h +++ b/src/include/86box/hdc_ide.h @@ -49,7 +49,7 @@ typedef struct ide_s { blocksize, blockcount, hdd_num, channel, pos, sector_pos, - lba, skip512, + lba, reset, mdma_mode, do_initial_read; uint32_t secount, sector, @@ -67,6 +67,7 @@ typedef struct ide_s { /* Stuff mostly used by ATAPI */ scsi_common_t *sc; int interrupt_drq; + double pending_delay; int (*get_max)(int ide_has_dma, int type); int (*get_timings)(int ide_has_dma, int type); From 4c93710d793cbcba2e230f4f0273490fc097f598 Mon Sep 17 00:00:00 2001 From: Adrien Moulin Date: Thu, 7 Jul 2022 23:58:02 +0200 Subject: [PATCH 27/31] Fix build error --- src/disk/hdd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index a9c840701..1b63a83e9 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -340,7 +340,6 @@ hdd_timing_read(hard_disk_t *hdd, uint32_t addr, uint32_t len) uint32_t space_needed = (addr + len) - (segment->lba_addr + cache->segment_size); segment->lba_addr += space_needed; } - hit = true; goto update_lru; } else { if (segment->lru > active_seg->lru) { From 0dc77c923895cb69ee93130791b0cfa03c6cb3cd Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Thu, 7 Jul 2022 17:25:35 -0400 Subject: [PATCH 28/31] XGA+XGA2 in win32 UI --- src/include/86box/resource.h | 3 +++ src/win/languages/cs-CZ.rc | 1 + src/win/languages/de-DE.rc | 1 + src/win/languages/dialogs.rc | 6 ++++++ src/win/languages/en-GB.rc | 1 + src/win/languages/en-US.rc | 1 + src/win/languages/es-ES.rc | 1 + src/win/languages/fi-FI.rc | 1 + src/win/languages/fr-FR.rc | 1 + src/win/languages/hr-HR.rc | 1 + src/win/languages/hu-HU.rc | 1 + src/win/languages/it-IT.rc | 1 + src/win/languages/ja-JP.rc | 1 + src/win/languages/ko-KR.rc | 1 + src/win/languages/pl-PL.rc | 1 + src/win/languages/pt-BR.rc | 1 + src/win/languages/pt-PT.rc | 1 + src/win/languages/ru-RU.rc | 1 + src/win/languages/sl-SI.rc | 1 + src/win/languages/tr-TR.rc | 1 + src/win/languages/uk-UA.rc | 1 + src/win/languages/zh-CN.rc | 1 + src/win/win_settings.c | 26 +++++++++++++++++++++++++- 23 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/include/86box/resource.h b/src/include/86box/resource.h index cd4eb1f83..75d056ea1 100644 --- a/src/include/86box/resource.h +++ b/src/include/86box/resource.h @@ -18,6 +18,7 @@ * Copyright 2008-2019 Sarah Walker. * Copyright 2016-2019 Miran Grca. * Copyright 2018,2019 David Hrdlička. + * Copyright 2021-2022 Jasmine Iwanek. */ #ifndef WIN_RESOURCE_H @@ -184,6 +185,8 @@ #define IDC_CHECK_VOODOO 1022 #define IDC_BUTTON_VOODOO 1023 #define IDC_CHECK_IBM8514 1024 +#define IDC_CHECK_XGA 1025 +#define IDC_BUTTON_XGA 1026 #define IDC_INPUT 1030 /* input config */ #define IDC_COMBO_MOUSE 1031 diff --git a/src/win/languages/cs-CZ.rc b/src/win/languages/cs-CZ.rc index 73d4effe1..a28b99a84 100644 --- a/src/win/languages/cs-CZ.rc +++ b/src/win/languages/cs-CZ.rc @@ -272,6 +272,7 @@ END #define STR_VIDEO "Grafika:" #define STR_VOODOO "Použít grafický akcelerátor Voodoo" #define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_XGA "XGA Graphics" #define STR_MOUSE "Myš:" #define STR_JOYSTICK "Joystick:" diff --git a/src/win/languages/de-DE.rc b/src/win/languages/de-DE.rc index 72ad32e54..27644e4a7 100644 --- a/src/win/languages/de-DE.rc +++ b/src/win/languages/de-DE.rc @@ -272,6 +272,7 @@ END #define STR_VIDEO "Videokarte:" #define STR_VOODOO "Voodoo-Grafik" #define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_XGA "XGA Graphics" #define STR_MOUSE "Maus:" #define STR_JOYSTICK "Joystick:" diff --git a/src/win/languages/dialogs.rc b/src/win/languages/dialogs.rc index 9d01e4cdf..8de358c5e 100644 --- a/src/win/languages/dialogs.rc +++ b/src/win/languages/dialogs.rc @@ -269,6 +269,12 @@ BEGIN CONTROL STR_IBM8514, IDC_CHECK_IBM8514, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 7, 46, 199, CFG_CHECKBOX_HEIGHT + + CONTROL STR_XGA, IDC_CHECK_XGA, + "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + 7, 65, 199, CFG_CHECKBOX_HEIGHT + PUSHBUTTON STR_CONFIGURE, IDC_BUTTON_XGA, + CFG_COMBO_BTN_LEFT, 64, CFG_BTN_WIDTH, CFG_BTN_HEIGHT END DLG_CFG_INPUT DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT diff --git a/src/win/languages/en-GB.rc b/src/win/languages/en-GB.rc index 82cb16cc5..fbbb982cf 100644 --- a/src/win/languages/en-GB.rc +++ b/src/win/languages/en-GB.rc @@ -272,6 +272,7 @@ END #define STR_VIDEO "Video:" #define STR_VOODOO "Voodoo Graphics" #define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_XGA "XGA Graphics" #define STR_MOUSE "Mouse:" #define STR_JOYSTICK "Joystick:" diff --git a/src/win/languages/en-US.rc b/src/win/languages/en-US.rc index ac3682818..5a5839686 100644 --- a/src/win/languages/en-US.rc +++ b/src/win/languages/en-US.rc @@ -272,6 +272,7 @@ END #define STR_VIDEO "Video:" #define STR_VOODOO "Voodoo Graphics" #define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_XGA "XGA Graphics" #define STR_MOUSE "Mouse:" #define STR_JOYSTICK "Joystick:" diff --git a/src/win/languages/es-ES.rc b/src/win/languages/es-ES.rc index b5161aad0..b7eb61d24 100644 --- a/src/win/languages/es-ES.rc +++ b/src/win/languages/es-ES.rc @@ -272,6 +272,7 @@ END #define STR_VIDEO "Vídeo:" #define STR_VOODOO "Voodoo Graphics" #define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_XGA "XGA Graphics" #define STR_MOUSE "Ratón:" #define STR_JOYSTICK "Mando:" diff --git a/src/win/languages/fi-FI.rc b/src/win/languages/fi-FI.rc index 8b394f550..a8dc55b72 100644 --- a/src/win/languages/fi-FI.rc +++ b/src/win/languages/fi-FI.rc @@ -272,6 +272,7 @@ END #define STR_VIDEO "Näytönohjain:" #define STR_VOODOO "Voodoo-grafiikkasuoritin" #define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_XGA "XGA Graphics" #define STR_MOUSE "Hiiri:" #define STR_JOYSTICK "Peliohjain:" diff --git a/src/win/languages/fr-FR.rc b/src/win/languages/fr-FR.rc index e63bb831a..11fc3360e 100644 --- a/src/win/languages/fr-FR.rc +++ b/src/win/languages/fr-FR.rc @@ -272,6 +272,7 @@ END #define STR_VIDEO "Vidéo:" #define STR_VOODOO "Graphique Voodoo" #define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_XGA "XGA Graphics" #define STR_MOUSE "Souris:" #define STR_JOYSTICK "Manette de commande:" diff --git a/src/win/languages/hr-HR.rc b/src/win/languages/hr-HR.rc index da3954cd1..60e6e28c4 100644 --- a/src/win/languages/hr-HR.rc +++ b/src/win/languages/hr-HR.rc @@ -272,6 +272,7 @@ END #define STR_VIDEO "Video:" #define STR_VOODOO "Voodoo grafika" #define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_XGA "XGA Graphics" #define STR_MOUSE "Miš:" #define STR_JOYSTICK "Palica za igru:" diff --git a/src/win/languages/hu-HU.rc b/src/win/languages/hu-HU.rc index 8ac86adff..6b4dae959 100644 --- a/src/win/languages/hu-HU.rc +++ b/src/win/languages/hu-HU.rc @@ -277,6 +277,7 @@ END #define STR_VIDEO "Videokártya:" #define STR_VOODOO "Voodoo-gyorsítókártya" #define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_XGA "XGA Graphics" #define STR_MOUSE "Egér:" #define STR_JOYSTICK "Játékvezérlő:" diff --git a/src/win/languages/it-IT.rc b/src/win/languages/it-IT.rc index 254491072..20d301f47 100644 --- a/src/win/languages/it-IT.rc +++ b/src/win/languages/it-IT.rc @@ -273,6 +273,7 @@ END #define STR_VIDEO "Video:" #define STR_VOODOO "Grafica Voodoo" #define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_XGA "XGA Graphics" #define STR_MOUSE "Mouse:" #define STR_JOYSTICK "Joystick:" diff --git a/src/win/languages/ja-JP.rc b/src/win/languages/ja-JP.rc index 01f0d7a24..151e13e65 100644 --- a/src/win/languages/ja-JP.rc +++ b/src/win/languages/ja-JP.rc @@ -272,6 +272,7 @@ END #define STR_VIDEO "ビデオカード:" #define STR_VOODOO "Voodooグラフィック" #define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_XGA "XGA Graphics" #define STR_MOUSE "マウス:" #define STR_JOYSTICK "ジョイスティック:" diff --git a/src/win/languages/ko-KR.rc b/src/win/languages/ko-KR.rc index c039e8129..831ca74bb 100644 --- a/src/win/languages/ko-KR.rc +++ b/src/win/languages/ko-KR.rc @@ -272,6 +272,7 @@ END #define STR_VIDEO "비디오 카드:" #define STR_VOODOO "Voodoo 그래픽" #define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_XGA "XGA Graphics" #define STR_MOUSE "마우스:" #define STR_JOYSTICK "조이스틱:" diff --git a/src/win/languages/pl-PL.rc b/src/win/languages/pl-PL.rc index 3c99f963d..211eb3ed8 100644 --- a/src/win/languages/pl-PL.rc +++ b/src/win/languages/pl-PL.rc @@ -272,6 +272,7 @@ END #define STR_VIDEO "Wideo:" #define STR_VOODOO "Grafika Voodoo" #define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_XGA "XGA Graphics" #define STR_MOUSE "Mysz:" #define STR_JOYSTICK "Joystick:" diff --git a/src/win/languages/pt-BR.rc b/src/win/languages/pt-BR.rc index ef75f2495..81b2e290a 100644 --- a/src/win/languages/pt-BR.rc +++ b/src/win/languages/pt-BR.rc @@ -275,6 +275,7 @@ END #define STR_VIDEO "Vídeo:" #define STR_VOODOO "3DFX Voodoo" #define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_XGA "XGA Graphics" #define STR_MOUSE "Mouse:" #define STR_JOYSTICK "Joystick:" diff --git a/src/win/languages/pt-PT.rc b/src/win/languages/pt-PT.rc index b2359b2e6..fafc21df4 100644 --- a/src/win/languages/pt-PT.rc +++ b/src/win/languages/pt-PT.rc @@ -272,6 +272,7 @@ END #define STR_VIDEO "Vídeo:" #define STR_VOODOO "Gráficos Voodoo" #define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_XGA "XGA Graphics" #define STR_MOUSE "Rato:" #define STR_JOYSTICK "Joystick:" diff --git a/src/win/languages/ru-RU.rc b/src/win/languages/ru-RU.rc index c3c24575e..15bd1752d 100644 --- a/src/win/languages/ru-RU.rc +++ b/src/win/languages/ru-RU.rc @@ -272,6 +272,7 @@ END #define STR_VIDEO "Видеокарта:" #define STR_VOODOO "Ускоритель Voodoo" #define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_XGA "XGA Graphics" #define STR_MOUSE "Мышь:" #define STR_JOYSTICK "Джойстик:" diff --git a/src/win/languages/sl-SI.rc b/src/win/languages/sl-SI.rc index b4fdba000..7d715c5ca 100644 --- a/src/win/languages/sl-SI.rc +++ b/src/win/languages/sl-SI.rc @@ -272,6 +272,7 @@ END #define STR_VIDEO "Video:" #define STR_VOODOO "Voodoo grafika" #define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_XGA "XGA Graphics" #define STR_MOUSE "Miška:" #define STR_JOYSTICK "Igralna palica:" diff --git a/src/win/languages/tr-TR.rc b/src/win/languages/tr-TR.rc index 8368380bb..cc3a98406 100644 --- a/src/win/languages/tr-TR.rc +++ b/src/win/languages/tr-TR.rc @@ -272,6 +272,7 @@ END #define STR_VIDEO "Ekran kartı:" #define STR_VOODOO "Voodoo Grafikleri" #define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_XGA "XGA Graphics" #define STR_MOUSE "Fare:" #define STR_JOYSTICK "Oyun kolu:" diff --git a/src/win/languages/uk-UA.rc b/src/win/languages/uk-UA.rc index b2a091cbe..dfb86cc8b 100644 --- a/src/win/languages/uk-UA.rc +++ b/src/win/languages/uk-UA.rc @@ -272,6 +272,7 @@ END #define STR_VIDEO "Відеокарта:" #define STR_VOODOO "Прискорювач Voodoo" #define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_XGA "XGA Graphics" #define STR_MOUSE "Миша:" #define STR_JOYSTICK "Джойстик:" diff --git a/src/win/languages/zh-CN.rc b/src/win/languages/zh-CN.rc index 14497df62..a3c324c6c 100644 --- a/src/win/languages/zh-CN.rc +++ b/src/win/languages/zh-CN.rc @@ -272,6 +272,7 @@ END #define STR_VIDEO "显卡:" #define STR_VOODOO "Voodoo Graphics" #define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_XGA "XGA Graphics" #define STR_MOUSE "鼠标:" #define STR_JOYSTICK "操纵杆:" diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 29cc23198..84ad26754 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -16,6 +16,7 @@ * Copyright 2016-2019 Miran Grca. * Copyright 2018,2019 David Hrdlička. * Copyright 2021 Laci bá' + * Copyright 2021-2022 Jasmine Iwanek. */ #define UNICODE #define BITMAP WINDOWS_BITMAP @@ -63,6 +64,7 @@ #include <86box/midi.h> #include <86box/snd_mpu401.h> #include <86box/video.h> +#include <86box/vid_xga_device.h> #include <86box/plat.h> #include <86box/ui.h> #include <86box/win.h> @@ -85,7 +87,7 @@ static int temp_dynarec; #endif /* Video category */ -static int temp_gfxcard, temp_ibm8514, temp_voodoo; +static int temp_gfxcard, temp_ibm8514, temp_voodoo, temp_xga; /* Input devices category */ static int temp_mouse, temp_joystick; @@ -333,6 +335,7 @@ win_settings_init(void) temp_gfxcard = gfxcard; temp_voodoo = voodoo_enabled; temp_ibm8514 = ibm8514_enabled; + temp_xga = xga_enabled; /* Input devices category */ temp_mouse = mouse_type; @@ -458,6 +461,7 @@ win_settings_changed(void) i = i || (gfxcard != temp_gfxcard); i = i || (voodoo_enabled != temp_voodoo); i = i || (ibm8514_enabled != temp_ibm8514); + i = i || (xga_enabled != temp_xga); /* Input devices category */ i = i || (mouse_type != temp_mouse); @@ -549,6 +553,7 @@ win_settings_save(void) gfxcard = temp_gfxcard; voodoo_enabled = temp_voodoo; ibm8514_enabled = temp_ibm8514; + xga_enabled = temp_xga; /* Input devices category */ mouse_type = temp_mouse; @@ -1116,6 +1121,11 @@ win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) settings_enable_window(hdlg, IDC_CHECK_IBM8514, machine_has_bus(temp_machine, MACHINE_BUS_ISA16) || machine_has_bus(temp_machine, MACHINE_BUS_MCA)); settings_set_check(hdlg, IDC_CHECK_IBM8514, temp_ibm8514); + + settings_enable_window(hdlg, IDC_CHECK_XGA, machine_has_bus(temp_machine, MACHINE_BUS_ISA16) || machine_has_bus(temp_machine, MACHINE_BUS_MCA)); + settings_set_check(hdlg, IDC_CHECK_XGA, temp_xga); + settings_enable_window(hdlg, IDC_BUTTON_XGA, (machine_has_bus(temp_machine, MACHINE_BUS_ISA16) || machine_has_bus(temp_machine, MACHINE_BUS_MCA)) && temp_xga); + return TRUE; case WM_COMMAND: @@ -1134,10 +1144,23 @@ win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) temp_ibm8514 = settings_get_check(hdlg, IDC_CHECK_IBM8514); break; + case IDC_CHECK_XGA: + temp_xga = settings_get_check(hdlg, IDC_CHECK_XGA); + settings_enable_window(hdlg, IDC_BUTTON_XGA, temp_xga); + break; + case IDC_BUTTON_VOODOO: temp_deviceconfig |= deviceconfig_open(hdlg, (void *)&voodoo_device); break; + case IDC_BUTTON_XGA: + if (machine_has_bus(temp_machine, MACHINE_BUS_MCA) > 0) { + temp_deviceconfig |= deviceconfig_open(hdlg, (void *)&xga_device); + } else { + temp_deviceconfig |= deviceconfig_open(hdlg, (void *)&xga_isa_device); + } + break; + case IDC_CONFIGURE_VID: temp_gfxcard = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO)]; temp_deviceconfig |= deviceconfig_open(hdlg, (void *)video_card_getdevice(temp_gfxcard)); @@ -1149,6 +1172,7 @@ win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) temp_gfxcard = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO)]; temp_voodoo = settings_get_check(hdlg, IDC_CHECK_VOODOO); temp_ibm8514 = settings_get_check(hdlg, IDC_CHECK_IBM8514); + temp_xga = settings_get_check(hdlg, IDC_CHECK_XGA); default: return FALSE; From 604d719fb7aa861843556ebabbd7a2d12c1169b8 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 8 Jul 2022 17:41:44 -0400 Subject: [PATCH 29/31] actuall build PAS16 on win32ui dev builds --- src/win/Makefile.mingw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 9c52afaaa..f44df8dde 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -71,7 +71,7 @@ ifeq ($(DEV_BUILD), y) OPEN_AT := y endif ifndef PAS16 - PAS16 := n + PAS16 := y endif ifndef SIO_DETECT SIO_DETECT := y From 62fd0feba14d3fa29a79cf209c1c76ea7a64c2dd Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 9 Jul 2022 13:51:12 +0600 Subject: [PATCH 30/31] qt: Make fatal messageboxes have the correct icons Fatals now exit the emulator properly --- src/qt/qt_mainwindow.cpp | 16 ++++++++++++---- src/qt/qt_mainwindow.hpp | 6 +++--- src/qt/qt_ui.cpp | 2 +- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index f0db0f019..a290a7b4c 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -36,6 +36,7 @@ extern "C" { #include <86box/config.h> #include <86box/keyboard.h> #include <86box/plat.h> +#include <86box/ui.h> #include <86box/discord.h> #include <86box/video.h> #include <86box/machine.h> @@ -1448,18 +1449,25 @@ void MainWindow::refreshMediaMenu() { ui->actionMCA_devices->setVisible(machine_has_bus(machine, MACHINE_BUS_MCA)); } -void MainWindow::showMessage(const QString& header, const QString& message) { +void MainWindow::showMessage(int flags, const QString& header, const QString& message) { if (QThread::currentThread() == this->thread()) { - showMessage_(header, message); + showMessage_(flags, header, message); } else { - emit showMessageForNonQtThread(header, message); + emit showMessageForNonQtThread(flags, header, message); } } -void MainWindow::showMessage_(const QString &header, const QString &message) { +void MainWindow::showMessage_(int flags, const QString &header, const QString &message) { QMessageBox box(QMessageBox::Warning, header, message, QMessageBox::NoButton, this); + if (flags & (MBX_FATAL)) { + box.setIcon(QMessageBox::Critical); + } + else if (!(flags & (MBX_ERROR | MBX_WARNING))) { + box.setIcon(QMessageBox::Warning); + } box.setTextFormat(Qt::TextFormat::RichText); box.exec(); + if (cpu_thread_run == 0) QApplication::exit(-1); } void MainWindow::keyPressEvent(QKeyEvent* event) diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index ffecdd773..ff16e6e88 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -24,7 +24,7 @@ public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); - void showMessage(const QString& header, const QString& message); + void showMessage(int flags, const QString& header, const QString& message); void getTitle(wchar_t* title); void blitToWidget(int x, int y, int w, int h); QSize getRenderWidgetSize(); @@ -45,7 +45,7 @@ signals: void setFullscreen(bool state); void setMouseCapture(bool state); - void showMessageForNonQtThread(const QString& header, const QString& message); + void showMessageForNonQtThread(int flags, const QString& header, const QString& message); void getTitleForNonQtThread(wchar_t* title); public slots: void showSettings(); @@ -100,7 +100,7 @@ private slots: void on_actionRenderer_options_triggered(); void refreshMediaMenu(); - void showMessage_(const QString& header, const QString& message); + void showMessage_(int flags, const QString& header, const QString& message); void getTitle_(wchar_t* title); void on_actionMCA_devices_triggered(); diff --git a/src/qt/qt_ui.cpp b/src/qt/qt_ui.cpp index 413057334..754e09e89 100644 --- a/src/qt/qt_ui.cpp +++ b/src/qt/qt_ui.cpp @@ -93,7 +93,7 @@ int ui_msgbox_header(int flags, void *header, void* message) { msgBox.exec(); } else { // else scope it to main_window - main_window->showMessage(hdr, msg); + main_window->showMessage(flags, hdr, msg); } return 0; } From 333e99113bb28da2ac59fa770ddbbe6ace099ed5 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 9 Jul 2022 23:19:18 +0200 Subject: [PATCH 31/31] IBM ESDI MCA, 8514/A, XGA and Rancho changes: ESDI MCA: Increased esdi_time from 200 to 512, should fix the timeout that caused the bad attention 03 fatal. Rancho: Added the Rancho RT1000B-MC MCA SCSI controller, it uses the 8.20R BIOS. 8514/A: Reworked the Outline command to satisfy the manual and the win2.10 (286/386) driver. XGA: Initial rom len is set to 0x8000 (which, after being configured, is set back to 0x2000) just to not make it hang with POST code 40 25 on most configurations. --- src/disk/hdc_esdi_mca.c | 30 ++-- src/include/86box/scsi_ncr5380.h | 1 + src/include/86box/vid_8514a.h | 4 +- src/scsi/scsi.c | 1 + src/scsi/scsi_ncr5380.c | 128 +++++++++++++- src/video/vid_8514a.c | 277 ++++++------------------------- src/video/vid_xga.c | 4 +- 7 files changed, 201 insertions(+), 244 deletions(-) diff --git a/src/disk/hdc_esdi_mca.c b/src/disk/hdc_esdi_mca.c index 3c29a9265..9d2881294 100644 --- a/src/disk/hdc_esdi_mca.c +++ b/src/disk/hdc_esdi_mca.c @@ -86,15 +86,15 @@ #define ESDI_IOADDR_SEC 0x3518 #define ESDI_IRQCHAN 14 -#define BIOS_FILE_L "roms/hdd/esdi/90x8969.bin" -#define BIOS_FILE_H "roms/hdd/esdi/90x8970.bin" +#define BIOS_FILE_L "roms/hdd/esdi/62-000193-036.BIN" +#define BIOS_FILE_H "roms/hdd/esdi/62-000194-036.BIN" -#define ESDI_TIME (200*TIMER_USEC) +#define ESDI_TIME 512 #define CMD_ADAPTER 0 -typedef struct esdi_drive { +typedef struct esdi_drive_t { int spt, hpc; int tracks; int sectors; @@ -102,7 +102,7 @@ typedef struct esdi_drive { int hdd_num; } drive_t; -typedef struct esdi { +typedef struct esdi_t { int8_t dma; uint32_t bios; @@ -133,7 +133,7 @@ typedef struct esdi { int command; int cmd_state; - int in_reset; + int in_reset, in_reset2; uint64_t callback; pc_timer_t timer; @@ -240,10 +240,10 @@ esdi_mca_set_callback(esdi_t *dev, uint64_t callback) if (callback) { dev->callback = callback; - timer_set_delay_u64(&dev->timer, dev->callback); + timer_on_auto(&dev->timer, dev->callback); } else { dev->callback = 0; - timer_disable(&dev->timer); + timer_stop(&dev->timer); } } @@ -824,11 +824,18 @@ esdi_read(uint16_t port, void *priv) uint8_t ret = 0xff; switch (port & 7) { - case 2: /*Basic status register*/ + case 2: /*Basic status register*/ + if (!dev->status) { + if (((dev->command == CMD_WRITE) || dev->in_reset2) && !dev->cmd_dev) { + dev->in_reset2 = 0; + dev->status |= STATUS_STATUS_OUT_FULL; + } else if (dev->command && (dev->cmd_dev == ATTN_HOST_ADAPTER)) + dev->status |= STATUS_STATUS_OUT_FULL; + } ret = dev->status; break; - case 3: /*IRQ status*/ + case 3: /*IRQ status*/ dev->status &= ~STATUS_IRQ; ret = dev->irq_status; break; @@ -852,6 +859,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv) case 2: /*Basic control register*/ if ((dev->basic_ctrl & CTRL_RESET) && !(val & CTRL_RESET)) { dev->in_reset = 1; + dev->in_reset2 = 1; esdi_mca_set_callback(dev, ESDI_TIME * 50); dev->status = STATUS_BUSY; } @@ -883,6 +891,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv) case ATTN_RESET: dev->in_reset = 1; + dev->in_reset2 = 1; esdi_mca_set_callback(dev, ESDI_TIME * 50); dev->status = STATUS_BUSY; break; @@ -1143,6 +1152,7 @@ esdi_init(const device_t *info) /* Mark for a reset. */ dev->in_reset = 1; + dev->in_reset2 = 1; esdi_mca_set_callback(dev, ESDI_TIME * 50); dev->status = STATUS_BUSY; diff --git a/src/include/86box/scsi_ncr5380.h b/src/include/86box/scsi_ncr5380.h index 6053e0275..5f6ded14b 100644 --- a/src/include/86box/scsi_ncr5380.h +++ b/src/include/86box/scsi_ncr5380.h @@ -26,6 +26,7 @@ extern const device_t scsi_lcs6821n_device; extern const device_t scsi_rt1000b_device; +extern const device_t scsi_rt1000mc_device; extern const device_t scsi_t128_device; extern const device_t scsi_t130b_device; extern const device_t scsi_ls2000_device; diff --git a/src/include/86box/vid_8514a.h b/src/include/86box/vid_8514a.h index 0bb1e85cd..a9816ac4a 100644 --- a/src/include/86box/vid_8514a.h +++ b/src/include/86box/vid_8514a.h @@ -62,7 +62,7 @@ typedef struct ibm8514_t int x1, x2, y1, y2; int sys_cnt, sys_cnt2; int temp_cnt; - int16_t cx, cy; + int16_t cx, cy, oldcy; int16_t sx, sy; int16_t dx, dy; int16_t err; @@ -80,7 +80,7 @@ typedef struct ibm8514_t int odd_in, odd_out; uint16_t scratch; - int fill_state, fill_drop; + int fill_state, xdir, ydir; } accel; uint16_t test; diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index 675abff26..b6db9e051 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -86,6 +86,7 @@ static SCSI_CARD scsi_cards[] = { { &scsi_ls2000_device, }, { &scsi_lcs6821n_device, }, { &scsi_rt1000b_device, }, + { &scsi_rt1000mc_device, }, { &scsi_t128_device, }, { &scsi_t130b_device, }, #ifdef WALTJE diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index ce43a9cf2..387d650f1 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -156,6 +156,7 @@ typedef struct { double period; int ncr_busy; + uint8_t pos_regs[8]; } ncr5380_t; #define STATE_IDLE 0 @@ -1435,6 +1436,64 @@ t128_write(uint32_t addr, uint8_t val, void *priv) } } +static uint8_t +rt1000b_mc_read(int port, void *priv) +{ + ncr5380_t *ncr_dev = (ncr5380_t *)priv; + + return(ncr_dev->pos_regs[port & 7]); +} + + +static void +rt1000b_mc_write(int port, uint8_t val, void *priv) +{ + ncr5380_t *ncr_dev = (ncr5380_t *)priv; + + /* MCA does not write registers below 0x0100. */ + if (port < 0x0102) return; + + mem_mapping_disable(&ncr_dev->bios_rom.mapping); + mem_mapping_disable(&ncr_dev->mapping); + + /* Save the MCA register value. */ + ncr_dev->pos_regs[port & 7] = val; + + if (ncr_dev->pos_regs[2] & 1) { + switch (ncr_dev->pos_regs[2] & 0xe0) { + case 0: + ncr_dev->rom_addr = 0xd4000; + break; + case 0x20: + ncr_dev->rom_addr = 0xd0000; + break; + case 0x40: + ncr_dev->rom_addr = 0xcc000; + break; + case 0x60: + ncr_dev->rom_addr = 0xc8000; + break; + case 0xc0: + ncr_dev->rom_addr = 0xdc000; + break; + case 0xe0: + ncr_dev->rom_addr = 0xd8000; + break; + } + + mem_mapping_set_addr(&ncr_dev->bios_rom.mapping, ncr_dev->rom_addr, 0x4000); + mem_mapping_set_addr(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000); + } +} + +static uint8_t +rt1000b_mc_feedb(void *priv) +{ + ncr5380_t *ncr_dev = (ncr5380_t *)priv; + + return ncr_dev->pos_regs[2] & 1; +} + static void * ncr_init(const device_t *info) { @@ -1462,10 +1521,14 @@ ncr_init(const device_t *info) ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); break; - case 1: /* Rancho RT1000B */ + case 1: /* Rancho RT1000B/MC */ ncr_dev->rom_addr = device_get_config_hex20("bios_addr"); ncr_dev->irq = device_get_config_int("irq"); ncr_dev->bios_ver = device_get_config_int("bios_ver"); + if (info->flags & DEVICE_MCA) { + ncr_dev->rom_addr = 0xd8000; + ncr_dev->bios_ver = 1; + } if (ncr_dev->bios_ver == 1) fn = RT1000B_820R_ROM; @@ -1475,10 +1538,20 @@ ncr_init(const device_t *info) rom_init(&ncr_dev->bios_rom, fn, ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000, - memio_read, NULL, NULL, - memio_write, NULL, NULL, - ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); + if (info->flags & DEVICE_MCA) { + mem_mapping_add(&ncr_dev->mapping, 0, 0, + memio_read, NULL, NULL, + memio_write, NULL, NULL, + ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); + ncr_dev->pos_regs[0] = 0x8d; + ncr_dev->pos_regs[1] = 0x70; + mca_add(rt1000b_mc_read, rt1000b_mc_write, rt1000b_mc_feedb, NULL, ncr_dev); + } else { + mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000, + memio_read, NULL, NULL, + memio_write, NULL, NULL, + ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); + } break; case 2: /* Trantor T130B */ @@ -1580,6 +1653,12 @@ rt1000b_available(void) return(rom_present(RT1000B_820R_ROM) && rom_present(RT1000B_810R_ROM)); } +static int +rt1000b_820_available(void) +{ + return(rom_present(RT1000B_820R_ROM)); +} + static int t130b_available(void) { @@ -1611,6 +1690,8 @@ static const device_config_t ncr5380_mmio_config[] = { .selection = { { .description = "C800H", .value = 0xc8000 }, { .description = "CC00H", .value = 0xcc000 }, + { .description = "D000H", .value = 0xd0000 }, + { .description = "D400H", .value = 0xd4000 }, { .description = "D800H", .value = 0xd8000 }, { .description = "DC00H", .value = 0xdc000 }, { .description = "" } @@ -1646,6 +1727,8 @@ static const device_config_t rancho_config[] = { .selection = { { .description = "C800H", .value = 0xc8000 }, { .description = "CC00H", .value = 0xcc000 }, + { .description = "D000H", .value = 0xd0000 }, + { .description = "D400H", .value = 0xd4000 }, { .description = "D800H", .value = 0xd8000 }, { .description = "DC00H", .value = 0xdc000 }, { .description = "" } @@ -1683,6 +1766,25 @@ static const device_config_t rancho_config[] = { { .name = "", .description = "", .type = CONFIG_END } }; +static const device_config_t rancho_mc_config[] = { + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 5, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + static const device_config_t t130b_config[] = { { .name = "bios_addr", @@ -1747,6 +1849,8 @@ static const device_config_t t128_config[] = { .selection = { { .description = "C800H", .value = 0xc8000 }, { .description = "CC00H", .value = 0xcc000 }, + { .description = "D000H", .value = 0xd0000 }, + { .description = "D400H", .value = 0xd4000 }, { .description = "D800H", .value = 0xd8000 }, { .description = "DC00H", .value = 0xdc000 }, { .description = "" } @@ -1806,6 +1910,20 @@ const device_t scsi_rt1000b_device = { .config = rancho_config }; +const device_t scsi_rt1000mc_device = { + .name = "Rancho RT1000B-MC", + .internal_name = "rt1000mc", + .flags = DEVICE_MCA, + .local = 1, + .init = ncr_init, + .close = ncr_close, + .reset = NULL, + { .available = rt1000b_820_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = rancho_mc_config +}; + const device_t scsi_t130b_device = { .name = "Trantor T130B", .internal_name = "t130b", diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 4731132f1..7f1c7d770 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -2555,18 +2555,12 @@ rect_fill: if (!cpu_input) { dev->accel.cx = dev->accel.cur_x; dev->accel.cy = dev->accel.cur_y; + dev->accel.oldcy = dev->accel.cy; - dev->accel.sy = dev->accel.maj_axis_pcnt; + dev->accel.xdir = (dev->accel.cmd & 0x20) ? 1 : -1; + dev->accel.ydir = (dev->accel.cmd & 0x80) ? 1 : -1; - if (dev->accel.cx < dev->accel.clip_left) - dev->accel.cx = dev->accel.clip_left; - else if (dev->accel.cx > clip_r) - dev->accel.cx = dev->accel.clip_left; - - dev->accel.sx = dev->accel.sy; - dev->accel.dx = dev->accel.destx_distp; - dev->accel.dy = dev->accel.desty_axstp; - dev->accel.err = dev->accel.err_term; + dev->accel.sy = 0; if (ibm8514_cpu_src(dev)) { dev->data_available = 0; @@ -2579,237 +2573,70 @@ rect_fill: } } - if (dev->accel.cmd & 8) { /*Vector Line*/ - while (count-- && (dev->accel.sy >= 0)) { - if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && - dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { - if (ibm8514_cpu_dest(dev) && (pixcntl == 0)) { - mix_dat = mix_mask; /* Mix data = forced to foreground register. */ - } else if (ibm8514_cpu_dest(dev) && (pixcntl == 3)) { - /* Mix data = current video memory value. */ - READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? mix_mask : 0; - } + while (count-- && (dev->accel.sy >= 0)) { + if (((dev->accel.cx) >= dev->accel.clip_left && (dev->accel.cx <= clip_r) && + (dev->accel.cy) >= dev->accel.clip_top && (dev->accel.cy) <= clip_b)) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: src_dat = bkgd_color; break; + case 1: src_dat = frgd_color; break; + case 2: src_dat = cpu_dat & 0xff; break; + case 3: src_dat = 0; break; + } - if (ibm8514_cpu_dest(dev)) { - READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, src_dat); - if (pixcntl == 3) - src_dat = ((src_dat & rd_mask) == rd_mask); - } else switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: src_dat = bkgd_color; break; - case 1: src_dat = frgd_color; break; - case 2: src_dat = cpu_dat & 0xff; break; - case 3: src_dat = 0; break; - } + READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & mix_mask, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if ((dev->accel.cmd & 4) && dev->accel.sy) { + if ((compare_mode == 0) || + ((compare_mode == 0x10) && (dest_dat >= compare)) || + ((compare_mode == 0x18) && (dest_dat < compare)) || + ((compare_mode == 0x20) && (dest_dat != compare)) || + ((compare_mode == 0x28) && (dest_dat == compare)) || + ((compare_mode == 0x30) && (dest_dat <= compare)) || + ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + MIX(mix_dat & mix_mask, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + if ((dev->accel.cmd & 4) && (dev->accel.sy < dev->accel.maj_axis_pcnt)) { + if (!dev->accel.sy) { WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { + } else if ((dev->accel.cmd & 0x40) && dev->accel.sy && (dev->accel.cy == dev->accel.oldcy + 1)) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 0x40) && dev->accel.sy && (dev->accel.err_term >= 0) && (dev->accel.cy == (dev->accel.oldcy + 1))) { WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); } } } - mix_dat <<= 1; - mix_dat |= 1; - cpu_dat >>= 8; - - if (dev->accel.sy == 0) { - break; - } - - switch (dev->accel.cmd & 0xe0) { - case 0x00: dev->accel.cx++; break; - case 0x20: dev->accel.cx++; dev->accel.cy--; break; - case 0x40: dev->accel.cy--; break; - case 0x60: dev->accel.cx--; dev->accel.cy--; break; - case 0x80: dev->accel.cx--; break; - case 0xa0: dev->accel.cx--; dev->accel.cy++; break; - case 0xc0: dev->accel.cy++; break; - case 0xe0: dev->accel.cx++; dev->accel.cy++; break; - } - - dev->accel.sy--; } - } else { /*Bresenham*/ - if (pixcntl == 1) { - dev->accel.temp_cnt = 8; - while (count-- && (dev->accel.sy >= 0)) { - if (dev->accel.temp_cnt == 0) { - dev->accel.temp_cnt = 8; - mix_dat = old_mix_dat; - } - if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && - dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { - if (ibm8514_cpu_dest(dev)) { - READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, src_dat); - } else switch ((mix_dat & 1) ? frgd_mix : bkgd_mix) { - case 0: src_dat = bkgd_color; break; - case 1: src_dat = frgd_color; break; - case 2: src_dat = cpu_dat & 0xff; break; - case 3: src_dat = 0; break; - } - READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + mix_dat <<= 1; + mix_dat |= 1; + cpu_dat >>= 8; - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & 1, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if ((dev->accel.cmd & 4) && dev->accel.sy) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } - } - } - dev->accel.temp_cnt--; - mix_dat >>= 1; - cpu_dat >>= 8; + if (dev->accel.sy == dev->accel.maj_axis_pcnt) { + return; + } - if (dev->accel.sy == 0) { - break; - } - - if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) { - dev->accel.err_term += dev->accel.destx_distp; - /*Step minor axis*/ - switch (dev->accel.cmd & 0xe0) { - case 0x00: dev->accel.cy--; break; - case 0x20: dev->accel.cy--; break; - case 0x40: dev->accel.cx--; break; - case 0x60: dev->accel.cx++; break; - case 0x80: dev->accel.cy++; break; - case 0xa0: dev->accel.cy++; break; - case 0xc0: dev->accel.cx--; break; - case 0xe0: dev->accel.cx++; break; - } - } else - dev->accel.err_term += dev->accel.desty_axstp; - - /*Step major axis*/ - switch (dev->accel.cmd & 0xe0) { - case 0x00: dev->accel.cx--; break; - case 0x20: dev->accel.cx++; break; - case 0x40: dev->accel.cy--; break; - case 0x60: dev->accel.cy--; break; - case 0x80: dev->accel.cx--; break; - case 0xa0: dev->accel.cx++; break; - case 0xc0: dev->accel.cy++; break; - case 0xe0: dev->accel.cy++; break; - } - - dev->accel.sy--; + if (dev->accel.cmd & 0x40) { + dev->accel.oldcy = dev->accel.cy; + dev->accel.cy += dev->accel.ydir; + if (dev->accel.err_term >= 0) { + dev->accel.err_term += dev->accel.destx_distp; + dev->accel.cx += dev->accel.xdir; + } else { + dev->accel.err_term += dev->accel.desty_axstp; } } else { - while (count-- && (dev->accel.sy >= 0)) { - if (dev->accel.cx < dev->accel.clip_left) - dev->accel.cx = dev->accel.clip_left; - else if (dev->accel.cx > clip_r) - dev->accel.cx = dev->accel.clip_left; - - if (((dev->accel.cx) >= dev->accel.clip_left && (dev->accel.cx) <= clip_r && - (dev->accel.cy) >= dev->accel.clip_top && (dev->accel.cy) <= clip_b)) { - if (ibm8514_cpu_dest(dev) && (pixcntl == 0)) { - mix_dat = mix_mask; /* Mix data = forced to foreground register. */ - } else if (ibm8514_cpu_dest(dev) && (pixcntl == 3)) { - /* Mix data = current video memory value. */ - READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? mix_mask : 0; - } - - if (ibm8514_cpu_dest(dev)) { - READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, src_dat); - if (pixcntl == 3) - src_dat = ((src_dat & rd_mask) == rd_mask); - } else switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: src_dat = bkgd_color; break; - case 1: src_dat = frgd_color; break; - case 2: src_dat = cpu_dat & 0xff; break; - case 3: src_dat = 0; break; - } - - READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & mix_mask, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if ((dev->accel.cmd & 4) && dev->accel.sy) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } - } - } - - mix_dat <<= 1; - mix_dat |= 1; - cpu_dat >>= 8; - - if (dev->accel.sy == 0) { - break; - } - - if (dev->accel.err >= dev->accel.sx) { - dev->accel.err += dev->accel.dx; - /*Step minor axis*/ - switch (dev->accel.cmd & 0xe0) { - case 0x00: dev->accel.cy--; break; - case 0x20: dev->accel.cy--; break; - case 0x40: dev->accel.cx--; break; - case 0x60: dev->accel.cx++; break; - case 0x80: dev->accel.cy++; break; - case 0xa0: dev->accel.cy++; break; - case 0xc0: dev->accel.cx--; break; - case 0xe0: dev->accel.cx++; break; - } - } else - dev->accel.err += dev->accel.dy; - - /*Step major axis*/ - switch (dev->accel.cmd & 0xe0) { - case 0x00: dev->accel.cx--; break; - case 0x20: dev->accel.cx++; break; - case 0x40: dev->accel.cy--; break; - case 0x60: dev->accel.cy--; break; - case 0x80: dev->accel.cx--; break; - case 0xa0: dev->accel.cx++; break; - case 0xc0: dev->accel.cy++; break; - case 0xe0: dev->accel.cy++; break; - } - - dev->accel.sy--; + dev->accel.cx += dev->accel.xdir; + if (dev->accel.err_term >= 0) { + dev->accel.err_term += dev->accel.destx_distp; + dev->accel.oldcy = dev->accel.cy; + dev->accel.cy += dev->accel.ydir; + } else { + dev->accel.err_term += dev->accel.desty_axstp; } } + + dev->accel.sy++; } - dev->accel.cur_x = dev->accel.cx; - dev->accel.cur_y = dev->accel.cy; break; case 6: /*BitBlt*/ diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 9bd6e3e8b..8edb7cca2 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -2704,7 +2704,7 @@ static void xga->on = 0; xga->hwcursor.xsize = 64; xga->hwcursor.ysize = 64; - xga->bios_rom.sz = 0x2000; + xga->bios_rom.sz = 0x8000; f = rom_fopen(xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, "rb"); (void)fseek(f, 0L, SEEK_END); @@ -2729,7 +2729,7 @@ static void xga->instance = 0; xga->rom_addr = 0; mem_mapping_add(&xga->bios_rom.mapping, - 0xdc000, xga->bios_rom.sz, + 0xd8000, xga->bios_rom.sz, rom_read, rom_readw, rom_readl, NULL, NULL, NULL, xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, &xga->bios_rom);