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.

This commit is contained in:
OBattler
2020-01-20 05:36:44 +01:00
parent f16e82655f
commit aa7dee91bc
7 changed files with 228 additions and 184 deletions

View File

@@ -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, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
* Copyright 2008-2020 Sarah Walker.
* Copyright 2016-2020 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
@@ -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
};

View File

@@ -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;

View File

@@ -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, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
* Copyright 2008-2020 Sarah Walker.
* Copyright 2016-2020 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
@@ -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)

View File

@@ -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, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -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
};

View File

@@ -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, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* 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;

View File

@@ -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, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -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;
}

View File

@@ -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, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
@@ -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 },