Merge pull request #3307 from 86Box/xga_fixes
Accelerator fixes: XGA and 8514/A, see below.
This commit is contained in:
@@ -83,6 +83,7 @@ typedef struct ibm8514_t {
|
|||||||
} accel;
|
} accel;
|
||||||
|
|
||||||
uint16_t test;
|
uint16_t test;
|
||||||
|
int ibm_mode;
|
||||||
|
|
||||||
int v_total, dispend, v_syncstart, split,
|
int v_total, dispend, v_syncstart, split,
|
||||||
h_disp, h_disp_old, h_total, h_disp_time, rowoffset,
|
h_disp, h_disp_old, h_total, h_disp_time, rowoffset,
|
||||||
@@ -107,5 +108,6 @@ typedef struct ibm8514_t {
|
|||||||
int blitter_busy;
|
int blitter_busy;
|
||||||
uint64_t blitter_time;
|
uint64_t blitter_time;
|
||||||
uint64_t status_time;
|
uint64_t status_time;
|
||||||
|
int pitch;
|
||||||
} ibm8514_t;
|
} ibm8514_t;
|
||||||
#endif /*VIDEO_8514A_H*/
|
#endif /*VIDEO_8514A_H*/
|
||||||
|
|||||||
@@ -184,6 +184,13 @@ extern int vga_on, ibm8514_on;
|
|||||||
|
|
||||||
extern void ibm8514_poll(ibm8514_t *dev, svga_t *svga);
|
extern void ibm8514_poll(ibm8514_t *dev, svga_t *svga);
|
||||||
extern void ibm8514_recalctimings(svga_t *svga);
|
extern void ibm8514_recalctimings(svga_t *svga);
|
||||||
|
extern uint8_t ibm8514_ramdac_in(uint16_t port, void *p);
|
||||||
|
extern void ibm8514_ramdac_out(uint16_t port, uint8_t val, void *p);
|
||||||
|
extern int ibm8514_cpu_src(svga_t *svga);
|
||||||
|
extern int ibm8514_cpu_dest(svga_t *svga);
|
||||||
|
extern void ibm8514_accel_out_pixtrans(svga_t *svga, uint16_t port, uint16_t val, int len);
|
||||||
|
extern void ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, uint8_t ssv, int len);
|
||||||
|
extern void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, int len);
|
||||||
|
|
||||||
extern void xga_poll(xga_t *xga, svga_t *svga);
|
extern void xga_poll(xga_t *xga, svga_t *svga);
|
||||||
extern void xga_recalctimings(svga_t *svga);
|
extern void xga_recalctimings(svga_t *svga);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -199,15 +199,19 @@ svga_out(uint16_t addr, uint8_t val, void *p)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 0x2ea:
|
||||||
case 0x3c6:
|
case 0x3c6:
|
||||||
svga->dac_mask = val;
|
svga->dac_mask = val;
|
||||||
break;
|
break;
|
||||||
|
case 0x2eb:
|
||||||
|
case 0x2ec:
|
||||||
case 0x3c7:
|
case 0x3c7:
|
||||||
case 0x3c8:
|
case 0x3c8:
|
||||||
svga->dac_pos = 0;
|
svga->dac_pos = 0;
|
||||||
svga->dac_status = addr & 0x03;
|
svga->dac_status = addr & 0x03;
|
||||||
svga->dac_addr = (val + (addr & 0x01)) & 255;
|
svga->dac_addr = (val + (addr & 0x01)) & 255;
|
||||||
break;
|
break;
|
||||||
|
case 0x2ed:
|
||||||
case 0x3c9:
|
case 0x3c9:
|
||||||
if (svga->adv_flags & FLAG_RAMDAC_SHIFT)
|
if (svga->adv_flags & FLAG_RAMDAC_SHIFT)
|
||||||
val <<= 2;
|
val <<= 2;
|
||||||
@@ -311,15 +315,19 @@ svga_in(uint16_t addr, void *p)
|
|||||||
case 0x3c5:
|
case 0x3c5:
|
||||||
ret = svga->seqregs[svga->seqaddr & 0x0f];
|
ret = svga->seqregs[svga->seqaddr & 0x0f];
|
||||||
break;
|
break;
|
||||||
|
case 0x2ea:
|
||||||
case 0x3c6:
|
case 0x3c6:
|
||||||
ret = svga->dac_mask;
|
ret = svga->dac_mask;
|
||||||
break;
|
break;
|
||||||
|
case 0x2eb:
|
||||||
case 0x3c7:
|
case 0x3c7:
|
||||||
ret = svga->dac_status;
|
ret = svga->dac_status;
|
||||||
break;
|
break;
|
||||||
|
case 0x2ec:
|
||||||
case 0x3c8:
|
case 0x3c8:
|
||||||
ret = svga->dac_addr;
|
ret = svga->dac_addr;
|
||||||
break;
|
break;
|
||||||
|
case 0x2ed:
|
||||||
case 0x3c9:
|
case 0x3c9:
|
||||||
index = (svga->dac_addr - 1) & 255;
|
index = (svga->dac_addr - 1) & 255;
|
||||||
switch (svga->dac_pos) {
|
switch (svga->dac_pos) {
|
||||||
@@ -572,7 +580,7 @@ svga_recalctimings(svga_t *svga)
|
|||||||
svga->recalctimings_ex(svga);
|
svga->recalctimings_ex(svga);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (ibm8514_on && ibm8514_enabled)
|
if (ibm8514_enabled)
|
||||||
ibm8514_recalctimings(svga);
|
ibm8514_recalctimings(svga);
|
||||||
if (xga_enabled)
|
if (xga_enabled)
|
||||||
xga_recalctimings(svga);
|
xga_recalctimings(svga);
|
||||||
@@ -872,7 +880,7 @@ svga_poll(void *p)
|
|||||||
svga->oddeven ^= 1;
|
svga->oddeven ^= 1;
|
||||||
|
|
||||||
svga->monitor->mon_changeframecount = svga->interlace ? 3 : 2;
|
svga->monitor->mon_changeframecount = svga->interlace ? 3 : 2;
|
||||||
svga->vslines = 0;
|
svga->vslines = 0;
|
||||||
|
|
||||||
if (svga->interlace && svga->oddeven)
|
if (svga->interlace && svga->oddeven)
|
||||||
svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5);
|
svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5);
|
||||||
@@ -893,22 +901,24 @@ svga_poll(void *p)
|
|||||||
svga->dispon = 1;
|
svga->dispon = 1;
|
||||||
svga->displine = (svga->interlace && svga->oddeven) ? 1 : 0;
|
svga->displine = (svga->interlace && svga->oddeven) ? 1 : 0;
|
||||||
|
|
||||||
svga->scrollcache = (svga->attrregs[0x13] & 0x0f);
|
if (!ibm8514_on) {
|
||||||
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/
|
svga->scrollcache = (svga->attrregs[0x13] & 0x0f);
|
||||||
if (svga->seqregs[1] & 1)
|
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/
|
||||||
|
if (svga->seqregs[1] & 1)
|
||||||
|
svga->scrollcache &= 0x07;
|
||||||
|
else {
|
||||||
|
svga->scrollcache++;
|
||||||
|
if (svga->scrollcache > 8)
|
||||||
|
svga->scrollcache = 0;
|
||||||
|
}
|
||||||
|
} else if ((svga->render == svga_render_2bpp_lowres) || (svga->render == svga_render_2bpp_highres) || (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres))
|
||||||
svga->scrollcache &= 0x07;
|
svga->scrollcache &= 0x07;
|
||||||
else {
|
else
|
||||||
svga->scrollcache++;
|
svga->scrollcache = (svga->scrollcache & 0x06) >> 1;
|
||||||
if (svga->scrollcache > 8)
|
|
||||||
svga->scrollcache = 0;
|
|
||||||
}
|
|
||||||
} else if ((svga->render == svga_render_2bpp_lowres) || (svga->render == svga_render_2bpp_highres) || (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres))
|
|
||||||
svga->scrollcache &= 0x07;
|
|
||||||
else
|
|
||||||
svga->scrollcache = (svga->scrollcache & 0x06) >> 1;
|
|
||||||
|
|
||||||
if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres))
|
if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres))
|
||||||
svga->scrollcache <<= 1;
|
svga->scrollcache <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
svga->x_add = (svga->monitor->mon_overscan_x >> 1) - svga->scrollcache;
|
svga->x_add = (svga->monitor->mon_overscan_x >> 1) - svga->scrollcache;
|
||||||
|
|
||||||
@@ -938,9 +948,9 @@ svga_init(const device_t *info, svga_t *svga, void *p, int memsize,
|
|||||||
{
|
{
|
||||||
int c, d, e;
|
int c, d, e;
|
||||||
|
|
||||||
svga->p = p;
|
svga->p = p;
|
||||||
svga->monitor_index = monitor_index_global;
|
svga->monitor_index = monitor_index_global;
|
||||||
svga->monitor = &monitors[svga->monitor_index];
|
svga->monitor = &monitors[svga->monitor_index];
|
||||||
|
|
||||||
for (c = 0; c < 256; c++) {
|
for (c = 0; c < 256; c++) {
|
||||||
e = c;
|
e = c;
|
||||||
@@ -954,10 +964,10 @@ svga_init(const device_t *info, svga_t *svga, void *p, int memsize,
|
|||||||
svga->attrregs[0x11] = 0;
|
svga->attrregs[0x11] = 0;
|
||||||
svga->overscan_color = 0x000000;
|
svga->overscan_color = 0x000000;
|
||||||
|
|
||||||
svga->monitor->mon_overscan_x = 16;
|
svga->monitor->mon_overscan_x = 16;
|
||||||
svga->monitor->mon_overscan_y = 32;
|
svga->monitor->mon_overscan_y = 32;
|
||||||
svga->x_add = 8;
|
svga->x_add = 8;
|
||||||
svga->y_add = 16;
|
svga->y_add = 16;
|
||||||
|
|
||||||
svga->crtc[0] = 63;
|
svga->crtc[0] = 63;
|
||||||
svga->crtc[6] = 255;
|
svga->crtc[6] = 255;
|
||||||
@@ -1096,8 +1106,10 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
|
|||||||
svga->xga.linear_endian_reverse = 1;
|
svga->xga.linear_endian_reverse = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
svga->xga.on = 0;
|
svga->xga.on = 0;
|
||||||
|
vga_on = !svga->xga.on;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
addr = svga_decode_addr(svga, addr, 1);
|
addr = svga_decode_addr(svga, addr, 1);
|
||||||
|
|
||||||
@@ -1286,16 +1298,20 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
|
|||||||
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*/
|
if (svga->xga.test == 0xa5) { /*Memory size test of XGA*/
|
||||||
svga->xga.on = 1;
|
svga->xga.on = 1;
|
||||||
|
vga_on = !svga->xga.on;
|
||||||
return svga->xga.test;
|
return svga->xga.test;
|
||||||
} else if (svga->xga.test == 0x5a) {
|
} else if (svga->xga.test == 0x5a) {
|
||||||
svga->xga.on = 1;
|
svga->xga.on = 1;
|
||||||
|
vga_on = !svga->xga.on;
|
||||||
return svga->xga.test;
|
return svga->xga.test;
|
||||||
} else if (addr == 0xa0000 || addr == 0xa0010) {
|
} else if (addr == 0xa0000 || addr == 0xa0010) {
|
||||||
addr += svga->xga.read_bank;
|
addr += svga->xga.read_bank;
|
||||||
return svga->xga.vram[addr & svga->xga.vram_mask];
|
return svga->xga.vram[addr & svga->xga.vram_mask];
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
svga->xga.on = 0;
|
svga->xga.on = 0;
|
||||||
|
vga_on = !svga->xga.on;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
addr = svga_decode_addr(svga, addr, 0);
|
addr = svga_decode_addr(svga, addr, 0);
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||||
* running old operating systems and software designed for IBM
|
* running old operating systems and software designed for IBM
|
||||||
* PC systems and compatibles from 1981 through fairly recent
|
* PC systems and compatibles from 1981 through fairly recent
|
||||||
* system designs based on the PCI bus.
|
* system designs based on the PCI bus.
|
||||||
*
|
*
|
||||||
* This file is part of the 86Box distribution.
|
* This file is part of the 86Box distribution.
|
||||||
*
|
*
|
||||||
* IBM XGA emulation.
|
* IBM XGA emulation.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Authors: TheCollector1995.
|
* Authors: TheCollector1995.
|
||||||
*
|
*
|
||||||
* Copyright 2022 TheCollector1995.
|
* Copyright 2022 TheCollector1995.
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@@ -38,16 +38,19 @@
|
|||||||
#define XGA_BIOS_PATH "roms/video/xga/XGA_37F9576_Ver200.BIN"
|
#define XGA_BIOS_PATH "roms/video/xga/XGA_37F9576_Ver200.BIN"
|
||||||
#define XGA2_BIOS_PATH "roms/video/xga/xga2_v300.bin"
|
#define XGA2_BIOS_PATH "roms/video/xga/xga2_v300.bin"
|
||||||
|
|
||||||
|
static video_timings_t timing_xga_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 };
|
||||||
|
static video_timings_t timing_xga_mca = { .type = VIDEO_MCA, .write_b = 4, .write_w = 5, .write_l = 10, .read_b = 5, .read_w = 5, .read_l = 10 };
|
||||||
|
|
||||||
static void xga_ext_outb(uint16_t addr, uint8_t val, void *p);
|
static void xga_ext_outb(uint16_t addr, uint8_t val, void *p);
|
||||||
static uint8_t xga_ext_inb(uint16_t addr, void *p);
|
static uint8_t xga_ext_inb(uint16_t addr, void *p);
|
||||||
|
|
||||||
static void
|
void
|
||||||
xga_updatemapping(svga_t *svga)
|
xga_updatemapping(svga_t *svga)
|
||||||
{
|
{
|
||||||
xga_t *xga = &svga->xga;
|
xga_t *xga = &svga->xga;
|
||||||
|
|
||||||
// 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);
|
//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->op_mode & 7) >= 4) || ((xga->op_mode & 7) == 0)) {
|
||||||
if (xga->aperture_cntl == 1) {
|
if (xga->aperture_cntl == 1) {
|
||||||
mem_mapping_disable(&svga->mapping);
|
mem_mapping_disable(&svga->mapping);
|
||||||
mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000);
|
mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000);
|
||||||
@@ -56,25 +59,22 @@ xga_updatemapping(svga_t *svga)
|
|||||||
if (!xga->linear_endian_reverse)
|
if (!xga->linear_endian_reverse)
|
||||||
mem_mapping_disable(&xga->linear_mapping);
|
mem_mapping_disable(&xga->linear_mapping);
|
||||||
} else if (xga->aperture_cntl == 0) {
|
} else if (xga->aperture_cntl == 0) {
|
||||||
linear:
|
|
||||||
mem_mapping_disable(&svga->mapping);
|
mem_mapping_disable(&svga->mapping);
|
||||||
mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000);
|
mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000);
|
||||||
mem_mapping_enable(&xga->video_mapping);
|
mem_mapping_enable(&xga->video_mapping);
|
||||||
xga->banked_mask = 0xffff;
|
xga->banked_mask = 0xffff;
|
||||||
if ((xga->pos_regs[4] & 1) && !xga->base_addr_1mb) {
|
if (xga->pos_regs[4] & 1)
|
||||||
xga->linear_size = 0x400000;
|
mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000);
|
||||||
mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, xga->linear_size);
|
else if (xga->base_addr_1mb)
|
||||||
} else {
|
mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000);
|
||||||
if (xga->base_addr_1mb) {
|
else
|
||||||
xga->linear_size = 0x100000;
|
mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000);
|
||||||
mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, xga->linear_size);
|
if (((xga->op_mode & 7) == 4) && ((svga->gdcreg[6] & 0x0c) == 0x0c) && !xga->a5_test && xga->on)
|
||||||
} else
|
|
||||||
mem_mapping_disable(&xga->linear_mapping);
|
|
||||||
}
|
|
||||||
xga->on = 0;
|
|
||||||
vga_on = 1;
|
|
||||||
if (((xga->op_mode & 7) == 4) && ((svga->gdcreg[6] & 0x0c) == 0x0c) && !xga->a5_test)
|
|
||||||
xga->linear_endian_reverse = 1;
|
xga->linear_endian_reverse = 1;
|
||||||
|
else if (((xga->op_mode & 7) == 0) && ((svga->gdcreg[6] & 0x0c) == 0x0c) && !xga->a5_test && !xga->on)
|
||||||
|
xga->linear_endian_reverse = 1;
|
||||||
|
xga->on = 0;
|
||||||
|
vga_on = !xga->on;
|
||||||
} else {
|
} else {
|
||||||
mem_mapping_disable(&svga->mapping);
|
mem_mapping_disable(&svga->mapping);
|
||||||
mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000);
|
mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000);
|
||||||
@@ -83,23 +83,17 @@ linear:
|
|||||||
mem_mapping_disable(&xga->linear_mapping);
|
mem_mapping_disable(&xga->linear_mapping);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!(xga->op_mode & 7)) {
|
|
||||||
goto linear;
|
|
||||||
}
|
|
||||||
if (xga->aperture_cntl == 2) {
|
|
||||||
mem_mapping_disable(&svga->mapping);
|
|
||||||
mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000);
|
|
||||||
mem_mapping_enable(&xga->video_mapping);
|
|
||||||
xga->banked_mask = 0xffff;
|
|
||||||
} else {
|
|
||||||
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);
|
|
||||||
xga->on = 0;
|
xga->on = 0;
|
||||||
vga_on = 1;
|
vga_on = !xga->on;
|
||||||
|
mem_mapping_disable(&svga->mapping);
|
||||||
|
if (xga->aperture_cntl == 2)
|
||||||
|
mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000);
|
||||||
|
else
|
||||||
|
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);
|
||||||
|
//pclog("XGA opmode (not extended) = %d, disp mode = %d, aperture = %d.\n", xga->op_mode & 7, xga->disp_cntl_2 & 7, xga->aperture_cntl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,8 +141,6 @@ xga_recalctimings(svga_t *svga)
|
|||||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 44900000.0;
|
svga->clock = (cpuclock * (double) (1ull << 32)) / 44900000.0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
vga_on = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,6 +284,8 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val)
|
|||||||
|
|
||||||
case 0x51:
|
case 0x51:
|
||||||
xga->disp_cntl_2 = val;
|
xga->disp_cntl_2 = val;
|
||||||
|
xga->on = ((val & 7) >= 3);
|
||||||
|
vga_on = !xga->on;
|
||||||
svga_recalctimings(svga);
|
svga_recalctimings(svga);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -318,7 +312,7 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val)
|
|||||||
else if (xga->sprite_pos >= 1)
|
else if (xga->sprite_pos >= 1)
|
||||||
xga->cursor_data_on = 1;
|
xga->cursor_data_on = 1;
|
||||||
else if (xga->aperture_cntl == 0) {
|
else if (xga->aperture_cntl == 0) {
|
||||||
if (xga->linear_endian_reverse)
|
if (xga->linear_endian_reverse && !(xga->access_mode & 8))
|
||||||
xga->cursor_data_on = 0;
|
xga->cursor_data_on = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -351,7 +345,7 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x65:
|
case 0x65:
|
||||||
svga->fullchange = changeframecount;
|
svga->fullchange = svga->monitor->mon_changeframecount;
|
||||||
switch (svga->dac_pos) {
|
switch (svga->dac_pos) {
|
||||||
case 0:
|
case 0:
|
||||||
svga->dac_r = val;
|
svga->dac_r = val;
|
||||||
@@ -406,7 +400,7 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *p)
|
|||||||
svga_t *svga = (svga_t *) p;
|
svga_t *svga = (svga_t *) p;
|
||||||
xga_t *xga = &svga->xga;
|
xga_t *xga = &svga->xga;
|
||||||
|
|
||||||
// pclog("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val);
|
//pclog("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val);
|
||||||
switch (addr & 0x0f) {
|
switch (addr & 0x0f) {
|
||||||
case 0:
|
case 0:
|
||||||
xga->op_mode = val;
|
xga->op_mode = val;
|
||||||
@@ -421,12 +415,10 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *p)
|
|||||||
xga->aperture_cntl = 0;
|
xga->aperture_cntl = 0;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
vga_on = 0;
|
|
||||||
xga->on = 1;
|
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
xga->ap_idx = val;
|
xga->ap_idx = val;
|
||||||
// pclog("Aperture CNTL = %d, val = %02x, up to bit6 = %02x\n", xga->aperture_cntl, val, val & 0x3f);
|
//pclog("Aperture CNTL = %d, val = %02x, up to bit6 = %02x\n", xga->aperture_cntl, val, val & 0x3f);
|
||||||
if ((xga->op_mode & 7) < 4) {
|
if ((xga->op_mode & 7) < 4) {
|
||||||
xga->write_bank = xga->read_bank = 0;
|
xga->write_bank = xga->read_bank = 0;
|
||||||
} else {
|
} else {
|
||||||
@@ -586,10 +578,10 @@ xga_ext_inb(uint16_t addr, void *p)
|
|||||||
ret = xga->disp_cntl_2;
|
ret = xga->disp_cntl_2;
|
||||||
break;
|
break;
|
||||||
case 0x52:
|
case 0x52:
|
||||||
ret = 0x0b;
|
ret = xga->type ? 0xfa : 0xea;
|
||||||
break;
|
break;
|
||||||
case 0x53:
|
case 0x53:
|
||||||
ret = 0x70;
|
ret = xga->type ? 0x53 : 0x30;
|
||||||
break;
|
break;
|
||||||
case 0x54:
|
case 0x54:
|
||||||
ret = xga->clk_sel_1;
|
ret = xga->clk_sel_1;
|
||||||
@@ -667,7 +659,7 @@ xga_ext_inb(uint16_t addr, void *p)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// pclog("[%04X:%08X]: EXT INB = %02x, ret = %02x\n", CS, cpu_state.pc, addr, ret);
|
//pclog("[%04X:%08X]: EXT INB = %02x, ret = %02x\n", CS, cpu_state.pc, addr, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -676,7 +668,7 @@ xga_ext_inb(uint16_t addr, void *p)
|
|||||||
|
|
||||||
#define WRITE(addr, dat) \
|
#define WRITE(addr, dat) \
|
||||||
xga->vram[((addr)) & (xga->vram_mask)] = dat; \
|
xga->vram[((addr)) & (xga->vram_mask)] = dat; \
|
||||||
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = changeframecount;
|
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount;
|
||||||
|
|
||||||
#define READW(addr, dat) \
|
#define READW(addr, dat) \
|
||||||
dat = *(uint16_t *) &xga->vram[(addr) & (xga->vram_mask)];
|
dat = *(uint16_t *) &xga->vram[(addr) & (xga->vram_mask)];
|
||||||
@@ -687,12 +679,12 @@ xga_ext_inb(uint16_t addr, void *p)
|
|||||||
|
|
||||||
#define WRITEW(addr, dat) \
|
#define WRITEW(addr, dat) \
|
||||||
*(uint16_t *) &xga->vram[((addr)) & (xga->vram_mask)] = dat; \
|
*(uint16_t *) &xga->vram[((addr)) & (xga->vram_mask)] = dat; \
|
||||||
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = changeframecount;
|
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount;
|
||||||
|
|
||||||
#define WRITEW_REVERSE(addr, dat) \
|
#define WRITEW_REVERSE(addr, dat) \
|
||||||
xga->vram[((addr + 1)) & (xga->vram_mask - 1)] = dat & 0xff; \
|
xga->vram[((addr + 1)) & (xga->vram_mask - 1)] = dat & 0xff; \
|
||||||
xga->vram[((addr)) & (xga->vram_mask - 1)] = dat >> 8; \
|
xga->vram[((addr)) & (xga->vram_mask - 1)] = dat >> 8; \
|
||||||
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = changeframecount;
|
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount;
|
||||||
|
|
||||||
#define ROP(mix, d, s) \
|
#define ROP(mix, d, s) \
|
||||||
{ \
|
{ \
|
||||||
@@ -908,12 +900,12 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui
|
|||||||
if (pixel & 1) {
|
if (pixel & 1) {
|
||||||
if (!skip) {
|
if (!skip) {
|
||||||
xga->vram[((addr)) & (xga->vram_mask)] |= mask;
|
xga->vram[((addr)) & (xga->vram_mask)] |= mask;
|
||||||
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = changeframecount;
|
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!skip) {
|
if (!skip) {
|
||||||
xga->vram[((addr)) & (xga->vram_mask)] &= ~mask;
|
xga->vram[((addr)) & (xga->vram_mask)] &= ~mask;
|
||||||
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = changeframecount;
|
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mem_writeb_phys(addr, byte);
|
mem_writeb_phys(addr, byte);
|
||||||
@@ -2198,7 +2190,7 @@ xga_write(uint32_t addr, uint8_t val, void *p)
|
|||||||
|
|
||||||
cycles -= video_timing_write_b;
|
cycles -= video_timing_write_b;
|
||||||
|
|
||||||
xga->changedvram[(addr & xga->vram_mask) >> 12] = changeframecount;
|
xga->changedvram[(addr & xga->vram_mask) >> 12] = svga->monitor->mon_changeframecount;
|
||||||
xga->vram[addr & xga->vram_mask] = val;
|
xga->vram[addr & xga->vram_mask] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2245,7 +2237,7 @@ xga_write_linear(uint32_t addr, uint8_t val, void *p)
|
|||||||
|
|
||||||
cycles -= video_timing_write_b;
|
cycles -= video_timing_write_b;
|
||||||
|
|
||||||
xga->changedvram[(addr & xga->vram_mask) >> 12] = changeframecount;
|
xga->changedvram[(addr & xga->vram_mask) >> 12] = svga->monitor->mon_changeframecount;
|
||||||
xga->vram[addr & xga->vram_mask] = val;
|
xga->vram[addr & xga->vram_mask] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2559,7 +2551,7 @@ xga_poll(xga_t *xga, svga_t *svga)
|
|||||||
|
|
||||||
xga->oddeven ^= 1;
|
xga->oddeven ^= 1;
|
||||||
|
|
||||||
changeframecount = xga->interlace ? 3 : 2;
|
svga->monitor->mon_changeframecount = xga->interlace ? 3 : 2;
|
||||||
|
|
||||||
if (xga->interlace && xga->oddeven)
|
if (xga->interlace && xga->oddeven)
|
||||||
xga->ma = xga->maback = xga->ma_latch + (xga->rowoffset << 1);
|
xga->ma = xga->maback = xga->ma_latch + (xga->rowoffset << 1);
|
||||||
@@ -2588,9 +2580,13 @@ xga_mca_read(int port, void *priv)
|
|||||||
{
|
{
|
||||||
svga_t *svga = (svga_t *) priv;
|
svga_t *svga = (svga_t *) priv;
|
||||||
xga_t *xga = &svga->xga;
|
xga_t *xga = &svga->xga;
|
||||||
|
uint8_t ret = xga->pos_regs[port & 7];
|
||||||
|
|
||||||
// pclog("[%04X:%08X]: POS Read Port = %x, val = %02x\n", CS, cpu_state.pc, port & 7, xga->pos_regs[port & 7]);
|
if (((port & 7) == 3) && !(ret & 1)) /*Always enable the mapping.*/
|
||||||
return (xga->pos_regs[port & 7]);
|
ret |= 1;
|
||||||
|
|
||||||
|
//pclog("[%04X:%08X]: POS Read Port = %x, val = %02x\n", CS, cpu_state.pc, port & 7, xga->pos_regs[port & 7]);
|
||||||
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -2607,11 +2603,13 @@ xga_mca_write(int port, uint8_t val, void *priv)
|
|||||||
mem_mapping_disable(&xga->bios_rom.mapping);
|
mem_mapping_disable(&xga->bios_rom.mapping);
|
||||||
mem_mapping_disable(&xga->memio_mapping);
|
mem_mapping_disable(&xga->memio_mapping);
|
||||||
xga->on = 0;
|
xga->on = 0;
|
||||||
vga_on = 1;
|
vga_on = !xga->on;
|
||||||
|
xga->linear_endian_reverse = 0;
|
||||||
|
xga->a5_test = 0;
|
||||||
|
|
||||||
/* Save the MCA register value. */
|
/* Save the MCA register value. */
|
||||||
xga->pos_regs[port & 7] = val;
|
xga->pos_regs[port & 7] = val;
|
||||||
if (!(xga->pos_regs[4] & 1)) /*MCA 4MB addressing on systems with more than 16MB of memory*/
|
if (!(xga->pos_regs[4] & 1) && (mem_size >= 16384)) /*MCA 4MB addressing on systems with more than 16MB of memory*/
|
||||||
xga->pos_regs[4] |= 1;
|
xga->pos_regs[4] |= 1;
|
||||||
|
|
||||||
if (xga->pos_regs[2] & 1) {
|
if (xga->pos_regs[2] & 1) {
|
||||||
@@ -2622,13 +2620,12 @@ xga_mca_write(int port, uint8_t val, void *priv)
|
|||||||
|
|
||||||
io_sethandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga);
|
io_sethandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga);
|
||||||
|
|
||||||
if (xga->pos_regs[3] & 1) {
|
if (xga->pos_regs[3] & 1)
|
||||||
mem_mapping_set_addr(&xga->bios_rom.mapping, xga->rom_addr, 0x2000);
|
mem_mapping_set_addr(&xga->bios_rom.mapping, xga->rom_addr, 0x2000);
|
||||||
} else {
|
else
|
||||||
mem_mapping_set_addr(&xga->memio_mapping, xga->rom_addr + 0x1c00 + (xga->instance * 0x80), 0x80);
|
mem_mapping_set_addr(&xga->memio_mapping, xga->rom_addr + 0x1c00 + (xga->instance * 0x80), 0x80);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// pclog("[%04X:%08X]: POS Write Port = %x, val = %02x, linear base = %08x, instance = %d, rom addr = %05x\n", CS, cpu_state.pc, port & 7, val, xga->linear_base, xga->instance, xga->rom_addr);
|
//pclog("[%04X:%08X]: POS Write Port = %x, val = %02x, linear base = %08x, instance = %d, rom addr = %05x\n", CS, cpu_state.pc, port & 7, val, xga->linear_base, xga->instance, xga->rom_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t
|
static uint8_t
|
||||||
@@ -2644,10 +2641,27 @@ static void
|
|||||||
xga_mca_reset(void *p)
|
xga_mca_reset(void *p)
|
||||||
{
|
{
|
||||||
svga_t *svga = (svga_t *) p;
|
svga_t *svga = (svga_t *) p;
|
||||||
|
xga_t *xga = &svga->xga;
|
||||||
|
|
||||||
|
xga->on = 0;
|
||||||
|
vga_on = !xga->on;
|
||||||
xga_mca_write(0x102, 0, svga);
|
xga_mca_write(0x102, 0, svga);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xga_reset(void *p)
|
||||||
|
{
|
||||||
|
svga_t *svga = (svga_t *) p;
|
||||||
|
xga_t *xga = &svga->xga;
|
||||||
|
|
||||||
|
mem_mapping_disable(&xga->bios_rom.mapping);
|
||||||
|
mem_mapping_disable(&xga->memio_mapping);
|
||||||
|
xga->on = 0;
|
||||||
|
vga_on = !xga->on;
|
||||||
|
xga->linear_endian_reverse = 0;
|
||||||
|
xga->a5_test = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static uint8_t
|
static uint8_t
|
||||||
xga_pos_in(uint16_t addr, void *priv)
|
xga_pos_in(uint16_t addr, void *priv)
|
||||||
{
|
{
|
||||||
@@ -2660,10 +2674,13 @@ static void
|
|||||||
*
|
*
|
||||||
xga_init(const device_t *info)
|
xga_init(const device_t *info)
|
||||||
{
|
{
|
||||||
|
if (svga_get_pri() == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
svga_t *svga = svga_get_pri();
|
svga_t *svga = svga_get_pri();
|
||||||
xga_t *xga = &svga->xga;
|
xga_t *xga = &svga->xga;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
uint32_t initial_bios_addr = device_get_config_hex20("init_bios_addr");
|
uint32_t temp;
|
||||||
uint8_t *rom = NULL;
|
uint8_t *rom = NULL;
|
||||||
|
|
||||||
xga->type = device_get_config_int("type");
|
xga->type = device_get_config_int("type");
|
||||||
@@ -2682,11 +2699,13 @@ static void
|
|||||||
|
|
||||||
f = rom_fopen(xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, "rb");
|
f = rom_fopen(xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, "rb");
|
||||||
(void) fseek(f, 0L, SEEK_END);
|
(void) fseek(f, 0L, SEEK_END);
|
||||||
|
temp = ftell(f);
|
||||||
(void) fseek(f, 0L, SEEK_SET);
|
(void) fseek(f, 0L, SEEK_SET);
|
||||||
|
|
||||||
rom = malloc(xga->bios_rom.sz);
|
rom = malloc(xga->bios_rom.sz);
|
||||||
memset(rom, 0xff, xga->bios_rom.sz);
|
memset(rom, 0xff, xga->bios_rom.sz);
|
||||||
(void) !fread(rom, xga->bios_rom.sz, 1, f);
|
(void) fread(rom, xga->bios_rom.sz, 1, f);
|
||||||
|
temp -= xga->bios_rom.sz;
|
||||||
(void) fclose(f);
|
(void) fclose(f);
|
||||||
|
|
||||||
xga->bios_rom.rom = rom;
|
xga->bios_rom.rom = rom;
|
||||||
@@ -2697,11 +2716,13 @@ static void
|
|||||||
|
|
||||||
xga->base_addr_1mb = 0;
|
xga->base_addr_1mb = 0;
|
||||||
if (info->flags & DEVICE_MCA) {
|
if (info->flags & DEVICE_MCA) {
|
||||||
|
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_xga_mca);
|
||||||
xga->linear_base = 0;
|
xga->linear_base = 0;
|
||||||
xga->instance = 0;
|
xga->instance = 0;
|
||||||
xga->rom_addr = 0;
|
xga->rom_addr = 0;
|
||||||
rom_init(&xga->bios_rom, xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, initial_bios_addr, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);
|
rom_init(&xga->bios_rom, xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, 0xc0000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);
|
||||||
} else {
|
} else {
|
||||||
|
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_xga_isa);
|
||||||
xga->pos_regs[2] = 1 | 0x0c | 0xf0;
|
xga->pos_regs[2] = 1 | 0x0c | 0xf0;
|
||||||
xga->instance = (xga->pos_regs[2] & 0x0e) >> 1;
|
xga->instance = (xga->pos_regs[2] & 0x0e) >> 1;
|
||||||
xga->pos_regs[4] = 1 | 2;
|
xga->pos_regs[4] = 1 | 2;
|
||||||
@@ -2768,30 +2789,11 @@ xga_force_redraw(void *p)
|
|||||||
{
|
{
|
||||||
svga_t *svga = (svga_t *) p;
|
svga_t *svga = (svga_t *) p;
|
||||||
|
|
||||||
svga->fullchange = changeframecount;
|
svga->fullchange = svga->monitor->mon_changeframecount;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const device_config_t xga_configuration[] = {
|
static const device_config_t xga_configuration[] = {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
{
|
|
||||||
.name = "init_bios_addr",
|
|
||||||
.description = "Initial MCA BIOS Address (before POS configuration)",
|
|
||||||
.type = CONFIG_HEX20,
|
|
||||||
.default_string = "",
|
|
||||||
.default_int = 0xc0000,
|
|
||||||
.file_filter = "",
|
|
||||||
.spinner = { 0 },
|
|
||||||
.selection = {
|
|
||||||
{ .description = "C000H", .value = 0xc0000 },
|
|
||||||
{ .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 = "" }
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
.name = "type",
|
.name = "type",
|
||||||
.description = "XGA type",
|
.description = "XGA type",
|
||||||
@@ -2813,7 +2815,7 @@ static const device_config_t xga_configuration[] = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ .name = "", .description = "", .type = CONFIG_END }
|
{ .name = "", .description = "", .type = CONFIG_END }
|
||||||
// clang-format on
|
// clang-format on
|
||||||
};
|
};
|
||||||
|
|
||||||
const device_t xga_device = {
|
const device_t xga_device = {
|
||||||
@@ -2823,7 +2825,7 @@ const device_t xga_device = {
|
|||||||
.local = 0,
|
.local = 0,
|
||||||
.init = xga_init,
|
.init = xga_init,
|
||||||
.close = xga_close,
|
.close = xga_close,
|
||||||
.reset = NULL,
|
.reset = xga_reset,
|
||||||
{ .available = xga_available },
|
{ .available = xga_available },
|
||||||
.speed_changed = xga_speed_changed,
|
.speed_changed = xga_speed_changed,
|
||||||
.force_redraw = xga_force_redraw,
|
.force_redraw = xga_force_redraw,
|
||||||
@@ -2837,7 +2839,7 @@ const device_t xga_isa_device = {
|
|||||||
.local = 0,
|
.local = 0,
|
||||||
.init = xga_init,
|
.init = xga_init,
|
||||||
.close = xga_close,
|
.close = xga_close,
|
||||||
.reset = NULL,
|
.reset = xga_reset,
|
||||||
{ .available = xga_available },
|
{ .available = xga_available },
|
||||||
.speed_changed = xga_speed_changed,
|
.speed_changed = xga_speed_changed,
|
||||||
.force_redraw = xga_force_redraw,
|
.force_redraw = xga_force_redraw,
|
||||||
|
|||||||
Reference in New Issue
Block a user