Skip to content

Commit

Permalink
Partly fixed display errors found in game Prehistorik 2 (issue #166).
Browse files Browse the repository at this point in the history
- Fixes in MAP13 disabled mode (VGA mode 6): half dot clock, color support
- Modified method get_vga_pixel(): now using row start address as an argument
  • Loading branch information
vruppert committed Dec 13, 2023
1 parent 7641d13 commit 5fec28c
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 34 deletions.
6 changes: 4 additions & 2 deletions bochs/iodev/display/vga.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002-2021 The Bochs Project
// Copyright (C) 2002-2023 The Bochs Project
// PCI VGA dummy adapter Copyright (C) 2002,2003 Mike Nordell
//
// This library is free software; you can redistribute it and/or
Expand Down Expand Up @@ -578,6 +578,7 @@ void bx_vga_c::update(void)
unsigned r, c, x, y;
unsigned xc, yc, xti, yti;
Bit8u *plane[4];
Bit16u row_addr;

BX_VGA_THIS determine_screen_dimensions(&iHeight, &iWidth);
if ((iWidth != BX_VGA_THIS s.last_xres) || (iHeight != BX_VGA_THIS s.last_yres) ||
Expand All @@ -599,10 +600,11 @@ void bx_vga_c::update(void)
for (r=0; r<Y_TILESIZE; r++) {
y = yc + r;
if (BX_VGA_THIS s.y_doublescan) y >>= 1;
row_addr = BX_VGA_THIS vbe.virtual_start + (y * BX_VGA_THIS s.line_offset);
for (c=0; c<X_TILESIZE; c++) {
x = xc + c;
BX_VGA_THIS s.tile[r*X_TILESIZE + c] =
BX_VGA_THIS get_vga_pixel(x, y, BX_VGA_THIS vbe.virtual_start, 0xffff, 0, plane);
BX_VGA_THIS get_vga_pixel(x, y, row_addr, 0xffff, 0, plane);
}
}
SET_TILE_UPDATED(BX_VGA_THIS, xti, yti, 0);
Expand Down
56 changes: 25 additions & 31 deletions bochs/iodev/display/vgacore.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1274,7 +1274,7 @@ void bx_vgacore_c::set_override(bool enabled, void *dev)
}
}

Bit8u bx_vgacore_c::get_vga_pixel(Bit16u x, Bit16u y, Bit16u saddr, Bit16u lc, bool bs, Bit8u **plane)
Bit8u bx_vgacore_c::get_vga_pixel(Bit16u x, Bit16u y, Bit16u raddr, Bit16u lc, bool bs, Bit8u **plane)
{
Bit8u attribute, bit_no, palette_reg_val, DAC_regno;
Bit32u byte_offset;
Expand All @@ -1284,13 +1284,7 @@ Bit8u bx_vgacore_c::get_vga_pixel(Bit16u x, Bit16u y, Bit16u saddr, Bit16u lc, b
x += BX_VGA_THIS s.attribute_ctrl.horiz_pel_panning;
}
bit_no = 7 - (x % 8);
if (y > lc) {
byte_offset = x / 8 +
((y - lc - 1) * BX_VGA_THIS s.line_offset);
} else {
byte_offset = saddr + x / 8 +
(y * BX_VGA_THIS s.line_offset);
}
byte_offset = raddr + (x / 8);
attribute =
(((plane[0][byte_offset] >> bit_no) & 0x01) << 0) |
(((plane[1][byte_offset] >> bit_no) & 0x01) << 1) |
Expand Down Expand Up @@ -1391,7 +1385,7 @@ void bx_vgacore_c::update(void)
// Graphics mode
Bit8u color;
Bit16u x, y, start_addr;
unsigned bit_no, r, c;
unsigned r, c;
unsigned long byte_offset;
unsigned xc, yc, xti, yti;

Expand All @@ -1412,9 +1406,17 @@ void bx_vgacore_c::update(void)
switch (BX_VGA_THIS s.graphics_ctrl.shift_reg) {
case 0: // interleaved shift
Bit8u attribute, palette_reg_val, DAC_regno;
Bit16u line_compare;
Bit16u line_compare, row_addr;
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];

line_compare = BX_VGA_THIS s.line_compare;
if (BX_VGA_THIS s.y_doublescan) line_compare >>= 1;

if ((BX_VGA_THIS s.CRTC.reg[0x17] & 1) == 0) { // CGA 640x200x2

for (yc=0, yti=0; yc<iHeight; yc+=Y_TILESIZE, yti++) {
Expand All @@ -1423,20 +1425,14 @@ void bx_vgacore_c::update(void)
for (r=0; r<Y_TILESIZE; r++) {
y = yc + r;
if (BX_VGA_THIS s.y_doublescan) y >>= 1;
/* 0 or 0x2000 */
row_addr = (start_addr & 0xdfff) + ((y & 1) << 13);
/* to the start of the line */
row_addr += (320 / 4) * (y / 2);
for (c=0; c<X_TILESIZE; c++) {

x = xc + c;
/* 0 or 0x2000 */
byte_offset = start_addr + ((y & 1) << 13);
/* to the start of the line */
byte_offset += (320 / 4) * (y / 2);
/* to the byte start */
byte_offset += (x / 8);

bit_no = 7 - (x % 8);
palette_reg_val = (((BX_VGA_THIS s.memory[byte_offset]) >> bit_no) & 1);
DAC_regno = BX_VGA_THIS s.attribute_ctrl.palette_reg[palette_reg_val];
BX_VGA_THIS s.tile[r*X_TILESIZE + c] = DAC_regno;
BX_VGA_THIS s.tile[r * X_TILESIZE + c] =
BX_VGA_THIS get_vga_pixel(x, y, row_addr, line_compare, cs_visible, plane);
}
}
SET_TILE_UPDATED(BX_VGA_THIS, xti, yti, 0);
Expand All @@ -1447,23 +1443,21 @@ void bx_vgacore_c::update(void)
} else { // output data in serial fashion with each display plane
// output on its associated serial output. Standard EGA/VGA format

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];
line_compare = BX_VGA_THIS s.line_compare;
if (BX_VGA_THIS s.y_doublescan) line_compare >>= 1;

for (yc=0, yti=0; yc<iHeight; yc+=Y_TILESIZE, yti++) {
for (xc=0, xti=0; xc<iWidth; xc+=X_TILESIZE, xti++) {
if (cs_toggle || GET_TILE_UPDATED (xti, yti)) {
for (r=0; r<Y_TILESIZE; r++) {
y = yc + r;
if (BX_VGA_THIS s.y_doublescan) y >>= 1;
if (y > line_compare) {
row_addr = (y - line_compare - 1) * BX_VGA_THIS s.line_offset;
} else {
row_addr = start_addr + (y * BX_VGA_THIS s.line_offset);
}
for (c=0; c<X_TILESIZE; c++) {
x = xc + c;
BX_VGA_THIS s.tile[r*X_TILESIZE + c] =
BX_VGA_THIS get_vga_pixel(x, y, start_addr, line_compare, cs_visible, plane);
BX_VGA_THIS s.tile[r * X_TILESIZE + c] =
BX_VGA_THIS get_vga_pixel(x, y, row_addr, line_compare, cs_visible, plane);
}
}
SET_TILE_UPDATED(BX_VGA_THIS, xti, yti, 0);
Expand Down
2 changes: 1 addition & 1 deletion bochs/iodev/display/vgacore.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ class bx_vgacore_c : public bx_vga_stub_c {
Bit32u read(Bit32u address, unsigned io_len);
void write(Bit32u address, Bit32u value, unsigned io_len, bool no_log);

Bit8u get_vga_pixel(Bit16u x, Bit16u y, Bit16u saddr, Bit16u lc, bool bs, Bit8u **plane);
Bit8u get_vga_pixel(Bit16u x, Bit16u y, Bit16u raddr, Bit16u lc, bool bs, Bit8u **plane);
virtual void update(void);
void determine_screen_dimensions(unsigned *piHeight, unsigned *piWidth);
void calculate_retrace_timing(void);
Expand Down

0 comments on commit 5fec28c

Please sign in to comment.