Merge pull request #4130 from 86Box/tc1995

Couple of changes in the video side.
This commit is contained in:
Miran Grča
2024-02-07 02:54:11 +01:00
committed by GitHub
7 changed files with 234 additions and 167 deletions

View File

@@ -64,6 +64,9 @@ typedef struct ibm8514_t {
int hwcursor_on;
int modechange;
uint64_t dispontime;
uint64_t dispofftime;
struct {
uint16_t subsys_cntl;
uint16_t setup_md;

View File

@@ -166,8 +166,10 @@ typedef struct svga_t {
latch_t latch;
pc_timer_t timer;
pc_timer_t timer8514;
double clock;
double clock8514;
hwcursor_t hwcursor;
hwcursor_t hwcursor_latch;
@@ -287,7 +289,7 @@ typedef struct svga_t {
extern int vga_on;
extern void ibm8514_poll(void *priv, svga_t *svga);
extern void ibm8514_poll(void *priv);
extern void ibm8514_recalctimings(svga_t *svga);
extern uint8_t ibm8514_ramdac_in(uint16_t port, void *priv);
extern void ibm8514_ramdac_out(uint16_t port, uint8_t val, void *priv);

View File

@@ -75,6 +75,7 @@ extern void svga_render_ABGR8888_highres(svga_t *svga);
extern void svga_render_RGBA8888_lowres(svga_t *svga);
extern void svga_render_RGBA8888_highres(svga_t *svga);
extern void ibm8514_render_blank(svga_t *svga);
extern void ibm8514_render_8bpp(svga_t *svga);
extern void ibm8514_render_15bpp(svga_t *svga);
extern void ibm8514_render_16bpp(svga_t *svga);

View File

@@ -925,7 +925,7 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len)
if (!(port & 1)) {
if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) {
dev->hsync_width = val;
dev->hblank_end_val = (dev->hblankstart + (dev->hsync_start & 0x1f) - 1) & 0x3f;
dev->hblank_end_val = (dev->hblankstart + (dev->hsync_width & 0x1f) - 1) & 0x3f;
}
}
ibm8514_log("IBM 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1);
@@ -3831,6 +3831,25 @@ bitblt:
}
}
void
ibm8514_render_blank(svga_t *svga)
{
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
if ((dev->displine + svga->y_add) < 0)
return;
if (dev->firstline_draw == 2000)
dev->firstline_draw = dev->displine;
dev->lastline_draw = dev->displine;
uint32_t *line_ptr = &svga->monitor->target_buffer->line[dev->displine + svga->y_add][svga->x_add];
uint32_t line_width = (uint32_t)(dev->h_disp) * sizeof(uint32_t);
if (dev->h_disp > 0)
memset(line_ptr, 0, line_width);
}
void
ibm8514_render_8bpp(svga_t *svga)
{
@@ -4106,148 +4125,153 @@ ibm8514_render_overscan_right(ibm8514_t *dev, svga_t *svga)
}
void
ibm8514_poll(void *priv, svga_t *svga)
ibm8514_poll(void *priv)
{
ibm8514_t *dev = (ibm8514_t *) priv;
svga_t *svga = (svga_t *)priv;
ibm8514_t *dev = (ibm8514_t *)svga->dev8514;
uint32_t x;
int wx;
int wy;
if (!dev->linepos) {
if ((dev->displine == dev->hwcursor_latch.y) && dev->hwcursor_latch.ena) {
dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - dev->hwcursor_latch.yoff;
dev->hwcursor_oddeven = 0;
}
if ((dev->displine == (dev->hwcursor_latch.y + 1)) && dev->hwcursor_latch.ena && dev->interlace) {
dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - (dev->hwcursor_latch.yoff + 1);
dev->hwcursor_oddeven = 1;
}
timer_advance_u64(&svga->timer, svga->dispofftime);
svga->cgastat |= 1;
dev->linepos = 1;
if (dev->dispon) {
dev->hdisp_on = 1;
dev->ma &= dev->vram_mask;
if (dev->firstline == 2000) {
dev->firstline = dev->displine;
video_wait_for_buffer_monitor(svga->monitor_index);
ibm8514_log("IBM 8514/A poll.\n");
if (dev->on[0] || dev->on[1]) {
ibm8514_log("ON!\n");
if (!dev->linepos) {
if ((dev->displine == dev->hwcursor_latch.y) && dev->hwcursor_latch.ena) {
dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - dev->hwcursor_latch.yoff;
dev->hwcursor_oddeven = 0;
}
if (dev->hwcursor_on)
dev->changedvram[dev->ma >> 12] = dev->changedvram[(dev->ma >> 12) + 1] = dev->interlace ? 3 : 2;
if ((dev->displine == (dev->hwcursor_latch.y + 1)) && dev->hwcursor_latch.ena && dev->interlace) {
dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - (dev->hwcursor_latch.yoff + 1);
dev->hwcursor_oddeven = 1;
}
svga->render8514(svga);
timer_advance_u64(&svga->timer8514, dev->dispofftime);
svga->cgastat |= 1;
dev->linepos = 1;
svga->x_add = (overscan_x >> 1);
ibm8514_render_overscan_left(dev, svga);
ibm8514_render_overscan_right(dev, svga);
svga->x_add = (overscan_x >> 1);
if (dev->dispon) {
dev->hdisp_on = 1;
if (dev->hwcursor_on) {
if (svga->hwcursor_draw)
svga->hwcursor_draw(svga, dev->displine + svga->y_add);
dev->hwcursor_on--;
if (dev->hwcursor_on && dev->interlace)
dev->ma &= dev->vram_mask;
if (dev->firstline == 2000) {
dev->firstline = dev->displine;
video_wait_for_buffer_monitor(svga->monitor_index);
}
if (dev->hwcursor_on)
dev->changedvram[dev->ma >> 12] = dev->changedvram[(dev->ma >> 12) + 1] = dev->interlace ? 3 : 2;
svga->render8514(svga);
svga->x_add = (overscan_x >> 1);
ibm8514_render_overscan_left(dev, svga);
ibm8514_render_overscan_right(dev, svga);
svga->x_add = (overscan_x >> 1);
if (dev->hwcursor_on) {
if (svga->hwcursor_draw)
svga->hwcursor_draw(svga, dev->displine + svga->y_add);
dev->hwcursor_on--;
if (dev->hwcursor_on && dev->interlace)
dev->hwcursor_on--;
}
if (dev->lastline < dev->displine)
dev->lastline = dev->displine;
}
if (dev->lastline < dev->displine)
dev->lastline = dev->displine;
}
dev->displine++;
if (dev->interlace)
dev->displine++;
if ((svga->cgastat & 8) && ((dev->displine & 0x0f) == (svga->crtc[0x11] & 0x0f)) && svga->vslines)
svga->cgastat &= ~8;
svga->vslines++;
if (dev->displine > 1500)
dev->displine = 0;
} else {
timer_advance_u64(&svga->timer, svga->dispontime);
if (dev->dispon)
svga->cgastat &= ~1;
dev->hdisp_on = 0;
if (dev->interlace)
dev->displine++;
if ((svga->cgastat & 8) && ((dev->displine & 0x0f) == (svga->crtc[0x11] & 0x0f)) && svga->vslines)
svga->cgastat &= ~8;
svga->vslines++;
if (dev->displine > 1500)
dev->displine = 0;
} else {
timer_advance_u64(&svga->timer8514, dev->dispontime);
if (dev->dispon)
svga->cgastat &= ~1;
dev->hdisp_on = 0;
dev->linepos = 0;
if (dev->dispon) {
if (dev->sc == dev->rowcount) {
dev->sc = 0;
dev->maback += (dev->rowoffset << 3);
if (dev->interlace)
dev->linepos = 0;
if (dev->dispon) {
if (dev->sc == dev->rowcount) {
dev->sc = 0;
dev->maback += (dev->rowoffset << 3);
if (dev->interlace)
dev->maback += (dev->rowoffset << 3);
dev->maback &= dev->vram_mask;
dev->ma = dev->maback;
} else {
dev->sc++;
dev->sc &= 0x1f;
dev->ma = dev->maback;
}
}
dev->vc++;
dev->vc &= 0x7ff;
if (dev->vc == dev->dispend) {
dev->dispon = 0;
for (x = 0; x < ((dev->vram_mask + 1) >> 12); x++) {
if (dev->changedvram[x])
dev->changedvram[x]--;
dev->maback &= dev->vram_mask;
dev->ma = dev->maback;
} else {
dev->sc++;
dev->sc &= 0x1f;
dev->ma = dev->maback;
}
}
if (svga->fullchange)
svga->fullchange--;
}
if (dev->vc == dev->v_syncstart) {
dev->dispon = 0;
svga->cgastat |= 8;
x = dev->h_disp;
dev->vc++;
dev->vc &= 0x7ff;
if (dev->interlace && !dev->oddeven)
dev->lastline++;
if (dev->interlace && dev->oddeven)
dev->firstline--;
if (dev->vc == dev->dispend) {
dev->dispon = 0;
wx = x;
wy = dev->lastline - dev->firstline;
svga_doblit(wx, wy, svga);
for (x = 0; x < ((dev->vram_mask + 1) >> 12); x++) {
if (dev->changedvram[x])
dev->changedvram[x]--;
}
dev->firstline = 2000;
dev->lastline = 0;
if (svga->fullchange)
svga->fullchange--;
}
if (dev->vc == dev->v_syncstart) {
dev->dispon = 0;
svga->cgastat |= 8;
x = dev->h_disp;
dev->firstline_draw = 2000;
dev->lastline_draw = 0;
if (dev->interlace && !dev->oddeven)
dev->lastline++;
if (dev->interlace && dev->oddeven)
dev->firstline--;
dev->oddeven ^= 1;
wx = x;
wy = dev->lastline - dev->firstline;
svga_doblit(wx, wy, svga);
svga->monitor->mon_changeframecount = dev->interlace ? 3 : 2;
svga->vslines = 0;
dev->firstline = 2000;
dev->lastline = 0;
if (dev->interlace && dev->oddeven)
dev->ma = dev->maback = (dev->rowoffset << 1);
else
dev->ma = dev->maback = 0;
dev->firstline_draw = 2000;
dev->lastline_draw = 0;
dev->ma = (dev->ma << 2);
dev->maback = (dev->maback << 2);
}
if (dev->vc == dev->v_total) {
dev->vc = 0;
dev->sc = 0;
dev->dispon = 1;
dev->displine = (dev->interlace && dev->oddeven) ? 1 : 0;
dev->oddeven ^= 1;
svga->x_add = (overscan_x >> 1);
svga->monitor->mon_changeframecount = dev->interlace ? 3 : 2;
svga->vslines = 0;
dev->hwcursor_on = 0;
dev->hwcursor_latch = dev->hwcursor;
if (dev->interlace && dev->oddeven)
dev->ma = dev->maback = (dev->rowoffset << 1);
else
dev->ma = dev->maback = 0;
dev->ma = (dev->ma << 2);
dev->maback = (dev->maback << 2);
}
if (dev->vc == dev->v_total) {
dev->vc = 0;
dev->sc = 0;
dev->dispon = 1;
dev->displine = (dev->interlace && dev->oddeven) ? 1 : 0;
svga->x_add = (overscan_x >> 1);
dev->hwcursor_on = 0;
dev->hwcursor_latch = dev->hwcursor;
}
}
}
}
@@ -4257,6 +4281,7 @@ ibm8514_recalctimings(svga_t *svga)
{
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
svga->render8514 = ibm8514_render_blank;
#ifdef ATI_8514_ULTRA
if (dev->extensions) {
if (svga->ext8514 != NULL)
@@ -4283,14 +4308,14 @@ ibm8514_recalctimings(svga_t *svga)
dev->h_disp = 1024;
dev->dispend = 768;
}
svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
} else {
dev->pitch = 640;
if (!dev->h_disp) {
dev->h_disp = 640;
dev->dispend = 480;
}
svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
}
if (dev->interlace) {
@@ -4429,6 +4454,8 @@ ibm8514_init(const device_t *info)
}
#endif
timer_add(&svga->timer8514, ibm8514_poll, svga, 0);
return svga;
}

View File

@@ -2485,9 +2485,6 @@ ati8514_recalctimings(svga_t *svga)
{
const mach_t *mach = (mach_t *) svga->ext8514;
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
uint32_t dot;
uint32_t adj_dot;
uint32_t eff_mask;
mach_log("ON0=%d, ON1=%d, vgahdisp=%d.\n", dev->on[0], dev->on[1], svga->hdisp);
if (dev->on[0] || dev->on[1]) {
@@ -2530,27 +2527,6 @@ ati8514_recalctimings(svga_t *svga)
mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, advfunc_cntl=%x, shadow=%x.\n", dev->accel.advfunc_cntl & 4, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, dev->accel.advfunc_cntl & 4, mach->shadow_set & 3);
svga->map8 = dev->pallook;
svga->render8514 = ibm8514_render_8bpp;
dot = svga->hblankstart;
adj_dot = svga->hblankstart;
eff_mask = 0x0000003f;
dev->hblank_sub = 0;
while (1) {
if (dot == dev->h_total)
dot = 0;
if (adj_dot >= dev->h_total)
dev->hblank_sub++;
if ((dot & 0x0000003f) == (svga->hblank_end_val & 0x0000003f))
break;
dot++;
adj_dot++;
}
dev->h_disp -= dev->hblank_sub);
} else {
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/
if (svga->seqregs[1] & 8) { /*40 column*/
@@ -2615,6 +2591,8 @@ mach_recalctimings(svga_t *svga)
} else
svga->ati_4color = 0;
}
svga->render8514 = ibm8514_render_blank;
mach_log("ON[0]=%d, ON[1]=%d, exton[0]=%d, exton[1]=%d, vendormode0=%d, vendormode1=%d.\n", dev->on[0], dev->on[1], mach->ext_on[0], mach->ext_on[1], dev->vendor_mode[0], dev->vendor_mode[1]);
if (dev->on[0] || dev->on[1]) {
mach_log("8514/A ON.\n");
@@ -2639,14 +2617,14 @@ mach_recalctimings(svga_t *svga)
if ((dev->local & 0xff) >= 0x02) {
if ((dev->accel.advfunc_cntl ^ dev->modechange) & 0x04) {
if ((mach->shadow_set ^ mach->compat_mode) & 0x03)
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
else
svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
} else {
if ((mach->shadow_set ^ mach->compat_mode) & 0x03)
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
else
svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
}
if (dev->interlace) {
@@ -2706,13 +2684,13 @@ mach_recalctimings(svga_t *svga)
}
switch (mach->regs[0xb8] & 0xc0) {
case 0x40:
svga->clock *= 2;
svga->clock8514 *= 2;
break;
case 0x80:
svga->clock *= 3;
svga->clock8514 *= 3;
break;
case 0xc0:
svga->clock *= 4;
svga->clock8514 *= 4;
break;
default:
@@ -2721,21 +2699,20 @@ mach_recalctimings(svga_t *svga)
} else {
if ((dev->accel.advfunc_cntl ^ dev->modechange) & 0x04) {
if ((mach->shadow_set ^ mach->compat_mode) & 0x03)
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
else
svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
} else {
if ((mach->shadow_set ^ mach->compat_mode) & 0x03)
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
else
svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
if (((mach->shadow_set & 0x03) != 0x02) || !(dev->accel.advfunc_cntl & 0x04)) { /*Shadow set of 2 and bit 2 of port 0x4ae8 mean 1024x768+*/
if (!(mach->accel.clock_sel & 0x01)) {
dev->h_disp = 640;
dev->dispend = 480;
}
dev->interlace = 0;
}
}
@@ -2754,7 +2731,7 @@ mach_recalctimings(svga_t *svga)
svga->map8 = dev->pallook;
svga->render8514 = ibm8514_render_8bpp;
if (mach->regs[0xb8] & 0x40)
svga->clock *= 2;
svga->clock8514 *= 2;
}
}
@@ -3670,7 +3647,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8
if (!(port & 1)) {
if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) {
dev->hsync_width = val;
dev->hblank_end_val = (dev->hblankstart + (dev->hsync_start & 0x1f) - 1) & 0x3f;
dev->hblank_end_val = (dev->hblankstart + (dev->hsync_width & 0x1f) - 1) & 0x3f;
}
}
mach_log("ATI 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1);
@@ -6080,6 +6057,8 @@ mach8_init(const device_t *info)
} else
ati_eeprom_load_mach8(&mach->eeprom, "mach8.nvr");
timer_add(&svga->timer8514, ibm8514_poll, svga, 0);
return mach;
}

View File

@@ -1643,10 +1643,6 @@ gd54xx_recalc_banking(gd54xx_t *gd54xx)
svga->extra_banks[1] = svga->extra_banks[0] + 0x8000;
}
if (!(svga->gdcreg[5] & 0x40) || !(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) {
svga->extra_banks[0] = 0;
svga->extra_banks[1] = 0x8000;
}
svga->write_bank = svga->read_bank = svga->extra_banks[0];
}

View File

@@ -222,6 +222,7 @@ svga_out(uint16_t addr, uint8_t val, void *priv)
svga_log("3C3: VGA ON = %d.\n", val & 0x01);
vga_on = val & 0x01;
svga_recalctimings(svga);
break;
case 0x3c4:
svga->seqaddr = val;
@@ -567,11 +568,15 @@ svga_set_ramdac_type(svga_t *svga, int type)
void
svga_recalctimings(svga_t *svga)
{
const ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
double crtcconst;
double _dispontime;
double _dispofftime;
double disptime;
double crtcconst8514;
double _dispontime8514;
double _dispofftime8514;
double disptime8514;
#ifdef ENABLE_SVGA_LOG
int vsyncend;
int vblankend;
@@ -805,6 +810,31 @@ svga_recalctimings(svga_t *svga)
}
svga->hdisp -= (svga->hblank_sub * svga->dots_per_clock);
if (ibm8514_active && (svga->dev8514 != NULL)) {
if (dev->on[0] || dev->on[1]) {
uint32_t dot8514 = dev->h_blankstart;
uint32_t adj_dot8514 = dev->h_blankstart;
uint32_t eff_mask8514 = 0x0000003f;
dev->hblank_sub = 0;
while (1) {
if (dot8514 == dev->h_total)
dot = 0;
if (adj_dot8514 >= dev->h_total)
dev->hblank_sub++;
if ((dot8514 & eff_mask8514) == (dev->h_blank_end_val & eff_mask8514))
break;
dot8514++;
adj_dot8514++;
}
dev->h_disp -= dev->hblank_sub;
}
}
}
if (svga->hdisp >= 2048)
@@ -817,6 +847,10 @@ svga_recalctimings(svga_t *svga)
svga->dispend = svga->vblankstart;
crtcconst = svga->clock * svga->char_width;
if (ibm8514_active && (svga->dev8514 != NULL)) {
if (dev->on[0] || dev->on[1])
crtcconst8514 = svga->clock8514;
}
#ifdef ENABLE_SVGA_LOG
vsyncend = (svga->vsyncstart & 0xfffffff0) | (svga->crtc[0x11] & 0x0f);
@@ -858,6 +892,13 @@ svga_recalctimings(svga_t *svga)
disptime = svga->htotal;
_dispontime = svga->hdisp_time;
if (ibm8514_active && (svga->dev8514 != NULL)) {
if (dev->on[0] || dev->on[1]) {
disptime8514 = dev->htotal;
_dispontime8514 = dev->hdisped;
}
}
if (svga->seqregs[1] & 8) {
disptime *= 2;
_dispontime *= 2;
@@ -874,6 +915,27 @@ svga_recalctimings(svga_t *svga)
if (svga->dispofftime < TIMER_USEC)
svga->dispofftime = TIMER_USEC;
if (ibm8514_active && (svga->dev8514 != NULL)) {
if (dev->on[0] || dev->on[1]) {
_dispofftime8514 = disptime8514 - _dispontime8514;
_dispontime8514 *= crtcconst8514;
_dispofftime8514 *= crtcconst8514;
dev->dispontime = (uint64_t) (_dispontime8514);
dev->dispofftime = (uint64_t) (_dispofftime8514);
if (dev->dispontime < TIMER_USEC)
dev->dispontime = TIMER_USEC;
if (dev->dispofftime < TIMER_USEC)
dev->dispofftime = TIMER_USEC;
timer_disable(&svga->timer);
timer_enable(&svga->timer8514);
} else {
timer_disable(&svga->timer8514);
timer_enable(&svga->timer);
}
}
if (!svga->force_old_addr)
svga_recalc_remap_func(svga);
@@ -946,10 +1008,6 @@ svga_poll(void *priv)
int old_ma;
if (!svga->override) {
if (ibm8514_active && dev && (dev->on[0] || dev->on[1])) {
ibm8514_poll(dev, svga);
return;
}
if (xga_active && xga && xga->on) {
if ((xga->disp_cntl_2 & 7) >= 2) {
xga_poll(xga, svga);
@@ -1347,9 +1405,10 @@ svga_decode_addr(svga_t *svga, uint32_t addr, int write)
}
if (memory_map_mode <= 1) {
if (svga->adv_flags & FLAG_EXTRA_BANKS)
addr = (addr & 0x17fff) + svga->extra_banks[(addr >> 15) & 1];
else {
if (svga->adv_flags & FLAG_EXTRA_BANKS) {
if ((svga->gdcreg[5] & 0x40) || svga->packed_chain4)
addr = (addr & 0x17fff) + svga->extra_banks[(addr >> 15) & 1];
} else {
if (write)
addr += svga->write_bank;
else