Merge branch 'master' of https://github.com/86Box/86Box into qt-opengl-renderer

This commit is contained in:
ts-korhonen
2022-03-02 17:32:32 +02:00
9 changed files with 1395 additions and 772 deletions

View File

@@ -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);

View File

@@ -15,7 +15,7 @@
</property>
<widget class="QWidget" name="centralwidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@@ -37,7 +37,14 @@
<number>0</number>
</property>
<item>
<widget class="RendererStack" name="stackedWidget"/>
<widget class="RendererStack" name="stackedWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>

View File

@@ -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())

View File

@@ -19,6 +19,7 @@
#include <QOpenGLShaderProgram>
#include <QOpenGLTexture>
#include <QSurfaceFormat>
#include <QOpenGLTexture>
#include <cmath>
@@ -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();

View File

@@ -202,6 +202,12 @@
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Time synchronization</string>
</property>

View File

@@ -404,7 +404,7 @@ 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) |
@@ -414,7 +414,7 @@ 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)
if (svga->packed_chain4 || svga->force_old_addr)
return in_addr;
return ((in_addr << 2) & 0x1fff8) |
@@ -424,7 +424,7 @@ 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)
if (svga->packed_chain4 || svga->force_old_addr)
return in_addr;
return ((in_addr << 2) & 0xfffc) |
@@ -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[] = {
static const device_config_t s3_orchid_86c911_config[] =
{
{
"memory", "Memory size", CONFIG_SELECTION, "", 1, "", { 0 },
{
{ "512 KB", 0 },
{ "1 MB", 1 },
{ "" }
{
"512 KB", 0
},
{
"1 MB", 1
},
{
""
}
}
},
{ "", "", -1 }
{
"", "", -1
}
};
static const device_config_t s3_9fx_config[] = {
static const device_config_t s3_9fx_config[] =
{
{
"memory", "Memory size", CONFIG_SELECTION, "", 2, "", { 0 },
{
{ "1 MB", 1 },
{ "2 MB", 2 },
{
"1 MB", 1
},
{
"2 MB", 2
},
/*Trio64 also supports 4 MB, however the Number Nine BIOS does not*/
{ "" }
{
""
}
}
},
{ "", "", -1 }
{
"", "", -1
}
};
static const device_config_t s3_phoenix_trio32_config[] = {
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 },
{ "" }
{
"512 KB", 0
},
{
"1 MB", 1
},
{
"2 MB", 2
},
{
""
}
}
},
{ "", "", -1 }
{
"", "", -1
}
};
static const device_config_t s3_standard_config[] = {
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 MB", 1
},
{
"2 MB", 2
},
{
"4 MB", 4
},
{
""
}
}
},
{ "", "", -1 }
{
"", "", -1
}
};
static const device_config_t s3_968_config[] = {
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 MB", 1
},
{
"2 MB", 2
},
{
"4 MB", 4
},
{
"8 MB", 8
},
{
""
}
}
},
{ "", "", -1 }
{
"", "", -1
}
};
// clang-format on
const device_t s3_orchid_86c911_isa_device =
{

View File

@@ -776,6 +776,7 @@ static void s3_virge_recalctimings(svga_t *svga)
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;
@@ -783,7 +784,6 @@ static void s3_virge_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;
@@ -813,8 +813,7 @@ static void s3_virge_recalctimings(svga_t *svga)
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");
}
@@ -940,8 +939,10 @@ static void s3_virge_updatemapping(virge_t *virge)
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);
@@ -4118,7 +4119,7 @@ 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();
@@ -4216,20 +4217,31 @@ 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 },
{ "" }
{
"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[] =
@@ -4237,22 +4249,42 @@ 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 },
{ "" }
{
"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[] =
@@ -4260,16 +4292,27 @@ static const device_config_t s3_trio3d2x_config[] =
{
"memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 },
{
{ "4 MB", 4 },
{ "8 MB", 8 },
{ "" }
{
"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 =
{

View File

@@ -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,6 +582,7 @@ svga_recalctimings(svga_t *svga)
if (svga->dispofftime < TIMER_USEC)
svga->dispofftime = TIMER_USEC;
if (!svga->force_old_addr)
svga_recalc_remap_func(svga);
/* Inform the user interface of any DPMS mode changes. */
@@ -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) {

View File

@@ -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) {
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) {
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,6 +396,58 @@ svga_render_2bpp_lowres(svga_t *svga)
if ((svga->displine + svga->y_add) < 0)
return;
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->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;
if (!(svga->crtc[0x17] & 0x40)) {
addr = (addr << 1) & svga->vram_mask;
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);
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) {
@@ -418,11 +485,13 @@ 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,6 +500,58 @@ svga_render_2bpp_highres(svga_t *svga)
if ((svga->displine + svga->y_add) < 0)
return;
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->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;
if (!(svga->crtc[0x17] & 0x40)) {
addr = (addr << 1) & svga->vram_mask;
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);
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) {
@@ -468,6 +589,7 @@ svga_render_2bpp_highres(svga_t *svga)
}
}
}
}
void
@@ -540,6 +662,68 @@ svga_render_4bpp_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];
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;
if (!(svga->crtc[0x17] & 0x40)) {
addr = (addr << 1) & svga->vram_mask;
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;
}
}
} else {
changed_addr = svga->remap_func(svga, svga->ma);
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
@@ -585,11 +769,13 @@ svga_render_4bpp_lowres(svga_t *svga)
}
}
}
}
void
svga_render_4bpp_highres(svga_t *svga)
{
int changed_offset;
int x, oddeven;
uint32_t addr, *p;
uint8_t edat[4];
@@ -599,6 +785,70 @@ 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;
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;
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
addr = 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;
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;
}
}
} else {
changed_addr = svga->remap_func(svga, svga->ma);
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
@@ -644,6 +894,7 @@ svga_render_4bpp_highres(svga_t *svga)
}
}
}
}
void
@@ -658,6 +909,28 @@ 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];
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) {
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;
}
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) {
@@ -694,6 +967,7 @@ svga_render_8bpp_lowres(svga_t *svga)
svga->ma &= svga->vram_display_mask;
}
}
}
void
@@ -708,6 +982,33 @@ 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];
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) {
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;
}
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) {
@@ -750,6 +1051,7 @@ svga_render_8bpp_highres(svga_t *svga)
svga->ma &= svga->vram_display_mask;
}
}
}
void
svga_render_8bpp_tseng_lowres(svga_t *svga)
@@ -871,6 +1173,32 @@ 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];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
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[(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[(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 {
changed_addr = svga->remap_func(svga, svga->ma);
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
@@ -912,6 +1240,7 @@ svga_render_15bpp_lowres(svga_t *svga)
svga->ma &= svga->vram_display_mask;
}
}
}
void
@@ -925,6 +1254,38 @@ 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];
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) {
if (svga->crtc[0x17] & 0x80) {
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
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[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[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[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 &= 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) {
@@ -972,6 +1333,7 @@ svga_render_15bpp_highres(svga_t *svga)
svga->ma &= svga->vram_display_mask;
}
}
}
void
@@ -1071,6 +1433,30 @@ svga_render_16bpp_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];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
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[(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[(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;
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) {
@@ -1112,6 +1498,7 @@ svga_render_16bpp_lowres(svga_t *svga)
svga->ma &= svga->vram_display_mask;
}
}
}
void
@@ -1125,6 +1512,38 @@ svga_render_16bpp_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];
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) {
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[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[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[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) {
@@ -1173,6 +1592,7 @@ svga_render_16bpp_highres(svga_t *svga)
svga->ma &= svga->vram_display_mask;
}
}
}
void
@@ -1182,10 +1602,32 @@ 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;
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;
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
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 {
changed_addr = svga->remap_func(svga, svga->ma);
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
@@ -1234,6 +1676,7 @@ svga_render_24bpp_lowres(svga_t *svga)
svga->ma &= svga->vram_display_mask;
}
}
}
void
@@ -1243,10 +1686,40 @@ 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];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) {
if (svga->crtc[0x17] & 0x80) {
dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
p[x] = dat & 0xffffff;
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 {
changed_addr = svga->remap_func(svga, svga->ma);
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
@@ -1295,6 +1768,7 @@ svga_render_24bpp_highres(svga_t *svga)
svga->ma &= svga->vram_display_mask;
}
}
}
void
@@ -1308,6 +1782,24 @@ 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;
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
if (svga->crtc[0x17] & 0x80)
dat = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
else
dat = 0x00000000;
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) {
@@ -1342,6 +1834,7 @@ svga_render_32bpp_lowres(svga_t *svga)
}
}
}
}
void
@@ -1355,6 +1848,25 @@ 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;
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[x] = dat & 0xffffff;
}
svga->ma += 4;
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) {
@@ -1388,6 +1900,7 @@ svga_render_32bpp_highres(svga_t *svga)
svga->ma &= svga->vram_display_mask;
}
}
}
void