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:
@@ -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
|
||||
};
|
||||
|
@@ -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;
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
};
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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 },
|
||||
|
Reference in New Issue
Block a user