From aa7dee91bc127d910cb1c51a4c7737d83fff4df5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 20 Jan 2020 05:36:44 +0100 Subject: [PATCH] Reimplemented the ATi EGA wonder on the EGA code instead of (S)VGA, now it actually works and has the same configuration options as the other EGA cards. --- src/video/vid_ati18800.c | 140 ++++--------------------------------- src/video/vid_ati18800.h | 1 - src/video/vid_ati_eeprom.c | 8 +-- src/video/vid_ega.c | 132 +++++++++++++++++++++++++++++++--- src/video/vid_ega.h | 12 ++-- src/video/vid_svga.c | 115 ++++++++++++++++++++---------- src/video/vid_table.c | 4 +- 7 files changed, 228 insertions(+), 184 deletions(-) diff --git a/src/video/vid_ati18800.c b/src/video/vid_ati18800.c index cbec53d5d..a62129f7d 100644 --- a/src/video/vid_ati18800.c +++ b/src/video/vid_ati18800.c @@ -8,13 +8,13 @@ * * ATI 18800 emulation (VGA Edge-16) * - * Version: @(#)vid_ati18800.c 1.0.16 2020/01/19 + * Version: @(#)vid_ati18800.c 1.0.17 2020/01/20 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. */ #include #include @@ -39,18 +39,15 @@ #endif #define BIOS_ROM_PATH_VGA88 L"roms/video/ati18800/vga88.bin" #define BIOS_ROM_PATH_EDGE16 L"roms/video/ati18800/vgaedge16.vbi" -#define BIOS_ROM_PATH_EGAWONDER800P L"roms/video/ati18800/ATI EGA Wonder 800+ N1.00.BIN" enum { #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) ATI18800_WONDER = 0, ATI18800_VGA88, - ATI18800_EDGE16, - ATI18800_EGAWONDER800P + ATI18800_EDGE16 #else ATI18800_VGA88 = 0, - ATI18800_EDGE16, - ATI18800_EGAWONDER800P + ATI18800_EDGE16 #endif }; @@ -64,10 +61,6 @@ typedef struct ati18800_t uint8_t regs[256]; int index; - - int is_ega; - int ega_switches; - int ega_switch_read; } ati18800_t; static video_timings_t timing_ati18800 = {VIDEO_ISA, 8, 16, 32, 8, 16, 32}; @@ -78,8 +71,7 @@ static void ati18800_out(uint16_t addr, uint8_t val, void *p) ati18800_t *ati18800 = (ati18800_t *)p; svga_t *svga = &ati18800->svga; uint8_t old; - int c; - + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -111,41 +103,6 @@ static void ati18800_out(uint16_t addr, uint8_t val, void *p) } break; - case 0x3c2: - if (ati18800->is_ega) - { - if ((val & 0x80) != (svga->miscout & 0x80)) - { - if (val & 0x80) - { - for (c = 0; c < 256; c++) - { - svga->pallook[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); - svga->pallook[c] += makecol32(((c >> 5) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 3) & 1) * 0x55); - } - svga->vertical_linedbl = 0; - } - else - { - for (c = 0; c < 256; c++) - { - if ((c & 0x17) == 6) - svga->pallook[c] = makecol32(0xaa, 0x55, 0x00); - else - { - svga->pallook[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); - svga->pallook[c] += makecol32(((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55); - } - } - svga->vertical_linedbl = 1; - } - - svga->fullchange = changeframecount; - } - ati18800->ega_switch_read = val & 0xc; - } - break; - case 0x3D4: svga->crtcreg = val & 0x3f; return; @@ -196,20 +153,6 @@ static uint8_t ati18800_in(uint16_t addr, void *p) } break; - case 0x3c2: - if (ati18800->is_ega) - { - switch (ati18800->ega_switch_read) - { - case 0xc: return (ati18800->ega_switches & 1) ? 0x10 : 0; - case 0x8: return (ati18800->ega_switches & 2) ? 0x10 : 0; - case 0x4: return (ati18800->ega_switches & 4) ? 0x10 : 0; - case 0x0: return (ati18800->ega_switches & 8) ? 0x10 : 0; - } - } else - temp = svga_in(addr, svga); - break; - case 0x3D4: temp = svga->crtcreg; break; @@ -245,32 +188,13 @@ static void ati18800_recalctimings(svga_t *svga) } } -static void ega_wonder_800_recalctimings(svga_t *svga) -{ - ati18800_t *ati18800 = (ati18800_t *)svga->p; - int clksel = ((svga->miscout & 0xc) >> 2) | ((ati18800->regs[0xbe] & 0x10) ? 4 : 0); - - switch (clksel) - { - case 0: svga->clock = (cpuclock * (double)(1ull << 32)) / 25175000.0; break; - case 1: svga->clock = (cpuclock * (double)(1ull << 32)) / 28322000.0; break; - case 4: svga->clock = (cpuclock * (double)(1ull << 32)) / 14318181.0; break; - case 5: svga->clock = (cpuclock * (double)(1ull << 32)) / 16257000.0; break; - case 7: default: svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; break; - } -} - - static void *ati18800_init(const device_t *info) { - int c; ati18800_t *ati18800 = malloc(sizeof(ati18800_t)); memset(ati18800, 0, sizeof(ati18800_t)); video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ati18800); - ati18800->is_ega = (info->local == ATI18800_EGAWONDER800P); - switch (info->local) { #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) case ATI18800_WONDER: @@ -286,46 +210,28 @@ static void *ati18800_init(const device_t *info) case ATI18800_EDGE16: rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_EDGE16, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); break; - case ATI18800_EGAWONDER800P: - rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_EGAWONDER800P, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - break; }; - - if ((info->local != ATI18800_EGAWONDER800P) && (info->local != ATI18800_EDGE16)) { - svga_init(&ati18800->svga, ati18800, 1 << 20, /*512kb*/ + + if (info->local == ATI18800_EDGE16) { + svga_init(&ati18800->svga, ati18800, 1 << 18, /*256kb*/ ati18800_recalctimings, ati18800_in, ati18800_out, NULL, NULL); } else { - svga_init(&ati18800->svga, ati18800, 1 << 18, /*256kb*/ - ega_wonder_800_recalctimings, + svga_init(&ati18800->svga, ati18800, 1 << 19, /*512kb*/ + ati18800_recalctimings, ati18800_in, ati18800_out, NULL, - NULL); + NULL); } io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); - if (info->local != ATI18800_EGAWONDER800P) - io_sethandler(0x03c0, 0x0020, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); - else { - io_sethandler(0x03c6, 0x0006, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); - io_sethandler(0x03ca, 0x0016, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); - - for (c = 0; c < 256; c++) { - ati18800->svga.pallook[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); - ati18800->svga.pallook[c] += makecol32(((c >> 5) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 3) & 1) * 0x55); - } - } + io_sethandler(0x03c0, 0x0020, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); ati18800->svga.miscout = 1; - if (info->local != ATI18800_EGAWONDER800P) - ati_eeprom_load(&ati18800->eeprom, L"ati18800.nvr", 0); - else { - ati18800->ega_switches = 9; - ati_eeprom_load(&ati18800->eeprom, L"egawonder800.nvr", 0); - } + ati_eeprom_load(&ati18800->eeprom, L"ati18800.nvr", 0); return ati18800; } @@ -347,11 +253,6 @@ static int ati18800_available(void) return rom_present(BIOS_ROM_PATH_EDGE16); } -static int ega_wonder_800_available(void) -{ - return rom_present(BIOS_ROM_PATH_EGAWONDER800P); -} - static void ati18800_close(void *p) { ati18800_t *ati18800 = (ati18800_t *)p; @@ -415,16 +316,3 @@ const device_t ati18800_device = ati18800_force_redraw, NULL }; - -const device_t ati_ega_wonder_800_device = -{ - "ATI EGA Wonder 800+", - DEVICE_ISA, ATI18800_EGAWONDER800P, - ati18800_init, - ati18800_close, - NULL, - ega_wonder_800_available, - ati18800_speed_changed, - ati18800_force_redraw, - NULL -}; diff --git a/src/video/vid_ati18800.h b/src/video/vid_ati18800.h index 725f5cc73..b41facab3 100644 --- a/src/video/vid_ati18800.h +++ b/src/video/vid_ati18800.h @@ -4,4 +4,3 @@ extern const device_t ati18800_wonder_device; extern const device_t ati18800_vga88_device; extern const device_t ati18800_device; -extern const device_t ati_ega_wonder_800_device; diff --git a/src/video/vid_ati_eeprom.c b/src/video/vid_ati_eeprom.c index c7debfcf2..a7fee5958 100644 --- a/src/video/vid_ati_eeprom.c +++ b/src/video/vid_ati_eeprom.c @@ -8,13 +8,13 @@ * * Emulation of the EEPROM on select ATI cards. * - * Version: @(#)vid_ati_eeprom.c 1.0.2 2018/04/11 + * Version: @(#)vid_ati_eeprom.c 1.0.3 2020/01/20 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. */ #include #include @@ -67,7 +67,7 @@ void ati_eeprom_load(ati_eeprom_t *eeprom, wchar_t *fn, int type) f = nvr_fopen(eeprom->fn, L"rb"); size = eeprom->type ? 512 : 128; if (!f) { - memset(eeprom->data, 0, size); + memset(eeprom->data, 0xff, size); return; } if (fread(eeprom->data, 1, size, f) != size) diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index acda3edde..05c617e2c 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -9,7 +9,7 @@ * Emulation of the EGA and Chips & Technologies SuperEGA * graphics cards. * - * Version: @(#)vid_ega.c 1.0.23 2019/11/19 + * Version: @(#)vid_ega.c 1.0.24 2019/11/20 * * Authors: Sarah Walker, * Miran Grca, @@ -31,6 +31,7 @@ #include "../rom.h" #include "../device.h" #include "video.h" +#include "vid_ati_eeprom.h" #include "vid_ega.h" #include "vid_ega_render.h" @@ -38,15 +39,17 @@ void ega_doblit(int y1, int y2, int wx, int wy, ega_t *ega); -#define BIOS_IBM_PATH L"roms/video/ega/ibm_6277356_ega_card_u44_27128.bin" -#define BIOS_CPQ_PATH L"roms/video/ega/108281-001.bin" -#define BIOS_SEGA_PATH L"roms/video/ega/lega.vbi" +#define BIOS_IBM_PATH L"roms/video/ega/ibm_6277356_ega_card_u44_27128.bin" +#define BIOS_CPQ_PATH L"roms/video/ega/108281-001.bin" +#define BIOS_SEGA_PATH L"roms/video/ega/lega.vbi" +#define BIOS_ATIEGA_PATH L"roms/video/ega/ATI EGA Wonder 800+ N1.00.BIN" enum { EGA_IBM = 0, EGA_COMPAQ, - EGA_SUPEREGA + EGA_SUPEREGA, + EGA_ATI }; @@ -74,6 +77,30 @@ ega_out(uint16_t addr, uint8_t val, void *p) addr ^= 0x60; switch (addr) { + case 0x1ce: + ega->index = val; + break; + case 0x1cf: + ega->regs[ega->index] = val; + switch (ega->index) { + case 0xb0: + ega_recalctimings(ega); + break; + case 0xb2: case 0xbe: +#if 0 + if (ega->regs[0xbe] & 8) { /*Read/write bank mode*/ + svga->read_bank = ((ega->regs[0xb2] >> 5) & 7) * 0x10000; + svga->write_bank = ((ega->regs[0xb2] >> 1) & 7) * 0x10000; + } else /*Single bank mode*/ + svga->read_bank = svga->write_bank = ((ega->regs[0xb2] >> 1) & 7) * 0x10000; +#endif + break; + case 0xb3: + ati_eeprom_write((ati_eeprom_t *) ega->eeprom, val & 8, val & 2, val & 1); + break; + } + break; + case 0x3c0: case 0x3c1: if (!ega->attrff) { ega->attraddr = val & 31; @@ -211,6 +238,22 @@ uint8_t ega_in(uint16_t addr, void *p) addr ^= 0x60; switch (addr) { + case 0x1ce: + ret = ega->index; + break; + case 0x1cf: + switch (ega->index) { + case 0xb7: + ret = ega->regs[ega->index] & ~8; + if (ati_eeprom_read((ati_eeprom_t *) ega->eeprom)) + ret |= 8; + break; + default: + ret = ega->regs[ega->index]; + break; + } + break; + case 0x3c0: ret = ega->attraddr | ega->attr_palette_enable; break; @@ -259,6 +302,8 @@ uint8_t ega_in(uint16_t addr, void *p) void ega_recalctimings(ega_t *ega) { + int clksel; + double _dispontime, _dispofftime, disptime; double crtcconst; @@ -291,8 +336,35 @@ ega_recalctimings(ega_t *ega) ega->linedbl = ega->crtc[9] & 0x80; ega->rowcount = ega->crtc[9] & 0x1f; - if (ega->vidclock) crtcconst = (ega->seqregs[1] & 1) ? MDACONST : (MDACONST * (9.0 / 8.0)); - else crtcconst = (ega->seqregs[1] & 1) ? CGACONST : (CGACONST * (9.0 / 8.0)); + if (ega->eeprom) { + clksel = ((ega->miscout & 0xc) >> 2) | ((ega->regs[0xbe] & 0x10) ? 4 : 0); + + switch (clksel) { + case 0: + crtcconst = (cpuclock / 25175000.0 * (double)(1ull << 32)); + break; + case 1: + crtcconst = (cpuclock / 28322000.0 * (double)(1ull << 32)); + break; + case 4: + crtcconst = (cpuclock / 14318181.0 * (double)(1ull << 32)); + break; + case 5: + crtcconst = (cpuclock / 16257000.0 * (double)(1ull << 32)); + break; + case 7: + default: + crtcconst = (cpuclock / 36000000.0 * (double)(1ull << 32)); + break; + } + if (!(ega->seqregs[1] & 1)) + crtcconst *= 9.0; + else + crtcconst *= 8.0; + } else { + if (ega->vidclock) crtcconst = (ega->seqregs[1] & 1) ? MDACONST : (MDACONST * (9.0 / 8.0)); + else crtcconst = (ega->seqregs[1] & 1) ? CGACONST : (CGACONST * (9.0 / 8.0)); + } ega->interlace = 0; @@ -353,11 +425,15 @@ ega_recalctimings(ega_t *ega) _dispontime = (double) (ega->crtc[1] + 1); } _dispofftime = disptime - _dispontime; - _dispontime = _dispontime * crtcconst; - _dispofftime = _dispofftime * crtcconst; + _dispontime *= crtcconst; + _dispofftime *= crtcconst; ega->dispontime = (uint64_t)(_dispontime); ega->dispofftime = (uint64_t)(_dispofftime); + if (ega->dispontime < TIMER_USEC) + ega->dispontime = TIMER_USEC; + if (ega->dispofftime < TIMER_USEC) + ega->dispofftime = TIMER_USEC; } @@ -399,9 +475,13 @@ ega_poll(void *p) ega->displine++; ega->ma = old_ma; - ega_render_overscan_left(ega); + ega->render(ega); + + ega->x_add = (overscan_x >> 1); + ega_render_overscan_left(ega); ega_render_overscan_right(ega); + ega->x_add = (overscan_x >> 1) - ega->scrollcache; ega->y_add >>= 1; ega->displine >>= 1; @@ -949,6 +1029,10 @@ ega_standalone_init(const device_t *info) rom_init(&ega->bios_rom, BIOS_SEGA_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); break; + case EGA_ATI: + rom_init(&ega->bios_rom, BIOS_ATIEGA_PATH, + 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + break; } if ((ega->bios_rom.rom[0x3ffe] == 0xaa) && (ega->bios_rom.rom[0x3fff] == 0x55)) { @@ -968,6 +1052,13 @@ ega_standalone_init(const device_t *info) mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); io_sethandler(0x03a0, 0x0040, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); + if (info->local == EGA_ATI) { + io_sethandler(0x01ce, 0x0002, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); + ega->eeprom = malloc(sizeof(ati_eeprom_t)); + memset(ega->eeprom, 0, sizeof(ati_eeprom_t)); + ati_eeprom_load((ati_eeprom_t *) ega->eeprom, L"egawonder800.nvr", 0); + } + return ega; } @@ -993,11 +1084,20 @@ sega_standalone_available(void) } +static int +atiega_standalone_available(void) +{ + return rom_present(BIOS_ATIEGA_PATH); +} + + static void ega_close(void *p) { ega_t *ega = (ega_t *)p; + if (ega->eeprom) + free(ega->eeprom); free(ega->vram); free(ega); } @@ -1121,3 +1221,15 @@ const device_t sega_device = NULL, ega_config }; + +const device_t atiega_device = +{ + "ATI EGA Wonder 800+", + DEVICE_ISA, + EGA_ATI, + ega_standalone_init, ega_close, NULL, + atiega_standalone_available, + ega_speed_changed, + NULL, + ega_config +}; diff --git a/src/video/vid_ega.h b/src/video/vid_ega.h index f64da0a01..099fab4a0 100644 --- a/src/video/vid_ega.h +++ b/src/video/vid_ega.h @@ -9,13 +9,13 @@ * Emulation of the EGA and Chips & Technologies SuperEGA * graphics cards. * - * Version: @(#)vid_ega.h 1.0.8 2019/10/03 + * Version: @(#)vid_ega.h 1.0.9 2020/01/20 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. */ #ifndef VIDEO_EGA_H # define VIDEO_EGA_H @@ -37,6 +37,7 @@ typedef struct ega_t { uint8_t attrregs[32]; uint8_t seqregs[64]; uint8_t egapal[16]; + uint8_t regs[256]; uint8_t *vram; @@ -51,7 +52,7 @@ typedef struct ega_t { hdisp, hdisp_old, htotal, hdisp_time, rowoffset, vblankstart, scrollcache, firstline, lastline, firstline_draw, lastline_draw, x_add, y_add, - displine, video_res_x, video_res_y, video_bpp; + displine, video_res_x, video_res_y, video_bpp, index; uint32_t charseta, charsetb, ma_latch, ma, maback, ca, vram_limit, overscan_color; @@ -64,6 +65,8 @@ typedef struct ega_t { double clock; void (*render)(struct ega_t *svga); + + void *eeprom; } ega_t; #endif @@ -72,6 +75,7 @@ typedef struct ega_t { extern const device_t ega_device; extern const device_t cpqega_device; extern const device_t sega_device; +extern const device_t atiega_device; #endif extern int update_overscan; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index d37f62a16..5314f33d8 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -11,7 +11,7 @@ * This is intended to be used by another SVGA driver, * and not as a card in it's own right. * - * Version: @(#)vid_svga.c 1.0.41 2020/01/18 + * Version: @(#)vid_svga.c 1.0.42 2020/01/20 * * Authors: Sarah Walker, * Miran Grca, @@ -565,6 +565,44 @@ svga_recalctimings(svga_t *svga) } +static void +svga_do_render(svga_t *svga) +{ + if (!svga->override) { + svga->render(svga); + + svga->x_add = (overscan_x >> 1); + svga_render_overscan_left(svga); + svga_render_overscan_right(svga); + svga->x_add = (overscan_x >> 1) - svga->scrollcache; + } + + if (svga->overlay_on) { + if (!svga->override && svga->overlay_draw) + svga->overlay_draw(svga, svga->displine + svga->y_add); + svga->overlay_on--; + if (svga->overlay_on && svga->interlace) + svga->overlay_on--; + } + + if (svga->dac_hwcursor_on) { + if (!svga->override && svga->dac_hwcursor_draw) + svga->dac_hwcursor_draw(svga, svga->displine + svga->y_add); + svga->dac_hwcursor_on--; + if (svga->dac_hwcursor_on && svga->interlace) + svga->dac_hwcursor_on--; + } + + if (svga->hwcursor_on) { + if (!svga->override && svga->hwcursor_draw) + svga->hwcursor_draw(svga, svga->displine + svga->y_add); + svga->hwcursor_on--; + if (svga->hwcursor_on && svga->interlace) + svga->hwcursor_on--; + } +} + + void svga_poll(void *p) { @@ -572,7 +610,7 @@ svga_poll(void *p) uint32_t x, blink_delay; int wx, wy; int skip = (svga->crtc[8] >> 5) & 0x03; - int ret; + int ret, old_ma; if (!svga->linepos) { if (svga->displine == svga->hwcursor_latch.y && svga->hwcursor_latch.ena) { @@ -625,38 +663,24 @@ svga_poll(void *p) svga->interlace ? 3 : 2; } - if (!svga->override) { - svga->render(svga); + if (svga->vertical_linedbl) { + old_ma = svga->ma; - svga->x_add = (overscan_x >> 1); - svga_render_overscan_left(svga); - svga_render_overscan_right(svga); - svga->x_add = (overscan_x >> 1) - svga->scrollcache; - } + svga->displine <<= 1; + svga->y_add <<= 1; - if (svga->overlay_on) { - if (!svga->override && svga->overlay_draw) - svga->overlay_draw(svga, svga->displine + svga->y_add); - svga->overlay_on--; - if (svga->overlay_on && svga->interlace) - svga->overlay_on--; - } + svga_do_render(svga); - if (svga->dac_hwcursor_on) { - if (!svga->override && svga->dac_hwcursor_draw) - svga->dac_hwcursor_draw(svga, svga->displine + svga->y_add); - svga->dac_hwcursor_on--; - if (svga->dac_hwcursor_on && svga->interlace) - svga->dac_hwcursor_on--; - } + svga->displine++; - if (svga->hwcursor_on) { - if (!svga->override && svga->hwcursor_draw) - svga->hwcursor_draw(svga, svga->displine + svga->y_add); - svga->hwcursor_on--; - if (svga->hwcursor_on && svga->interlace) - svga->hwcursor_on--; - } + svga->ma = old_ma; + + svga_do_render(svga); + + svga->y_add >>= 1; + svga->displine >>= 1; + } else + svga_do_render(svga); if (svga->lastline < svga->displine) svga->lastline = svga->displine; @@ -758,10 +782,16 @@ svga_poll(void *p) svga->firstline--; wx = x; - wy = svga->lastline - svga->firstline; - if (!svga->override/* && (wx > 0) && (wy > 0)*/) - svga_doblit(svga->firstline_draw, svga->lastline_draw + 1, wx, wy, svga); + if (!svga->override) { + if (svga->vertical_linedbl) { + wy = (svga->lastline - svga->firstline) << 1; + svga_doblit(svga->firstline_draw << 1, (svga->lastline_draw + 1) << 1, wx, wy, svga); + } else { + wy = svga->lastline - svga->firstline; + svga_doblit(svga->firstline_draw, svga->lastline_draw + 1, wx, wy, svga); + } + } svga->firstline = 2000; svga->lastline = 0; @@ -1213,6 +1243,12 @@ svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) x_start = (enable_overscan) ? 0 : (overscan_x >> 1); bottom = (overscan_y >> 1) + (svga->crtc[8] & 0x1f); + if (svga->vertical_linedbl) { + y_add <<= 1; + y_start <<= 1; + bottom <<= 1; + } + if ((wx <= 0) || (wy <= 0)) { video_blit_memtoscreen(x_start, y_start, 0, 0, 0, 0); return; @@ -1223,8 +1259,13 @@ svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) return; } + if (svga->vertical_linedbl) + svga->y_add <<= 1; + xs_temp = wx; ys_temp = wy + 1; + if (svga->vertical_linedbl) + ys_temp++; if (xs_temp < 64) xs_temp = 640; if (ys_temp < 32) @@ -1244,10 +1285,7 @@ svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) } else suppress_overscan = 0; - if (svga->vertical_linedbl) - set_screen_size(xsize + x_add, (ysize + y_add) * 2); - else - set_screen_size(xsize + x_add, ysize + y_add); + set_screen_size(xsize + x_add, ysize + y_add); if (video_force_resize_get()) video_force_resize_set(0); @@ -1271,6 +1309,9 @@ svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) } video_blit_memtoscreen(x_start, y_start, y1, y2 + y_add, xsize + x_add, ysize + y_add); + + if (svga->vertical_linedbl) + svga->vertical_linedbl >>= 1; } diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 10844bf6a..ac4a26084 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -8,7 +8,7 @@ * * Define all known video cards. * - * Version: @(#)vid_table.c 1.0.47 2020/01/19 + * Version: @(#)vid_table.c 1.0.48 2020/01/20 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -80,7 +80,7 @@ static const VIDEO_CARD video_cards[] = { { "None", "none", NULL }, { "Internal", "internal", NULL }, - { "[ISA] ATI EGA Wonder 800+", "egawonder800", &ati_ega_wonder_800_device }, + { "[ISA] ATI EGA Wonder 800+", "egawonder800", &atiega_device }, { "[ISA] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_isa", &mach64gx_isa_device }, { "[ISA] ATI Korean VGA (ATI-28800-5)", "ati28800k", &ati28800k_device }, { "[ISA] ATI VGA-88 (ATI-18800-1)", "ati18800v", &ati18800_vga88_device },