diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h
index 1e8cc2b91..1502fba2d 100644
--- a/src/include/86box/vid_svga.h
+++ b/src/include/86box/vid_svga.h
@@ -158,7 +158,8 @@ typedef struct svga_t
/*Force CRTC to dword mode, regardless of CR14/CR17. Required for S3 enhanced mode*/
int force_dword_mode;
- int force_byte_mode;
+
+ int force_old_addr;
int remap_required;
uint32_t (*remap_func)(struct svga_t *svga, uint32_t in_addr);
diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui
index 69197d015..60b77d290 100644
--- a/src/qt/qt_mainwindow.ui
+++ b/src/qt/qt_mainwindow.ui
@@ -15,7 +15,7 @@
-
+
0
0
@@ -37,7 +37,14 @@
0
-
-
+
+
+
+ 0
+ 0
+
+
+
diff --git a/src/qt/qt_opengloptions.cpp b/src/qt/qt_opengloptions.cpp
index 3222d940c..73eaad98e 100644
--- a/src/qt/qt_opengloptions.cpp
+++ b/src/qt/qt_opengloptions.cpp
@@ -169,10 +169,10 @@ OpenGLOptions::addShader(const QString &path)
.toStdString());
};
- if (!shader->addShaderFromSourceCode(QOpenGLShader::Vertex, version_line % "\n#define VERTEX\n" % shader_text))
+ if (!shader->addShaderFromSourceCode(QOpenGLShader::Vertex, version_line % "\n#extension GL_ARB_shading_language_420pack : enable\n" % "\n#define VERTEX\n" % shader_text))
throw_shader_error(tr("Error compiling vertex shader in file \"%1\""));
- if (!shader->addShaderFromSourceCode(QOpenGLShader::Fragment, version_line % "\n#define FRAGMENT\n" % shader_text))
+ if (!shader->addShaderFromSourceCode(QOpenGLShader::Fragment, version_line % "\n#extension GL_ARB_shading_language_420pack : enable\n" "\n#define FRAGMENT\n" % shader_text))
throw_shader_error(tr("Error compiling fragment shader in file \"%1\""));
if (!shader->link())
diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp
index f1e44f3a9..9240b2604 100644
--- a/src/qt/qt_openglrenderer.cpp
+++ b/src/qt/qt_openglrenderer.cpp
@@ -19,6 +19,7 @@
#include
#include
#include
+#include
#include
@@ -89,8 +90,8 @@ OpenGLRenderer::resizeEvent(QResizeEvent *event)
glViewport(
destination.x(),
destination.y(),
- destination.width(),
- destination.height());
+ destination.width() * devicePixelRatio(),
+ destination.height() * devicePixelRatio());
}
bool
@@ -374,7 +375,7 @@ OpenGLRenderer::onBlit(int buf_idx, int x, int y, int w, int h)
/* Resize the texture */
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
- glTexImage2D(GL_TEXTURE_2D, 0, QOpenGLTexture::RGBA8_UNorm, source.width(), source.height(), 0, QOpenGLTexture::BGRA, QOpenGLTexture::UInt32_RGBA8_Rev, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, (GLenum)QOpenGLTexture::RGBA8_UNorm, source.width(), source.height(), 0, (GLenum)QOpenGLTexture::BGRA, (GLenum)QOpenGLTexture::UInt32_RGBA8_Rev, NULL);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBufferID);
}
@@ -383,7 +384,7 @@ OpenGLRenderer::onBlit(int buf_idx, int x, int y, int w, int h)
glPixelStorei(GL_UNPACK_SKIP_PIXELS, BUFFERPIXELS * buf_idx + y * ROW_LENGTH + x);
glPixelStorei(GL_UNPACK_ROW_LENGTH, ROW_LENGTH);
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, QOpenGLTexture::BGRA, QOpenGLTexture::UInt32_RGBA8_Rev, NULL);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, (GLenum)QOpenGLTexture::BGRA, (GLenum)QOpenGLTexture::UInt32_RGBA8_Rev, NULL);
/* TODO: check if fence sync is implementable here and still has any benefit. */
glFinish();
diff --git a/src/qt/qt_settingsmachine.ui b/src/qt/qt_settingsmachine.ui
index fabb52fe9..30f375f7e 100644
--- a/src/qt/qt_settingsmachine.ui
+++ b/src/qt/qt_settingsmachine.ui
@@ -202,6 +202,12 @@
-
+
+
+ 0
+ 0
+
+
Time synchronization
diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c
index e77817782..e8826f4e4 100644
--- a/src/video/vid_s3.c
+++ b/src/video/vid_s3.c
@@ -404,9 +404,9 @@ static void s3_pci_write(int func, int addr, uint8_t val, void *p);
static __inline uint32_t
dword_remap(svga_t *svga, uint32_t in_addr)
{
- if (svga->packed_chain4)
+ if (svga->packed_chain4 || svga->force_old_addr)
return in_addr;
-
+
return ((in_addr << 2) & 0x3fff0) |
((in_addr >> 14) & 0xc) |
(in_addr & ~0x3fffc);
@@ -414,9 +414,9 @@ dword_remap(svga_t *svga, uint32_t in_addr)
static __inline uint32_t
dword_remap_w(svga_t *svga, uint32_t in_addr)
{
- if (svga->packed_chain4)
- return in_addr;
-
+ if (svga->packed_chain4 || svga->force_old_addr)
+ return in_addr;
+
return ((in_addr << 2) & 0x1fff8) |
((in_addr >> 14) & 0x6) |
(in_addr & ~0x1fffe);
@@ -424,9 +424,9 @@ dword_remap_w(svga_t *svga, uint32_t in_addr)
static __inline uint32_t
dword_remap_l(svga_t *svga, uint32_t in_addr)
{
- if (svga->packed_chain4)
- return in_addr;
-
+ if (svga->packed_chain4 || svga->force_old_addr)
+ return in_addr;
+
return ((in_addr << 2) & 0xfffc) |
((in_addr >> 14) & 0x3) |
(in_addr & ~0xffff);
@@ -2552,6 +2552,7 @@ s3_out(uint16_t addr, uint8_t val, void *p)
{
case 0x31:
s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4);
+ svga->force_dword_mode = !!(val & 0x08);
break;
case 0x32:
if ((svga->crtc[0x31] & 0x30) && (svga->crtc[0x51] & 0x01) && (val & 0x40))
@@ -2971,7 +2972,6 @@ static void s3_recalctimings(svga_t *svga)
}
if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) {
- svga->fb_only = 1;
switch (svga->bpp) {
case 8:
svga->render = svga_render_8bpp_highres;
@@ -3154,7 +3154,6 @@ static void s3_recalctimings(svga_t *svga)
break;
}
} else {
- svga->fb_only = 0;
if (!svga->scrblank && svga->attr_palette_enable) {
if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) {
if ((svga->crtc[0x31] & 0x08) && ((svga->gdcreg[5] & 0x60) == 0x00)) {
@@ -3208,7 +3207,6 @@ static void s3_trio64v_recalctimings(svga_t *svga)
svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10));
if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) {
- svga->fb_only = 1;
switch (svga->bpp) {
case 8:
svga->render = svga_render_8bpp_highres;
@@ -3229,13 +3227,10 @@ static void s3_trio64v_recalctimings(svga_t *svga)
svga->render = svga_render_32bpp_highres;
break;
}
- } else
- svga->fb_only = 0;
+ }
}
else /*Streams mode*/
{
- svga->fb_only = 1;
-
if (s3->streams.buffer_ctrl & 1)
svga->ma_latch = s3->streams.pri_fb1 >> 2;
else
@@ -3379,7 +3374,12 @@ s3_updatemapping(s3_t *s3)
mem_mapping_set_addr(&s3->linear_mapping, s3->linear_base, s3->linear_size);
}
+ if (s3->chip >= S3_TRIO64V)
+ svga->fb_only = 1;
} else {
+ if (s3->chip >= S3_TRIO64V)
+ svga->fb_only = 0;
+
mem_mapping_disable(&s3->linear_mapping);
}
@@ -7140,6 +7140,8 @@ static void *s3_init(const device_t *info)
s3->card_type = info->local;
+ svga->force_old_addr = 1;
+
switch(s3->card_type) {
case S3_ORCHID_86C911:
case S3_DIAMOND_STEALTH_VRAM:
@@ -7401,8 +7403,6 @@ static void *s3_init(const device_t *info)
return NULL;
}
- svga->packed_chain4 = 1;
-
if (s3->pci)
s3->card = pci_add_card(PCI_ADD_VIDEO, s3_pci_read, s3_pci_write, s3);
@@ -7609,73 +7609,124 @@ static void s3_force_redraw(void *p)
s3->svga.fullchange = changeframecount;
}
-// clang-format off
-static const device_config_t s3_orchid_86c911_config[] = {
- {
- "memory", "Memory size", CONFIG_SELECTION, "", 1, "", { 0 },
- {
- { "512 KB", 0 },
- { "1 MB", 1 },
- { "" }
- }
- },
- { "", "", -1 }
+static const device_config_t s3_orchid_86c911_config[] =
+{
+ {
+ "memory", "Memory size", CONFIG_SELECTION, "", 1, "", { 0 },
+ {
+ {
+ "512 KB", 0
+ },
+ {
+ "1 MB", 1
+ },
+ {
+ ""
+ }
+ }
+ },
+ {
+ "", "", -1
+ }
};
-static const device_config_t s3_9fx_config[] = {
- {
- "memory", "Memory size", CONFIG_SELECTION, "", 2, "", { 0 },
- {
- { "1 MB", 1 },
- { "2 MB", 2 },
- /*Trio64 also supports 4 MB, however the Number Nine BIOS does not*/
- { "" }
- }
- },
- { "", "", -1 }
+static const device_config_t s3_9fx_config[] =
+{
+ {
+ "memory", "Memory size", CONFIG_SELECTION, "", 2, "", { 0 },
+ {
+ {
+ "1 MB", 1
+ },
+ {
+ "2 MB", 2
+ },
+ /*Trio64 also supports 4 MB, however the Number Nine BIOS does not*/
+ {
+ ""
+ }
+ }
+ },
+ {
+ "", "", -1
+ }
};
-static const device_config_t s3_phoenix_trio32_config[] = {
- {
- "memory", "Memory size", CONFIG_SELECTION, "", 2, "", { 0 },
- {
- { "512 KB", 0 },
- { "1 MB", 1 },
- { "2 MB", 2 },
- { "" }
- }
- },
- { "", "", -1 }
+static const device_config_t s3_phoenix_trio32_config[] =
+{
+ {
+ "memory", "Memory size", CONFIG_SELECTION, "", 2, "", { 0 },
+ {
+ {
+ "512 KB", 0
+ },
+ {
+ "1 MB", 1
+ },
+ {
+ "2 MB", 2
+ },
+ {
+ ""
+ }
+ }
+ },
+ {
+ "", "", -1
+ }
};
-static const device_config_t s3_standard_config[] = {
- {
- "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 },
- {
- { "1 MB", 1 },
- { "2 MB", 2 },
- { "4 MB", 4 },
- { "" }
- }
- },
- { "", "", -1 }
+static const device_config_t s3_standard_config[] =
+{
+ {
+ "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 },
+ {
+ {
+ "1 MB", 1
+ },
+ {
+ "2 MB", 2
+ },
+ {
+ "4 MB", 4
+ },
+ {
+ ""
+ }
+ }
+ },
+ {
+ "", "", -1
+ }
};
-static const device_config_t s3_968_config[] = {
- {
- "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 },
- {
- { "1 MB", 1 },
- { "2 MB", 2 },
- { "4 MB", 4 },
- { "8 MB", 8 },
- { "" }
- }
- },
- { "", "", -1 }
+static const device_config_t s3_968_config[] =
+{
+ {
+ "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 },
+ {
+ {
+ "1 MB", 1
+ },
+ {
+ "2 MB", 2
+ },
+ {
+ "4 MB", 4
+ },
+ {
+ "8 MB", 8
+ },
+ {
+ ""
+ }
+ }
+ },
+ {
+ "", "", -1
+ }
};
-// clang-format on
const device_t s3_orchid_86c911_isa_device =
{
@@ -8333,7 +8384,7 @@ const device_t s3_elsa_winner2000_pro_x_964_pci_device =
S3_ELSAWIN2KPROX_964,
s3_init,
s3_close,
- s3_reset,
+ s3_reset,
{ s3_elsa_winner2000_pro_x_964_available },
s3_speed_changed,
s3_force_redraw,
@@ -8348,7 +8399,7 @@ const device_t s3_elsa_winner2000_pro_x_pci_device =
S3_ELSAWIN2KPROX,
s3_init,
s3_close,
- s3_reset,
+ s3_reset,
{ s3_elsa_winner2000_pro_x_available },
s3_speed_changed,
s3_force_redraw,
@@ -8363,7 +8414,7 @@ const device_t s3_trio64v2_dx_pci_device =
S3_TRIO64V2_DX,
s3_init,
s3_close,
- s3_reset,
+ s3_reset,
{ s3_trio64v2_dx_available },
s3_speed_changed,
s3_force_redraw,
@@ -8379,7 +8430,7 @@ const device_t s3_trio64v2_dx_onboard_pci_device =
S3_TRIO64V2_DX_ONBOARD,
s3_init,
s3_close,
- NULL,
+ NULL,
{ NULL },
s3_speed_changed,
s3_force_redraw,
diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c
index 4acaa0aa0..6f46278da 100644
--- a/src/video/vid_s3_virge.c
+++ b/src/video/vid_s3_virge.c
@@ -117,10 +117,10 @@ typedef struct s3d_t
{
uint32_t cmd_set;
int clip_l, clip_r, clip_t, clip_b;
-
+
uint32_t dest_base;
uint32_t dest_str;
-
+
uint32_t z_base;
uint32_t z_str;
@@ -136,14 +136,14 @@ typedef struct s3d_t
int32_t TdWdX, TdWdY;
uint32_t tws;
-
+
int32_t TdDdX, TdDdY;
uint32_t tds;
-
+
int16_t TdGdX, TdBdX, TdRdX, TdAdX;
int16_t TdGdY, TdBdY, TdRdY, TdAdY;
uint32_t tgs, tbs, trs, tas;
-
+
uint32_t TdXdY12;
uint32_t txend12;
uint32_t TdXdY01;
@@ -161,9 +161,9 @@ typedef struct virge_t
mem_mapping_t linear_mapping;
mem_mapping_t mmio_mapping;
mem_mapping_t new_mmio_mapping;
-
+
rom_t bios_rom;
-
+
svga_t svga;
uint8_t bank;
@@ -195,7 +195,7 @@ typedef struct virge_t
uint32_t hwc_fg_col, hwc_bg_col;
int hwc_col_stack_pos;
-
+
struct
{
uint32_t src_base;
@@ -212,21 +212,21 @@ typedef struct virge_t
int r_width, r_height;
int rsrc_x, rsrc_y;
int rdest_x, rdest_y;
-
+
int lxend0, lxend1;
int32_t ldx;
uint32_t lxstart, lystart;
int lycnt;
int line_dir;
-
+
int src_x, src_y;
int dest_x, dest_y;
int w, h;
uint8_t rop;
-
+
int data_left_count;
uint32_t data_left;
-
+
uint32_t pattern_8[8*8];
uint32_t pattern_16[8*8];
uint32_t pattern_24[8*8];
@@ -240,14 +240,14 @@ typedef struct virge_t
uint32_t pycnt;
uint32_t dest_l, dest_r;
} s3d;
-
+
s3d_t s3d_tri;
s3d_t s3d_buffer[RB_SIZE];
int s3d_read_idx, s3d_write_idx;
int s3d_busy;
int render_idx;
-
+
struct
{
uint32_t pri_ctrl;
@@ -273,9 +273,9 @@ typedef struct virge_t
uint32_t pri_size;
uint32_t sec_start;
uint32_t sec_size;
-
+
int sdif;
-
+
int pri_x, pri_y, pri_w, pri_h;
int sec_x, sec_y, sec_w, sec_h;
} streams;
@@ -285,7 +285,7 @@ typedef struct virge_t
uint32_t dma_ptr;
uint64_t blitter_time;
volatile int fifo_slot;
-
+
pc_timer_t tri_timer;
int virge_busy, local;
@@ -297,7 +297,7 @@ typedef struct virge_t
uint8_t serialport;
void *i2c, *ddc;
-
+
int waiting;
} virge_t;
@@ -324,29 +324,29 @@ enum
{
CMD_SET_AE = 1,
CMD_SET_HC = (1 << 1),
-
+
CMD_SET_FORMAT_MASK = (7 << 2),
CMD_SET_FORMAT_8 = (0 << 2),
CMD_SET_FORMAT_16 = (1 << 2),
CMD_SET_FORMAT_24 = (2 << 2),
-
+
CMD_SET_MS = (1 << 6),
CMD_SET_IDS = (1 << 7),
CMD_SET_MP = (1 << 8),
CMD_SET_TP = (1 << 9),
-
+
CMD_SET_ITA_MASK = (3 << 10),
CMD_SET_ITA_BYTE = (0 << 10),
CMD_SET_ITA_WORD = (1 << 10),
CMD_SET_ITA_DWORD = (2 << 10),
-
+
CMD_SET_ZUP = (1 << 23),
-
+
CMD_SET_ZB_MODE = (3 << 24),
CMD_SET_XP = (1 << 25),
CMD_SET_YP = (1 << 26),
-
+
CMD_SET_COMMAND_MASK = (15 << 27)
};
@@ -440,7 +440,7 @@ static void
render_thread(void *param)
{
virge_t *virge = (virge_t *)param;
-
+
while (virge->render_thread_run) {
thread_wait_event(virge->wake_render_thread, -1);
thread_reset_event(virge->wake_render_thread);
@@ -467,9 +467,9 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p)
uint8_t old;
uint32_t cursoraddr;
- if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
+ if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
addr ^= 0x60;
-
+
switch (addr)
{
case 0x3c5:
@@ -495,7 +495,7 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p)
return;
}
break;
-
+
case 0x3d4:
svga->crtcreg = val;
return;
@@ -503,7 +503,7 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p)
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80))
return;
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80))
- val = (svga->crtc[7] & ~0x10) | (val & 0x10);
+ val = (svga->crtc[7] & ~0x10) | (val & 0x10);
if ((svga->crtcreg >= 0x20) && (svga->crtcreg < 0x40) &&
(svga->crtcreg != 0x36) && (svga->crtcreg != 0x38) &&
(svga->crtcreg != 0x39) && ((svga->crtc[0x38] & 0xcc) != 0x48))
@@ -516,10 +516,10 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p)
return;
old = svga->crtc[svga->crtcreg];
svga->crtc[svga->crtcreg] = val;
-
+
if (svga->crtcreg > 0x18)
s3_virge_log("OUTB VGA reg = %02x, val = %02x\n", svga->crtcreg, val);
-
+
switch (svga->crtcreg)
{
case 0x31:
@@ -528,11 +528,11 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p)
case 0x32:
s3_virge_update_irqs(virge);
break;
-
+
case 0x69:
virge->ma_ext = val & 0x1f;
break;
-
+
case 0x35:
virge->bank = (virge->bank & 0x70) | (val & 0xf);
if (svga->chain4)
@@ -555,12 +555,12 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p)
else
svga->write_bank = svga->read_bank = virge->bank << 14;
break;
-
+
case 0x3a:
if (val & 0x10)
svga->gdcreg[5] |= 0x40; /*Horrible cheat*/
break;
-
+
case 0x45:
svga->hwcursor.ena = val & 1;
break;
@@ -573,7 +573,7 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p)
cursoraddr = (virge->memory_size == 8) ? 0x1fff : 0x0fff;
svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & cursoraddr) * 1024) + (svga->hwcursor.yoff * 16);
break;
-
+
case 0x4a:
switch (virge->hwc_col_stack_pos)
{
@@ -614,12 +614,12 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p)
svga->dpms = (svga->seqregs[0x0d] & 0x50) || (svga->crtc[0x56] & 0x06);
old = ~val; /* force recalc */
break;
-
+
case 0x5c:
if ((val & 0xa0) == 0x80)
i2c_gpio_set(virge->i2c, !!(val & 0x40), !!(val & 0x10));
break;
-
+
case 0x67:
switch (val >> 4)
{
@@ -630,7 +630,7 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p)
default: svga->bpp = 8; break;
}
break;
-
+
case 0xaa:
i2c_gpio_set(virge->i2c, !!(val & SERIAL_PORT_SCW), !!(val & SERIAL_PORT_SDW));
break;
@@ -660,8 +660,8 @@ static uint8_t s3_virge_in(uint16_t addr, void *p)
virge_t *virge = (virge_t *)p;
svga_t *svga = &virge->svga;
uint8_t ret;
-
- if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
+
+ if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
addr ^= 0x60;
switch (addr)
@@ -671,7 +671,7 @@ static uint8_t s3_virge_in(uint16_t addr, void *p)
ret = 0xff;
else
ret = svga_in(addr, svga);
- break;
+ break;
case 0x3c5:
if (svga->seqaddr >= 8)
@@ -690,7 +690,7 @@ static uint8_t s3_virge_in(uint16_t addr, void *p)
{
case 0x2d: ret = virge->virge_id_high; break; /*Extended chip ID*/
case 0x2e: ret = virge->virge_id_low; break; /*New chip ID*/
- case 0x2f: ret = virge->virge_rev; break;
+ case 0x2f: ret = virge->virge_rev; break;
case 0x30: ret = virge->virge_id; break; /*Chip ID*/
case 0x31: ret = (svga->crtc[0x31] & 0xcf) | ((virge->ma_ext & 3) << 4); break;
case 0x33: ret = (svga->crtc[0x33] | 0x04); break;
@@ -724,16 +724,16 @@ static uint8_t s3_virge_in(uint16_t addr, void *p)
} else
ret = svga->crtc[0xaa];
break;
-
+
default:
ret = svga->crtc[svga->crtcreg];
break;
}
break;
-
+
default:
ret = svga_in(addr, svga);
- break;
+ break;
}
return ret;
}
@@ -741,7 +741,7 @@ static uint8_t s3_virge_in(uint16_t addr, void *p)
static void s3_virge_recalctimings(svga_t *svga)
{
virge_t *virge = (virge_t *)svga->p;
-
+
svga->hdisp = svga->hdisp_old;
if (svga->crtc[0x5d] & 0x01) svga->htotal += 0x100;
@@ -759,36 +759,36 @@ static void s3_virge_recalctimings(svga_t *svga)
if (((svga->miscout >> 2) & 3) == 3) {
int n = svga->seqregs[0x12] & 0x1f;
int r = (svga->seqregs[0x12] >> 5);
-
- if (virge->chip == S3_VIRGEVX || virge->chip == S3_VIRGEDX)
+
+ if (virge->chip == S3_VIRGEVX || virge->chip == S3_VIRGEDX)
r &= 7;
else if (virge->chip >= S3_VIRGEGX2)
r &= 10;
else
r &= 3;
-
+
int m = svga->seqregs[0x13] & 0x7f;
double freq = (((double)m + 2) / (((double)n + 2) * (double)(1 << r))) * 14318184.0;
svga->clock = (cpuclock * (float)(1ull << 32)) / freq;
}
-
+
if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/
- {
+ {
+ svga->fb_only = 0;
svga->ma_latch |= (virge->ma_ext << 16);
if (svga->crtc[0x51] & 0x30) svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4;
else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100;
if (!svga->rowoffset) svga->rowoffset = 256;
-
+
svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10));
if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) {
- svga->fb_only = 1;
switch (svga->bpp) {
- case 8:
- svga->render = svga_render_8bpp_highres;
+ case 8:
+ svga->render = svga_render_8bpp_highres;
break;
- case 15:
+ case 15:
svga->render = svga_render_15bpp_highres;
if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2)
{
@@ -796,12 +796,12 @@ static void s3_virge_recalctimings(svga_t *svga)
svga->hdisp >>= 1;
}
break;
- case 16:
+ case 16:
svga->render = svga_render_16bpp_highres;
if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2)
{
svga->htotal >>= 1;
- svga->hdisp >>= 1;
+ svga->hdisp >>= 1;
}
break;
case 24:
@@ -809,28 +809,27 @@ static void s3_virge_recalctimings(svga_t *svga)
if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2)
svga->rowoffset = (svga->rowoffset * 3) / 4; /*Hack*/
break;
- case 32:
+ case 32:
svga->render = svga_render_32bpp_highres;
break;
}
- } else
- svga->fb_only = 0;
+ }
svga->vram_display_mask = (!(svga->crtc[0x31] & 0x08) && (svga->crtc[0x32] & 0x40)) ? 0x3ffff : virge->vram_mask;
s3_virge_log("VGA mode\n");
}
else /*Streams mode*/
{
svga->fb_only = 1;
-
+
if (virge->streams.buffer_ctrl & 1)
svga->ma_latch = virge->streams.pri_fb1 >> 2;
else
svga->ma_latch = virge->streams.pri_fb0 >> 2;
-
+
svga->hdisp = virge->streams.pri_w + 1;
if (virge->streams.pri_h < svga->dispend)
svga->dispend = virge->streams.pri_h;
-
+
svga->overlay.x = virge->streams.sec_x - virge->streams.pri_x;
svga->overlay.y = virge->streams.sec_y - virge->streams.pri_y;
svga->overlay.ysize = virge->streams.sec_h;
@@ -847,21 +846,21 @@ static void s3_virge_recalctimings(svga_t *svga)
switch ((virge->streams.pri_ctrl >> 24) & 0x7)
{
case 0: /*RGB-8 (CLUT)*/
- svga->render = svga_render_8bpp_highres;
+ svga->render = svga_render_8bpp_highres;
break;
- case 3: /*KRGB-16 (1.5.5.5)*/
+ case 3: /*KRGB-16 (1.5.5.5)*/
svga->htotal >>= 1;
- svga->render = svga_render_15bpp_highres;
+ svga->render = svga_render_15bpp_highres;
break;
- case 5: /*RGB-16 (5.6.5)*/
+ case 5: /*RGB-16 (5.6.5)*/
svga->htotal >>= 1;
- svga->render = svga_render_16bpp_highres;
+ svga->render = svga_render_16bpp_highres;
break;
- case 6: /*RGB-24 (8.8.8)*/
- svga->render = svga_render_24bpp_highres;
+ case 6: /*RGB-24 (8.8.8)*/
+ svga->render = svga_render_24bpp_highres;
break;
case 7: /*XRGB-32 (X.8.8.8)*/
- svga->render = svga_render_32bpp_highres;
+ svga->render = svga_render_32bpp_highres;
break;
}
svga->vram_display_mask = virge->vram_mask;
@@ -881,7 +880,7 @@ static void s3_virge_updatemapping(virge_t *virge)
return;
}
- s3_virge_log("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc);
+ s3_virge_log("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc);
/*Banked framebuffer*/
switch (svga->gdcreg[6] & 0xc) { /*VGA mapping*/
case 0x0: /*128k at A0000*/
@@ -901,7 +900,7 @@ static void s3_virge_updatemapping(virge_t *virge)
svga->banked_mask = 0x7fff;
break;
}
-
+
virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24);
s3_virge_log("Linear framebuffer %02X, linear base = %08x, display mask = %08x\n", svga->crtc[0x58] & 0x17, virge->linear_base, svga->vram_display_mask);
@@ -937,13 +936,15 @@ static void s3_virge_updatemapping(virge_t *virge)
} else {
virge->linear_base &= 0xfc000000;
}
-
+
mem_mapping_set_addr(&virge->linear_mapping, virge->linear_base, virge->linear_size);
}
+ svga->fb_only = 1;
} else {
mem_mapping_disable(&virge->linear_mapping);
+ svga->fb_only = 0;
}
-
+
s3_virge_log("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x38);
/* Memory mapped I/O. */
@@ -983,8 +984,8 @@ s3_virge_mmio_fifo_write(uint32_t addr, uint8_t val, virge_t *virge)
case 0x859c:
virge->cmd_dma = val;
break;
- }
- }
+ }
+ }
}
static void
@@ -1003,7 +1004,7 @@ s3_virge_mmio_fifo_write_w(uint32_t addr, uint16_t val, virge_t *virge)
static void
s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge)
-{
+{
if ((addr & 0xfffc) < 0x8000) {
if (virge->s3d.cmd_set & CMD_SET_MS)
s3_virge_bitblt(virge, 32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24));
@@ -1015,7 +1016,7 @@ s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge)
case 0x8590:
virge->cmd_dma_base = val;
break;
-
+
case 0x8594:
virge->dma_ptr = val;
break;
@@ -1026,7 +1027,7 @@ s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge)
case 0x859c:
virge->cmd_dma = val;
break;
-
+
case 0xa000: case 0xa004: case 0xa008: case 0xa00c:
case 0xa010: case 0xa014: case 0xa018: case 0xa01c:
case 0xa020: case 0xa024: case 0xa028: case 0xa02c:
@@ -1068,7 +1069,7 @@ s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge)
virge->s3d.pattern_8[y*8 + x + 1] = val >> 8;
virge->s3d.pattern_8[y*8 + x + 2] = val >> 16;
virge->s3d.pattern_8[y*8 + x + 3] = val >> 24;
-
+
x = (addr >> 1) & 6;
y = (addr >> 4) & 7;
virge->s3d.pattern_16[y*8 + x] = val & 0xffff;
@@ -1194,7 +1195,7 @@ s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge)
if (virge->s3d.cmd_set & CMD_SET_AE)
s3_virge_bitblt(virge, -1, 0);
break;
-
+
case 0xb0f4: case 0xb4f4:
virge->s3d_tri.fog_b = val & 0xff;
virge->s3d_tri.fog_g = (val >> 8) & 0xff;
@@ -1298,7 +1299,7 @@ s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge)
virge->s3d_tri.tas = (val >> 16) & 0xffff;
virge->s3d_tri.trs = val & 0xffff;
break;
-
+
case 0xb554:
virge->s3d_tri.TdZdX = val;
break;
@@ -1361,7 +1362,7 @@ s3_virge_mmio_read(uint32_t addr, void *p)
if (virge->fifo_slot)
virge->fifo_slot--;
return ret;
-
+
case 0x83b0: case 0x83b1: case 0x83b2: case 0x83b3:
case 0x83b4: case 0x83b5: case 0x83b6: case 0x83b7:
case 0x83b8: case 0x83b9: case 0x83ba: case 0x83bb:
@@ -1375,10 +1376,10 @@ s3_virge_mmio_read(uint32_t addr, void *p)
case 0x83d8: case 0x83d9: case 0x83da: case 0x83db:
case 0x83dc: case 0x83dd: case 0x83de: case 0x83df:
return s3_virge_in(addr & 0x3ff, virge);
-
+
case 0x859c:
return virge->cmd_dma;
-
+
case 0xff20: case 0xff21:
ret = virge->serialport & ~(SERIAL_PORT_SCR | SERIAL_PORT_SDR);
if ((virge->serialport & SERIAL_PORT_SCW) && i2c_gpio_get_scl(virge->i2c))
@@ -1394,9 +1395,9 @@ s3_virge_mmio_read_w(uint32_t addr, void *p)
{
virge_t *virge = (virge_t *)p;
uint16_t ret = 0xffff;
-
+
s3_virge_log("[%04X:%08X]: MMIO ReadW addr = %04x\n", CS, cpu_state.pc, addr & 0xfffe);
-
+
switch (addr & 0xfffe) {
case 0x8504:
if (!virge->fifo_slot)
@@ -1407,10 +1408,10 @@ s3_virge_mmio_read_w(uint32_t addr, void *p)
ret |= 0x30; /*A bit of a workaround at the moment.*/
s3_virge_update_irqs(virge);
return ret;
-
+
case 0x859c:
return virge->cmd_dma;
-
+
default:
return s3_virge_mmio_read(addr, virge) |
(s3_virge_mmio_read(addr + 1, virge) << 8);
@@ -1493,7 +1494,7 @@ s3_virge_mmio_read_l(uint32_t addr, void *p)
break;
case 0x81fc:
ret = virge->streams.sec_size;
- break;
+ break;
case 0x8504:
if (virge->s3d_busy || virge->fifo_slot) {
@@ -1510,7 +1511,7 @@ s3_virge_mmio_read_l(uint32_t addr, void *p)
virge->fifo_slot--;
s3_virge_update_irqs(virge);
break;
-
+
case 0x8590:
ret = virge->cmd_dma_base;
break;
@@ -1522,7 +1523,7 @@ s3_virge_mmio_read_l(uint32_t addr, void *p)
case 0x859c:
ret = virge->cmd_dma;
break;
-
+
case 0xa4d4:
ret = virge->s3d.src_base;
break;
@@ -1568,11 +1569,11 @@ s3_virge_mmio_read_l(uint32_t addr, void *p)
case 0xa50c:
ret = (virge->s3d.rdest_x << 16) | virge->s3d.rdest_y;
break;
-
+
default:
ret = s3_virge_mmio_read(addr, virge) |
(s3_virge_mmio_read(addr + 1, virge) << 8) |
- (s3_virge_mmio_read(addr + 2, virge) << 16) |
+ (s3_virge_mmio_read(addr + 2, virge) << 16) |
(s3_virge_mmio_read(addr + 3, virge) << 24);
break;
}
@@ -1626,7 +1627,7 @@ s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p)
if ((addr & 0xfffe) == 0x83d4) {
s3_virge_mmio_write(addr, val, virge);
s3_virge_mmio_write(addr + 1, val >> 8, virge);
- }
+ }
}
}
@@ -1634,12 +1635,12 @@ static void
s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p)
{
virge_t *virge = (virge_t *)p;
- svga_t *svga = &virge->svga;
-
+ svga_t *svga = &virge->svga;
+
s3_virge_log("[%04X:%08X]: MMIO WriteL addr = %04x, val = %04x\n", CS, cpu_state.pc, addr & 0xfffc, val);
if (((addr & 0xfffc) >= 0x8590) || ((addr & 0xfffc) < 0x8000))
if ((addr & 0xfffc) == 0xff20)
- s3_virge_mmio_write(addr, val, virge);
+ s3_virge_mmio_write(addr, val, virge);
else {
s3_virge_mmio_fifo_write_l(addr, val, virge);
}
@@ -1734,38 +1735,38 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p)
case 0x81f0:
virge->streams.pri_start = val;
virge->streams.pri_x = (val >> 16) & 0x7ff;
- virge->streams.pri_y = val & 0x7ff;
+ virge->streams.pri_y = val & 0x7ff;
svga_recalctimings(svga);
svga->fullchange = changeframecount;
break;
case 0x81f4:
virge->streams.pri_size = val;
virge->streams.pri_w = (val >> 16) & 0x7ff;
- virge->streams.pri_h = val & 0x7ff;
+ virge->streams.pri_h = val & 0x7ff;
svga_recalctimings(svga);
svga->fullchange = changeframecount;
break;
case 0x81f8:
virge->streams.sec_start = val;
virge->streams.sec_x = (val >> 16) & 0x7ff;
- virge->streams.sec_y = val & 0x7ff;
+ virge->streams.sec_y = val & 0x7ff;
svga_recalctimings(svga);
svga->fullchange = changeframecount;
break;
case 0x81fc:
virge->streams.sec_size = val;
virge->streams.sec_w = (val >> 16) & 0x7ff;
- virge->streams.sec_h = val & 0x7ff;
+ virge->streams.sec_h = val & 0x7ff;
svga_recalctimings(svga);
svga->fullchange = changeframecount;
break;
-
+
case 0x8504:
virge->subsys_stat &= ~(val & 0xff);
virge->subsys_cntl = (val >> 8);
s3_virge_update_irqs(virge);
break;
-
+
case 0x850c:
virge->advfunc_cntl = val & 0xff;
s3_virge_updatemapping(virge);
@@ -1809,7 +1810,7 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p)
y > s3d_tri->clip_b)) \
update = 0; \
}
-
+
#define MIX() \
{ \
@@ -1861,7 +1862,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
uint32_t source = 0, dest = 0, pattern;
uint32_t out = 0;
int update;
-
+
switch (virge->s3d.cmd_set & CMD_SET_FORMAT_MASK)
{
case CMD_SET_FORMAT_8:
@@ -1892,7 +1893,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
}
if (virge->s3d.cmd_set & CMD_SET_MP)
pattern_data = mono_pattern;
-
+
switch (virge->s3d.cmd_set & CMD_SET_ITA_MASK)
{
case CMD_SET_ITA_BYTE:
@@ -1937,7 +1938,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
virge->s3d.h = virge->s3d.r_height;
virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff;
virge->s3d.data_left_count = 0;
-
+
s3_virge_log("BitBlt start src_x=%i,src_y=%i,dest_x=%i,dest_y=%i,w=%i,h=%i,rop=%02X,src_base=%x,dest_base=%x\n",
virge->s3d.src_x,
virge->s3d.src_y,
@@ -1948,7 +1949,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
virge->s3d.rop,
virge->s3d.src_base,
virge->s3d.dest_base);
-
+
if (virge->s3d.cmd_set & CMD_SET_IDS)
return;
}
@@ -2019,7 +2020,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
WRITE(dest_addr, out);
}
-
+
virge->s3d.src_x += x_inc;
virge->s3d.src_x &= 0x7ff;
virge->s3d.dest_x += x_inc;
@@ -2033,7 +2034,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
virge->s3d.src_y += y_inc;
virge->s3d.dest_y += y_inc;
virge->s3d.h--;
-
+
switch (virge->s3d.cmd_set & (CMD_SET_MS | CMD_SET_IDS))
{
case CMD_SET_IDS:
@@ -2053,10 +2054,10 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
}
}
else
- virge->s3d.w--;
+ virge->s3d.w--;
}
break;
-
+
case CMD_SET_COMMAND_RECTFILL:
/*No source, pattern = pat_fg_clr*/
if (count == -1)
@@ -2068,7 +2069,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
virge->s3d.w = virge->s3d.r_width;
virge->s3d.h = virge->s3d.r_height;
virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff;
-
+
s3_virge_log("RctFll start %i,%i %i,%i %02X %08x\n", virge->s3d.dest_x,
virge->s3d.dest_y,
virge->s3d.w,
@@ -2114,11 +2115,11 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
}
}
else
- virge->s3d.w--;
+ virge->s3d.w--;
count--;
}
break;
-
+
case CMD_SET_COMMAND_LINE:
if (count == -1)
{
@@ -2132,7 +2133,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
int x;
int new_x;
int first_pixel = 1;
-
+
x = virge->s3d.dest_x >> 20;
if (virge->s3d.h == virge->s3d.lycnt &&
@@ -2145,11 +2146,11 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
else
new_x = (virge->s3d.dest_x + virge->s3d.ldx) >> 20;
-
+
if ((virge->s3d.line_dir && x > new_x) ||
(!virge->s3d.line_dir && x < new_x))
goto skip_line;
-
+
do
{
uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str);
@@ -2178,7 +2179,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
WRITE(dest_addr, out);
}
-
+
if (x < new_x)
x++;
else if (x > new_x)
@@ -2224,7 +2225,7 @@ skip_line:
WRITE(dest_addr, out);
}
-
+
x = (x + xdir) & 0x7ff;
}
while (x != (xend + xdir));
@@ -2273,21 +2274,21 @@ typedef struct s3d_state_t
int32_t r, g, b, a, u, v, d, w;
int32_t base_r, base_g, base_b, base_a, base_u, base_v, base_d, base_w;
-
+
uint32_t base_z;
uint32_t tbu, tbv;
uint32_t cmd_set;
int max_d;
-
+
uint16_t *texture[10];
-
+
uint32_t tex_bdr_clr;
-
+
int32_t x1, x2;
int y;
-
+
rgba_t dest_rgba;
} s3d_state_t;
@@ -2295,7 +2296,7 @@ typedef struct s3d_texture_state_t
{
int level;
int texture_shift;
-
+
int32_t u, v;
} s3d_texture_state_t;
@@ -2391,7 +2392,7 @@ static void tex_ARGB8888_nowrap(s3d_state_t *state, s3d_texture_state_t *texture
static void tex_sample_normal(s3d_state_t *state)
{
s3d_texture_state_t texture_state;
-
+
texture_state.level = state->max_d;
texture_state.texture_shift = 18 + (9 - texture_state.level);
texture_state.u = state->u + state->tbu;
@@ -2429,12 +2430,12 @@ static void tex_sample_normal_filter(s3d_state_t *state)
texture_state.u = state->u + state->tbu + tex_offset;
texture_state.v = state->v + state->tbv + tex_offset;
tex_read(state, &texture_state, &tex_samples[3]);
-
+
d[0] = (256 - du) * (256 - dv);
d[1] = du * (256 - dv);
d[2] = (256 - du) * dv;
d[3] = du * dv;
-
+
state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16;
state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16;
state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16;
@@ -2468,7 +2469,7 @@ static void tex_sample_mipmap_filter(s3d_state_t *state)
texture_state.level = 0;
texture_state.texture_shift = 18 + (9 - texture_state.level);
tex_offset = 1 << texture_state.texture_shift;
-
+
texture_state.u = state->u + state->tbu;
texture_state.v = state->v + state->tbv;
tex_read(state, &texture_state, &tex_samples[0]);
@@ -2491,7 +2492,7 @@ static void tex_sample_mipmap_filter(s3d_state_t *state)
d[1] = du * (256 - dv);
d[2] = (256 - du) * dv;
d[3] = du * dv;
-
+
state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16;
state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16;
state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16;
@@ -2505,9 +2506,9 @@ static void tex_sample_persp_normal(s3d_state_t *state)
if (state->w)
w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w);
-
+
texture_state.level = state->max_d;
- texture_state.texture_shift = 18 + (9 - texture_state.level);
+ texture_state.texture_shift = 18 + (9 - texture_state.level);
texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu;
texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv;
@@ -2532,7 +2533,7 @@ static void tex_sample_persp_normal_filter(s3d_state_t *state)
texture_state.level = state->max_d;
texture_state.texture_shift = 18 + (9 - texture_state.level);
tex_offset = 1 << texture_state.texture_shift;
-
+
texture_state.u = u;
texture_state.v = v;
tex_read(state, &texture_state, &tex_samples[0]);
@@ -2555,7 +2556,7 @@ static void tex_sample_persp_normal_filter(s3d_state_t *state)
d[1] = du * (256 - dv);
d[2] = (256 - du) * dv;
d[3] = du * dv;
-
+
state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16;
state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16;
state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16;
@@ -2569,9 +2570,9 @@ static void tex_sample_persp_normal_375(s3d_state_t *state)
if (state->w)
w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w);
-
+
texture_state.level = state->max_d;
- texture_state.texture_shift = 18 + (9 - texture_state.level);
+ texture_state.texture_shift = 18 + (9 - texture_state.level);
texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu;
texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv;
@@ -2592,7 +2593,7 @@ static void tex_sample_persp_normal_filter_375(s3d_state_t *state)
u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu;
v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv;
-
+
texture_state.level = state->max_d;
texture_state.texture_shift = 18 + (9 - texture_state.level);
tex_offset = 1 << texture_state.texture_shift;
@@ -2619,7 +2620,7 @@ static void tex_sample_persp_normal_filter_375(s3d_state_t *state)
d[1] = du * (256 - dv);
d[2] = (256 - du) * dv;
d[3] = du * dv;
-
+
state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16;
state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16;
state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16;
@@ -2634,7 +2635,7 @@ static void tex_sample_persp_mipmap(s3d_state_t *state)
if (state->w)
w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w);
-
+
texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf);
if (texture_state.level < 0)
texture_state.level = 0;
@@ -2659,7 +2660,7 @@ static void tex_sample_persp_mipmap_filter(s3d_state_t *state)
u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu;
v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv;
-
+
texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf);
if (texture_state.level < 0)
texture_state.level = 0;
@@ -2688,7 +2689,7 @@ static void tex_sample_persp_mipmap_filter(s3d_state_t *state)
d[1] = du * (256 - dv);
d[2] = (256 - du) * dv;
d[3] = du * dv;
-
+
state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16;
state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16;
state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16;
@@ -2702,7 +2703,7 @@ static void tex_sample_persp_mipmap_375(s3d_state_t *state)
if (state->w)
w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w);
-
+
texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf);
if (texture_state.level < 0)
texture_state.level = 0;
@@ -2727,13 +2728,13 @@ static void tex_sample_persp_mipmap_filter_375(s3d_state_t *state)
u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu;
v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv;
-
+
texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf);
if (texture_state.level < 0)
texture_state.level = 0;
texture_state.texture_shift = 18 + (9 - texture_state.level);
tex_offset = 1 << texture_state.texture_shift;
-
+
texture_state.u = u;
texture_state.v = v;
tex_read(state, &texture_state, &tex_samples[0]);
@@ -2756,7 +2757,7 @@ static void tex_sample_persp_mipmap_filter_375(s3d_state_t *state)
d[1] = du * (256 - dv);
d[2] = (256 - du) * dv;
d[3] = du * dv;
-
+
state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16;
state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16;
state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16;
@@ -2780,7 +2781,7 @@ static void tex_sample_persp_mipmap_filter_375(s3d_state_t *state)
b = ((b) < 0) ? 0 : 0xff; \
if ((a) & ~0xff) \
a = ((a) < 0) ? 0 : 0xff;
-
+
#define CLAMP_RGB(r, g, b) do \
{ \
if ((r) < 0) \
@@ -2845,11 +2846,11 @@ static void dest_pixel_lit_texture_reflection(s3d_state_t *state)
static void dest_pixel_lit_texture_modulate(s3d_state_t *state)
{
int r = state->r >> 7, g = state->g >> 7, b = state->b >> 7, a = state->a >> 7;
-
+
tex_sample(state);
-
+
CLAMP_RGBA(r, g, b, a);
-
+
state->dest_rgba.r = ((state->dest_rgba.r) * r) >> 8;
state->dest_rgba.g = ((state->dest_rgba.g) * g) >> 8;
state->dest_rgba.b = ((state->dest_rgba.b) * b) >> 8;
@@ -2864,13 +2865,13 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3
uint8_t *vram = (uint8_t *)svga->vram;
int x_dir = s3d_tri->tlr ? 1 : -1;
-
+
int use_z = !(s3d_tri->cmd_set & CMD_SET_ZB_MODE);
int y_count = yc;
-
+
int bpp = (s3d_tri->cmd_set >> 2) & 7;
-
+
uint32_t dest_offset = 0, z_offset = 0;
uint32_t src_col;
@@ -2888,7 +2889,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3
int update;
uint16_t src_z = 0;
-
+
if (s3d_tri->cmd_set & CMD_SET_HC)
{
if (state->y < s3d_tri->clip_t)
@@ -2896,10 +2897,10 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3
if (state->y > s3d_tri->clip_b)
{
int diff_y = state->y - s3d_tri->clip_b;
-
+
if (diff_y > y_count)
diff_y = y_count;
-
+
state->base_u += (s3d_tri->TdUdY * diff_y);
state->base_v += (s3d_tri->TdVdY * diff_y);
state->base_z += (s3d_tri->TdZdY * diff_y);
@@ -2922,7 +2923,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3
dest_offset = s3d_tri->dest_base + (state->y * s3d_tri->dest_str);
z_offset = s3d_tri->z_base + (state->y * s3d_tri->z_str);
-
+
while (y_count > 0)
{
x = (state->x1 + ((1 << 20) - 1)) >> 20;
@@ -2964,7 +2965,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3
if (x < s3d_tri->clip_l)
{
int diff_x = s3d_tri->clip_l - x;
-
+
z += (s3d_tri->TdZdX * diff_x);
state->u += (s3d_tri->TdUdX * diff_x);
state->v += (s3d_tri->TdVdX * diff_x);
@@ -2974,7 +2975,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3
state->a += (s3d_tri->TdAdX * diff_x);
state->d += (s3d_tri->TdDdX * diff_x);
state->w += (s3d_tri->TdWdX * diff_x);
-
+
x = s3d_tri->clip_l;
}
}
@@ -2989,7 +2990,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3
if (x > s3d_tri->clip_r)
{
int diff_x = x - s3d_tri->clip_r;
-
+
z += (s3d_tri->TdZdX * diff_x);
state->u += (s3d_tri->TdUdX * diff_x);
state->v += (s3d_tri->TdVdX * diff_x);
@@ -2999,7 +3000,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3
state->a += (s3d_tri->TdAdX * diff_x);
state->d += (s3d_tri->TdDdX * diff_x);
state->w += (s3d_tri->TdWdX * diff_x);
-
+
x = s3d_tri->clip_r;
}
}
@@ -3012,7 +3013,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3
x &= 0xfff;
xe &= 0xfff;
-
+
while (x != xe) {
update = 1;
_x = x; _y = state->y;
@@ -3104,7 +3105,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3
switch (bpp)
{
- case 0: /*8 bpp*/
+ case 0: /*8 bpp*/
/*Not implemented yet*/
break;
case 1: /*16 bpp*/
@@ -3138,13 +3139,13 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3
state->w += s3d_tri->TdWdX;
dest_addr += x_offset;
z_addr += xz_offset;
-
+
x = (x + x_dir) & 0xfff;
}
}
y_count--;
-
+
tri_skip_line:
state->x1 += dx1;
state->x2 += dx2;
@@ -3187,11 +3188,11 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri)
state.tbu = s3d_tri->tbu << 11;
state.tbv = s3d_tri->tbv << 11;
-
+
state.max_d = (s3d_tri->cmd_set >> 8) & 15;
-
+
state.tex_bdr_clr = s3d_tri->tex_bdr_clr;
-
+
state.cmd_set = s3d_tri->cmd_set;
state.base_u = s3d_tri->tus;
@@ -3203,7 +3204,7 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri)
state.base_a = (int32_t)s3d_tri->tas;
state.base_d = s3d_tri->tds;
state.base_w = s3d_tri->tws;
-
+
tex_base = s3d_tri->tex_base;
for (c = 9; c >= 0; c--)
{
@@ -3242,8 +3243,8 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri)
default:
s3_virge_log("bad triangle type %x\n", (s3d_tri->cmd_set >> 27) & 0xf);
return;
- }
-
+ }
+
switch (((s3d_tri->cmd_set >> 12) & 7) | ((s3d_tri->cmd_set & (1 << 29)) ? 8 : 0))
{
case 0: case 1:
@@ -3283,7 +3284,7 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri)
tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter : tex_sample_persp_normal;
break;
}
-
+
switch ((s3d_tri->cmd_set >> 5) & 7)
{
case 0:
@@ -3307,9 +3308,9 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri)
tri(virge, s3d_tri, &state, s3d_tri->ty01, s3d_tri->TdXdY02, s3d_tri->TdXdY01);
state.x2 = s3d_tri->txend12;
tri(virge, s3d_tri, &state, s3d_tri->ty12, s3d_tri->TdXdY02, s3d_tri->TdXdY12);
-
+
end_time = plat_timer_read();
-
+
virge->blitter_time += end_time - start_time;
}
@@ -3327,17 +3328,17 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine)
svga->hwcursor_latch.addr += 16;
switch (svga->bpp)
- {
+ {
case 15:
fg = video_15to32[virge->hwc_fg_col & 0xffff];
bg = video_15to32[virge->hwc_bg_col & 0xffff];
break;
-
+
case 16:
fg = video_16to32[virge->hwc_fg_col & 0xffff];
bg = video_16to32[virge->hwc_bg_col & 0xffff];
break;
-
+
case 24: case 32:
fg = virge->hwc_fg_col;
bg = virge->hwc_bg_col;
@@ -3363,7 +3364,7 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine)
if (dat[0] & 0x8000)
buffer32->line[displine][offset + svga->x_add] = (dat[1] & 0x8000) ? fg : bg;
}
-
+
offset++;
dat[0] <<= 1;
dat[1] <<= 1;
@@ -3381,7 +3382,7 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine)
else if (dat[1] & 0x8000)
buffer32->line[displine][offset + svga->x_add] ^= 0xffffff;
}
-
+
offset++;
dat[0] <<= 1;
dat[1] <<= 1;
@@ -3630,7 +3631,7 @@ static void s3_virge_overlay_draw(svga_t *svga, int displine)
int x;
uint32_t *p;
uint8_t *src = &svga->vram[svga->overlay_latch.addr];
-
+
p = &(buffer32->line[displine][offset + svga->x_add]);
if ((offset + virge->streams.sec_w) > virge->streams.pri_w)
@@ -3639,7 +3640,7 @@ static void s3_virge_overlay_draw(svga_t *svga, int displine)
x_size = virge->streams.sec_w + 1;
OVERLAY_SAMPLE();
-
+
for (x = 0; x < x_size; x++)
{
*p++ = r[x_read] | (g[x_read] << 8) | (b[x_read] << 16);
@@ -3672,22 +3673,22 @@ static uint8_t s3_virge_pci_read(int func, int addr, void *p)
switch (addr) {
case 0x00: ret = 0x33; break; /*'S3'*/
case 0x01: ret = 0x53; break;
-
+
case 0x02: ret = virge->virge_id_low; break;
case 0x03: ret = virge->virge_id_high; break;
case PCI_REG_COMMAND: ret = virge->pci_regs[PCI_REG_COMMAND] & 0x27; break;
-
+
case 0x07: ret = virge->pci_regs[0x07] & 0x36; break;
-
+
case 0x08: ret = virge->virge_rev; break; /*Revision ID*/
case 0x09: ret = 0; break; /*Programming interface*/
-
+
case 0x0a: ret = 0x00; break; /*Supports VGA interface*/
case 0x0b: ret = 0x03; break;
case 0x0d: ret = virge->pci_regs[0x0d] & 0xf8; break;
-
+
case 0x10: ret = 0x00; break;/*Linear frame buffer address*/
case 0x11: ret = 0x00; break;
case 0x12: ret = 0x00; break;
@@ -3706,12 +3707,12 @@ static uint8_t s3_virge_pci_read(int func, int addr, void *p)
case 0x34: ret = (virge->chip >= S3_VIRGEGX2) ? 0xdc : 0x00; break;
case 0x3c: ret = virge->pci_regs[0x3c]; break;
-
+
case 0x3d: ret = PCI_INTA; break; /*INTA*/
-
+
case 0x3e: ret = 0x04; break;
case 0x3f: ret = 0xff; break;
-
+
case 0x80: ret = 0x02; break; /* AGP capability */
case 0x81: ret = 0x00; break;
case 0x82: ret = 0x10; break; /* assumed AGP 1.0 */
@@ -3745,8 +3746,8 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p)
case 0x00: case 0x01: case 0x02: case 0x03:
case 0x08: case 0x09: case 0x0a: case 0x0b:
case 0x3d: case 0x3e: case 0x3f:
- return;
-
+ return;
+
case PCI_REG_COMMAND:
if (val & PCI_COMMAND_IO)
{
@@ -3756,12 +3757,12 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p)
else
io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge);
virge->pci_regs[PCI_REG_COMMAND] = val & 0x27;
- s3_virge_updatemapping(virge);
+ s3_virge_updatemapping(virge);
return;
case 0x07:
virge->pci_regs[0x07] = val & 0x3e;
return;
- case 0x0d:
+ case 0x0d:
virge->pci_regs[0x0d] = val & 0xf8;
return;
@@ -3785,7 +3786,7 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p)
mem_mapping_disable(&virge->bios_rom.mapping);
}
return;
- case 0x3c:
+ case 0x3c:
virge->pci_regs[0x3c] = val;
return;
@@ -3833,7 +3834,7 @@ static void s3_virge_reset(void *priv)
virge->pci_regs[0x06] = 0;
virge->pci_regs[0x07] = 2;
virge->pci_regs[0x32] = 0x0c;
- virge->pci_regs[0x3d] = 1;
+ virge->pci_regs[0x3d] = 1;
virge->pci_regs[0x3e] = 4;
virge->pci_regs[0x3f] = 0xff;
@@ -3887,7 +3888,7 @@ static void s3_virge_reset(void *priv)
else
virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5);
break;
- }
+ }
if (virge->local == S3_VIRGE_GX)
virge->svga.crtc[0x36] |= (1 << 2);
}
@@ -3916,8 +3917,8 @@ static void *s3_virge_init(const device_t *info)
virge->memory_size = 4;
else
virge->memory_size = device_get_config_int("memory");
-
-
+
+
switch(info->local) {
case S3_VIRGE_325:
bios_fn = ROM_VIRGE_325;
@@ -3965,7 +3966,7 @@ static void *s3_virge_init(const device_t *info)
rom_init(&virge->bios_rom, (char *) bios_fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL);
else
rom_init(&virge->bios_rom, (char *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
-
+
mem_mapping_disable(&virge->bios_rom.mapping);
mem_mapping_add(&virge->linear_mapping, 0, 0, svga_read_linear,
@@ -4003,10 +4004,10 @@ static void *s3_virge_init(const device_t *info)
virge->pci_regs[0x06] = 0;
virge->pci_regs[0x07] = 2;
virge->pci_regs[0x32] = 0x0c;
- virge->pci_regs[0x3d] = 1;
+ virge->pci_regs[0x3d] = 1;
virge->pci_regs[0x3e] = 4;
virge->pci_regs[0x3f] = 0xff;
-
+
virge->virge_rev = 0;
virge->virge_id = 0xe1;
virge->is_agp = !!(info->flags & DEVICE_AGP);
@@ -4105,11 +4106,11 @@ static void *s3_virge_init(const device_t *info)
else
virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5);
break;
- }
+ }
if (info->local == S3_VIRGE_GX)
virge->svga.crtc[0x36] |= (1 << 2);
}
-
+
virge->svga.crtc[0x37] = 1 | (7 << 5);
virge->svga.crtc[0x53] = 8;
@@ -4117,8 +4118,8 @@ static void *s3_virge_init(const device_t *info)
virge->i2c = i2c_gpio_init("ddc_s3_virge");
virge->ddc = ddc_init(i2c_gpio_get_bus(virge->i2c));
-
- virge->svga.packed_chain4 = 1;
+
+ virge->svga.force_old_addr = 1;
virge->wake_render_thread = thread_create_event();
virge->wake_main_thread = thread_create_event();
@@ -4127,9 +4128,9 @@ static void *s3_virge_init(const device_t *info)
virge->render_thread = thread_create(render_thread, virge);
timer_add(&virge->tri_timer, s3_virge_tri_timer, virge, 0);
-
+
virge->local = info->local;
-
+
return virge;
}
@@ -4148,7 +4149,7 @@ static void s3_virge_close(void *p)
ddc_close(virge->ddc);
i2c_gpio_close(virge->i2c);
-
+
free(virge);
}
@@ -4205,7 +4206,7 @@ static int s3_trio3d2x_available(void)
static void s3_virge_speed_changed(void *p)
{
virge_t *virge = (virge_t *)p;
-
+
svga_recalctimings(&virge->svga);
}
@@ -4216,60 +4217,102 @@ static void s3_virge_force_redraw(void *p)
virge->svga.fullchange = changeframecount;
}
-// clang-format off
static const device_config_t s3_virge_config[] =
{
- {
- "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 },
{
- { "2 MB", 2 },
- { "4 MB", 4 },
- { "" }
+ "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 },
+ {
+ {
+ "2 MB", 2
+ },
+ {
+ "4 MB", 4
+ },
+ {
+ ""
+ }
+ }
+ },
+ {
+ "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1
+ },
+ {
+ "dithering", "Dithering", CONFIG_BINARY, "", 1
+ },
+ {
+ "", "", -1
}
- },
- { "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 },
- { "dithering", "Dithering", CONFIG_BINARY, "", 1 },
- { "", "", -1 }
};
static const device_config_t s3_virge_stb_config[] =
{
- {
- "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 },
{
- { "2 MB", 2 },
- { "4 MB", 4 },
- { "8 MB", 8 },
- { "" }
+ "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 },
+ {
+ {
+ "2 MB", 2
+ },
+ {
+ "4 MB", 4
+ },
+ {
+ "8 MB", 8
+ },
+ {
+ ""
+ }
+ }
+ },
+ {
+ "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1
+ },
+ {
+ "dithering", "Dithering", CONFIG_BINARY, "", 1
+ },
+ {
+ "", "", -1
}
- },
- { "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 },
- { "dithering", "Dithering", CONFIG_BINARY, "", 1 },
- { "", "", -1 }
};
static const device_config_t s3_virge_357_config[] =
{
- { "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 },
- { "dithering", "Dithering", CONFIG_BINARY, "", 1 },
- { "", "", -1 }
+ {
+ "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1
+ },
+ {
+ "dithering", "Dithering", CONFIG_BINARY, "", 1
+ },
+ {
+ "", "", -1
+ }
};
static const device_config_t s3_trio3d2x_config[] =
{
- {
- "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 },
{
- { "4 MB", 4 },
- { "8 MB", 8 },
- { "" }
+ "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 },
+ {
+ {
+ "4 MB", 4
+ },
+ {
+ "8 MB", 8
+ },
+ {
+ ""
+ }
+ }
+ },
+ {
+ "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1
+ },
+ {
+ "dithering", "Dithering", CONFIG_BINARY, "", 1
+ },
+ {
+ "", "", -1
}
- },
- { "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 },
- { "dithering", "Dithering", CONFIG_BINARY, "", 1 },
- { "", "", -1 }
};
-// clang-format on
const device_t s3_virge_325_pci_device =
{
@@ -4279,7 +4322,7 @@ const device_t s3_virge_325_pci_device =
S3_VIRGE_325,
s3_virge_init,
s3_virge_close,
- s3_virge_reset,
+ s3_virge_reset,
{ s3_virge_325_available },
s3_virge_speed_changed,
s3_virge_force_redraw,
@@ -4294,7 +4337,7 @@ const device_t s3_diamond_stealth_2000_pci_device =
S3_DIAMOND_STEALTH3D_2000,
s3_virge_init,
s3_virge_close,
- s3_virge_reset,
+ s3_virge_reset,
{ s3_virge_325_diamond_available },
s3_virge_speed_changed,
s3_virge_force_redraw,
@@ -4309,7 +4352,7 @@ const device_t s3_diamond_stealth_3000_pci_device =
S3_DIAMOND_STEALTH3D_3000,
s3_virge_init,
s3_virge_close,
- s3_virge_reset,
+ s3_virge_reset,
{ s3_virge_988_diamond_available },
s3_virge_speed_changed,
s3_virge_force_redraw,
@@ -4324,7 +4367,7 @@ const device_t s3_stb_velocity_3d_pci_device =
S3_STB_VELOCITY_3D,
s3_virge_init,
s3_virge_close,
- s3_virge_reset,
+ s3_virge_reset,
{ s3_virge_988_stb_available },
s3_virge_speed_changed,
s3_virge_force_redraw,
@@ -4339,7 +4382,7 @@ const device_t s3_virge_375_pci_device =
S3_VIRGE_DX,
s3_virge_init,
s3_virge_close,
- s3_virge_reset,
+ s3_virge_reset,
{ s3_virge_375_available },
s3_virge_speed_changed,
s3_virge_force_redraw,
@@ -4354,7 +4397,7 @@ const device_t s3_diamond_stealth_2000pro_pci_device =
S3_DIAMOND_STEALTH3D_2000PRO,
s3_virge_init,
s3_virge_close,
- s3_virge_reset,
+ s3_virge_reset,
{ s3_virge_375_diamond_available },
s3_virge_speed_changed,
s3_virge_force_redraw,
@@ -4369,7 +4412,7 @@ const device_t s3_virge_385_pci_device =
S3_VIRGE_GX,
s3_virge_init,
s3_virge_close,
- s3_virge_reset,
+ s3_virge_reset,
{ s3_virge_385_available },
s3_virge_speed_changed,
s3_virge_force_redraw,
@@ -4384,7 +4427,7 @@ const device_t s3_virge_357_pci_device =
S3_VIRGE_GX2,
s3_virge_init,
s3_virge_close,
- s3_virge_reset,
+ s3_virge_reset,
{ s3_virge_357_available },
s3_virge_speed_changed,
s3_virge_force_redraw,
@@ -4399,7 +4442,7 @@ const device_t s3_virge_357_agp_device =
S3_VIRGE_GX2,
s3_virge_init,
s3_virge_close,
- s3_virge_reset,
+ s3_virge_reset,
{ s3_virge_357_available },
s3_virge_speed_changed,
s3_virge_force_redraw,
@@ -4414,7 +4457,7 @@ const device_t s3_diamond_stealth_4000_pci_device =
S3_DIAMOND_STEALTH3D_4000,
s3_virge_init,
s3_virge_close,
- s3_virge_reset,
+ s3_virge_reset,
{ s3_virge_357_diamond_available },
s3_virge_speed_changed,
s3_virge_force_redraw,
@@ -4429,7 +4472,7 @@ const device_t s3_diamond_stealth_4000_agp_device =
S3_DIAMOND_STEALTH3D_4000,
s3_virge_init,
s3_virge_close,
- s3_virge_reset,
+ s3_virge_reset,
{ s3_virge_357_diamond_available },
s3_virge_speed_changed,
s3_virge_force_redraw,
@@ -4444,7 +4487,7 @@ const device_t s3_trio3d2x_pci_device =
S3_TRIO_3D2X,
s3_virge_init,
s3_virge_close,
- s3_virge_reset,
+ s3_virge_reset,
{ s3_trio3d2x_available },
s3_virge_speed_changed,
s3_virge_force_redraw,
@@ -4459,7 +4502,7 @@ const device_t s3_trio3d2x_agp_device =
S3_TRIO_3D2X,
s3_virge_init,
s3_virge_close,
- s3_virge_reset,
+ s3_virge_reset,
{ s3_trio3d2x_available },
s3_virge_speed_changed,
s3_virge_force_redraw,
diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c
index 9640b5540..20c4d6dd6 100644
--- a/src/video/vid_svga.c
+++ b/src/video/vid_svga.c
@@ -179,7 +179,7 @@ svga_out(uint16_t addr, uint8_t val, void *p)
svga->chain2_write = !(val & 4);
svga->chain4 = val & 8;
svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) &&
- !svga->gdcreg[1]) && ((svga->chain4 && svga->packed_chain4) || svga->fb_only) && !(svga->adv_flags & FLAG_ADDR_BY8);
+ !svga->gdcreg[1]) && ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && !(svga->adv_flags & FLAG_ADDR_BY8);
break;
}
break;
@@ -264,7 +264,7 @@ svga_out(uint16_t addr, uint8_t val, void *p)
}
svga->gdcreg[svga->gdcaddr & 15] = val;
svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) &&
- !svga->gdcreg[1]) && ((svga->chain4 && svga->packed_chain4) || svga->fb_only);
+ !svga->gdcreg[1]) && ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only);
if (((svga->gdcaddr & 15) == 5 && (val ^ o) & 0x70) ||
((svga->gdcaddr & 15) == 6 && (val ^ o) & 1))
svga_recalctimings(svga);
@@ -582,7 +582,8 @@ svga_recalctimings(svga_t *svga)
if (svga->dispofftime < TIMER_USEC)
svga->dispofftime = TIMER_USEC;
- svga_recalc_remap_func(svga);
+ if (!svga->force_old_addr)
+ svga_recalc_remap_func(svga);
/* Inform the user interface of any DPMS mode changes. */
if (svga->dpms) {
@@ -1068,7 +1069,7 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
addr <<= 4;
else if ((svga->adv_flags & FLAG_ADDR_BY8) && (svga->writemode < 4))
addr <<= 3;
- else if (((svga->chain4 && svga->packed_chain4) || svga->fb_only) && (svga->writemode < 4)) {
+ else if (((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && (svga->writemode < 4)) {
writemask2 = 1 << (addr & 3);
addr &= ~3;
} else if (svga->chain4 && (svga->writemode < 4)) {
@@ -1256,7 +1257,7 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
addr <<= 4;
else if (svga->adv_flags & FLAG_ADDR_BY8)
addr <<= 3;
- else if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) {
+ else if ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) {
addr &= svga->decode_mask;
if (svga->translate_address)
addr = svga->translate_address(addr, p);
@@ -1266,7 +1267,7 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
for (i = 0; i < count; i++)
svga->latch.b[i] = svga->vram[latch_addr | i];
return svga->vram[addr & svga->vram_mask];
- } else if (svga->chain4) {
+ } else if (svga->chain4 && !svga->force_old_addr) {
readplane = addr & 3;
addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
} else if (svga->chain2_read) {
diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c
index ddd3ad0eb..2d23231be 100644
--- a/src/video/vid_svga_render.c
+++ b/src/video/vid_svga_render.c
@@ -117,6 +117,7 @@ svga_render_text_40(svga_t *svga)
uint8_t chr, attr, dat;
uint32_t charaddr;
int fg, bg;
+ uint32_t addr = 0;
if ((svga->displine + svga->y_add) < 0)
return;
@@ -130,13 +131,19 @@ svga_render_text_40(svga_t *svga)
xinc = (svga->seqregs[1] & 1) ? 16 : 18;
for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) {
- uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask;
+ if (!svga->force_old_addr)
+ addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask;
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
if (svga->crtc[0x17] & 0x80) {
- chr = svga->vram[addr];
- attr = svga->vram[addr+1];
+ if (svga->force_old_addr) {
+ chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask];
+ attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask];
+ } else {
+ chr = svga->vram[addr];
+ attr = svga->vram[addr+1];
+ }
} else
chr = attr = 0;
@@ -186,6 +193,7 @@ svga_render_text_80(svga_t *svga)
uint8_t chr, attr, dat;
uint32_t charaddr;
int fg, bg;
+ uint32_t addr = 0;
if ((svga->displine + svga->y_add) < 0)
return;
@@ -199,13 +207,19 @@ svga_render_text_80(svga_t *svga)
xinc = (svga->seqregs[1] & 1) ? 8 : 9;
for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) {
- uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask;
+ if (!svga->force_old_addr)
+ addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask;
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
if (svga->crtc[0x17] & 0x80) {
- chr = svga->vram[addr];
- attr = svga->vram[addr+1];
+ if (svga->force_old_addr) {
+ chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask];
+ attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask];
+ } else {
+ chr = svga->vram[addr];
+ attr = svga->vram[addr+1];
+ }
} else
chr = attr = 0;
@@ -244,7 +258,7 @@ svga_render_text_80(svga_t *svga)
}
}
-
+/*Not available on most generic cards.*/
void
svga_render_text_80_ksc5601(svga_t *svga)
{
@@ -373,6 +387,7 @@ svga_render_text_80_ksc5601(svga_t *svga)
void
svga_render_2bpp_lowres(svga_t *svga)
{
+ int changed_offset;
int x;
uint8_t dat[2];
uint32_t addr, *p;
@@ -381,41 +396,94 @@ svga_render_2bpp_lowres(svga_t *svga)
if ((svga->displine + svga->y_add) < 0)
return;
- changed_addr = svga->remap_func(svga, svga->ma);
+ if (svga->force_old_addr) {
+ changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12;
+
+ if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
- if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
- p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
- if (svga->firstline_draw == 2000)
- svga->firstline_draw = svga->displine;
- svga->lastline_draw = svga->displine;
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) {
+ addr = svga->ma;
- for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) {
- addr = svga->remap_func(svga, svga->ma);
+ if (!(svga->crtc[0x17] & 0x40)) {
+ addr = (addr << 1) & svga->vram_mask;
+ addr &= ~7;
- dat[0] = svga->vram[addr];
- dat[1] = svga->vram[addr | 0x1];
- if (svga->seqregs[1] & 4)
- svga->ma += 2;
- else
- svga->ma += 4;
+ if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000))
+ addr |= 4;
- svga->ma &= svga->vram_mask;
+ if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000))
+ addr |= 4;
+ }
- if (svga->crtc[0x17] & 0x80) {
- p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]];
- p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]];
- p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]];
- p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]];
- p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]];
- p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]];
- p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]];
- p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]];
- } else
- memset(p, 0x00, 16 * sizeof(uint32_t));
+ if (!(svga->crtc[0x17] & 0x01))
+ addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0);
- p += 16;
- }
+ if (!(svga->crtc[0x17] & 0x02))
+ addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0);
+
+ dat[0] = svga->vram[addr];
+ dat[1] = svga->vram[addr | 0x1];
+ if (svga->seqregs[1] & 4)
+ svga->ma += 2;
+ else
+ svga->ma += 4;
+ svga->ma &= svga->vram_mask;
+ if (svga->crtc[0x17] & 0x80) {
+ p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]];
+ p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]];
+ p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]];
+ p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]];
+ p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]];
+ p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]];
+ p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]];
+ p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]];
+ } else
+ memset(p, 0x00, 16 * sizeof(uint32_t));
+ p += 16;
+ }
+ }
+ } else {
+ changed_addr = svga->remap_func(svga, svga->ma);
+
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
+
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
+
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) {
+ addr = svga->remap_func(svga, svga->ma);
+
+ dat[0] = svga->vram[addr];
+ dat[1] = svga->vram[addr | 0x1];
+ if (svga->seqregs[1] & 4)
+ svga->ma += 2;
+ else
+ svga->ma += 4;
+
+ svga->ma &= svga->vram_mask;
+
+ if (svga->crtc[0x17] & 0x80) {
+ p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]];
+ p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]];
+ p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]];
+ p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]];
+ p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]];
+ p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]];
+ p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]];
+ p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]];
+ } else
+ memset(p, 0x00, 16 * sizeof(uint32_t));
+
+ p += 16;
+ }
+ }
}
}
@@ -423,6 +491,7 @@ svga_render_2bpp_lowres(svga_t *svga)
void
svga_render_2bpp_highres(svga_t *svga)
{
+ int changed_offset;
int x;
uint8_t dat[2];
uint32_t addr, *p;
@@ -431,42 +500,95 @@ svga_render_2bpp_highres(svga_t *svga)
if ((svga->displine + svga->y_add) < 0)
return;
- changed_addr = svga->remap_func(svga, svga->ma);
+ if (svga->force_old_addr) {
+ changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12;
- if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
- p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
+ if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
- if (svga->firstline_draw == 2000)
- svga->firstline_draw = svga->displine;
- svga->lastline_draw = svga->displine;
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
- for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
- addr = svga->remap_func(svga, svga->ma);
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
+ addr = svga->ma;
- dat[0] = svga->vram[addr];
- dat[1] = svga->vram[addr | 0x1];
- if (svga->seqregs[1] & 4)
- svga->ma += 2;
- else
- svga->ma += 4;
+ if (!(svga->crtc[0x17] & 0x40)) {
+ addr = (addr << 1) & svga->vram_mask;
+ addr &= ~7;
- svga->ma &= svga->vram_mask;
+ if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000))
+ addr |= 4;
- if (svga->crtc[0x17] & 0x80) {
- p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]];
- p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]];
- p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]];
- p[3] = svga->pallook[svga->egapal[dat[0] & 3]];
- p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]];
- p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]];
- p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]];
- p[7] = svga->pallook[svga->egapal[dat[1] & 3]];
- } else
- memset(p, 0x00, 8 * sizeof(uint32_t));
+ if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000))
+ addr |= 4;
+ }
- p += 8;
+ if (!(svga->crtc[0x17] & 0x01))
+ addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0);
+
+ if (!(svga->crtc[0x17] & 0x02))
+ addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0);
+
+ dat[0] = svga->vram[addr];
+ dat[1] = svga->vram[addr | 0x1];
+ if (svga->seqregs[1] & 4)
+ svga->ma += 2;
+ else
+ svga->ma += 4;
+ svga->ma &= svga->vram_mask;
+ if (svga->crtc[0x17] & 0x80) {
+ p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]];
+ p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]];
+ p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]];
+ p[3] = svga->pallook[svga->egapal[dat[0] & 3]];
+ p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]];
+ p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]];
+ p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]];
+ p[7] = svga->pallook[svga->egapal[dat[1] & 3]];
+ } else
+ memset(p, 0x00, 8 * sizeof(uint32_t));
+ p += 8;
+ }
+ }
+ } else {
+ changed_addr = svga->remap_func(svga, svga->ma);
+
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
+
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
+
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
+ addr = svga->remap_func(svga, svga->ma);
+
+ dat[0] = svga->vram[addr];
+ dat[1] = svga->vram[addr | 0x1];
+ if (svga->seqregs[1] & 4)
+ svga->ma += 2;
+ else
+ svga->ma += 4;
+
+ svga->ma &= svga->vram_mask;
+
+ if (svga->crtc[0x17] & 0x80) {
+ p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]];
+ p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]];
+ p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]];
+ p[3] = svga->pallook[svga->egapal[dat[0] & 3]];
+ p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]];
+ p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]];
+ p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]];
+ p[7] = svga->pallook[svga->egapal[dat[1] & 3]];
+ } else
+ memset(p, 0x00, 8 * sizeof(uint32_t));
+
+ p += 8;
+ }
+ }
}
- }
}
@@ -540,56 +662,120 @@ svga_render_4bpp_lowres(svga_t *svga)
if ((svga->displine + svga->y_add) < 0)
return;
- changed_addr = svga->remap_func(svga, svga->ma);
+ if (svga->force_old_addr) {
+ if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
- if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
- p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
- if (svga->firstline_draw == 2000)
- svga->firstline_draw = svga->displine;
- svga->lastline_draw = svga->displine;
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) {
+ addr = svga->ma;
+ oddeven = 0;
- for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) {
- addr = svga->remap_func(svga, svga->ma);
- oddeven = 0;
+ if (!(svga->crtc[0x17] & 0x40)) {
+ addr = (addr << 1) & svga->vram_mask;
- if (svga->seqregs[1] & 4) {
- oddeven = (addr & 4) ? 1 : 0;
- edat[0] = svga->vram[addr | oddeven];
- edat[2] = svga->vram[addr | oddeven | 0x2];
- edat[1] = edat[3] = 0;
- svga->ma += 2;
- } else {
- *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]);
- svga->ma += 4;
+ if (svga->seqregs[1] & 4)
+ oddeven = (addr & 4) ? 1 : 0;
+
+ addr &= ~7;
+
+ if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000))
+ addr |= 4;
+ if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000))
+ addr |= 4;
+ }
+
+ if (!(svga->crtc[0x17] & 0x01))
+ addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0);
+ if (!(svga->crtc[0x17] & 0x02))
+ addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0);
+
+ if (svga->seqregs[1] & 4) {
+ edat[0] = svga->vram[addr | oddeven];
+ edat[2] = svga->vram[addr | oddeven | 0x2];
+ edat[1] = edat[3] = 0;
+ svga->ma += 2;
+ } else {
+ *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]);
+ svga->ma += 4;
+ }
+ svga->ma &= svga->vram_mask;
+
+ if (svga->crtc[0x17] & 0x80) {
+ dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
+ p[0] = p[1] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
+ p[2] = p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
+ dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
+ p[4] = p[5] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
+ p[6] = p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
+ dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
+ p[8] = p[9] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
+ p[10] = p[11] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
+ dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
+ p[12] = p[13] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
+ p[14] = p[15] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
+ } else
+ memset(p, 0x00, 16 * sizeof(uint32_t));
+
+ p += 16;
}
- svga->ma &= svga->vram_mask;
+ }
+ } else {
+ changed_addr = svga->remap_func(svga, svga->ma);
- if (svga->crtc[0x17] & 0x80) {
- dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
- p[0] = p[1] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
- p[2] = p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
- dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
- p[4] = p[5] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
- p[6] = p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
- dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
- p[8] = p[9] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
- p[10] = p[11] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
- dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
- p[12] = p[13] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
- p[14] = p[15] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
- } else
- memset(p, 0x00, 16 * sizeof(uint32_t));
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
- p += 16;
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
+
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) {
+ addr = svga->remap_func(svga, svga->ma);
+ oddeven = 0;
+
+ if (svga->seqregs[1] & 4) {
+ oddeven = (addr & 4) ? 1 : 0;
+ edat[0] = svga->vram[addr | oddeven];
+ edat[2] = svga->vram[addr | oddeven | 0x2];
+ edat[1] = edat[3] = 0;
+ svga->ma += 2;
+ } else {
+ *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]);
+ svga->ma += 4;
+ }
+ svga->ma &= svga->vram_mask;
+
+ if (svga->crtc[0x17] & 0x80) {
+ dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
+ p[0] = p[1] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
+ p[2] = p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
+ dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
+ p[4] = p[5] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
+ p[6] = p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
+ dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
+ p[8] = p[9] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
+ p[10] = p[11] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
+ dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
+ p[12] = p[13] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
+ p[14] = p[15] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
+ } else
+ memset(p, 0x00, 16 * sizeof(uint32_t));
+
+ p += 16;
+ }
+ }
}
- }
}
void
svga_render_4bpp_highres(svga_t *svga)
{
+ int changed_offset;
int x, oddeven;
uint32_t addr, *p;
uint8_t edat[4];
@@ -598,51 +784,116 @@ svga_render_4bpp_highres(svga_t *svga)
if ((svga->displine + svga->y_add) < 0)
return;
+
+ if (svga->force_old_addr) {
+ changed_offset = (svga->ma + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12;
- changed_addr = svga->remap_func(svga, svga->ma);
+ if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
- if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
- p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
- if (svga->firstline_draw == 2000)
- svga->firstline_draw = svga->displine;
- svga->lastline_draw = svga->displine;
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
+ addr = svga->ma;
+ oddeven = 0;
- for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
- addr = svga->remap_func(svga, svga->ma);
- oddeven = 0;
+ if (!(svga->crtc[0x17] & 0x40)) {
+ addr = (addr << 1) & svga->vram_mask;
- if (svga->seqregs[1] & 4) {
- oddeven = (addr & 4) ? 1 : 0;
- edat[0] = svga->vram[addr | oddeven];
- edat[2] = svga->vram[addr | oddeven | 0x2];
- edat[1] = edat[3] = 0;
- svga->ma += 2;
- } else {
- *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]);
- svga->ma += 4;
+ if (svga->seqregs[1] & 4)
+ oddeven = (addr & 4) ? 1 : 0;
+
+ addr &= ~7;
+
+ if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000))
+ addr |= 4;
+ if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000))
+ addr |= 4;
+ }
+
+ if (!(svga->crtc[0x17] & 0x01))
+ addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0);
+ if (!(svga->crtc[0x17] & 0x02))
+ addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0);
+
+ if (svga->seqregs[1] & 4) {
+ edat[0] = svga->vram[addr | oddeven];
+ edat[2] = svga->vram[addr | oddeven | 0x2];
+ edat[1] = edat[3] = 0;
+ svga->ma += 2;
+ } else {
+ *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]);
+ svga->ma += 4;
+ }
+ svga->ma &= svga->vram_mask;
+
+ if (svga->crtc[0x17] & 0x80) {
+ dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
+ p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
+ p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
+ dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
+ p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
+ p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
+ dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
+ p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
+ p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
+ dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
+ p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
+ p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
+ } else
+ memset(p, 0x00, 8 * sizeof(uint32_t));
+
+ p += 8;
}
- svga->ma &= svga->vram_mask;
+ }
+ } else {
+ changed_addr = svga->remap_func(svga, svga->ma);
- if (svga->crtc[0x17] & 0x80) {
- dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
- p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
- p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
- dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
- p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
- p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
- dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
- p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
- p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
- dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
- p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
- p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
- } else
- memset(p, 0x00, 8 * sizeof(uint32_t));
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
- p += 8;
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
+
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
+ addr = svga->remap_func(svga, svga->ma);
+ oddeven = 0;
+
+ if (svga->seqregs[1] & 4) {
+ oddeven = (addr & 4) ? 1 : 0;
+ edat[0] = svga->vram[addr | oddeven];
+ edat[2] = svga->vram[addr | oddeven | 0x2];
+ edat[1] = edat[3] = 0;
+ svga->ma += 2;
+ } else {
+ *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]);
+ svga->ma += 4;
+ }
+ svga->ma &= svga->vram_mask;
+
+ if (svga->crtc[0x17] & 0x80) {
+ dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
+ p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
+ p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
+ dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
+ p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
+ p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
+ dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
+ p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
+ p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
+ dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
+ p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
+ p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
+ } else
+ memset(p, 0x00, 8 * sizeof(uint32_t));
+
+ p += 8;
+ }
+ }
}
- }
}
@@ -657,19 +908,18 @@ svga_render_8bpp_lowres(svga_t *svga)
if ((svga->displine + svga->y_add) < 0)
return;
+
+ if (svga->force_old_addr) {
+ if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
- changed_addr = svga->remap_func(svga, svga->ma);
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
- if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
- p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
-
- if (svga->firstline_draw == 2000)
- svga->firstline_draw = svga->displine;
- svga->lastline_draw = svga->displine;
-
- if (!svga->remap_required) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
+
p[0] = p[1] = svga->map8[dat & 0xff];
p[2] = p[3] = svga->map8[(dat >> 8) & 0xff];
p[4] = p[5] = svga->map8[(dat >> 16) & 0xff];
@@ -678,21 +928,45 @@ svga_render_8bpp_lowres(svga_t *svga)
svga->ma += 4;
p += 8;
}
+ svga->ma &= svga->vram_display_mask;
+ }
} else {
- for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
- addr = svga->remap_func(svga, svga->ma);
- dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
- p[0] = p[1] = svga->map8[dat & 0xff];
- p[2] = p[3] = svga->map8[(dat >> 8) & 0xff];
- p[4] = p[5] = svga->map8[(dat >> 16) & 0xff];
- p[6] = p[7] = svga->map8[(dat >> 24) & 0xff];
+ changed_addr = svga->remap_func(svga, svga->ma);
- svga->ma += 4;
- p += 8;
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
+
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
+
+ if (!svga->remap_required) {
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
+ dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
+ p[0] = p[1] = svga->map8[dat & 0xff];
+ p[2] = p[3] = svga->map8[(dat >> 8) & 0xff];
+ p[4] = p[5] = svga->map8[(dat >> 16) & 0xff];
+ p[6] = p[7] = svga->map8[(dat >> 24) & 0xff];
+
+ svga->ma += 4;
+ p += 8;
+ }
+ } else {
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
+ addr = svga->remap_func(svga, svga->ma);
+ dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+ p[0] = p[1] = svga->map8[dat & 0xff];
+ p[2] = p[3] = svga->map8[(dat >> 8) & 0xff];
+ p[4] = p[5] = svga->map8[(dat >> 16) & 0xff];
+ p[6] = p[7] = svga->map8[(dat >> 24) & 0xff];
+
+ svga->ma += 4;
+ p += 8;
+ }
+ }
+ svga->ma &= svga->vram_display_mask;
}
}
- svga->ma &= svga->vram_display_mask;
- }
}
@@ -707,17 +981,15 @@ svga_render_8bpp_highres(svga_t *svga)
if ((svga->displine + svga->y_add) < 0)
return;
+
+ if (svga->force_old_addr) {
+ if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
- changed_addr = svga->remap_func(svga, svga->ma);
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
- if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
- p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
-
- if (svga->firstline_draw == 2000)
- svga->firstline_draw = svga->displine;
- svga->lastline_draw = svga->displine;
-
- if (!svga->remap_required) {
for (x = 0; x <= (svga->hdisp/* + svga->scrollcache*/); x += 8) {
dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
p[0] = svga->map8[dat & 0xff];
@@ -734,21 +1006,51 @@ svga_render_8bpp_highres(svga_t *svga)
svga->ma += 8;
p += 8;
}
+ svga->ma &= svga->vram_display_mask;
+ }
} else {
- for (x = 0; x <= (svga->hdisp/* + svga->scrollcache*/); x += 4) {
- addr = svga->remap_func(svga, svga->ma);
- dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
- p[0] = svga->map8[dat & 0xff];
- p[1] = svga->map8[(dat >> 8) & 0xff];
- p[2] = svga->map8[(dat >> 16) & 0xff];
- p[3] = svga->map8[(dat >> 24) & 0xff];
+ changed_addr = svga->remap_func(svga, svga->ma);
- svga->ma += 4;
- p += 4;
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
+
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
+
+ if (!svga->remap_required) {
+ for (x = 0; x <= (svga->hdisp/* + svga->scrollcache*/); x += 8) {
+ dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
+ p[0] = svga->map8[dat & 0xff];
+ p[1] = svga->map8[(dat >> 8) & 0xff];
+ p[2] = svga->map8[(dat >> 16) & 0xff];
+ p[3] = svga->map8[(dat >> 24) & 0xff];
+
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]);
+ p[4] = svga->map8[dat & 0xff];
+ p[5] = svga->map8[(dat >> 8) & 0xff];
+ p[6] = svga->map8[(dat >> 16) & 0xff];
+ p[7] = svga->map8[(dat >> 24) & 0xff];
+
+ svga->ma += 8;
+ p += 8;
+ }
+ } else {
+ for (x = 0; x <= (svga->hdisp/* + svga->scrollcache*/); x += 4) {
+ addr = svga->remap_func(svga, svga->ma);
+ dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+ p[0] = svga->map8[dat & 0xff];
+ p[1] = svga->map8[(dat >> 8) & 0xff];
+ p[2] = svga->map8[(dat >> 16) & 0xff];
+ p[3] = svga->map8[(dat >> 24) & 0xff];
+
+ svga->ma += 4;
+ p += 4;
+ }
+ }
+ svga->ma &= svga->vram_display_mask;
}
}
- svga->ma &= svga->vram_display_mask;
- }
}
void
@@ -870,47 +1172,74 @@ svga_render_15bpp_lowres(svga_t *svga)
if ((svga->displine + svga->y_add) < 0)
return;
+
+ if (svga->force_old_addr) {
+ if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
- changed_addr = svga->remap_func(svga, svga->ma);
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
- if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
- p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
-
- if (svga->firstline_draw == 2000)
- svga->firstline_draw = svga->displine;
- svga->lastline_draw = svga->displine;
-
- if (!svga->remap_required) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) {
if (svga->crtc[0x17] & 0x80) {
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
- *p++ = video_15to32[dat & 0xffff];
- *p++ = video_15to32[dat >> 16];
+ p[(x << 1)] = p[(x << 1) + 1] = video_15to32[dat & 0xffff];
+ p[(x << 1) + 2] = p[(x << 1) + 3] = video_15to32[dat >> 16];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
- *p++ = video_15to32[dat & 0xffff];
- *p++ = video_15to32[dat >> 16];
+ p[(x << 1) + 4] = p[(x << 1) + 5] = video_15to32[dat & 0xffff];
+ p[(x << 1) + 6] = p[(x << 1) + 7] = video_15to32[dat >> 16];
} else
memset(&(p[(x << 1)]), 0x00, 8 * sizeof(uint32_t));
}
svga->ma += x << 1;
+ svga->ma &= svga->vram_display_mask;
+ }
} else {
- for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) {
- if (svga->crtc[0x17] & 0x80) {
- addr = svga->remap_func(svga, svga->ma);
- dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+ changed_addr = svga->remap_func(svga, svga->ma);
- *p++ = video_15to32[dat & 0xffff];
- *p++ = video_15to32[dat >> 16];
- } else
- memset(&(p[x]), 0x00, 2 * sizeof(uint32_t));
- svga->ma += 4;
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
+
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
+
+ if (!svga->remap_required) {
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) {
+ if (svga->crtc[0x17] & 0x80) {
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
+
+ *p++ = video_15to32[dat & 0xffff];
+ *p++ = video_15to32[dat >> 16];
+
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
+
+ *p++ = video_15to32[dat & 0xffff];
+ *p++ = video_15to32[dat >> 16];
+ } else
+ memset(&(p[(x << 1)]), 0x00, 8 * sizeof(uint32_t));
+ }
+ svga->ma += x << 1;
+ } else {
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) {
+ if (svga->crtc[0x17] & 0x80) {
+ addr = svga->remap_func(svga, svga->ma);
+ dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+
+ *p++ = video_15to32[dat & 0xffff];
+ *p++ = video_15to32[dat >> 16];
+ } else
+ memset(&(p[x]), 0x00, 2 * sizeof(uint32_t));
+ svga->ma += 4;
+ }
+ }
+ svga->ma &= svga->vram_display_mask;
}
}
- svga->ma &= svga->vram_display_mask;
- }
}
@@ -924,53 +1253,86 @@ svga_render_15bpp_highres(svga_t *svga)
if ((svga->displine + svga->y_add) < 0)
return;
+
+ if (svga->force_old_addr) {
+ if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
- changed_addr = svga->remap_func(svga, svga->ma);
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
- if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
- p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
-
- if (svga->firstline_draw == 2000)
- svga->firstline_draw = svga->displine;
- svga->lastline_draw = svga->displine;
-
- if (!svga->remap_required) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
if (svga->crtc[0x17] & 0x80) {
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
- *p++ = video_15to32[dat & 0xffff];
- *p++ = video_15to32[dat >> 16];
+ p[x] = video_15to32[dat & 0xffff];
+ p[x + 1] = video_15to32[dat >> 16];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
- *p++ = video_15to32[dat & 0xffff];
- *p++ = video_15to32[dat >> 16];
+ p[x + 2] = video_15to32[dat & 0xffff];
+ p[x + 3] = video_15to32[dat >> 16];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]);
- *p++ = video_15to32[dat & 0xffff];
- *p++ = video_15to32[dat >> 16];
+ p[x + 4] = video_15to32[dat & 0xffff];
+ p[x + 5] = video_15to32[dat >> 16];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]);
- *p++ = video_15to32[dat & 0xffff];
- *p++ = video_15to32[dat >> 16];
+ p[x + 6] = video_15to32[dat & 0xffff];
+ p[x + 7] = video_15to32[dat >> 16];
} else
memset(&(p[x]), 0x00, 8 * sizeof(uint32_t));
}
- svga->ma += x << 1;
+ svga->ma += x << 1;
+ svga->ma &= svga->vram_display_mask;
+ }
} else {
- for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) {
- if (svga->crtc[0x17] & 0x80) {
- addr = svga->remap_func(svga, svga->ma);
- dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+ changed_addr = svga->remap_func(svga, svga->ma);
- *p++ = video_15to32[dat & 0xffff];
- *p++ = video_15to32[dat >> 16];
- } else
- memset(&(p[x]), 0x00, 2 * sizeof(uint32_t));
- svga->ma += 4;
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
+
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
+
+ if (!svga->remap_required) {
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
+ if (svga->crtc[0x17] & 0x80) {
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
+ *p++ = video_15to32[dat & 0xffff];
+ *p++ = video_15to32[dat >> 16];
+
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
+ *p++ = video_15to32[dat & 0xffff];
+ *p++ = video_15to32[dat >> 16];
+
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]);
+ *p++ = video_15to32[dat & 0xffff];
+ *p++ = video_15to32[dat >> 16];
+
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]);
+ *p++ = video_15to32[dat & 0xffff];
+ *p++ = video_15to32[dat >> 16];
+ } else
+ memset(&(p[x]), 0x00, 8 * sizeof(uint32_t));
+ }
+ svga->ma += x << 1;
+ } else {
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) {
+ if (svga->crtc[0x17] & 0x80) {
+ addr = svga->remap_func(svga, svga->ma);
+ dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+
+ *p++ = video_15to32[dat & 0xffff];
+ *p++ = video_15to32[dat >> 16];
+ } else
+ memset(&(p[x]), 0x00, 2 * sizeof(uint32_t));
+ svga->ma += 4;
+ }
+ }
+ svga->ma &= svga->vram_display_mask;
}
}
- svga->ma &= svga->vram_display_mask;
- }
}
@@ -1071,46 +1433,71 @@ svga_render_16bpp_lowres(svga_t *svga)
if ((svga->displine + svga->y_add) < 0)
return;
- changed_addr = svga->remap_func(svga, svga->ma);
+ if (svga->force_old_addr) {
+ if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
- if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
- p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
- if (svga->firstline_draw == 2000)
- svga->firstline_draw = svga->displine;
- svga->lastline_draw = svga->displine;
-
- if (!svga->remap_required) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) {
if (svga->crtc[0x17] & 0x80) {
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
-
- *p++ = video_16to32[dat & 0xffff];
- *p++ = video_16to32[dat >> 16];
+ p[(x << 1)] = p[(x << 1) + 1] = video_16to32[dat & 0xffff];
+ p[(x << 1) + 2] = p[(x << 1) + 3] = video_16to32[dat >> 16];
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
-
- *p++ = video_16to32[dat & 0xffff];
- *p++ = video_16to32[dat >> 16];
+ p[(x << 1) + 4] = p[(x << 1) + 5] = video_16to32[dat & 0xffff];
+ p[(x << 1) + 6] = p[(x << 1) + 7] = video_16to32[dat >> 16];
} else
memset(&(p[(x << 1)]), 0x00, 8 * sizeof(uint32_t));
}
- svga->ma += x << 1;
- } else {
- for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) {
- if (svga->crtc[0x17] & 0x80) {
- addr = svga->remap_func(svga, svga->ma);
- dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
-
- *p++ = video_16to32[dat & 0xffff];
- *p++ = video_16to32[dat >> 16];
- } else
- memset(&(p[x]), 0x00, 2 * sizeof(uint32_t));
+ svga->ma += x << 1;
+ svga->ma &= svga->vram_display_mask;
}
- svga->ma += 4;
+ } else {
+ changed_addr = svga->remap_func(svga, svga->ma);
+
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
+
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
+
+ if (!svga->remap_required) {
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) {
+ if (svga->crtc[0x17] & 0x80) {
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
+
+ *p++ = video_16to32[dat & 0xffff];
+ *p++ = video_16to32[dat >> 16];
+
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
+
+ *p++ = video_16to32[dat & 0xffff];
+ *p++ = video_16to32[dat >> 16];
+ } else
+ memset(&(p[(x << 1)]), 0x00, 8 * sizeof(uint32_t));
+ }
+ svga->ma += x << 1;
+ } else {
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) {
+ if (svga->crtc[0x17] & 0x80) {
+ addr = svga->remap_func(svga, svga->ma);
+ dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+
+ *p++ = video_16to32[dat & 0xffff];
+ *p++ = video_16to32[dat >> 16];
+ } else
+ memset(&(p[x]), 0x00, 2 * sizeof(uint32_t));
+ }
+ svga->ma += 4;
+ }
+ svga->ma &= svga->vram_display_mask;
+ }
}
- svga->ma &= svga->vram_display_mask;
- }
}
@@ -1124,54 +1511,87 @@ svga_render_16bpp_highres(svga_t *svga)
if ((svga->displine + svga->y_add) < 0)
return;
-
- changed_addr = svga->remap_func(svga, svga->ma);
-
- if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
+
+ if (svga->force_old_addr) {
+ if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) {
p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
- if (svga->firstline_draw == 2000)
+ if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
- if (!svga->remap_required) {
- for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
- if (svga->crtc[0x17] & 0x80) {
- dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
- *p++ = video_16to32[dat & 0xffff];
- *p++ = video_16to32[dat >> 16];
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
+ if (svga->crtc[0x17] & 0x80) {
+ uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
+ p[x] = video_16to32[dat & 0xffff];
+ p[x + 1] = video_16to32[dat >> 16];
- dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
- *p++ = video_16to32[dat & 0xffff];
- *p++ = video_16to32[dat >> 16];
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
+ p[x + 2] = video_16to32[dat & 0xffff];
+ p[x + 3] = video_16to32[dat >> 16];
- dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]);
- *p++ = video_16to32[dat & 0xffff];
- *p++ = video_16to32[dat >> 16];
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]);
+ p[x + 4] = video_16to32[dat & 0xffff];
+ p[x + 5] = video_16to32[dat >> 16];
- dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]);
- *p++ = video_16to32[dat & 0xffff];
- *p++ = video_16to32[dat >> 16];
- } else
- memset(&(p[x]), 0x00, 8 * sizeof(uint32_t));
- }
- svga->ma += x << 1;
- } else {
- for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) {
- if (svga->crtc[0x17] & 0x80) {
- addr = svga->remap_func(svga, svga->ma);
- dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
-
- *p++ = video_16to32[dat & 0xffff];
- *p++ = video_16to32[dat >> 16];
- } else
- memset(&(p[x]), 0x00, 2 * sizeof(uint32_t));
-
- svga->ma += 4;
- }
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]);
+ p[x + 6] = video_16to32[dat & 0xffff];
+ p[x + 7] = video_16to32[dat >> 16];
+ } else
+ memset(&(p[x]), 0x00, 8 * sizeof(uint32_t));
}
+ svga->ma += x << 1;
svga->ma &= svga->vram_display_mask;
- }
+ }
+ } else {
+ changed_addr = svga->remap_func(svga, svga->ma);
+
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
+
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
+
+ if (!svga->remap_required) {
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
+ if (svga->crtc[0x17] & 0x80) {
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
+ *p++ = video_16to32[dat & 0xffff];
+ *p++ = video_16to32[dat >> 16];
+
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
+ *p++ = video_16to32[dat & 0xffff];
+ *p++ = video_16to32[dat >> 16];
+
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]);
+ *p++ = video_16to32[dat & 0xffff];
+ *p++ = video_16to32[dat >> 16];
+
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]);
+ *p++ = video_16to32[dat & 0xffff];
+ *p++ = video_16to32[dat >> 16];
+ } else
+ memset(&(p[x]), 0x00, 8 * sizeof(uint32_t));
+ }
+ svga->ma += x << 1;
+ } else {
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) {
+ if (svga->crtc[0x17] & 0x80) {
+ addr = svga->remap_func(svga, svga->ma);
+ dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+
+ *p++ = video_16to32[dat & 0xffff];
+ *p++ = video_16to32[dat >> 16];
+ } else
+ memset(&(p[x]), 0x00, 2 * sizeof(uint32_t));
+
+ svga->ma += 4;
+ }
+ }
+ svga->ma &= svga->vram_display_mask;
+ }
+ }
}
@@ -1182,56 +1602,79 @@ svga_render_24bpp_lowres(svga_t *svga)
uint32_t *p;
uint32_t changed_addr, addr;
uint32_t dat0, dat1, dat2;
+ uint32_t fg;
if ((svga->displine + svga->y_add) < 0)
return;
+
+ if (svga->force_old_addr) {
+ if ((svga->displine + svga->y_add) < 0)
+ return;
- changed_addr = svga->remap_func(svga, svga->ma);
+ if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) {
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
- if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
- p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
-
- if (svga->firstline_draw == 2000)
- svga->firstline_draw = svga->displine;
- svga->lastline_draw = svga->displine;
-
- if (!svga->remap_required) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
- if (svga->crtc[0x17] & 0x80) {
- dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
- dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]);
- dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]);
- } else
- dat0 = dat1 = dat2 = 0x00000000;
-
- p[0] = p[1] = dat0 & 0xffffff;
- p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8);
- p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16);
- p[6] = p[7] = dat2 >> 8;
-
- svga->ma += 12;
+ if (svga->crtc[0x17] & 0x80)
+ fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
+ else
+ fg = 0x00000000;
+ svga->ma += 3;
+ svga->ma &= svga->vram_display_mask;
+ buffer32->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] =
+ buffer32->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = fg;
}
- } else {
- for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) {
- if (svga->crtc[0x17] & 0x80) {
- addr = svga->remap_func(svga, svga->ma);
- dat0 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
- addr = svga->remap_func(svga, svga->ma + 4);
- dat1 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
- addr = svga->remap_func(svga, svga->ma + 8);
- dat2 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
- } else
- dat0 = dat1 = dat2 = 0x00000000;
-
- p[0] = p[1] = dat0 & 0xffffff;
- p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8);
- p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16);
- p[6] = p[7] = dat2 >> 8;
-
- svga->ma += 12;
}
- }
- svga->ma &= svga->vram_display_mask;
+ } else {
+ changed_addr = svga->remap_func(svga, svga->ma);
+
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
+
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
+
+ if (!svga->remap_required) {
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
+ if (svga->crtc[0x17] & 0x80) {
+ dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
+ dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]);
+ dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]);
+ } else
+ dat0 = dat1 = dat2 = 0x00000000;
+
+ p[0] = p[1] = dat0 & 0xffffff;
+ p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8);
+ p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16);
+ p[6] = p[7] = dat2 >> 8;
+
+ svga->ma += 12;
+ }
+ } else {
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) {
+ if (svga->crtc[0x17] & 0x80) {
+ addr = svga->remap_func(svga, svga->ma);
+ dat0 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+ addr = svga->remap_func(svga, svga->ma + 4);
+ dat1 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+ addr = svga->remap_func(svga, svga->ma + 8);
+ dat2 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+ } else
+ dat0 = dat1 = dat2 = 0x00000000;
+
+ p[0] = p[1] = dat0 & 0xffffff;
+ p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8);
+ p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16);
+ p[6] = p[7] = dat2 >> 8;
+
+ svga->ma += 12;
+ }
+ }
+ svga->ma &= svga->vram_display_mask;
+ }
}
}
@@ -1243,57 +1686,88 @@ svga_render_24bpp_highres(svga_t *svga)
uint32_t *p;
uint32_t changed_addr, addr;
uint32_t dat0, dat1, dat2;
+ uint32_t dat;
if ((svga->displine + svga->y_add) < 0)
return;
+
+ if (svga->force_old_addr) {
+ if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
- changed_addr = svga->remap_func(svga, svga->ma);
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
- if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
- p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
-
- if (svga->firstline_draw == 2000)
- svga->firstline_draw = svga->displine;
- svga->lastline_draw = svga->displine;
-
- if (!svga->remap_required) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) {
if (svga->crtc[0x17] & 0x80) {
- dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
- dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]);
- dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]);
+ dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
+ p[x] = dat & 0xffffff;
- *p++ = dat0 & 0xffffff;
- *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8);
- *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16);
- *p++ = dat2 >> 8;
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + 3) & svga->vram_display_mask]);
+ p[x + 1] = dat & 0xffffff;
+
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + 6) & svga->vram_display_mask]);
+ p[x + 2] = dat & 0xffffff;
+
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + 9) & svga->vram_display_mask]);
+ p[x + 3] = dat & 0xffffff;
} else
memset(&(p[x]), 0x0, 4 * sizeof(uint32_t));
svga->ma += 12;
}
+ svga->ma &= svga->vram_display_mask;
+ }
} else {
- for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) {
- if (svga->crtc[0x17] & 0x80) {
- addr = svga->remap_func(svga, svga->ma);
- dat0 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
- addr = svga->remap_func(svga, svga->ma + 4);
- dat1 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
- addr = svga->remap_func(svga, svga->ma + 8);
- dat2 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+ changed_addr = svga->remap_func(svga, svga->ma);
- *p++ = dat0 & 0xffffff;
- *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8);
- *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16);
- *p++ = dat2 >> 8;
- } else
- memset(&(p[x]), 0x0, 4 * sizeof(uint32_t));
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
- svga->ma += 12;
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
+
+ if (!svga->remap_required) {
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) {
+ if (svga->crtc[0x17] & 0x80) {
+ dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
+ dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]);
+ dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]);
+
+ *p++ = dat0 & 0xffffff;
+ *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8);
+ *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16);
+ *p++ = dat2 >> 8;
+ } else
+ memset(&(p[x]), 0x0, 4 * sizeof(uint32_t));
+
+ svga->ma += 12;
+ }
+ } else {
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) {
+ if (svga->crtc[0x17] & 0x80) {
+ addr = svga->remap_func(svga, svga->ma);
+ dat0 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+ addr = svga->remap_func(svga, svga->ma + 4);
+ dat1 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+ addr = svga->remap_func(svga, svga->ma + 8);
+ dat2 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+
+ *p++ = dat0 & 0xffffff;
+ *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8);
+ *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16);
+ *p++ = dat2 >> 8;
+ } else
+ memset(&(p[x]), 0x0, 4 * sizeof(uint32_t));
+
+ svga->ma += 12;
+ }
}
+ svga->ma &= svga->vram_display_mask;
+ }
}
- svga->ma &= svga->vram_display_mask;
- }
}
@@ -1307,40 +1781,59 @@ svga_render_32bpp_lowres(svga_t *svga)
if ((svga->displine + svga->y_add) < 0)
return;
+
+ if (svga->force_old_addr) {
+ if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) {
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
- changed_addr = svga->remap_func(svga, svga->ma);
-
- if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
- p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
-
- if (svga->firstline_draw == 2000)
- svga->firstline_draw = svga->displine;
- svga->lastline_draw = svga->displine;
-
- if (!svga->remap_required) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
if (svga->crtc[0x17] & 0x80)
- dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
+ dat = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
else
dat = 0x00000000;
- *p++ = dat & 0xffffff;
- *p++ = dat & 0xffffff;
- }
- svga->ma += (x * 4);
- } else {
- for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
- if (svga->crtc[0x17] & 0x80) {
- addr = svga->remap_func(svga, svga->ma);
- dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
- } else
- dat = 0x00000000;
- *p++ = dat & 0xffffff;
- *p++ = dat & 0xffffff;
svga->ma += 4;
+ svga->ma &= svga->vram_display_mask;
+ buffer32->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] =
+ buffer32->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = dat;
+ }
+ }
+ } else {
+ changed_addr = svga->remap_func(svga, svga->ma);
+
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
+
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
+
+ if (!svga->remap_required) {
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
+ if (svga->crtc[0x17] & 0x80)
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
+ else
+ dat = 0x00000000;
+ *p++ = dat & 0xffffff;
+ *p++ = dat & 0xffffff;
+ }
+ svga->ma += (x * 4);
+ } else {
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
+ if (svga->crtc[0x17] & 0x80) {
+ addr = svga->remap_func(svga, svga->ma);
+ dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+ } else
+ dat = 0x00000000;
+ *p++ = dat & 0xffffff;
+ *p++ = dat & 0xffffff;
+ svga->ma += 4;
+ }
+ svga->ma &= svga->vram_display_mask;
+ }
}
- svga->ma &= svga->vram_display_mask;
}
- }
}
@@ -1354,39 +1847,59 @@ svga_render_32bpp_highres(svga_t *svga)
if ((svga->displine + svga->y_add) < 0)
return;
+
+ if (svga->force_old_addr) {
+ if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
+
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
- changed_addr = svga->remap_func(svga, svga->ma);
-
- if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
- p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
-
- if (svga->firstline_draw == 2000)
- svga->firstline_draw = svga->displine;
- svga->lastline_draw = svga->displine;
-
- if (!svga->remap_required) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
- if (svga->crtc[0x17] & 0x80) {
+ if (svga->crtc[0x17] & 0x80)
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
- *p++ = dat & 0xffffff;
- } else
- memset(&(p[x]), 0x0, 1 * sizeof(uint32_t));
+ else
+ dat = 0x00000000;
+ p[x] = dat & 0xffffff;
+ }
+ svga->ma += 4;
+ svga->ma &= svga->vram_display_mask;
}
- svga->ma += (x * 4);
} else {
- for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
- if (svga->crtc[0x17] & 0x80) {
- addr = svga->remap_func(svga, svga->ma);
- dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
- *p++ = dat & 0xffffff;
- } else
- memset(&(p[x]), 0x0, 1 * sizeof(uint32_t));
+ changed_addr = svga->remap_func(svga, svga->ma);
- svga->ma += 4;
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
+ p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
+
+ if (svga->firstline_draw == 2000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
+
+ if (!svga->remap_required) {
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
+ if (svga->crtc[0x17] & 0x80) {
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
+ *p++ = dat & 0xffffff;
+ } else
+ memset(&(p[x]), 0x0, 1 * sizeof(uint32_t));
+ }
+ svga->ma += (x * 4);
+ } else {
+ for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
+ if (svga->crtc[0x17] & 0x80) {
+ addr = svga->remap_func(svga, svga->ma);
+ dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+ *p++ = dat & 0xffffff;
+ } else
+ memset(&(p[x]), 0x0, 1 * sizeof(uint32_t));
+
+ svga->ma += 4;
+ }
+ }
+ svga->ma &= svga->vram_display_mask;
}
}
- svga->ma &= svga->vram_display_mask;
- }
}