Added currently disabled set of fixes for the VGA memory management.
- Added disabled definition VGA_MEM_FIX in vgacore.h. The VGA core code works as usual unless you uncomment the define. - Added correct implementation of the "chain four" and "odd/even" addressing mode. This should fix the Debian / GRUB boot issue (#257) with both Bochs VBE and Cirrus. - Added some compatibility code to make the gui text update work as usual. - Tested all VGA modes except 256-color word mode (no test case). - Some more testing with old DOS games may be required before I enable it by default and finally remove the legacy code.
This commit is contained in:
parent
fd68912dc7
commit
945ee597f0
@ -1735,12 +1735,16 @@ void bx_svga_cirrus_c::svga_write_crtc(Bit32u address, unsigned index, Bit8u val
|
||||
|
||||
if (update_pitch) {
|
||||
if ((BX_CIRRUS_THIS crtc.reg[0x1b] & 0x02) != 0) {
|
||||
#ifndef VGA_MEM_FIX
|
||||
if (!BX_CIRRUS_THIS s.sequencer.chain_four) {
|
||||
BX_CIRRUS_THIS s.plane_shift = 19;
|
||||
}
|
||||
#endif
|
||||
BX_CIRRUS_THIS s.ext_offset = BX_CIRRUS_THIS bank_base[0];
|
||||
} else {
|
||||
#ifndef VGA_MEM_FIX
|
||||
BX_CIRRUS_THIS s.plane_shift = 16;
|
||||
#endif
|
||||
BX_CIRRUS_THIS s.ext_offset = 0;
|
||||
}
|
||||
BX_CIRRUS_THIS svga_pitch = (BX_CIRRUS_THIS crtc.reg[0x13] << 3) | ((BX_CIRRUS_THIS crtc.reg[0x1b] & 0x10) << 7);
|
||||
|
@ -578,7 +578,9 @@ void bx_vga_c::update(void)
|
||||
} else {
|
||||
unsigned r, c, x, y;
|
||||
unsigned xc, yc, xti, yti;
|
||||
#ifndef VGA_MEM_FIX
|
||||
Bit8u *plane[4];
|
||||
#endif
|
||||
Bit32u row_addr;
|
||||
|
||||
if (BX_VGA_THIS vbe.yres < 1024) {
|
||||
@ -595,11 +597,12 @@ void bx_vga_c::update(void)
|
||||
BX_VGA_THIS s.last_bpp = 8;
|
||||
}
|
||||
|
||||
#ifndef VGA_MEM_FIX
|
||||
plane[0] = &BX_VGA_THIS s.memory[0<<VBE_DISPI_4BPP_PLANE_SHIFT];
|
||||
plane[1] = &BX_VGA_THIS s.memory[1<<VBE_DISPI_4BPP_PLANE_SHIFT];
|
||||
plane[2] = &BX_VGA_THIS s.memory[2<<VBE_DISPI_4BPP_PLANE_SHIFT];
|
||||
plane[3] = &BX_VGA_THIS s.memory[3<<VBE_DISPI_4BPP_PLANE_SHIFT];
|
||||
|
||||
#endif
|
||||
for (yc=0, yti=0; yc<iHeight; yc+=Y_TILESIZE, yti++) {
|
||||
for (xc=0, xti=0; xc<iWidth; xc+=X_TILESIZE, xti++) {
|
||||
if (GET_TILE_UPDATED (xti, yti)) {
|
||||
@ -610,7 +613,11 @@ void bx_vga_c::update(void)
|
||||
for (c=0; c<X_TILESIZE; c++) {
|
||||
x = xc + c;
|
||||
BX_VGA_THIS s.tile[r*X_TILESIZE + c] =
|
||||
#ifdef VGA_MEM_FIX
|
||||
BX_VGA_THIS get_vga_pixel(x, y, row_addr, 0xffff, 0, BX_VGA_THIS s.memory);
|
||||
#else
|
||||
BX_VGA_THIS get_vga_pixel(x, y, row_addr, 0xffff, 0, plane);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
SET_TILE_UPDATED(BX_VGA_THIS, xti, yti, 0);
|
||||
@ -1139,12 +1146,16 @@ Bit32u bx_vga_c::vbe_write(Bit32u address, Bit32u value, unsigned io_len)
|
||||
BX_VGA_THIS s.last_bpp = depth;
|
||||
BX_VGA_THIS s.last_fh = 0;
|
||||
} else {
|
||||
#ifndef VGA_MEM_FIX
|
||||
BX_VGA_THIS s.plane_shift = VBE_DISPI_4BPP_PLANE_SHIFT;
|
||||
#endif
|
||||
BX_VGA_THIS s.ext_offset = (BX_VGA_THIS vbe.bank[0] << 16);
|
||||
}
|
||||
} else if (((value & VBE_DISPI_ENABLED) == 0) && BX_VGA_THIS vbe.enabled) {
|
||||
BX_INFO(("VBE disabling"));
|
||||
#ifndef VGA_MEM_FIX
|
||||
BX_VGA_THIS s.plane_shift = 16;
|
||||
#endif
|
||||
BX_VGA_THIS s.ext_offset = 0;
|
||||
}
|
||||
BX_VGA_THIS vbe.enabled = ((value & VBE_DISPI_ENABLED) != 0);
|
||||
|
@ -27,7 +27,9 @@
|
||||
// Bochs VBE definitions
|
||||
|
||||
#define VBE_DISPI_TOTAL_VIDEO_MEMORY_MB 16
|
||||
#ifndef VGA_MEM_FIX
|
||||
#define VBE_DISPI_4BPP_PLANE_SHIFT 22
|
||||
#endif
|
||||
|
||||
#define VBE_DISPI_BANK_ADDRESS 0xA0000
|
||||
|
||||
|
@ -144,7 +144,9 @@ void bx_vgacore_c::init_standard_vga(void)
|
||||
BX_VGA_THIS s.sequencer.extended_mem = 1; // display mem greater than 64K
|
||||
BX_VGA_THIS s.sequencer.odd_even = 1; // use sequential addressing mode
|
||||
|
||||
#ifndef VGA_MEM_FIX
|
||||
BX_VGA_THIS s.plane_shift = 16;
|
||||
#endif
|
||||
BX_VGA_THIS s.dac_shift = 2;
|
||||
BX_VGA_THIS s.last_bpp = 8;
|
||||
BX_VGA_THIS s.vclk[0] = 25175000;
|
||||
@ -343,7 +345,9 @@ void bx_vgacore_c::vgacore_register_state(bx_list_c *parent)
|
||||
sprintf(name, "%d", i);
|
||||
new bx_shadow_num_c(vclk, name, &BX_VGA_THIS s.vclk[i]);
|
||||
}
|
||||
#ifndef VGA_MEM_FIX
|
||||
new bx_shadow_num_c(list, "plane_shift", &BX_VGA_THIS s.plane_shift);
|
||||
#endif
|
||||
new bx_shadow_num_c(list, "dac_shift", &BX_VGA_THIS s.dac_shift);
|
||||
new bx_shadow_num_c(list, "ext_offset", &BX_VGA_THIS s.ext_offset);
|
||||
BXRS_PARAM_BOOL(list, ext_y_dblsize, BX_VGA_THIS s.ext_y_dblsize);
|
||||
@ -1218,10 +1222,18 @@ void bx_vgacore_c::set_override(bool enabled, void *dev)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef VGA_MEM_FIX
|
||||
Bit8u bx_vgacore_c::get_vga_pixel(Bit16u x, Bit16u y, Bit32u raddr, Bit16u lc, bool bs, Bit8u *vgamem_ptr)
|
||||
#else
|
||||
Bit8u bx_vgacore_c::get_vga_pixel(Bit16u x, Bit16u y, Bit32u raddr, Bit16u lc, bool bs, Bit8u **plane)
|
||||
#endif
|
||||
{
|
||||
Bit8u attribute, bit_no, palette_reg_val, DAC_regno;
|
||||
#ifdef VGA_MEM_FIX
|
||||
Bit32u vgamem_mask = BX_VGA_THIS s.memsize - 1;
|
||||
#else
|
||||
Bit32u plane_mask = ((Bit32u)1 << BX_VGA_THIS s.plane_shift) - 1;
|
||||
#endif
|
||||
Bit32u byte_offset;
|
||||
|
||||
if (BX_VGA_THIS s.x_dotclockdiv2) x >>= 1;
|
||||
@ -1229,12 +1241,21 @@ Bit8u bx_vgacore_c::get_vga_pixel(Bit16u x, Bit16u y, Bit32u raddr, Bit16u lc, b
|
||||
x += BX_VGA_THIS s.attribute_ctrl.horiz_pel_panning;
|
||||
}
|
||||
bit_no = 7 - (x % 8);
|
||||
#ifdef VGA_MEM_FIX
|
||||
byte_offset = ((raddr + (x / 8)) << 2) & vgamem_mask;
|
||||
attribute =
|
||||
(((vgamem_ptr[byte_offset] >> bit_no) & 0x01) << 0) |
|
||||
(((vgamem_ptr[byte_offset + 1] >> bit_no) & 0x01) << 1) |
|
||||
(((vgamem_ptr[byte_offset + 2] >> bit_no) & 0x01) << 2) |
|
||||
(((vgamem_ptr[byte_offset + 3] >> bit_no) & 0x01) << 3);
|
||||
#else
|
||||
byte_offset = (raddr + (x / 8)) & plane_mask;
|
||||
attribute =
|
||||
(((plane[0][byte_offset] >> bit_no) & 0x01) << 0) |
|
||||
(((plane[1][byte_offset] >> bit_no) & 0x01) << 1) |
|
||||
(((plane[2][byte_offset] >> bit_no) & 0x01) << 2) |
|
||||
(((plane[3][byte_offset] >> bit_no) & 0x01) << 3);
|
||||
#endif
|
||||
|
||||
attribute &= BX_VGA_THIS s.attribute_ctrl.color_plane_enable;
|
||||
// undocumented feature ???: colors 0..7 high intensity, colors 8..15 blinking
|
||||
@ -1293,8 +1314,28 @@ bool bx_vgacore_c::skip_update(void)
|
||||
|
||||
void bx_vgacore_c::update_charmap(void)
|
||||
{
|
||||
#ifdef VGA_MEM_FIX
|
||||
Bit8u charmap[0x2000];
|
||||
Bit32u addr;
|
||||
|
||||
addr = (BX_VGA_THIS s.charmap_address1 << 2);
|
||||
for (int i = 0; i < 0x2000; i++) {
|
||||
charmap[i] = BX_VGA_THIS s.memory[addr + 2];
|
||||
addr += 4;
|
||||
}
|
||||
bx_gui->set_text_charmap(0, charmap);
|
||||
if (BX_VGA_THIS s.charmap_address2 != BX_VGA_THIS s.charmap_address1) {
|
||||
addr = (BX_VGA_THIS s.charmap_address2 << 2) + 2;
|
||||
for (int i = 0; i < 0x2000; i++) {
|
||||
charmap[i] = BX_VGA_THIS s.memory[addr];
|
||||
addr += 4;
|
||||
}
|
||||
}
|
||||
bx_gui->set_text_charmap(1, charmap);
|
||||
#else
|
||||
bx_gui->set_text_charmap(0, &BX_VGA_THIS s.memory[0x20000 + BX_VGA_THIS s.charmap_address1]);
|
||||
bx_gui->set_text_charmap(1, &BX_VGA_THIS s.memory[0x20000 + BX_VGA_THIS s.charmap_address2]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void bx_vgacore_c::update(void)
|
||||
@ -1335,7 +1376,8 @@ void bx_vgacore_c::update(void)
|
||||
if (BX_VGA_THIS s.graphics_ctrl.graphics_alpha) {
|
||||
// Graphics mode
|
||||
Bit8u color;
|
||||
Bit16u x, y, start_addr, line_offset;
|
||||
Bit32u x, y, line_offset;
|
||||
Bit32u start_addr;
|
||||
unsigned r, c;
|
||||
unsigned long byte_offset;
|
||||
unsigned xc, yc, xti, yti;
|
||||
@ -1359,13 +1401,14 @@ void bx_vgacore_c::update(void)
|
||||
Bit8u attribute, palette_reg_val, DAC_regno;
|
||||
Bit16u line_compare;
|
||||
Bit32u row_addr;
|
||||
#ifndef VGA_MEM_FIX
|
||||
Bit8u *plane[4];
|
||||
|
||||
plane[0] = &BX_VGA_THIS s.memory[0 << BX_VGA_THIS s.plane_shift];
|
||||
plane[1] = &BX_VGA_THIS s.memory[1 << BX_VGA_THIS s.plane_shift];
|
||||
plane[2] = &BX_VGA_THIS s.memory[2 << BX_VGA_THIS s.plane_shift];
|
||||
plane[3] = &BX_VGA_THIS s.memory[3 << BX_VGA_THIS s.plane_shift];
|
||||
|
||||
#endif
|
||||
line_compare = BX_VGA_THIS s.line_compare;
|
||||
if (BX_VGA_THIS s.y_doublescan) line_compare >>= 1;
|
||||
|
||||
@ -1384,7 +1427,11 @@ void bx_vgacore_c::update(void)
|
||||
for (c=0; c<X_TILESIZE; c++) {
|
||||
x = xc + c;
|
||||
BX_VGA_THIS s.tile[r * X_TILESIZE + c] =
|
||||
#ifdef VGA_MEM_FIX
|
||||
BX_VGA_THIS get_vga_pixel(x, y, row_addr, line_compare, cs_visible, BX_VGA_THIS s.memory);
|
||||
#else
|
||||
BX_VGA_THIS get_vga_pixel(x, y, row_addr, line_compare, cs_visible, plane);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
SET_TILE_UPDATED(BX_VGA_THIS, xti, yti, 0);
|
||||
@ -1409,7 +1456,11 @@ void bx_vgacore_c::update(void)
|
||||
for (c=0; c<X_TILESIZE; c++) {
|
||||
x = xc + c;
|
||||
BX_VGA_THIS s.tile[r * X_TILESIZE + c] =
|
||||
#ifdef VGA_MEM_FIX
|
||||
BX_VGA_THIS get_vga_pixel(x, y, row_addr, line_compare, cs_visible, BX_VGA_THIS s.memory);
|
||||
#else
|
||||
BX_VGA_THIS get_vga_pixel(x, y, row_addr, line_compare, cs_visible, plane);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
SET_TILE_UPDATED(BX_VGA_THIS, xti, yti, 0);
|
||||
@ -1445,6 +1496,9 @@ void bx_vgacore_c::update(void)
|
||||
byte_offset += ((y & 1) << 13);
|
||||
|
||||
attribute = 6 - 2 * (x % 4);
|
||||
#ifdef VGA_MEM_FIX
|
||||
byte_offset = ((byte_offset & ~1) << 1) | (byte_offset & 1);
|
||||
#endif
|
||||
palette_reg_val = (BX_VGA_THIS s.memory[byte_offset]) >> attribute;
|
||||
palette_reg_val &= 3;
|
||||
DAC_regno = BX_VGA_THIS s.attribute_ctrl.palette_reg[palette_reg_val];
|
||||
@ -1468,13 +1522,19 @@ void bx_vgacore_c::update(void)
|
||||
if (BX_VGA_THIS s.y_doublescan) line_compare >>= 1;
|
||||
|
||||
if (BX_VGA_THIS s.CRTC.reg[0x14] & 0x40) { // DW set: doubleword mode
|
||||
#ifndef VGA_MEM_FIX
|
||||
unsigned long plane;
|
||||
#endif
|
||||
|
||||
if (BX_VGA_THIS s.misc_output.select_high_bank != 1)
|
||||
BX_PANIC(("update: select_high_bank != 1"));
|
||||
|
||||
#ifdef VGA_MEM_FIX
|
||||
line_offset = BX_VGA_THIS s.line_offset;
|
||||
start_addr <<= 2;
|
||||
#else
|
||||
line_offset = BX_VGA_THIS s.line_offset >> 2;
|
||||
|
||||
#endif
|
||||
for (yc=0, yti=0; yc<iHeight; yc+=Y_TILESIZE, yti++) {
|
||||
for (xc=0, xti=0; xc<iWidth; xc+=X_TILESIZE, xti++) {
|
||||
if (GET_TILE_UPDATED (xti, yti)) {
|
||||
@ -1488,8 +1548,12 @@ void bx_vgacore_c::update(void)
|
||||
}
|
||||
for (c=0; c<X_TILESIZE; c++) {
|
||||
x = (xc + c) >> 1;
|
||||
#ifdef VGA_MEM_FIX
|
||||
byte_offset = (row_addr + x) & 0xffff;
|
||||
#else
|
||||
plane = (x % 4);
|
||||
byte_offset = row_addr + (plane << 16) + (x >> 2);
|
||||
#endif
|
||||
color = BX_VGA_THIS s.memory[byte_offset];
|
||||
BX_VGA_THIS s.tile[r*X_TILESIZE + c] = color;
|
||||
}
|
||||
@ -1500,9 +1564,17 @@ void bx_vgacore_c::update(void)
|
||||
}
|
||||
}
|
||||
} else if (BX_VGA_THIS s.CRTC.reg[0x17] & 0x40) { // B/W set: byte mode, modeX
|
||||
#ifndef VGA_MEM_FIX
|
||||
unsigned long plane;
|
||||
#endif
|
||||
Bit8u h_panning;
|
||||
|
||||
#ifdef VGA_MEM_FIX
|
||||
line_offset = BX_VGA_THIS s.line_offset << 2;
|
||||
start_addr <<= 2;
|
||||
#else
|
||||
line_offset = BX_VGA_THIS s.line_offset;
|
||||
#endif
|
||||
for (yc=0, yti=0; yc<iHeight; yc+=Y_TILESIZE, yti++) {
|
||||
for (xc=0, xti=0; xc<iWidth; xc+=X_TILESIZE, xti++) {
|
||||
if (GET_TILE_UPDATED (xti, yti)) {
|
||||
@ -1511,18 +1583,22 @@ void bx_vgacore_c::update(void)
|
||||
if (BX_VGA_THIS s.y_doublescan) y >>= 1;
|
||||
h_panning = BX_VGA_THIS s.attribute_ctrl.horiz_pel_panning / 2;
|
||||
if (y > line_compare) {
|
||||
row_addr = (y - line_compare - 1) * BX_VGA_THIS s.line_offset;
|
||||
row_addr = (y - line_compare - 1) * line_offset;
|
||||
if (BX_VGA_THIS s.attribute_ctrl.mode_ctrl.pixel_panning_compat) {
|
||||
h_panning = 0;
|
||||
}
|
||||
} else {
|
||||
row_addr = start_addr + (y * BX_VGA_THIS s.line_offset);
|
||||
row_addr = start_addr + (y * line_offset);
|
||||
}
|
||||
for (c=0; c<X_TILESIZE; c++) {
|
||||
x = (xc + c) >> 1;
|
||||
x += h_panning;
|
||||
#ifdef VGA_MEM_FIX
|
||||
byte_offset = (row_addr + x) & 0x3ffff;
|
||||
#else
|
||||
plane = (x % 4);
|
||||
byte_offset = (plane << 16) + ((row_addr + (x >> 2)) & 0xffff);
|
||||
#endif
|
||||
color = BX_VGA_THIS s.memory[byte_offset];
|
||||
BX_VGA_THIS s.tile[r*X_TILESIZE + c] = color;
|
||||
}
|
||||
@ -1533,20 +1609,25 @@ void bx_vgacore_c::update(void)
|
||||
}
|
||||
}
|
||||
} else { // word mode
|
||||
#ifndef VGA_MEM_FIX
|
||||
unsigned long plane;
|
||||
|
||||
#endif
|
||||
BX_INFO(("256-color word mode untested"));
|
||||
for (yc=0, yti=0; yc<iHeight; yc+=Y_TILESIZE, yti++) {
|
||||
for (xc=0, xti=0; xc<iWidth; xc+=X_TILESIZE, xti++) {
|
||||
if (GET_TILE_UPDATED (xti, yti)) {
|
||||
for (r=0; r<Y_TILESIZE; r++) {
|
||||
y = yc + r;
|
||||
if (BX_VGA_THIS s.y_doublescan) y >>= 1;
|
||||
row_addr = start_addr + (y * BX_VGA_THIS s.line_offset);
|
||||
for (c=0; c<X_TILESIZE; c++) {
|
||||
x = (xc + c) >> 1;
|
||||
#ifdef VGA_MEM_FIX
|
||||
byte_offset = (row_addr + ((x & ~1) << 1)) | (x & 1);
|
||||
#else
|
||||
plane = (x % 4);
|
||||
byte_offset = (plane << 16) +
|
||||
(y * BX_VGA_THIS s.line_offset)
|
||||
+ ((x >> 1) & ~0x01);
|
||||
byte_offset = (plane << 16) + row_addr + ((x >> 1) & ~0x01);
|
||||
#endif
|
||||
color = BX_VGA_THIS s.memory[start_addr + byte_offset];
|
||||
BX_VGA_THIS s.tile[r*X_TILESIZE + c] = color;
|
||||
}
|
||||
@ -1652,15 +1733,33 @@ void bx_vgacore_c::update(void)
|
||||
(cursor_address > (tm_info.start_address + tm_info.line_offset * rows))) {
|
||||
cursor_address = 0xffff;
|
||||
}
|
||||
bx_gui->text_update_common(BX_VGA_THIS s.text_snapshot,
|
||||
BX_VGA_THIS s.memory,
|
||||
#ifdef VGA_MEM_FIX
|
||||
int size = text_snap_size[BX_VGA_THIS s.graphics_ctrl.memory_mapping];
|
||||
Bit8u *textmode_buffer = new Bit8u[size];
|
||||
for (int i = 0; i < size; i += 2) {
|
||||
textmode_buffer[i] = BX_VGA_THIS s.memory[i * 2];
|
||||
textmode_buffer[i + 1] = BX_VGA_THIS s.memory[i * 2 + 1];
|
||||
}
|
||||
bx_gui->text_update_common(BX_VGA_THIS s.text_snapshot, textmode_buffer,
|
||||
cursor_address, &tm_info);
|
||||
#else
|
||||
bx_gui->text_update_common(BX_VGA_THIS s.text_snapshot, BX_VGA_THIS s.memory,
|
||||
cursor_address, &tm_info);
|
||||
#endif
|
||||
if (BX_VGA_THIS s.vga_mem_updated > 0) {
|
||||
// screen updated, copy new VGA memory contents into text snapshot
|
||||
#ifdef VGA_MEM_FIX
|
||||
memcpy(BX_VGA_THIS s.text_snapshot, textmode_buffer,
|
||||
tm_info.line_offset * rows + tm_info.start_address);
|
||||
#else
|
||||
memcpy(BX_VGA_THIS s.text_snapshot, BX_VGA_THIS s.memory,
|
||||
tm_info.line_offset * rows + tm_info.start_address);
|
||||
#endif
|
||||
BX_VGA_THIS s.vga_mem_updated = 0;
|
||||
}
|
||||
#ifdef VGA_MEM_FIX
|
||||
delete [] textmode_buffer;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -1689,7 +1788,9 @@ Bit8u bx_vgacore_c::mem_read(bx_phy_address addr)
|
||||
{
|
||||
Bit32u offset;
|
||||
Bit8u read_map_select = BX_VGA_THIS s.graphics_ctrl.read_map_select;
|
||||
#ifndef VGA_MEM_FIX
|
||||
Bit8u *plane0, *plane1, *plane2, *plane3;
|
||||
#endif
|
||||
|
||||
if (addr >= 0xA0000) {
|
||||
switch (BX_VGA_THIS s.graphics_ctrl.memory_mapping) {
|
||||
@ -1714,20 +1815,40 @@ Bit8u bx_vgacore_c::mem_read(bx_phy_address addr)
|
||||
|
||||
if (BX_VGA_THIS s.sequencer.chain_four) {
|
||||
// Mode 13h: 320 x 200 256 color mode: chained pixel representation
|
||||
#ifdef VGA_MEM_FIX
|
||||
return BX_VGA_THIS s.memory[offset];
|
||||
#else
|
||||
return BX_VGA_THIS s.memory[(offset >> 2) + ((offset % 4) << 16)];
|
||||
#endif
|
||||
#ifdef VGA_MEM_FIX
|
||||
} else if (BX_VGA_THIS s.graphics_ctrl.odd_even) {
|
||||
Bit8u plane = (read_map_select & 2) | (offset & 1);
|
||||
return BX_VGA_THIS s.memory[((offset & ~1) << 1) | plane];
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef VGA_MEM_FIX
|
||||
offset += BX_VGA_THIS s.ext_offset;
|
||||
#else
|
||||
plane0 = &BX_VGA_THIS s.memory[(0 << BX_VGA_THIS s.plane_shift) + BX_VGA_THIS s.ext_offset];
|
||||
plane1 = &BX_VGA_THIS s.memory[(1 << BX_VGA_THIS s.plane_shift) + BX_VGA_THIS s.ext_offset];
|
||||
plane2 = &BX_VGA_THIS s.memory[(2 << BX_VGA_THIS s.plane_shift) + BX_VGA_THIS s.ext_offset];
|
||||
plane3 = &BX_VGA_THIS s.memory[(3 << BX_VGA_THIS s.plane_shift) + BX_VGA_THIS s.ext_offset];
|
||||
#endif
|
||||
|
||||
switch (BX_VGA_THIS s.graphics_ctrl.read_mode) {
|
||||
case 0: /* read mode 0 */
|
||||
#ifdef VGA_MEM_FIX
|
||||
BX_VGA_THIS s.graphics_ctrl.latch[0] = BX_VGA_THIS s.memory[offset << 2];
|
||||
BX_VGA_THIS s.graphics_ctrl.latch[1] = BX_VGA_THIS s.memory[(offset << 2) + 1];
|
||||
BX_VGA_THIS s.graphics_ctrl.latch[2] = BX_VGA_THIS s.memory[(offset << 2) + 2];
|
||||
BX_VGA_THIS s.graphics_ctrl.latch[3] = BX_VGA_THIS s.memory[(offset << 2) + 3];
|
||||
#else
|
||||
BX_VGA_THIS s.graphics_ctrl.latch[0] = plane0[offset];
|
||||
BX_VGA_THIS s.graphics_ctrl.latch[1] = plane1[offset];
|
||||
BX_VGA_THIS s.graphics_ctrl.latch[2] = plane2[offset];
|
||||
BX_VGA_THIS s.graphics_ctrl.latch[3] = plane3[offset];
|
||||
#endif
|
||||
return BX_VGA_THIS s.graphics_ctrl.latch[read_map_select];
|
||||
|
||||
case 1: /* read mode 1 */
|
||||
@ -1737,10 +1858,17 @@ Bit8u bx_vgacore_c::mem_read(bx_phy_address addr)
|
||||
|
||||
color_compare = BX_VGA_THIS s.graphics_ctrl.color_compare & 0x0f;
|
||||
color_dont_care = BX_VGA_THIS s.graphics_ctrl.color_dont_care & 0x0f;
|
||||
#ifdef VGA_MEM_FIX
|
||||
latch0 = BX_VGA_THIS s.graphics_ctrl.latch[0] = BX_VGA_THIS s.memory[offset << 2];
|
||||
latch1 = BX_VGA_THIS s.graphics_ctrl.latch[1] = BX_VGA_THIS s.memory[(offset << 2) + 1];
|
||||
latch2 = BX_VGA_THIS s.graphics_ctrl.latch[2] = BX_VGA_THIS s.memory[(offset << 2) + 2];
|
||||
latch3 = BX_VGA_THIS s.graphics_ctrl.latch[3] = BX_VGA_THIS s.memory[(offset << 2) + 3];
|
||||
#else
|
||||
latch0 = BX_VGA_THIS s.graphics_ctrl.latch[0] = plane0[offset];
|
||||
latch1 = BX_VGA_THIS s.graphics_ctrl.latch[1] = plane1[offset];
|
||||
latch2 = BX_VGA_THIS s.graphics_ctrl.latch[2] = plane2[offset];
|
||||
latch3 = BX_VGA_THIS s.graphics_ctrl.latch[3] = plane3[offset];
|
||||
#endif
|
||||
|
||||
latch0 ^= ccdat[color_compare][0];
|
||||
latch1 ^= ccdat[color_compare][1];
|
||||
@ -1788,7 +1916,9 @@ void bx_vgacore_c::mem_write(bx_phy_address addr, Bit8u value)
|
||||
Bit8u new_val[4] = {0,0,0,0};
|
||||
unsigned start_addr;
|
||||
Bit8u sequ_map_mask = BX_VGA_THIS s.sequencer.map_mask & 0x0f;
|
||||
#ifndef VGA_MEM_FIX
|
||||
Bit8u *plane0, *plane1, *plane2, *plane3;
|
||||
#endif
|
||||
|
||||
if (addr >= 0xA0000) {
|
||||
switch (BX_VGA_THIS s.graphics_ctrl.memory_mapping) {
|
||||
@ -1816,7 +1946,11 @@ void bx_vgacore_c::mem_write(bx_phy_address addr, Bit8u value)
|
||||
|
||||
if (BX_VGA_THIS s.sequencer.chain_four) {
|
||||
// 320 x 200 256 color mode: chained pixel representation
|
||||
#ifdef VGA_MEM_FIX
|
||||
BX_VGA_THIS s.memory[offset] = value;
|
||||
#else
|
||||
BX_VGA_THIS s.memory[(offset >> 2) + ((offset % 4) << 16)] = value;
|
||||
#endif
|
||||
BX_VGA_THIS s.vga_mem_updated |= (1 << (offset % 4));
|
||||
if (BX_VGA_THIS s.graphics_ctrl.graphics_alpha) {
|
||||
unsigned x_tileno, y_tileno;
|
||||
@ -1847,12 +1981,53 @@ void bx_vgacore_c::mem_write(bx_phy_address addr, Bit8u value)
|
||||
}
|
||||
}
|
||||
return;
|
||||
#ifdef VGA_MEM_FIX
|
||||
} else if (BX_VGA_THIS s.graphics_ctrl.odd_even) {
|
||||
Bit8u plane = (BX_VGA_THIS s.graphics_ctrl.read_map_select & 2) | (offset & 1);
|
||||
if (sequ_map_mask & (1 << plane)) {
|
||||
BX_VGA_THIS s.memory[((offset & ~1) << 1) | plane] = value;
|
||||
BX_VGA_THIS s.vga_mem_updated |= (1 << plane);
|
||||
if (BX_VGA_THIS s.graphics_ctrl.graphics_alpha) {
|
||||
unsigned x_tileno, y_tileno;
|
||||
if ((BX_VGA_THIS s.CRTC.reg[0x17] & 1) == 0) { // MAP13 (CGA 320x200x4
|
||||
unsigned xc, yc;
|
||||
|
||||
if ((BX_VGA_THIS s.CRTC.reg[0x17] & 0x40) == 0) {
|
||||
start_addr <<= 1;
|
||||
}
|
||||
offset -= start_addr;
|
||||
if (offset >= 0x2000) {
|
||||
yc = (((offset - 0x2000) / (320 / 4)) << 1) + 1;
|
||||
xc = ((offset - 0x2000) % (320 / 4)) << 2;
|
||||
} else {
|
||||
yc = (offset / (320 / 4)) << 1;
|
||||
xc = (offset % (320 / 4)) << 2;
|
||||
}
|
||||
if ((BX_VGA_THIS s.graphics_ctrl.shift_reg == 0) || BX_VGA_THIS s.x_dotclockdiv2) {
|
||||
xc <<= 1;
|
||||
}
|
||||
x_tileno = xc / X_TILESIZE;
|
||||
if (BX_VGA_THIS s.y_doublescan) {
|
||||
y_tileno = yc / (Y_TILESIZE / 2);
|
||||
} else {
|
||||
y_tileno = yc / Y_TILESIZE;
|
||||
}
|
||||
SET_TILE_UPDATED(BX_VGA_THIS, x_tileno, y_tileno, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef VGA_MEM_FIX
|
||||
offset += BX_VGA_THIS s.ext_offset;
|
||||
#else
|
||||
plane0 = &BX_VGA_THIS s.memory[(0 << BX_VGA_THIS s.plane_shift) + BX_VGA_THIS s.ext_offset];
|
||||
plane1 = &BX_VGA_THIS s.memory[(1 << BX_VGA_THIS s.plane_shift) + BX_VGA_THIS s.ext_offset];
|
||||
plane2 = &BX_VGA_THIS s.memory[(2 << BX_VGA_THIS s.plane_shift) + BX_VGA_THIS s.ext_offset];
|
||||
plane3 = &BX_VGA_THIS s.memory[(3 << BX_VGA_THIS s.plane_shift) + BX_VGA_THIS s.ext_offset];
|
||||
#endif
|
||||
|
||||
switch (BX_VGA_THIS s.graphics_ctrl.write_mode) {
|
||||
unsigned i;
|
||||
@ -2100,13 +2275,29 @@ void bx_vgacore_c::mem_write(bx_phy_address addr, Bit8u value)
|
||||
if (sequ_map_mask & 0x0f) {
|
||||
BX_VGA_THIS s.vga_mem_updated |= (sequ_map_mask & 0x0f);
|
||||
if (sequ_map_mask & 0x01)
|
||||
#ifdef VGA_MEM_FIX
|
||||
BX_VGA_THIS s.memory[offset << 2] = new_val[0];
|
||||
#else
|
||||
plane0[offset] = new_val[0];
|
||||
#endif
|
||||
if (sequ_map_mask & 0x02)
|
||||
#ifdef VGA_MEM_FIX
|
||||
BX_VGA_THIS s.memory[(offset << 2) + 1] = new_val[1];
|
||||
#else
|
||||
plane1[offset] = new_val[1];
|
||||
#endif
|
||||
if (sequ_map_mask & 0x04)
|
||||
#ifdef VGA_MEM_FIX
|
||||
BX_VGA_THIS s.memory[(offset << 2) + 2] = new_val[2];
|
||||
#else
|
||||
plane2[offset] = new_val[2];
|
||||
#endif
|
||||
if (sequ_map_mask & 0x08)
|
||||
#ifdef VGA_MEM_FIX
|
||||
BX_VGA_THIS s.memory[(offset << 2) + 3] = new_val[3];
|
||||
#else
|
||||
plane3[offset] = new_val[3];
|
||||
#endif
|
||||
|
||||
if (BX_VGA_THIS s.graphics_ctrl.graphics_alpha) {
|
||||
unsigned x_tileno, y_tileno;
|
||||
|
@ -23,6 +23,8 @@
|
||||
#ifndef BX_IODEV_VGACORE_H
|
||||
#define BX_IODEV_VGACORE_H
|
||||
|
||||
//#define VGA_MEM_FIX
|
||||
|
||||
// Make colour
|
||||
#define MAKE_COLOUR(red, red_shiftfrom, red_shiftto, red_mask, \
|
||||
green, green_shiftfrom, green_shiftto, green_mask, \
|
||||
@ -125,7 +127,11 @@ protected:
|
||||
Bit32u read(Bit32u address, unsigned io_len);
|
||||
void write(Bit32u address, Bit32u value, unsigned io_len, bool no_log);
|
||||
|
||||
#ifdef VGA_MEM_FIX
|
||||
Bit8u get_vga_pixel(Bit16u x, Bit16u y, Bit32u raddr, Bit16u lc, bool bs, Bit8u *vgamem_ptr);
|
||||
#else
|
||||
Bit8u get_vga_pixel(Bit16u x, Bit16u y, Bit32u raddr, Bit16u lc, bool bs, Bit8u **plane);
|
||||
#endif
|
||||
virtual void update(void);
|
||||
void determine_screen_dimensions(unsigned *piHeight, unsigned *piWidth);
|
||||
void calculate_retrace_timing(void);
|
||||
@ -253,7 +259,9 @@ protected:
|
||||
Bit32u vrend_usec;
|
||||
Bit64u display_start_usec;
|
||||
// shift values for extensions
|
||||
#ifndef VGA_MEM_FIX
|
||||
Bit8u plane_shift;
|
||||
#endif
|
||||
Bit8u dac_shift;
|
||||
Bit32u ext_offset;
|
||||
bool ext_y_dblsize;
|
||||
|
Loading…
Reference in New Issue
Block a user