Merge pull request #4919 from 86Box/tc1995

Big video changes of the day (October 26th, 2024)
This commit is contained in:
Miran Grča
2024-10-26 21:37:35 +02:00
committed by GitHub
13 changed files with 3029 additions and 4200 deletions

View File

@@ -52,7 +52,7 @@ typedef struct ibm8514_t {
int type;
int local;
int bpp;
int on[2];
int on;
int accel_bpp;
uint32_t vram_size;
@@ -102,6 +102,8 @@ typedef struct ibm8514_t {
uint16_t frgd_mix;
uint16_t multifunc_cntl;
uint16_t multifunc[16];
uint16_t clip_right;
uint16_t clip_bottom;
int16_t clip_left;
int16_t clip_top;
uint8_t pix_trans[2];
@@ -112,8 +114,6 @@ typedef struct ibm8514_t {
int x3;
int y1;
int y2;
int sys_cnt;
int sys_cnt2;
int temp_cnt;
int16_t cx;
int16_t cx_back;
@@ -127,20 +127,14 @@ typedef struct ibm8514_t {
int16_t err;
uint32_t src;
uint32_t dest;
uint32_t newsrc_blt;
uint32_t newdest_blt;
uint32_t newdest_in;
uint32_t newdest_out;
uint8_t *writemono;
uint8_t *nibbleset;
int x_count;
int xx_count;
int y_count;
int input;
int input2;
int output;
int output2;
uint16_t cur_x_bit12;
uint16_t cur_y_bit12;
int ssv_len;
uint8_t ssv_dir;
uint8_t ssv_draw;
@@ -156,7 +150,6 @@ typedef struct ibm8514_t {
} accel;
uint16_t test;
int vendor_mode[2];
int h_blankstart;
int h_blank_end_val;
int hblankstart;
@@ -227,6 +220,11 @@ typedef struct ibm8514_t {
int ext_pitch;
int ext_crt_pitch;
int extensions;
int linear;
int _4bpp;
uint32_t vram_amount;
int vram_512k_8514;
PALETTE _8514pal;
latch8514_t latch;
} ibm8514_t;

View File

@@ -41,8 +41,6 @@ typedef struct mach_t {
int ramdac_type;
int old_mode;
uint32_t memory;
uint16_t config1;
uint16_t config2;
@@ -73,9 +71,7 @@ typedef struct mach_t {
uint8_t bank_r;
uint16_t shadow_set;
uint16_t shadow_cntl;
int ext_on[2];
int extended_mode;
int compat_mode;
int override_resolution;
struct {
uint8_t line_idx;
@@ -84,6 +80,12 @@ typedef struct mach_t {
uint8_t patt_len;
uint8_t pix_trans[2];
uint8_t eeprom_control;
uint8_t alu_bg_fn;
uint8_t alu_fg_fn;
uint16_t clip_left;
uint16_t clip_right;
uint16_t clip_top;
uint16_t clip_bottom;
uint16_t dest_x_end;
uint16_t dest_x_start;
uint16_t dest_y_end;
@@ -102,14 +104,14 @@ typedef struct mach_t {
uint16_t ge_offset_hi;
uint16_t linedraw_opt;
uint16_t max_waitstates;
uint8_t patt_data_idx;
uint8_t patt_data[0x18];
uint16_t scan_to_x;
uint16_t scratch0;
uint16_t scratch1;
uint16_t test;
uint16_t pattern;
uint16_t test2;
int patt_data_idx_reg;
int patt_data_idx;
int src_y_dir;
int cmd_type;
int block_write_mono_pattern_enable;
@@ -144,9 +146,8 @@ typedef struct mach_t {
int stepx;
int stepy;
int src_stepx;
uint8_t color_pattern[16];
uint8_t color_pattern_full[32];
uint16_t color_pattern_word[8];
uint8_t mono_pattern_normal[16];
uint8_t color_pattern[32];
int mono_pattern[8][8];
uint32_t ge_offset;
uint32_t crt_offset;

View File

@@ -369,6 +369,7 @@ uint32_t svga_mask_addr(uint32_t addr, svga_t *svga);
uint32_t svga_mask_changedaddr(uint32_t addr, svga_t *svga);
void svga_doblit(int wx, int wy, svga_t *svga);
void svga_poll(void *priv);
enum {
RAMDAC_6BIT = 0,
@@ -396,6 +397,9 @@ extern void att498_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv
extern uint8_t att498_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga);
extern float av9194_getclock(int clock, void *priv);
extern void bt481_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga);
extern uint8_t bt481_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga);
extern void bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svga_t *svga);
extern uint8_t bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga);
extern void bt48x_recalctimings(void *priv, svga_t *svga);
@@ -452,6 +456,7 @@ extern const device_t att491_ramdac_device;
extern const device_t att492_ramdac_device;
extern const device_t att498_ramdac_device;
extern const device_t av9194_device;
extern const device_t bt481_ramdac_device;
extern const device_t bt484_ramdac_device;
extern const device_t att20c504_ramdac_device;
extern const device_t bt485_ramdac_device;

View File

@@ -31,13 +31,11 @@ typedef struct xga_hwcursor_t {
} xga_hwcursor_t;
typedef struct xga_t {
mem_mapping_t membios_mapping;
mem_mapping_t memio_mapping;
mem_mapping_t linear_mapping;
mem_mapping_t video_mapping;
rom_t bios_rom;
rom_t membios_rom;
rom_t vga_bios_rom;
rom_t bios_rom2;
xga_hwcursor_t hwcursor;
xga_hwcursor_t hwcursor_latch;
PALETTE extpal;
@@ -153,6 +151,7 @@ typedef struct xga_t {
int a5_test;
int type;
int bus;
int busy;
uint32_t linear_base;
uint32_t linear_size;

View File

@@ -19,7 +19,7 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c
vid_sigma.c vid_wy700.c vid_ega.c vid_ega_render.c vid_svga.c vid_8514a.c
vid_svga_render.c vid_ddc.c vid_vga.c vid_ati_eeprom.c vid_ati18800.c
vid_ati28800.c vid_ati_mach8.c vid_ati_mach64.c vid_ati68875_ramdac.c
vid_ati68860_ramdac.c vid_bt48x_ramdac.c vid_chips_69000.c
vid_ati68860_ramdac.c vid_bt481_ramdac.c vid_bt48x_ramdac.c vid_chips_69000.c
vid_av9194.c vid_icd2061.c vid_ics2494.c vid_ics2595.c vid_cl54xx.c
vid_et3000.c vid_et4000.c vid_sc1148x_ramdac.c vid_sc1502x_ramdac.c
vid_et4000w32.c vid_stg_ramdac.c vid_ht216.c vid_oak_oti.c vid_paradise.c

File diff suppressed because it is too large Load Diff

View File

@@ -74,16 +74,16 @@ ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga)
switch (addr) {
case 0:
svga_out((dev && (dev->on[0] || dev->on[1])) ? 0x2ec : 0x3c8, val, svga);
svga_out((dev && dev->on) ? 0x2ec : 0x3c8, val, svga);
break;
case 1:
svga_out((dev && (dev->on[0] || dev->on[1])) ? 0x2ed : 0x3c9, val, svga);
svga_out((dev && dev->on) ? 0x2ed : 0x3c9, val, svga);
break;
case 2:
svga_out((dev && (dev->on[0] || dev->on[1])) ? 0x2ea : 0x3c6, val, svga);
svga_out((dev && dev->on) ? 0x2ea : 0x3c6, val, svga);
break;
case 3:
svga_out((dev && (dev->on[0] || dev->on[1])) ? 0x2eb : 0x3c7, val, svga);
svga_out((dev && dev->on) ? 0x2eb : 0x3c7, val, svga);
break;
default:
ramdac->regs[addr & 0xf] = val;
@@ -181,16 +181,16 @@ ati68860_ramdac_in(uint16_t addr, void *priv, svga_t *svga)
switch (addr) {
case 0:
temp = svga_in((dev && (dev->on[0] || dev->on[1])) ? 0x2ec : 0x3c8, svga);
temp = svga_in((dev && dev->on) ? 0x2ec : 0x3c8, svga);
break;
case 1:
temp = svga_in((dev && (dev->on[0] || dev->on[1])) ? 0x2ed : 0x3c9, svga);
temp = svga_in((dev && dev->on) ? 0x2ed : 0x3c9, svga);
break;
case 2:
temp = svga_in((dev && (dev->on[0] || dev->on[1])) ? 0x2ea : 0x3c6, svga);
temp = svga_in((dev && dev->on) ? 0x2ea : 0x3c6, svga);
break;
case 3:
temp = svga_in((dev && (dev->on[0] || dev->on[1])) ? 0x2eb : 0x3c7, svga);
temp = svga_in((dev && dev->on) ? 0x2eb : 0x3c7, svga);
break;
case 4:
case 8:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,160 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Emulation of the Brooktree BT481 true colour RAMDAC
* family.
*
*
*
* Authors: TheCollector1995.
*
* Copyright 2024 TheCollector1995.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/timer.h>
#include <86box/video.h>
#include <86box/vid_svga.h>
typedef struct bt481_ramdac_t {
int state;
uint8_t cmd;
} bt481_ramdac_t;
static void
bt481_ramdac_command(uint8_t val, void *priv, svga_t *svga)
{
bt481_ramdac_t *ramdac = (bt481_ramdac_t *) priv;
ramdac->cmd = val;
pclog("RAMDAC CMD=%02x.\n", val);
switch ((ramdac->cmd >> 4) & 0x0f) {
default:
case 0x00:
svga->bpp = 8;
break;
case 0x08:
case 0x0a:
svga->bpp = 15;
break;
case 0x09:
case 0x0c:
svga->bpp = 16;
break;
case 0x0e:
case 0x0f:
svga->bpp = 24;
break;
}
svga_recalctimings(svga);
}
void
bt481_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga)
{
bt481_ramdac_t *ramdac = (bt481_ramdac_t *) priv;
uint8_t rs = (addr & 0x03) | ((!!rs2) << 2);
switch (rs) {
case 0x00:
case 0x01:
case 0x03:
case 0x04:
case 0x05:
case 0x07:
svga_out(addr, val, svga);
ramdac->state = 0;
break;
case 0x02:
pclog("RAMDAC Write State=%x.\n", ramdac->state);
switch (ramdac->state) {
case 4:
bt481_ramdac_command(val, ramdac, svga);
break;
default:
svga_out(addr, val, svga);
break;
}
break;
case 0x06:
bt481_ramdac_command(val, ramdac, svga);
ramdac->state = 0;
break;
default:
break;
}
}
uint8_t
bt481_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga)
{
bt481_ramdac_t * ramdac = (bt481_ramdac_t *) priv;
uint8_t temp = 0xff;
uint8_t rs = (addr & 0x03) | ((!!rs2) << 2);
switch (rs) {
case 0x02:
case 0x06:
switch (ramdac->state) {
case 4:
temp = ramdac->cmd;
break;
default:
temp = svga_in(addr, svga);
ramdac->state++;
break;
}
break;
default:
temp = svga_in(addr, svga);
ramdac->state = 0;
break;
}
pclog("RAMDAC IN=%02x, ret=%02x.\n", rs, temp);
return temp;
}
static void *
bt481_ramdac_init(const device_t *info)
{
bt481_ramdac_t *ramdac = (bt481_ramdac_t *) malloc(sizeof(bt481_ramdac_t));
memset(ramdac, 0, sizeof(bt481_ramdac_t));
return ramdac;
}
static void
bt481_ramdac_close(void *priv)
{
bt481_ramdac_t *ramdac = (bt481_ramdac_t *) priv;
if (ramdac)
free(ramdac);
}
const device_t bt481_ramdac_device = {
.name = "Brooktree Bt481 RAMDAC",
.internal_name = "bt481_ramdac",
.flags = 0,
.local = 0,
.init = bt481_ramdac_init,
.close = bt481_ramdac_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -303,7 +303,7 @@ paradise_remap(paradise_t *paradise)
void
paradise_recalctimings(svga_t *svga)
{
const paradise_t *paradise = (paradise_t *) svga->priv;
paradise_t *paradise = (paradise_t *) svga->priv;
svga->lowres = !(svga->gdcreg[0x0e] & 0x01);
@@ -337,15 +337,11 @@ paradise_recalctimings(svga_t *svga)
svga->hdisp >>= 1;
if (svga->hdisp == 788)
svga->hdisp += 12;
if (svga->hdisp == 800)
svga->ma_latch -= 3;
} else if (svga->bpp == 15) {
svga->render = svga_render_15bpp_highres;
svga->hdisp >>= 1;
if (svga->hdisp == 788)
svga->hdisp += 12;
if (svga->hdisp == 800)
svga->ma_latch -= 3;
} else
svga->render = svga_render_8bpp_highres;
@@ -366,6 +362,11 @@ paradise_write(uint32_t addr, uint8_t val, void *priv)
uint32_t prev_addr;
uint32_t prev_addr2;
if (!(svga->attrregs[0x10] & 0x40)) {
svga_write(addr, val, svga);
return;
}
addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3];
/*Could be done in a better way but it works.*/
@@ -399,6 +400,11 @@ paradise_writew(uint32_t addr, uint16_t val, void *priv)
uint32_t prev_addr;
uint32_t prev_addr2;
if (!(svga->attrregs[0x10] & 0x40)) {
svga_writew(addr, val, svga);
return;
}
addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3];
/*Could be done in a better way but it works.*/
@@ -432,6 +438,9 @@ paradise_read(uint32_t addr, void *priv)
uint32_t prev_addr;
uint32_t prev_addr2;
if (!(svga->attrregs[0x10] & 0x40))
return svga_read(addr, svga);
addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3];
/*Could be done in a better way but it works.*/
@@ -465,6 +474,9 @@ paradise_readw(uint32_t addr, void *priv)
uint32_t prev_addr;
uint32_t prev_addr2;
if (!(svga->attrregs[0x10] & 0x40))
return svga_readw(addr, svga);
addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3];
/*Could be done in a better way but it works.*/

File diff suppressed because it is too large Load Diff

View File

@@ -149,13 +149,13 @@ svga_out(uint16_t addr, uint8_t val, void *priv)
case 2:
index = dev->dac_addr & 0xff;
dev->dac_b = val;
svga->vgapal[index].r = dev->dac_r;
svga->vgapal[index].g = dev->dac_g;
svga->vgapal[index].b = dev->dac_b;
dev->_8514pal[index].r = dev->dac_r;
dev->_8514pal[index].g = dev->dac_g;
dev->_8514pal[index].b = dev->dac_b;
if (svga->ramdac_type == RAMDAC_8BIT)
dev->pallook[index] = makecol32(svga->vgapal[index].r, svga->vgapal[index].g, svga->vgapal[index].b);
dev->pallook[index] = makecol32(dev->_8514pal[index].r, dev->_8514pal[index].g, dev->_8514pal[index].b);
else
dev->pallook[index] = makecol32(video_6to8[svga->vgapal[index].r & 0x3f], video_6to8[svga->vgapal[index].g & 0x3f], video_6to8[svga->vgapal[index].b & 0x3f]);
dev->pallook[index] = makecol32(video_6to8[dev->_8514pal[index].r & 0x3f], video_6to8[dev->_8514pal[index].g & 0x3f], video_6to8[dev->_8514pal[index].b & 0x3f]);
dev->dac_pos = 0;
dev->dac_addr = (dev->dac_addr + 1) & 0xff;
break;
@@ -221,11 +221,8 @@ svga_out(uint16_t addr, uint8_t val, void *priv)
case 0x3c3:
if (xga_active && xga)
xga->on = (val & 0x01) ? 0 : 1;
if (ibm8514_active && dev) {
dev->on[0] = (val & 0x01) ? 0 : 1;
if (dev->local & 0xff)
dev->on[1] = dev->on[0];
}
if (ibm8514_active && dev)
dev->on = (val & 0x01) ? 0 : 1;
svga_log("3C3: VGA ON = %d.\n", val & 0x01);
vga_on = val & 0x01;
@@ -399,24 +396,24 @@ svga_in(uint16_t addr, void *priv)
case 0:
dev->dac_pos++;
if (svga->ramdac_type == RAMDAC_8BIT)
ret = svga->vgapal[index].r;
ret = dev->_8514pal[index].r;
else
ret = svga->vgapal[index].r & 0x3f;
ret = dev->_8514pal[index].r & 0x3f;
break;
case 1:
dev->dac_pos++;
if (svga->ramdac_type == RAMDAC_8BIT)
ret = svga->vgapal[index].g;
ret = dev->_8514pal[index].g;
else
ret = svga->vgapal[index].g & 0x3f;
ret = dev->_8514pal[index].g & 0x3f;
break;
case 2:
dev->dac_pos = 0;
dev->dac_addr = (dev->dac_addr + 1) & 0xff;
if (svga->ramdac_type == RAMDAC_8BIT)
ret = svga->vgapal[index].b;
ret = dev->_8514pal[index].b;
else
ret = svga->vgapal[index].b & 0x3f;
ret = dev->_8514pal[index].b & 0x3f;
break;
default:
@@ -551,11 +548,11 @@ svga_set_ramdac_type(svga_t *svga, int type)
for (int c = 0; c < 256; c++) {
if (ibm8514_active && dev) {
if (svga->ramdac_type == RAMDAC_8BIT)
dev->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b);
dev->pallook[c] = makecol32(dev->_8514pal[c].r, dev->_8514pal[c].g, dev->_8514pal[c].b);
else
dev->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4,
(svga->vgapal[c].g & 0x3f) * 4,
(svga->vgapal[c].b & 0x3f) * 4);
dev->pallook[c] = makecol32((dev->_8514pal[c].r & 0x3f) * 4,
(dev->_8514pal[c].g & 0x3f) * 4,
(dev->_8514pal[c].b & 0x3f) * 4);
}
if (xga_active && xga) {
if (svga->ramdac_type == RAMDAC_8BIT)
@@ -829,7 +826,7 @@ svga_recalctimings(svga_t *svga)
#ifdef TBD
if (ibm8514_active && (svga->dev8514 != NULL)) {
if (dev->on[0] || dev->on[1]) {
if (dev->on) {
uint32_t dot8514 = dev->h_blankstart;
uint32_t adj_dot8514 = dev->h_blankstart;
uint32_t eff_mask8514 = 0x0000003f;
@@ -867,7 +864,7 @@ svga_recalctimings(svga_t *svga)
crtcconst = svga->clock * svga->char_width;
if (ibm8514_active && (svga->dev8514 != NULL)) {
if (dev->on[0] || dev->on[1])
if (dev->on)
crtcconst8514 = svga->clock8514;
}
@@ -912,7 +909,7 @@ svga_recalctimings(svga_t *svga)
_dispontime = svga->hdisp_time;
if (ibm8514_active && (svga->dev8514 != NULL)) {
if (dev->on[0] || dev->on[1]) {
if (dev->on) {
disptime8514 = dev->h_total ? dev->h_total : TIMER_USEC;
_dispontime8514 = dev->hdisped;
}
@@ -935,7 +932,7 @@ svga_recalctimings(svga_t *svga)
svga->dispofftime = TIMER_USEC;
if (ibm8514_active && (svga->dev8514 != NULL)) {
if (dev->on[0] || dev->on[1]) {
if (dev->on) {
_dispofftime8514 = disptime8514 - _dispontime8514;
_dispontime8514 *= crtcconst8514;
_dispofftime8514 *= crtcconst8514;
@@ -1464,9 +1461,10 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv)
if (!linear) {
xga_write_test(addr, val, svga);
addr = svga_decode_addr(svga, addr, 1);
if (addr == 0xffffffff)
if (addr == 0xffffffff) {
svga_log("WriteCommon Over.\n");
return;
}
}
if (!(svga->gdcreg[6] & 1))
@@ -1498,8 +1496,10 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv)
if (svga->translate_address)
addr = svga->translate_address(addr, priv);
if (addr >= svga->vram_max)
if (addr >= svga->vram_max) {
svga_log("WriteBankedOver=%08x, val=%02x.\n", addr & svga->vram_mask, val);
return;
}
addr &= svga->vram_mask;
@@ -1651,7 +1651,6 @@ svga_read_common(uint32_t addr, uint8_t linear, void *priv)
if (!linear) {
(void) xga_read_test(addr, svga);
addr = svga_decode_addr(svga, addr, 0);
if (addr == 0xffffffff)
return 0xff;
}
@@ -1873,6 +1872,8 @@ svga_writew_common(uint32_t addr, uint16_t val, uint8_t linear, void *priv)
cycles -= svga->monitor->mon_video_timing_write_w;
if (!linear) {
xga_write_test(addr, val & 0xff, svga);
xga_write_test(addr + 1, val >> 8, svga);
addr = svga_decode_addr(svga, addr, 1);
if (addr == 0xffffffff)
@@ -1929,6 +1930,10 @@ svga_writel_common(uint32_t addr, uint32_t val, uint8_t linear, void *priv)
cycles -= svga->monitor->mon_video_timing_write_l;
if (!linear) {
xga_write_test(addr, val & 0xff, svga);
xga_write_test(addr + 1, (val >> 8) & 0xff, svga);
xga_write_test(addr + 2, (val >> 16) & 0xff, svga);
xga_write_test(addr + 3, (val >> 24) & 0xff, svga);
addr = svga_decode_addr(svga, addr, 1);
if (addr == 0xffffffff)
@@ -1961,6 +1966,7 @@ svga_writel_common(uint32_t addr, uint32_t val, uint8_t linear, void *priv)
}
if (addr >= svga->vram_max)
return;
addr &= svga->vram_mask;
svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount;
@@ -2006,7 +2012,6 @@ svga_readw_common(uint32_t addr, uint8_t linear, void *priv)
if (!linear) {
addr = svga_decode_addr(svga, addr, 0);
if (addr == 0xffffffff)
return 0xffff;
}
@@ -2053,7 +2058,6 @@ svga_readl_common(uint32_t addr, uint8_t linear, void *priv)
if (!linear) {
addr = svga_decode_addr(svga, addr, 0);
if (addr == 0xffffffff)
return 0xffffffff;
}

View File

@@ -54,6 +54,13 @@ static void xga_render_4bpp(svga_t *svga);
static void xga_render_8bpp(svga_t *svga);
static void xga_render_16bpp(svga_t *svga);
static void xga_write(uint32_t addr, uint8_t val, void *priv);
static void xga_writew(uint32_t addr, uint16_t val, void *priv);
static void xga_writel(uint32_t addr, uint32_t val, void *priv);
static uint8_t xga_read(uint32_t addr, void *priv);
static uint16_t xga_readw(uint32_t addr, void *priv);
static uint32_t xga_readl(uint32_t addr, void *priv);
int xga_active = 0;
#ifdef ENABLE_XGA_LOG
@@ -184,7 +191,7 @@ xga_updatemapping(svga_t *svga)
xga_log("XGA: Extended Graphics mode.\n");
switch (xga->aperture_cntl) {
case 0:
xga_log("XGA: No 64KB aperture: 1MB=%x, 4MB=%x.\n", xga->base_addr_1mb, xga->linear_base);
xga_log("XGA: No 64KB aperture: 1MB=%x, 4MB=%x, SVGA Mapping Base=%x.\n", xga->base_addr_1mb, xga->linear_base, svga->mapping.base);
if (xga->base_addr_1mb) {
mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000);
mem_mapping_enable(&xga->linear_mapping);
@@ -194,18 +201,39 @@ xga_updatemapping(svga_t *svga)
} else
mem_mapping_disable(&xga->linear_mapping);
mem_mapping_disable(&xga->video_mapping);
mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
switch (svga->gdcreg[6] & 0xc) {
case 0x0: /*128k at A0000*/
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
svga->banked_mask = 0xffff;
break;
case 0x4: /*64k at A0000*/
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
svga->banked_mask = 0xffff;
break;
case 0x8: /*32k at B0000*/
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
svga->banked_mask = 0x7fff;
break;
case 0xC: /*32k at B8000*/
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
svga->banked_mask = 0x7fff;
break;
default:
break;
}
break;
case 1:
xga_log("XGA: 64KB aperture at A0000.\n");
mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000);
mem_mapping_enable(&xga->video_mapping);
mem_mapping_set_handler(&svga->mapping, xga_read, xga_readw, xga_readl, xga_write, xga_writew, xga_writel);
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
xga->banked_mask = 0xffff;
break;
case 2:
xga_log("XGA: 64KB aperture at B0000.\n");
mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000);
mem_mapping_enable(&xga->video_mapping);
mem_mapping_set_handler(&svga->mapping, xga_read, xga_readw, xga_readl, xga_write, xga_writew, xga_writel);
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x10000);
xga->banked_mask = 0xffff;
break;
default:
@@ -244,7 +272,7 @@ xga_recalctimings(svga_t *svga)
xga->ma_latch = xga->disp_start_addr;
xga_log("XGA ClkSel1 = %d, ClkSel2 = %02x.\n", (xga->clk_sel_1 >> 2) & 3, xga->clk_sel_2 & 0x80);
xga_log("XGA ClkSel1 = %d, ClkSel2 = %02x, dispcntl2=%02x.\n", (xga->clk_sel_1 >> 2) & 3, xga->clk_sel_2 & 0x80, xga->disp_cntl_2 & 0xc0);
switch ((xga->clk_sel_1 >> 2) & 3) {
case 0:
xga_log("HDISP VGA0 = %d, XGA = %d.\n", svga->hdisp, xga->h_disp);
@@ -798,19 +826,10 @@ xga_ext_inb(uint16_t addr, void *priv)
#define READW(addr, dat) \
dat = *(uint16_t *) &xga->vram[(addr) & (xga->vram_mask)];
#define READW_INV(addr, dat) \
dat = xga->vram[(addr + 1) & (xga->vram_mask)]; \
dat |= (xga->vram[(addr) & (xga->vram_mask)] << 8);
#define WRITEW(addr, dat) \
*(uint16_t *) &xga->vram[((addr)) & (xga->vram_mask)] = dat; \
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount;
#define WRITEW_INV(addr, dat) \
xga->vram[((addr + 1)) & (xga->vram_mask)] = dat & 0xff; \
xga->vram[((addr)) & (xga->vram_mask)] = dat >> 8; \
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount;
#define ROP(mix, d, s) \
{ \
switch ((mix) ? (xga->accel.frgd_mix & 0x1f) : (xga->accel.bkgd_mix & 0x1f)) { \
@@ -884,7 +903,7 @@ xga_ext_inb(uint16_t addr, void *priv)
}
static uint32_t
xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int width)
xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, uint32_t base, int width)
{
const xga_t *xga = (xga_t *) svga->xga;
uint32_t addr = base;
@@ -903,27 +922,19 @@ xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t b
} else
byte = mem_readb_phys(addr);
if (xga->linear_endian_reverse)
bits = 7 - (x & 7);
else {
if (xga->accel.px_map_format[xga->accel.dst_map] & 8) {
if ((xga->accel.px_map_format[xga->accel.src_map] & 8) && (xga->accel.px_map_format[map] & 8))
bits = (x & 7);
else
bits = 7 - (x & 7);
} else {
if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8))
bits = (x & 7);
else
bits = 7 - (x & 7);
}
bits = 7 - (x & 7);
if (!(xga->accel.px_map_format[xga->accel.src_map] & 0x08) && !(xga->accel.px_map_format[xga->accel.dst_map] & 0x08)) {
if (((xga->accel.px_map_format[xga->accel.src_map] & 0x07) >= 0x02) && ((xga->accel.px_map_format[xga->accel.dst_map] & 0x07) >= 0x02))
bits ^= 7;
}
px = (byte >> bits) & 1;
return px;
}
static uint32_t
xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int width, UNUSED(int usesrc))
xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int width)
{
xga_t *xga = (xga_t *) svga->xga;
uint32_t addr = base;
@@ -935,7 +946,7 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int
if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff)))
skip = 1;
switch (xga->accel.px_map_format[map] & 7) {
switch (xga->accel.px_map_format[map] & 0x07) {
case 0: /*1-bit*/
addr += (y * (width >> 3));
addr += (x >> 3);
@@ -944,14 +955,11 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int
} else
byte = mem_readb_phys(addr);
if (xga->linear_endian_reverse)
if (xga->accel.px_map_format[map] & 0x08)
bits = (x & 7);
else
bits = 7 - (x & 7);
else {
if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8))
bits = (x & 7);
else
bits = 7 - (x & 7);
}
px = (byte >> bits) & 1;
return px;
case 2: /*4-bit*/
@@ -975,17 +983,19 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int
case 4: /*16-bit*/
addr += (y * (width << 1));
addr += (x << 1);
if (xga->linear_endian_reverse) {
byte = mem_readw_phys(addr);
if ((xga->access_mode & 7) == 4)
byte = ((byte & 0xff00) >> 8) | ((byte & 0x00ff) << 8);
else if (xga->access_mode & 8)
byte = ((byte & 0xff00) >> 8) | ((byte & 0x00ff) << 8);
} else {
if (xga->access_mode & 0x08) {
if (!skip) {
READW(addr, byte);
} else
byte = mem_readb_phys(addr) | (mem_readb_phys(addr + 1) << 8);
byte = mem_readw_phys(addr);
} else {
if (!skip) {
READW(addr, byte);
} else {
byte = mem_readw_phys(addr);
if ((xga->access_mode & 0x07) == 0x04)
byte = ((byte & 0xff00) >> 8) | ((byte & 0x00ff) << 8);
}
}
return byte;
@@ -1007,7 +1017,7 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui
if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff)))
skip = 1;
switch (xga->accel.px_map_format[map] & 7) {
switch (xga->accel.px_map_format[map] & 0x07) {
case 0: /*1-bit*/
addr += (y * (width >> 3));
addr += (x >> 3);
@@ -1016,15 +1026,11 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui
} else
byte = mem_readb_phys(addr);
if (xga->linear_endian_reverse) {
if ((xga->accel.px_map_format[map] & 0x08) || (xga->accel.px_map_format[xga->accel.src_map] & 0x08))
mask = 1 << (x & 7);
else
mask = 1 << (7 - (x & 7));
} else {
if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) {
mask = 1 << (x & 7);
} else {
mask = 1 << (7 - (x & 7));
}
}
byte = (byte & ~mask) | ((pixel ? 0xff : 0) & mask);
if (pixel & 1) {
if (!skip) {
@@ -1044,18 +1050,14 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui
addr += (x >> 1);
if (!skip) {
READ(addr, byte);
} else {
} else
byte = mem_readb_phys(addr);
}
if (xga->linear_endian_reverse)
if (xga->accel.px_map_format[map] & 0x08)
mask = 0x0f << ((x & 1) << 2);
else
mask = 0x0f << ((1 - (x & 1)) << 2);
else {
if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8))
mask = 0x0f << ((x & 1) << 2);
else
mask = 0x0f << ((1 - (x & 1)) << 2);
}
byte = (byte & ~mask) | (pixel & mask);
if (!skip) {
WRITE(addr, byte);
@@ -1073,14 +1075,16 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui
case 4: /*16-bit*/
addr += (y * width << 1);
addr += (x << 1);
if (xga->linear_endian_reverse) {
if ((xga->access_mode & 7) == 4)
pixel = ((pixel & 0xff00) >> 8) | ((pixel & 0x00ff) << 8);
else if (xga->access_mode & 8)
pixel = ((pixel & 0xff00) >> 8) | ((pixel & 0x00ff) << 8);
if (xga->access_mode & 0x08) {
if (!skip) {
WRITEW(addr, pixel);
}
} else {
if (!skip) {
WRITEW(addr, pixel);
} else {
if ((xga->access_mode & 0x07) == 0x04)
pixel = ((pixel & 0xff00) >> 8) | ((pixel & 0x00ff) << 8);
}
}
mem_writew_phys(addr, pixel);
@@ -1159,8 +1163,8 @@ xga_short_stroke(svga_t *svga, uint8_t ssv)
while (y >= 0) {
if (xga->accel.command & 0xc0) {
if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0);
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
@@ -1179,8 +1183,8 @@ xga_short_stroke(svga_t *svga, uint8_t ssv)
}
}
} else {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0);
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
@@ -1270,8 +1274,8 @@ xga_line_draw_write(svga_t *svga)
if (xga->accel.command & 0xc0) {
if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) {
if (draw_pixel) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, cx, cy, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0);
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, cx, cy, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
ROP(1, dest_dat, src_dat);
@@ -1281,8 +1285,8 @@ xga_line_draw_write(svga_t *svga)
}
} else {
if (draw_pixel) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, cx, cy, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0);
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, cx, cy, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
ROP(1, dest_dat, src_dat);
@@ -1330,8 +1334,8 @@ xga_line_draw_write(svga_t *svga)
while (y >= 0) {
if (xga->accel.command & 0xc0) {
if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0);
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
@@ -1346,8 +1350,8 @@ xga_line_draw_write(svga_t *svga)
}
}
} else {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0);
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
@@ -1465,7 +1469,7 @@ xga_bitblt(svga_t *svga)
else {
if ((dstwidth == (xga->h_disp - 1)) && (srcwidth == 1)) {
if ((xga->accel.dst_map == 1) && (xga->accel.src_map == 2)) {
if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0b) && (xga->accel.px_map_format[xga->accel.src_map] >= 0x0b))
if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0a) && (xga->accel.px_map_format[xga->accel.src_map] >= 0x0a))
xga->accel.pattern = 1;
}
}
@@ -1486,8 +1490,8 @@ xga_bitblt(svga_t *svga)
while (xga->accel.y >= 0) {
if (xga->accel.command & 0xc0) {
if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : frgdcol;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(1, dest_dat, src_dat);
@@ -1497,8 +1501,8 @@ xga_bitblt(svga_t *svga)
}
} else {
if ((dx >= 0) && (dx <= dstwidth) && (dy >= 0) && (dy <= dstheight)) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : frgdcol;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(1, dest_dat, src_dat);
@@ -1549,12 +1553,12 @@ xga_bitblt(svga_t *svga)
if (dstwidth == (xga->h_disp - 1)) {
if (srcwidth == (xga->h_disp - 1)) {
if ((xga->accel.src_map == 1) && (xga->accel.dst_map == 1) && (xga->accel.pat_src == 2)) {
if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0b) && (xga->accel.px <= 7) && (xga->accel.py <= 3))
if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0a) && (xga->accel.px <= 7) && (xga->accel.py <= 3))
xga->accel.pattern = 1;
}
} else {
if (!xga->accel.src_map && (xga->accel.dst_map == 1) && (xga->accel.pat_src == 2)) {
if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0b) && (xga->accel.px <= 7) && (xga->accel.py <= 3)) {
if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0a) && (xga->accel.px <= 7) && (xga->accel.py <= 3)) {
if ((patwidth >= 7) && ((xga->accel.command & 0xc0) == 0x40))
xga->accel.pattern = 0;
else
@@ -1585,15 +1589,15 @@ xga_bitblt(svga_t *svga)
if ((((xga->accel.command >> 24) & 0x0f) == 0x0a) && ((xga->accel.bkgd_mix & 0x1f) == 5)) {
while (xga->accel.y >= 0) {
mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, xga->accel.pat_src, patbase, patwidth + 1);
mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, patbase, patwidth + 1);
if (mix)
xga->accel.filling = !xga->accel.filling;
if (xga->accel.command & 0xc0) {
if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol;
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : frgdcol;
if (xga->accel.filling) {
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, 1024, 0);
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, 1024);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(1, dest_dat, src_dat);
@@ -1605,9 +1609,9 @@ xga_bitblt(svga_t *svga)
}
} else {
if ((dx >= 0) && (dx <= dstwidth) && (dy >= 0) && (dy <= dstheight)) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol;
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : frgdcol;
if (xga->accel.filling) {
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(1, dest_dat, src_dat);
@@ -1647,16 +1651,16 @@ xga_bitblt(svga_t *svga)
}
} else {
while (xga->accel.y >= 0) {
mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, xga->accel.pat_src, patbase, patwidth + 1);
mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, patbase, patwidth + 1);
if (xga->accel.command & 0xc0) {
if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) {
if (mix)
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol;
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : frgdcol;
else
src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol;
src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : bkgdcol;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(mix, dest_dat, src_dat);
@@ -1667,11 +1671,11 @@ xga_bitblt(svga_t *svga)
} else {
if ((dx >= 0) && (dx <= dstwidth) && (dy >= 0) && (dy <= dstheight)) {
if (mix)
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol;
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : frgdcol;
else
src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol;
src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : bkgdcol;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(mix, dest_dat, src_dat);
@@ -1800,6 +1804,10 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len)
case 0x1c:
xga->accel.px_map_format[xga->accel.px_map_idx] = val;
if (val & 0x08)
xga_log("Big Endian Pixel Format=%d, AccessMode=%x.\n", xga->accel.px_map_idx, xga->access_mode & 0x08);
else
xga_log("Little Endian Pixel Format=%d, AccessMode=%x.\n", xga->accel.px_map_idx, xga->access_mode & 0x08);
break;
case 0x20:
@@ -2155,6 +2163,7 @@ exec_command:
xga->accel.pat_src = ((xga->accel.command >> 12) & 0x0f);
xga->accel.dst_map = ((xga->accel.command >> 16) & 0x0f);
xga->accel.src_map = ((xga->accel.command >> 20) & 0x0f);
xga_log("PATMAP=%x, DSTMAP=%x, SRCMAP=%x.\n", xga->accel.px_map_format[xga->accel.pat_src], xga->accel.px_map_format[xga->accel.dst_map], xga->accel.px_map_format[xga->accel.src_map]);
#ifdef ENABLE_XGA_LOG
if (xga->accel.pat_src)
@@ -2531,29 +2540,21 @@ xga_render_4bpp(svga_t *svga)
xga->lastline_draw = xga->displine;
for (int x = 0; x <= xga->h_disp; x += 16) {
for (int x = 0; x <= xga->h_disp; x += 8) {
dat = *(uint32_t *) (&xga->vram[xga->ma & xga->vram_mask]);
p[0] = xga->pallook[dat & 0x0f];
p[1] = xga->pallook[(dat >> 4) & 0x0f];
p[2] = xga->pallook[(dat >> 8) & 0x0f];
p[3] = xga->pallook[(dat >> 12) & 0x0f];
p[4] = xga->pallook[(dat >> 16) & 0x0f];
p[5] = xga->pallook[(dat >> 20) & 0x0f];
p[6] = xga->pallook[(dat >> 24) & 0x0f];
p[7] = xga->pallook[(dat >> 28) & 0x0f];
p[1] = xga->pallook[(dat >> 8) & 0x0f];
p[2] = xga->pallook[(dat >> 16) & 0x0f];
p[3] = xga->pallook[(dat >> 24) & 0x0f];
dat = *(uint32_t *) (&xga->vram[(xga->ma + 4) & xga->vram_mask]);
p[8] = xga->pallook[dat & 0x0f];
p[9] = xga->pallook[(dat >> 4) & 0x0f];
p[10] = xga->pallook[(dat >> 8) & 0x0f];
p[11] = xga->pallook[(dat >> 12) & 0x0f];
p[12] = xga->pallook[(dat >> 16) & 0x0f];
p[13] = xga->pallook[(dat >> 20) & 0x0f];
p[14] = xga->pallook[(dat >> 24) & 0x0f];
p[15] = xga->pallook[(dat >> 28) & 0x0f];
dat = *(uint32_t *) (&xga->vram[(xga->ma + 2) & xga->vram_mask]);
p[4] = xga->pallook[dat & 0x0f];
p[5] = xga->pallook[(dat >> 8) & 0x0f];
p[6] = xga->pallook[(dat >> 16) & 0x0f];
p[7] = xga->pallook[(dat >> 24) & 0x0f];
xga->ma += 8;
p += 16;
p += 8;
}
xga->ma &= xga->vram_mask;
}
@@ -2643,7 +2644,8 @@ xga_write_test(uint32_t addr, uint8_t val, void *priv)
xga_t *xga = (xga_t *) svga->xga;
if (xga_active && xga) {
if (((xga->op_mode & 7) >= 1) && (xga->aperture_cntl >= 1)) {
if (((xga->op_mode & 7) >= 1) && xga->aperture_cntl) {
xga_log("WriteAddr=%05x.\n", addr);
if (val == 0xa5) { /*Memory size test of XGA*/
xga->test = val;
if (addr == 0xa0001)
@@ -2653,28 +2655,39 @@ xga_write_test(uint32_t addr, uint8_t val, void *priv)
xga->on = 0;
vga_on = 1;
xga->disp_cntl_2 = 0;
xga_log("XGA test1 addr=%05x, test=%02x.\n", addr, xga->a5_test);
} else if (val == 0x5a) {
xga->test = val;
xga->on = 0;
vga_on = 1;
xga->disp_cntl_2 = 0;
xga_log("XGA test2 addr = %05x.\n", addr);
} else if ((addr == 0xa0000) || (addr == 0xa0010)) {
addr += xga->write_bank;
xga->vram[addr & xga->vram_mask] = val;
xga_log("XGA Linear endian reverse write, val = %02x, addr = %05x, banked mask = %04x, a5test=%d.\n", val, addr, svga->banked_mask, xga->a5_test);
if (!xga->a5_test)
xga->linear_endian_reverse = 1;
}
} else {
} else if (xga->aperture_cntl) {
xga->on = 0;
vga_on = 1;
}
}
}
static void
xga_write_banked(uint32_t addr, uint8_t val, void *priv)
{
svga_t *svga = (svga_t *) priv;
xga_t *xga = (xga_t *) svga->xga;
if (xga->access_mode & 0x08) {
if ((xga->access_mode & 0x07) == 0x04)
addr ^= 1;
}
xga->changedvram[(addr & xga->vram_mask) >> 12] = svga->monitor->mon_changeframecount;
xga->vram[addr & xga->vram_mask] = val;
}
static void
xga_write(uint32_t addr, uint8_t val, void *priv)
{
@@ -2689,33 +2702,45 @@ xga_write(uint32_t addr, uint8_t val, void *priv)
cycles -= svga->monitor->mon_video_timing_write_b;
if (xga->access_mode & 8) {
if ((xga->access_mode & 7) == 4)
addr ^= 1;
}
xga->changedvram[(addr & xga->vram_mask) >> 12] = svga->monitor->mon_changeframecount;
xga->vram[addr & xga->vram_mask] = val;
xga_write_banked(addr, val, svga);
}
static void
xga_writew(uint32_t addr, uint16_t val, void *priv)
{
svga_t *svga = (svga_t *) priv;
svga_t *svga = (svga_t *) priv;
xga_t *xga = (xga_t *) svga->xga;
xga_write(addr, val & 0xff, svga);
xga_write(addr + 1, val >> 8, svga);
addr &= xga->banked_mask;
addr += xga->write_bank;
if (addr >= xga->vram_size)
return;
cycles -= svga->monitor->mon_video_timing_write_w;
xga_write_banked(addr, val & 0xff, svga);
xga_write_banked(addr + 1, val >> 8, svga);
}
static void
xga_writel(uint32_t addr, uint32_t val, void *priv)
{
svga_t *svga = (svga_t *) priv;
svga_t *svga = (svga_t *) priv;
xga_t *xga = (xga_t *) svga->xga;
xga_write(addr, val & 0xff, svga);
xga_write(addr + 1, (val >> 8) & 0xff, svga);
xga_write(addr + 2, (val >> 16) & 0xff, svga);
xga_write(addr + 3, (val >> 24) & 0xff, svga);
addr &= xga->banked_mask;
addr += xga->write_bank;
if (addr >= xga->vram_size)
return;
cycles -= svga->monitor->mon_video_timing_write_l;
xga_write_banked(addr, val & 0xff, svga);
xga_write_banked(addr + 1, val >> 8, svga);
xga_write_banked(addr + 2, val >> 16, svga);
xga_write_banked(addr + 3, val >> 24, svga);
}
uint8_t
@@ -2726,7 +2751,7 @@ xga_read_test(uint32_t addr, void *priv)
uint8_t ret = 0x00;
if (xga_active && xga) {
if (((xga->op_mode & 7) >= 1) && (xga->aperture_cntl >= 1)) {
if (((xga->op_mode & 7) >= 1) && xga->aperture_cntl) {
if (xga->test == 0xa5) { /*Memory size test of XGA*/
if (addr == 0xa0001) {
ret = xga->test;
@@ -2753,7 +2778,7 @@ xga_read_test(uint32_t addr, void *priv)
addr += xga->read_bank;
return xga->vram[addr & xga->vram_mask];
}
} else {
} else if (xga->aperture_cntl) {
xga->on = 0;
vga_on = 1;
}
@@ -2762,12 +2787,29 @@ xga_read_test(uint32_t addr, void *priv)
}
static uint8_t
xga_read(uint32_t addr, void *priv)
xga_read_banked(uint32_t addr, void *priv)
{
svga_t *svga = (svga_t *) priv;
xga_t *xga = (xga_t *) svga->xga;
uint8_t ret = 0xff;
if (xga->access_mode & 0x08) {
if ((xga->access_mode & 0x07) == 0x04)
addr ^= 1;
}
ret = xga->vram[addr & xga->vram_mask];
return ret;
}
static uint8_t
xga_read(uint32_t addr, void *priv)
{
svga_t *svga = (svga_t *) priv;
xga_t *xga = (xga_t *) svga->xga;
uint8_t ret = 0xff;
addr &= xga->banked_mask;
addr += xga->read_bank;
@@ -2778,13 +2820,7 @@ xga_read(uint32_t addr, void *priv)
cycles -= svga->monitor->mon_video_timing_read_b;
if (xga->access_mode & 8) {
if ((xga->access_mode & 7) == 4)
addr ^= 1;
}
ret = xga->vram[addr & xga->vram_mask];
ret = xga_read_banked(addr, svga);
return ret;
}
@@ -2792,11 +2828,21 @@ static uint16_t
xga_readw(uint32_t addr, void *priv)
{
svga_t *svga = (svga_t *) priv;
xga_t *xga = (xga_t *) svga->xga;
uint16_t ret = 0xffff;
ret = xga_read(addr, svga);
ret |= (xga_read(addr + 1, svga) << 8);
addr &= xga->banked_mask;
addr += xga->read_bank;
if (addr >= xga->vram_size) {
xga_log("Over Read ADDR=%x.\n", addr);
return ret;
}
cycles -= svga->monitor->mon_video_timing_read_w;
ret = xga_read_banked(addr, svga);
ret |= (xga_read_banked(addr + 1, svga) << 8);
return ret;
}
@@ -2804,13 +2850,23 @@ static uint32_t
xga_readl(uint32_t addr, void *priv)
{
svga_t *svga = (svga_t *) priv;
xga_t *xga = (xga_t *) svga->xga;
uint32_t ret = 0xffffffff;
ret = xga_read(addr, svga);
ret |= (xga_read(addr + 1, svga) << 8);
ret |= (xga_read(addr + 2, svga) << 16);
ret |= (xga_read(addr + 3, svga) << 24);
addr &= xga->banked_mask;
addr += xga->read_bank;
if (addr >= xga->vram_size) {
xga_log("Over Read ADDR=%x.\n", addr);
return ret;
}
cycles -= svga->monitor->mon_video_timing_read_l;
ret = xga_read_banked(addr, svga);
ret |= (xga_read_banked(addr + 1, svga) << 8);
ret |= (xga_read_banked(addr + 2, svga) << 16);
ret |= (xga_read_banked(addr + 3, svga) << 24);
return ret;
}
@@ -2820,6 +2876,7 @@ xga_write_linear(uint32_t addr, uint8_t val, void *priv)
svga_t *svga = (svga_t *) priv;
xga_t *xga = (xga_t *) svga->xga;
xga_log("WrtieLL XGA=%d.\n", xga->on);
if (!xga->on) {
svga_write_linear(addr, val, svga);
return;
@@ -2834,12 +2891,9 @@ xga_write_linear(uint32_t addr, uint8_t val, void *priv)
cycles -= svga->monitor->mon_video_timing_write_b;
if (xga->linear_endian_reverse) {
if ((xga->access_mode & 7) == 4) {
if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) == 4)
addr ^= 1;
} else if (xga->access_mode & 8) {
if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) == 4)
if (!(xga->access_mode & 0x08)) {
if ((xga->access_mode & 0x07) == 0x04) {
if ((xga->accel.px_map_format[xga->accel.dst_map] & 0x07) == 0x04)
addr ^= 1;
}
}
@@ -2899,12 +2953,9 @@ xga_read_linear(uint32_t addr, void *priv)
cycles -= svga->monitor->mon_video_timing_read_b;
if (xga->linear_endian_reverse) {
if ((xga->access_mode & 7) == 4) {
if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) == 4)
addr ^= 1;
} else if (xga->access_mode & 8) {
if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) == 4)
if (!(xga->access_mode & 0x08)) {
if ((xga->access_mode & 0x07) == 0x04) {
if ((xga->accel.px_map_format[xga->accel.dst_map] & 0x07) == 0x04)
addr ^= 1;
}
}
@@ -3145,11 +3196,12 @@ xga_mca_write(int port, uint8_t val, void *priv)
mem_mapping_disable(&xga->memio_mapping);
xga->on = 0;
vga_on = 1;
xga->linear_endian_reverse = 0;
xga->a5_test = 0;
/* Save the MCA register value. */
xga->pos_regs[port & 7] = val;
if (!(xga->pos_regs[4] & 1) && (mem_size >= 15360)) /*MCA 4MB addressing on systems with more than 16MB of memory*/
xga->pos_regs[4] |= 1;
if (xga->pos_regs[2] & 1) {
xga->instance = (xga->pos_regs[2] & 0x0e) >> 1;
@@ -3184,15 +3236,10 @@ static void
xga_mca_reset(void *priv)
{
svga_t *svga = (svga_t *) priv;
xga_t *xga = (xga_t *) svga->xga;
mem_mapping_disable(&xga->memio_mapping);
xga->on = 0;
vga_on = 1;
xga_log("MCA Reset.\n");
mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
xga_mca_write(0x102, 0, svga);
xga->linear_endian_reverse = 0;
xga->a5_test = 0;
}
static void
@@ -3207,8 +3254,8 @@ xga_reset(void *priv)
xga->on = 0;
vga_on = 1;
xga->linear_endian_reverse = 0;
xga->a5_test = 0;
mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
}
static uint8_t
@@ -3345,8 +3392,11 @@ xga_pos_out(uint16_t addr, uint8_t val, void *priv)
break;
case 0x0104:
xga_log("104Write=%02x.\n", val);
if ((xga->pos_idx & 3) == 0)
if ((xga->pos_idx & 3) == 0) {
xga->pos_regs[4] = val;
if (!(xga->pos_regs[4] & 0x01) && (mem_size >= 15360)) /*4MB addressing on systems with more than 15MB of memory*/
xga->pos_regs[4] |= 0x01;
}
break;
case 0x0105:
xga_log("105Write=%02x.\n", val);
@@ -3405,7 +3455,6 @@ xga_init(const device_t *info)
xga->on = 0;
xga->hwcursor.cur_xsize = 64;
xga->hwcursor.cur_ysize = 64;
xga->linear_endian_reverse = 0;
xga->a5_test = 0;
if (info->flags & DEVICE_MCA) {
@@ -3431,7 +3480,7 @@ xga_init(const device_t *info)
xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xf0) >> 4) * 0x2000);
xga->instance = (xga->pos_regs[2] & 0x0e) >> 1;
xga->pos_regs[2] |= 0x01;
if (mem_size >= 16384) {
if (mem_size >= 15360) {
xga->pos_regs[4] |= 0x01;
xga->pos_regs[5] = 0;
} else {
@@ -3450,9 +3499,6 @@ xga_init(const device_t *info)
}
}
mem_mapping_add(&xga->video_mapping, 0, 0, xga_read, xga_readw, xga_readl,
xga_write, xga_writew, xga_writel,
NULL, MEM_MAPPING_EXTERNAL, svga);
mem_mapping_add(&xga->linear_mapping, 0, 0, xga_read_linear, xga_readw_linear, xga_readl_linear,
xga_write_linear, xga_writew_linear, xga_writel_linear,
NULL, MEM_MAPPING_EXTERNAL, svga);