Video, Storage and MCA changes/fixes.

1. Cirrus Logic GD54xx, Paradise/WD VGA now reset the interlace once a text mode is issued if not done automatically.
2. Paradise/WD's 15/16bpp modes using the 800x600 resolution now have the correct ma_latch, should fix most operating systems drivers using this combo.
3. More fixes (hopefully) to the accelerated pitch and rowoffset of the Trident TGUI cards (9440AGi and 96x0XGi), should fix issues with delayed displays mode changes under various operating systems (e.g.: Win3.1x).
4. Preliminary implementation of the Area Fill command of XGA, which is issued while using various painting and/or calc utilities on Win3.1x (IBM XGA updated drivers, e.g.: 2.12).
5. Preliminary (and incomplete) 4bpp XGA mode.
6. The XGA memory test for the 0xa5 using writes (used by various operating systems) no longer conflicts with DOS' XGAKIT's memory detection.
7. Small ROP fixes to both XGA and 8514/A.
8. Re-organized the mapping of the Mach32 chipset, especially when to enable the ATI mode or switching back to IBM mode, should fix LFB conflicts with various operating systems.
9. According to The OS/2 Museum, the Adaptec AHA-154xB series of SCSI cards fail the ASPI4DOS.SYS 3.36 signature check, so now make the changes accordingly.
10. Remove useless and crashy bios-less option of the Trantor T128.
11. The Image Manager 1024 card can also be used on a XT (although only if it has a V20/V30).
12. Re-organized the IBM PS/2 model 60 initialization as well as its right POS machine ID (though an update to sc.exe is still required for the POST memory amount to work normally).
This commit is contained in:
TC1995
2023-09-30 22:08:08 +02:00
parent b1c7834476
commit 6802c0593b
13 changed files with 587 additions and 275 deletions

View File

@@ -366,6 +366,7 @@ typedef struct SGE_t {
#define X54X_INT_GEOM_WRITABLE 8
#define X54X_MBX_24BIT 16
#define X54X_ISAPNP 32
#define X54X_HAS_SIGNATURE 64
typedef struct x54x_t {
/* 32 bytes */
@@ -404,7 +405,7 @@ typedef struct x54x_t {
/* for multi-threading, keep these volatile */
volatile uint8_t Status;
volatile uint8_t Interrupt;
volatile uint8_t Interrupt;
volatile uint8_t MailboxIsBIOS;
volatile uint8_t ToRaise;
volatile uint8_t flags;

View File

@@ -201,6 +201,8 @@ typedef struct xga_t {
int dst_map;
int bkgd_src;
int fore_src;
int oldx;
int oldy;
int x;
int y;
int sx;
@@ -211,6 +213,7 @@ typedef struct xga_t {
int py;
int pattern;
int command_len;
int filling;
uint32_t short_stroke;
uint32_t color_cmp;

View File

@@ -362,11 +362,6 @@ static void
model_50_write(uint16_t port, uint8_t val)
{
switch (port) {
case 0x100:
ps2.io_id = val;
break;
case 0x101:
break;
case 0x102:
lpt1_remove();
serial_remove(ps2.uart);
@@ -499,11 +494,6 @@ static void
model_55sx_write(uint16_t port, uint8_t val)
{
switch (port) {
case 0x100:
ps2.io_id = val;
break;
case 0x101:
break;
case 0x102:
lpt1_remove();
serial_remove(ps2.uart);
@@ -563,10 +553,6 @@ static void
model_70_type3_write(uint16_t port, uint8_t val)
{
switch (port) {
case 0x100:
break;
case 0x101:
break;
case 0x102:
lpt1_remove();
serial_remove(ps2.uart);
@@ -621,10 +607,6 @@ static void
model_80_write(uint16_t port, uint8_t val)
{
switch (port) {
case 0x100:
break;
case 0x101:
break;
case 0x102:
lpt1_remove();
serial_remove(ps2.uart);
@@ -985,12 +967,12 @@ ps2_mca_mem_d071_init(int start_mb)
}
static void
ps2_mca_board_model_50_init(int slots)
ps2_mca_board_model_50_init(void)
{
ps2_mca_board_common_init();
mem_remap_top(384);
mca_init(slots);
mca_init(4);
device_add(&keyboard_ps2_mca_2_device);
ps2.planar_read = model_50_read;
@@ -1005,6 +987,29 @@ ps2_mca_board_model_50_init(int slots)
device_add(&ps1vga_mca_device);
}
static void
ps2_mca_board_model_60_init(void)
{
ps2_mca_board_common_init();
mem_remap_top(384);
mca_init(8);
device_add(&keyboard_ps2_mca_2_device);
ps2.planar_read = model_50_read;
ps2.planar_write = model_50_write;
if (mem_size > 2048) {
/* Only 2 MB supported on planar, create a memory expansion card for the rest */
ps2_mca_mem_fffc_init(2);
}
device_add(&ps2_nvr_55ls_device);
if (gfxcard[0] == VID_INTERNAL)
device_add(&ps1vga_mca_device);
}
static void
ps2_mca_board_model_55sx_init(int has_sec_nvram, int slots)
{
@@ -1051,10 +1056,8 @@ ps2_mca_board_model_55sx_init(int has_sec_nvram, int slots)
mca_init(slots);
device_add(&keyboard_ps2_device);
if (has_sec_nvram == 1)
if (has_sec_nvram)
device_add(&ps2_nvr_55ls_device);
else if (has_sec_nvram == 2)
device_add(&ps2_nvr_device);
ps2.planar_read = model_55sx_read;
ps2.planar_write = model_55sx_write;
@@ -1312,7 +1315,7 @@ ps2_mca_board_model_70_type34_init(int is_type4, int slots)
}
static void
ps2_mca_board_model_80_type2_init(int is486ps2)
ps2_mca_board_model_80_type2_init(void)
{
ps2_mca_board_common_init();
@@ -1372,7 +1375,7 @@ ps2_mca_board_model_80_type2_init(int is486ps2)
NULL);
mem_mapping_disable(&ps2.split_mapping);
if ((mem_size > 4096) && !is486ps2) {
if (mem_size > 4096) {
/* Only 4 MB supported on planar, create a memory expansion card for the rest */
if (mem_size > 12288)
ps2_mca_mem_d071_init(4);
@@ -1426,7 +1429,7 @@ machine_ps2_model_50_init(const machine_t *model)
machine_ps2_common_init(model);
ps2.planar_id = 0xfbff;
ps2_mca_board_model_50_init(4);
ps2_mca_board_model_50_init();
return ret;
}
@@ -1448,8 +1451,8 @@ machine_ps2_model_60_init(const machine_t *model)
machine_ps2_common_init(model);
ps2.planar_id = 0xfbff;
ps2_mca_board_model_50_init(8);
ps2.planar_id = 0xf7ff;
ps2_mca_board_model_60_init();
return ret;
}
@@ -1509,7 +1512,6 @@ machine_ps2_model_70_type3_init(const machine_t *model)
machine_ps2_common_init(model);
ps2.planar_id = 0xf9ff;
ps2_mca_board_model_70_type34_init(0, 4);
return ret;
@@ -1530,7 +1532,7 @@ machine_ps2_model_80_init(const machine_t *model)
machine_ps2_common_init(model);
ps2.planar_id = 0xfdff;
ps2_mca_board_model_80_type2_init(0);
ps2_mca_board_model_80_type2_init();
return ret;
}
@@ -1550,7 +1552,6 @@ machine_ps2_model_80_axx_init(const machine_t *model)
machine_ps2_common_init(model);
ps2.planar_id = 0xfff9;
ps2_mca_board_model_70_type34_init(0, 8);
return ret;
@@ -1571,7 +1572,6 @@ machine_ps2_model_70_type4_init(const machine_t *model)
machine_ps2_common_init(model);
ps2.planar_id = 0xf9ff;
ps2_mca_board_model_70_type34_init(1, 4);
return ret;

View File

@@ -1553,10 +1553,14 @@ ncr_init(const device_t *info)
ncr_dev->bios_ver = 1;
}
if (ncr_dev->bios_ver == 1)
fn = RT1000B_820R_ROM;
else
fn = RT1000B_810R_ROM;
switch (ncr_dev->bios_ver) {
case 0:
fn = RT1000B_810R_ROM;
break;
case 1:
fn = RT1000B_820R_ROM;
break;
}
rom_init(&ncr_dev->bios_rom, fn,
ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
@@ -1601,9 +1605,8 @@ ncr_init(const device_t *info)
ncr_dev->irq = device_get_config_int("irq");
ncr_dev->t128.bios_enabled = device_get_config_int("boot");
if (ncr_dev->t128.bios_enabled)
rom_init(&ncr_dev->bios_rom, T128_ROM,
ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
rom_init(&ncr_dev->bios_rom, T128_ROM,
ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000,
t128_read, NULL, NULL,
@@ -1635,15 +1638,12 @@ ncr_init(const device_t *info)
ncr_log("%s\n", temp);
ncr_reset(ncr_dev, &ncr_dev->ncr);
if (ncr_dev->type < 3 || ncr_dev->type == 4) {
if ((ncr_dev->type < 3) || (ncr_dev->type == 4)) {
ncr_dev->status_ctrl = STATUS_BUFFER_NOT_READY;
ncr_dev->buffer_host_pos = 128;
} else {
ncr_dev->t128.status = 0x04;
ncr_dev->t128.host_pos = 512;
if (!ncr_dev->t128.bios_enabled)
ncr_dev->t128.status |= 0x80;
}
timer_add(&ncr_dev->timer, ncr_callback, ncr_dev, 0);
@@ -1894,13 +1894,6 @@ static const device_config_t t128_config[] = {
{ .description = "" }
},
},
{
.name = "boot",
.description = "Enable Boot ROM",
.type = CONFIG_BINARY,
.default_string = "",
.default_int = 1
},
{ .name = "", .description = "", .type = CONFIG_END }
};
// clang-format on

View File

@@ -103,7 +103,7 @@ x54x_irq(x54x_t *dev, int set)
else
picintc(1 << irq);
}
}
}
}
static void
@@ -466,6 +466,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
}
return 0;
break;
case 0x02: /* Read Desired Sectors to Memory */
case 0x03: /* Write Desired Sectors from Memory */
@@ -1341,24 +1342,27 @@ x54x_in(uint16_t port, void *priv)
if (dev->flags & X54X_INT_GEOM_WRITABLE)
ret = dev->Geometry;
else {
switch (dev->Geometry) {
default:
case 0:
ret = 'A';
break;
case 1:
ret = 'D';
break;
case 2:
ret = 'A';
break;
case 3:
ret = 'P';
break;
}
ret ^= 1;
dev->Geometry++;
dev->Geometry &= 0x03;
if (dev->flags & X54X_HAS_SIGNATURE) {
switch (dev->Geometry) {
default:
case 0:
ret = 'A';
break;
case 1:
ret = 'D';
break;
case 2:
ret = 'A';
break;
case 3:
ret = 'P';
break;
}
ret ^= 1;
dev->Geometry++;
dev->Geometry &= 0x03;
} else
ret = 0xff;
break;
}
break;

View File

@@ -144,13 +144,13 @@ ibm8514_log(const char *fmt, ...)
dest_dat = MAX(src_dat, dest_dat); \
break; \
case 0x15: \
dest_dat = (dest_dat - src_dat) / 2; \
dest_dat = (dest_dat - src_dat) >> 1; \
break; \
case 0x16: \
dest_dat = (src_dat - dest_dat) / 2; \
dest_dat = (src_dat - dest_dat) >> 1; \
break; \
case 0x17: \
dest_dat = (dest_dat + src_dat) / 2; \
dest_dat = (dest_dat + src_dat) >> 1; \
break; \
case 0x18: \
dest_dat = MAX(0, (dest_dat - src_dat)); \
@@ -162,7 +162,7 @@ ibm8514_log(const char *fmt, ...)
dest_dat = MAX(0, (src_dat - dest_dat)); \
break; \
case 0x1b: \
dest_dat = MIN(0xff, (dest_dat + src_dat)); \
dest_dat = MIN(~0, (dest_dat + src_dat)); \
break; \
case 0x1c: \
dest_dat = MAX(0, (dest_dat - src_dat)) / 2; \
@@ -174,7 +174,7 @@ ibm8514_log(const char *fmt, ...)
dest_dat = MAX(0, (src_dat - dest_dat)) / 2; \
break; \
case 0x1f: \
dest_dat = (0xff < (src_dat + dest_dat)) ? 0xff : ((src_dat + dest_dat) / 2); \
dest_dat = (~0 < (src_dat + dest_dat)) ? ~0 : ((src_dat + dest_dat) >> 1); \
break; \
} \
}
@@ -1297,7 +1297,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
/*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled.
When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on
the NOP command)*/
ibm8514_log("CMD8514: CMD=%d, full=%04x, pixcntl=%x, count=%d.\n", cmd, dev->accel.cmd, pixcntl, count);
ibm8514_log("CMD8514: CMD=%d, full=%04x, pixcntl=%x, count=%d, frgdmix = %02x, bkgdmix = %02x, polygon=%x.\n", cmd, dev->accel.cmd, pixcntl, count, frgd_mix, bkgd_mix, dev->accel.multifunc[0x0a] & 6);
switch (cmd) {
case 0: /*NOP (Short Stroke Vectors)*/
@@ -3057,13 +3057,39 @@ rect_fill:
old_dest_dat = dest_dat;
MIX(mix_dat & mix_mask, dest_dat, src_dat);
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
if ((dev->accel.cmd & 4) && (dev->accel.sy < dev->accel.maj_axis_pcnt)) {
if (!dev->accel.sy) {
WRITE((dev->accel.cy * dev->pitch) + (dev->accel.cx), dest_dat);
} else if ((dev->accel.cmd & 0x40) && dev->accel.sy && (dev->accel.cy == (dev->accel.oldcy + 1))) {
WRITE((dev->accel.cy * dev->pitch) + (dev->accel.cx), dest_dat);
} else if (!(dev->accel.cmd & 0x40) && dev->accel.sy && (dev->accel.err_term >= 0) && (dev->accel.cy == (dev->accel.oldcy + 1))) {
if (dev->accel.cmd & 4) {
if (dev->accel.sy < dev->accel.maj_axis_pcnt) {
if (dev->accel.cmd & 0x40) {
WRITE((dev->accel.cy * dev->pitch) + (dev->accel.cx), dest_dat);
} else {
if (dev->accel.cy == (dev->accel.oldcy + 1)) {
if (dev->accel.cmd & 0x20) {
if (dev->accel.err_term < (dev->accel.destx_distp + dev->accel.desty_axstp)) {
WRITE((dev->accel.cy * dev->pitch) + (dev->accel.cx), dest_dat);
}
} else {
if (dev->accel.err_term >= 0) {
WRITE((dev->accel.cy * dev->pitch) + (dev->accel.cx), dest_dat);
}
}
}
}
}
} else {
if (dev->accel.cmd & 0x40) {
WRITE((dev->accel.cy * dev->pitch) + (dev->accel.cx), dest_dat);
} else {
if (dev->accel.cy == (dev->accel.oldcy + 1)) {
if (dev->accel.cmd & 0x20) {
if (dev->accel.err_term < (dev->accel.destx_distp + dev->accel.desty_axstp)) {
WRITE((dev->accel.cy * dev->pitch) + (dev->accel.cx), dest_dat);
}
} else {
if (dev->accel.err_term >= 0) {
WRITE((dev->accel.cy * dev->pitch) + (dev->accel.cx), dest_dat);
}
}
}
}
}
}
@@ -3080,7 +3106,42 @@ rect_fill:
break;
}
if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) {
/*Step major axis*/
switch (dev->accel.cmd & 0xe0) {
case 0x00:
dev->accel.cx--;
break;
case 0x20:
dev->accel.cx++;
break;
case 0x40:
dev->accel.oldcy = dev->accel.cy;
dev->accel.cy--;
break;
case 0x60:
dev->accel.oldcy = dev->accel.cy;
dev->accel.cy--;
break;
case 0x80:
dev->accel.cx--;
break;
case 0xa0:
dev->accel.cx++;
break;
case 0xc0:
dev->accel.oldcy = dev->accel.cy;
dev->accel.cy++;
break;
case 0xe0:
dev->accel.oldcy = dev->accel.cy;
dev->accel.cy++;
break;
default:
break;
}
if (dev->accel.err_term >= 0) {
dev->accel.err_term += dev->accel.destx_distp;
/*Step minor axis*/
switch (dev->accel.cmd & 0xe0) {
@@ -3119,41 +3180,6 @@ rect_fill:
} else
dev->accel.err_term += dev->accel.desty_axstp;
/*Step major axis*/
switch (dev->accel.cmd & 0xe0) {
case 0x00:
dev->accel.cx--;
break;
case 0x20:
dev->accel.cx++;
break;
case 0x40:
dev->accel.oldcy = dev->accel.cy;
dev->accel.cy--;
break;
case 0x60:
dev->accel.oldcy = dev->accel.cy;
dev->accel.cy--;
break;
case 0x80:
dev->accel.cx--;
break;
case 0xa0:
dev->accel.cx++;
break;
case 0xc0:
dev->accel.oldcy = dev->accel.cy;
dev->accel.cy++;
break;
case 0xe0:
dev->accel.oldcy = dev->accel.cy;
dev->accel.cy++;
break;
default:
break;
}
dev->accel.sy++;
}
break;

View File

@@ -99,6 +99,7 @@ typedef struct mach_t {
uint8_t bank_w;
uint8_t bank_r;
uint16_t shadow_set;
int ext_on;
struct {
uint8_t line_idx;
@@ -2599,7 +2600,6 @@ mach_recalctimings(svga_t *svga)
if (dev->on) {
mach_log("8514/A ON.\n");
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
if (dev->local >= 2) {
dev->h_disp = (dev->hdisp + 1) << 3;
dev->h_total = (dev->htotal + 1);
@@ -2614,6 +2614,9 @@ mach_recalctimings(svga_t *svga)
if (dev->dispend == 598)
dev->dispend += 2;
if (dev->h_disp == 1024)
dev->accel.advfunc_cntl |= 4; /*Bit 2 means high resolution e.g.: 1024x768*/
if (dev->accel.advfunc_cntl & 4) {
if (mach->shadow_set & 2) {
if (dev->h_disp == 8) {
@@ -2622,14 +2625,20 @@ mach_recalctimings(svga_t *svga)
dev->v_total = 1536;
dev->v_syncstart = 1536;
}
}
mach_log("Shadow set 2.\n");
svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
} else
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
} else {
if (mach->shadow_set & 1) {
if (dev->h_disp == 1024) {
dev->h_disp = 640;
dev->dispend = 480;
}
if (dev->h_disp == 1024) {
dev->h_disp = 640;
dev->dispend = 480;
}
if (mach->shadow_set & 1) {
mach_log("Shadow set 1.\n");
svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
} else
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
}
if (dev->interlace) {
@@ -2721,14 +2730,18 @@ mach_recalctimings(svga_t *svga)
dev->v_total = 1536;
dev->v_syncstart = 1536;
}
}
svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
} else
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
} else {
if (mach->shadow_set & 1) {
if (dev->h_disp == 1024) {
dev->h_disp = 640;
dev->dispend = 480;
}
if (dev->h_disp == 1024) {
dev->h_disp = 640;
dev->dispend = 480;
}
if (mach->shadow_set & 1) {
svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
} else
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen);
}
if (dev->interlace) {
dev->dispend >>= 1;
@@ -2740,7 +2753,7 @@ mach_recalctimings(svga_t *svga)
}
dev->pitch = dev->ext_pitch;
dev->rowoffset = dev->ext_crt_pitch;
mach_log("hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x.\n", dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0);
mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x.\n", dev->accel.advfunc_cntl & 4, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0);
svga->map8 = dev->pallook;
svga->render8514 = ibm8514_render_8bpp;
if (mach->regs[0xb8] & 0x40)
@@ -2750,6 +2763,7 @@ mach_recalctimings(svga_t *svga)
if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) {
if (((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1))) {
mach_log("VGA clock=%02x.\n", mach->regs[0xa7] & 0x80);
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen);
if (mach->regs[0xa7] & 0x80)
svga->clock *= 3;
@@ -3688,7 +3702,9 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach)
} else {
dev->on = (dev->accel.advfunc_cntl & 0x01);
vga_on = !dev->on;
mach_log("ATI 8514/A: (0x4ae8) val = %04x\n", val & 0x01);
mach->ext_on = dev->on;
mach_log("ATI 8514/A: (0x4ae9) val = %04x, ext = %d.\n", dev->accel.advfunc_cntl & 0x01, mach->ext_on);
mach32_updatemapping(mach);
}
svga_recalctimings(svga);
break;
@@ -3777,6 +3793,7 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach)
case 0x36ee:
case 0x36ef:
mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val);
WRITE8(port, mach->misc, val);
mach->misc &= 0xfff0;
break;
@@ -3813,21 +3830,27 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach)
case 0x4aef:
WRITE8(port, mach->accel.clock_sel, val);
if (port & 1) {
mach_log("ATI 8514/A: (0x4aee) val = %04x\n", mach->accel.clock_sel & 0x01);
dev->on = mach->accel.clock_sel & 0x01;
vga_on = !dev->on;
pclog("ATI 8514/A: (0x4aef) val = %04x, ext = %d.\n", mach->accel.clock_sel & 0x01, mach->ext_on);
}
svga_recalctimings(svga);
break;
case 0x52ee:
case 0x52ef:
mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val);
WRITE8(port, mach->accel.scratch0, val);
if (port & 1)
mach->ext_on = 1;
break;
case 0x56ee:
case 0x56ef:
mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val);
WRITE8(port, mach->accel.scratch1, val);
if (port & 1)
mach->ext_on = 1;
break;
case 0x5aee:
@@ -4744,13 +4767,8 @@ mach32_write_linear(uint32_t addr, uint8_t val, void *priv)
static void
mach32_write(uint32_t addr, uint8_t val, void *priv)
{
svga_t *svga = (svga_t *) priv;
const ibm8514_t *dev = &svga->dev8514;
if (!dev->on) {
svga_write(addr, val, svga);
return;
}
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
addr = (addr & svga->banked_mask) + svga->write_bank;
mach32_write_linear(addr, val, svga);
@@ -4759,33 +4777,25 @@ mach32_write(uint32_t addr, uint8_t val, void *priv)
static void
mach32_writew(uint32_t addr, uint16_t val, void *priv)
{
svga_t *svga = (svga_t *) priv;
const ibm8514_t *dev = &svga->dev8514;
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
if (!dev->on) {
svga_writew(addr, val, svga);
return;
}
mach32_write(addr, val & 0xff, svga);
mach32_write(addr + 1, val >> 8, svga);
addr = (addr & svga->banked_mask) + svga->write_bank;
mach32_write_linear(addr, val & 0xff, svga);
mach32_write_linear(addr + 1, val >> 8, svga);
}
static void
mach32_writel(uint32_t addr, uint32_t val, void *priv)
{
svga_t *svga = (svga_t *) priv;
const ibm8514_t *dev = &svga->dev8514;
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
if (!dev->on) {
svga_writel(addr, val, svga);
return;
}
mach32_write(addr, val & 0xff, svga);
mach32_write(addr + 1, val >> 8, svga);
mach32_write(addr + 2, val >> 16, svga);
mach32_write(addr + 3, val >> 24, svga);
addr = (addr & svga->banked_mask) + svga->write_bank;
mach32_write_linear(addr, val & 0xff, svga);
mach32_write_linear(addr + 1, val >> 8, svga);
mach32_write_linear(addr + 2, val >> 16, svga);
mach32_write_linear(addr + 3, val >> 24, svga);
}
static uint8_t
@@ -4872,15 +4882,10 @@ mach32_read_linear(uint32_t addr, void *priv)
static uint8_t
mach32_read(uint32_t addr, void *priv)
{
svga_t *svga = (svga_t *) priv;
const ibm8514_t *dev = &svga->dev8514;
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
uint8_t ret;
if (!dev->on) {
ret = svga_read(addr, svga);
return ret;
}
addr = (addr & svga->banked_mask) + svga->read_bank;
ret = mach32_read_linear(addr, svga);
return ret;
@@ -4889,36 +4894,28 @@ mach32_read(uint32_t addr, void *priv)
static uint16_t
mach32_readw(uint32_t addr, void *priv)
{
svga_t *svga = (svga_t *) priv;
const ibm8514_t *dev = &svga->dev8514;
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
uint16_t ret;
if (!dev->on) {
ret = svga_readw(addr, svga);
return ret;
}
ret = mach32_read(addr, svga);
ret |= (mach32_read(addr + 1, svga) << 8);
addr = (addr & svga->banked_mask) + svga->read_bank;
ret = mach32_read_linear(addr, svga);
ret |= (mach32_read_linear(addr + 1, svga) << 8);
return ret;
}
static uint32_t
mach32_readl(uint32_t addr, void *priv)
{
svga_t *svga = (svga_t *) priv;
const ibm8514_t *dev = &svga->dev8514;
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
uint32_t ret;
if (!dev->on) {
ret = svga_readl(addr, svga);
return ret;
}
ret = mach32_read(addr, svga);
ret |= (mach32_read(addr + 1, svga) << 8);
ret |= (mach32_read(addr + 2, svga) << 16);
ret |= (mach32_read(addr + 3, svga) << 24);
addr = (addr & svga->banked_mask) + svga->read_bank;
ret = mach32_read_linear(addr, svga);
ret |= (mach32_read_linear(addr + 1, svga) << 8);
ret |= (mach32_read_linear(addr + 2, svga) << 16);
ret |= (mach32_read_linear(addr + 3, svga) << 24);
return ret;
}
@@ -4986,7 +4983,7 @@ mach32_ap_writel(uint32_t addr, uint32_t val, void *priv)
mach_accel_outw(0x02e8 + (port_dword << 8) + 4, val >> 16, mach);
}
} else {
mach_log("Linear WORDL Write=%08x, val=%08x, mode=%d, rop=%02x.\n", addr, val, mach->svga.writemode, mach->svga.gdcreg[3] & 0x18);
mach_log("Linear WORDL Write=%08x.\n", addr);
mach32_write_linear(addr, val & 0xff, svga);
mach32_write_linear(addr + 1, val >> 8, svga);
mach32_write_linear(addr + 2, val >> 16, svga);
@@ -5069,6 +5066,7 @@ static void
mach32_updatemapping(mach_t *mach)
{
svga_t *svga = &mach->svga;
ibm8514_t *dev = &svga->dev8514;
if (mach->pci_bus && (!(mach->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))) {
mem_mapping_disable(&svga->mapping);
@@ -5118,6 +5116,13 @@ mach32_updatemapping(mach_t *mach)
mach->ap_size = 4;
mem_mapping_disable(&mach->mmio_linear_mapping);
}
if (mach->ext_on && (dev->local >= 2)) {
mem_mapping_set_handler(&svga->mapping, mach32_read, mach32_readw, mach32_readl, mach32_write, mach32_writew, mach32_writel);
mem_mapping_set_p(&svga->mapping, mach);
} else {
mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
mem_mapping_set_p(&svga->mapping, svga);
}
}
static void
@@ -5692,7 +5697,6 @@ mach8_init(const device_t *info)
mach->config1 |= 0x0400;
svga->clock_gen = device_add(&ati18811_0_device);
}
mem_mapping_set_handler(&svga->mapping, mach32_read, mach32_readw, mach32_readl, mach32_write, mach32_writew, mach32_writel);
mem_mapping_add(&mach->mmio_linear_mapping, 0, 0, mach32_ap_readb, mach32_ap_readw, mach32_ap_readl, mach32_ap_writeb, mach32_ap_writew, mach32_ap_writel, NULL, MEM_MAPPING_EXTERNAL, mach);
mem_mapping_disable(&mach->mmio_linear_mapping);
} else {

View File

@@ -1739,6 +1739,10 @@ gd54xx_recalctimings(svga_t *svga)
svga->interlace = (svga->crtc[0x1a] & 0x01);
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/
svga->interlace = 0;
}
svga->map8 = svga->pallook;
if (svga->seqregs[7] & CIRRUS_SR7_BPP_SVGA) {
if (linedbl)
@@ -1921,6 +1925,13 @@ gd54xx_recalctimings(svga_t *svga)
}
svga->vram_display_mask = (svga->crtc[0x1b] & 2) ? gd54xx->vram_mask : 0x3ffff;
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/
if (svga->seqregs[1] & 8) {
svga->render = svga_render_text_40;
} else
svga->render = svga_render_text_80;
}
}
static void

View File

@@ -1085,7 +1085,7 @@ im1024_speed_changed(void *priv)
const device_t im1024_device = {
.name = "ImageManager 1024",
.internal_name = "im1024",
.flags = DEVICE_ISA | DEVICE_AT,
.flags = DEVICE_ISA,
.local = 0,
.init = im1024_init,
.close = im1024_close,

View File

@@ -341,23 +341,44 @@ paradise_recalctimings(svga_t *svga)
}
}
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/
svga->interlace = 0;
}
if (paradise->type < WD90C30) {
if (svga->bpp >= 8 && !svga->lowres) {
if ((svga->bpp >= 8) && !svga->lowres) {
svga->render = svga_render_8bpp_highres;
}
} else {
if (svga->bpp >= 8 && !svga->lowres) {
if ((svga->bpp >= 8) && !svga->lowres) {
if (svga->bpp == 16) {
svga->render = svga_render_16bpp_highres;
svga->hdisp >>= 1;
if (svga->hdisp == 788)
svga->hdisp += 12;
if (svga->hdisp == 800)
svga->ma_latch -= 3;
} else if (svga->bpp == 15) {
svga->render = svga_render_15bpp_highres;
svga->hdisp >>= 1;
if (svga->hdisp == 788)
svga->hdisp += 12;
if (svga->hdisp == 800)
svga->ma_latch -= 3;
} else {
svga->render = svga_render_8bpp_highres;
}
}
}
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/
if (svga->hdisp == 360)
svga->hdisp <<= 1;
if (svga->seqregs[1] & 8) {
svga->render = svga_render_text_40;
} else
svga->render = svga_render_text_80;
}
}
static void

View File

@@ -830,7 +830,7 @@ svga_poll(void *priv)
return;
}
if (xga_active && xga->on) {
if ((xga->disp_cntl_2 & 7) >= 3) {
if ((xga->disp_cntl_2 & 7) >= 2) {
xga_poll(xga, svga);
return;
}
@@ -1247,11 +1247,12 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv)
if (((xga->op_mode & 7) >= 4) && (xga->aperture_cntl >= 1)) {
if (val == 0xa5) { /*Memory size test of XGA*/
xga->test = val;
xga->a5_test = 1;
if (addr == 0xa0001)
xga->a5_test = 1;
xga->on = 0;
vga_on = 1;
xga->disp_cntl_2 = 0;
xga->clk_sel_1 = 0;
svga_log("XGA test1 addr = %05x.\n", addr);
return;
} else if (val == 0x5a) {
@@ -1259,7 +1260,7 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv)
xga->on = 0;
vga_on = 1;
xga->disp_cntl_2 = 0;
xga->clk_sel_1 = 0;
svga_log("XGA test2 addr = %05x.\n", addr);
return;
} else if ((addr == 0xa0000) || (addr == 0xa0010)) {
addr += xga->write_bank;
@@ -1469,6 +1470,7 @@ svga_read_common(uint32_t addr, uint8_t linear, void *priv)
xga->on = 1;
vga_on = 0;
} else if ((addr == 0xa0000) && xga->a5_test) { /*This is required by XGAKIT to pass the memory test*/
svga_log("A5 test bank = %x.\n", addr);
addr += xga->read_bank;
ret = xga->vram[addr & xga->vram_mask];
} else {
@@ -1476,7 +1478,7 @@ svga_read_common(uint32_t addr, uint8_t linear, void *priv)
xga->on = 1;
vga_on = 0;
}
svga_log("A5 read: XGA ON = %d, addr = %05x.\n", xga->on, addr);
svga_log("A5 read: XGA ON = %d, addr = %05x, ret = %02x, test1 = %x.\n", xga->on, addr, ret, xga->a5_test);
return ret;
} else if (xga->test == 0x5a) {
ret = xga->test;

View File

@@ -1399,6 +1399,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
uint32_t trans_col = (tgui->accel.flags & TGUI_TRANSREV) ? tgui->accel.fg_col : tgui->accel.bg_col;
uint16_t *vram_w = (uint16_t *) svga->vram;
uint32_t *vram_l = (uint32_t *) svga->vram;
uint8_t ger22upper = (tgui->accel.ger22 >> 8);
if (tgui->accel.bpp == 0) {
trans_col &= 0xff;
@@ -1454,6 +1455,16 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
}
}
/*For delayed mode switches.*/
if (tgui->type == TGUI_9440) {
if (tgui->accel.pitch == 800)
tgui->accel.pitch += 32;
if (tgui->accel.bpp == 1) {
if (!ger22upper)
tgui->accel.pitch = svga->rowoffset << 2;
}
}
#if 0
pclog("TGUI accel command = %x, ger22 = %04x, hdisp = %d, dispend = %d, vtotal = %d, rowoffset = %d, svgabpp = %d, interlace = %d, accelbpp = %d, pitch = %d.\n", tgui->accel.command, tgui->accel.ger22, svga->hdisp, svga->dispend, svga->vtotal, svga->rowoffset, svga->bpp, svga->interlace, tgui->accel.bpp, tgui->accel.pitch);
#endif
@@ -2066,6 +2077,19 @@ tgui_accel_out(uint16_t addr, uint8_t val, void *priv)
case 0x2123:
//pclog("Pitch IO23: val = %02x, rowoffset = %x, pitch = %d.\n", val, svga->rowoffset, tgui->accel.pitch);
switch (svga->bpp) {
case 8:
case 24:
tgui->accel.bpp = 0;
break;
case 15:
case 16:
tgui->accel.bpp = 1;
break;
case 32:
tgui->accel.bpp = 3;
break;
}
tgui->accel.ger22 = (tgui->accel.ger22 & 0xff) | (val << 8);
if ((val & 0x80) || ((val & 0xc0) == 0x40))
tgui->accel.pitch = svga->rowoffset << 3;
@@ -2075,15 +2099,14 @@ tgui_accel_out(uint16_t addr, uint8_t val, void *priv)
tgui->accel.pitch = 1024;
}
if (tgui->accel.pitch == 800)
tgui->accel.pitch += 32;
if (tgui->accel.bpp == 1)
tgui->accel.pitch >>= 1;
else if (tgui->accel.bpp == 3)
tgui->accel.pitch >>= 2;
if (tgui->accel.pitch == 800)
tgui->accel.pitch += 32;
svga_recalctimings(svga);
break;
@@ -2722,7 +2745,19 @@ tgui_accel_write(uint32_t addr, uint8_t val, void *priv)
break;
case 0x23:
//pclog("Pitch MM23: val = %02x, rowoffset = %x, pitch = %d.\n", val, svga->rowoffset, tgui->accel.pitch);
switch (svga->bpp) {
case 8:
case 24:
tgui->accel.bpp = 0;
break;
case 15:
case 16:
tgui->accel.bpp = 1;
break;
case 32:
tgui->accel.bpp = 3;
break;
}
tgui->accel.ger22 = (tgui->accel.ger22 & 0xff) | (val << 8);
if ((val & 0x80) || ((val & 0xc0) == 0x40))
tgui->accel.pitch = svga->rowoffset << 3;
@@ -2732,14 +2767,15 @@ tgui_accel_write(uint32_t addr, uint8_t val, void *priv)
tgui->accel.pitch = 1024;
}
if (tgui->accel.pitch == 800)
tgui->accel.pitch += 32;
if (tgui->accel.bpp == 1)
tgui->accel.pitch >>= 1;
else if (tgui->accel.bpp == 3)
tgui->accel.pitch >>= 2;
if (tgui->accel.pitch == 800)
tgui->accel.pitch += 32;
//pclog("Pitch MM23: fullval = %04x, rowoffset = %x, pitch = %d.\n", tgui->accel.ger22, svga->rowoffset, tgui->accel.pitch);
svga_recalctimings(svga);
break;

View File

@@ -49,6 +49,7 @@ static uint8_t xga_ext_inb(uint16_t addr, void *priv);
static void xga_writew(uint32_t addr, uint16_t val, void *priv);
static uint16_t xga_readw(uint32_t addr, void *priv);
static void xga_render_4bpp(svga_t *svga);
static void xga_render_8bpp(svga_t *svga);
static void xga_render_16bpp(svga_t *svga);
@@ -376,7 +377,7 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val)
case 0x51:
xga_log("Reg51 write = %02x.\n", val);
xga->disp_cntl_2 = val;
xga->on = ((val & 7) >= 3);
xga->on = ((val & 7) >= 2);
vga_on = !xga->on;
svga_recalctimings(svga);
break;
@@ -406,7 +407,7 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val)
if ((xga->sprite_pos >= 0) && (xga->sprite_pos <= 16)) {
if ((xga->op_mode & 7) >= 5)
xga->cursor_data_on = 1;
else if ((xga->sprite_pos >= 1) || ((xga->disp_cntl_2 & 7) == 4))
else if ((xga->sprite_pos >= 1) || (((xga->disp_cntl_2 & 7) == 2) || (xga->disp_cntl_2 & 7) == 4))
xga->cursor_data_on = 1;
else if (xga->aperture_cntl == 0) {
if (xga->linear_endian_reverse && !(xga->access_mode & 8))
@@ -888,7 +889,7 @@ xga_ext_inb(uint16_t addr, void *priv)
d = MIN(s, d); \
break; \
case 0x12: \
d = MIN(0xff, s + d); \
d = MIN(~0, s + d); \
break; \
case 0x13: \
d = MAX(0, d - s); \
@@ -908,7 +909,7 @@ xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t b
const xga_t *xga = &svga->xga;
uint32_t addr = base;
int bits;
uint32_t byte;
uint8_t byte;
uint8_t px;
int skip = 0;
@@ -978,6 +979,15 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int
}
px = (byte >> bits) & 1;
return px;
case 2: /*4-bit*/
addr += (y * (width >> 1));
addr += (x >> 1);
if (!skip) {
READ(addr, byte);
} else {
byte = mem_readb_phys(addr);
}
return byte;
case 3: /*8-bit*/
addr += (y * width);
addr += x;
@@ -1060,6 +1070,29 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui
}
mem_writeb_phys(addr, byte);
break;
case 2: /*4-bit*/
addr += (y * (width >> 1));
addr += (x >> 1);
if (!skip) {
READ(addr, byte);
} else {
byte = mem_readb_phys(addr);
}
if (xga->linear_endian_reverse) {
mask = 0x0f << ((1 - (x & 1)) << 2);
} else {
if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) {
mask = 0x0f << ((x & 1) << 2);
} else {
mask = 0x0f << ((1 - (x & 1)) << 2);
}
}
byte = (byte & ~mask) | (pixel & mask);
if (!skip) {
WRITE(addr, byte);
}
mem_writeb_phys(addr, byte);
break;
case 3: /*8-bit*/
addr += (y * width);
addr += x;
@@ -1076,14 +1109,12 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui
pixel = ((pixel & 0xff00) >> 8) | ((pixel & 0x00ff) << 8);
else if (xga->access_mode & 8)
pixel = ((pixel & 0xff00) >> 8) | ((pixel & 0x00ff) << 8);
mem_writew_phys(addr, pixel);
} else {
if (!skip) {
WRITEW(addr, pixel);
}
mem_writew_phys(addr, pixel);
}
mem_writew_phys(addr, pixel);
break;
default:
@@ -1257,7 +1288,7 @@ xga_line_draw_write(svga_t *svga)
err = (xga->accel.bres_err_term);
if (xga->accel.bres_err_term & 0x2000)
destxtmp |= ~0x1fff;
err |= ~0x1fff;
if (xga->accel.octant & 0x02) {
ydir = -1;
@@ -1279,6 +1310,9 @@ xga_line_draw_write(svga_t *svga)
if (xga->accel.dst_map_y >= 0x1800)
dy |= ~0x17ff;
if ((xga->accel.command & 0x30) == 0x30)
xga_log("Line Draw Write: BLTWIDTH=%d, BLTHEIGHT=%d, FRGDCOLOR=%04x, XDIR=%i, YDIR=%i, steep=%s, ERR=%04x.\n", xga->accel.blt_width, xga->accel.blt_height, xga->accel.frgd_color & 0xffff, xdir, ydir, (xga->accel.octant & 0x01) ? "0" : "1", err);
if (xga->accel.octant & 0x01) {
steep = 0;
SWAP(dx, dy);
@@ -1287,6 +1321,7 @@ xga_line_draw_write(svga_t *svga)
if (xga->accel.pat_src == 8) {
while (y >= 0) {
draw_pixel = 1;
if (xga->accel.command & 0xc0) {
if (steep) {
if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) {
@@ -1303,6 +1338,21 @@ xga_line_draw_write(svga_t *svga)
xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1);
else if (((xga->accel.command & 0x30) == 0x20) && y)
xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1);
else if ((xga->accel.command & 0x30) == 0x30) {
if (err < 0)
draw_pixel = 0;
else {
if (ydir == -1) { /*Bottom-to-Top*/
if (!x)
draw_pixel = 0;
} else { /*Top-to-Bottom*/
if (!y)
draw_pixel = 0;
}
}
if (draw_pixel)
xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1);
}
}
}
} else {
@@ -1320,6 +1370,17 @@ xga_line_draw_write(svga_t *svga)
xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1);
else if (((xga->accel.command & 0x30) == 0x20) && y)
xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1);
else if ((xga->accel.command & 0x30) == 0x30) {
if (xdir == -1) { /*Bottom-to-Top*/
if (!x)
draw_pixel = 0;
} else { /*Top-to-Bottom*/
if (!y)
draw_pixel = 0;
}
if (draw_pixel)
xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1);
}
}
}
}
@@ -1338,6 +1399,21 @@ xga_line_draw_write(svga_t *svga)
xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1);
else if (((xga->accel.command & 0x30) == 0x20) && y)
xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1);
else if ((xga->accel.command & 0x30) == 0x30) {
if (err < 0)
draw_pixel = 0;
else {
if (ydir == -1) { /*Bottom-to-Top*/
if (!x)
draw_pixel = 0;
} else { /*Top-to-Bottom*/
if (!y)
draw_pixel = 0;
}
}
if (draw_pixel)
xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1);
}
}
} else {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color;
@@ -1353,6 +1429,17 @@ xga_line_draw_write(svga_t *svga)
xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1);
else if (((xga->accel.command & 0x30) == 0x20) && y)
xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1);
else if ((xga->accel.command & 0x30) == 0x30) {
if (xdir == -1) { /*Bottom-to-Top*/
if (!x)
draw_pixel = 0;
} else { /*Top-to-Bottom*/
if (!y)
draw_pixel = 0;
}
if (draw_pixel)
xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1);
}
}
}
}
@@ -1361,7 +1448,7 @@ xga_line_draw_write(svga_t *svga)
break;
}
while (err > 0) {
while (err >= 0) {
dy += ydir;
err -= (dmajor << 1);
}
@@ -1383,10 +1470,13 @@ xga_line_draw_write(svga_t *svga)
}
}
#undef SWAP
static void
xga_bitblt(svga_t *svga)
{
xga_t *xga = &svga->xga;
uint8_t area_state = 0;
uint32_t src_dat;
uint32_t dest_dat;
uint32_t old_dest_dat;
@@ -1405,9 +1495,12 @@ xga_bitblt(svga_t *svga)
#endif
uint32_t frgdcol = xga->accel.frgd_color;
uint32_t bkgdcol = xga->accel.bkgd_color;
int mix = 0;
int mix = 0;
int xdir;
int ydir;
int skip = 0;
int x = 0;
int y = 0;
if (xga->accel.octant & 0x02) {
ydir = -1;
@@ -1556,17 +1649,105 @@ xga_bitblt(svga_t *svga)
xga_log("Pattern Map = %d: CMD = %08x: PATBase = %08x, SRCBase = %08x, DSTBase = %08x\n",
xga->accel.pat_src, xga->accel.command, patbase, srcbase, dstbase);
xga_log("CMD = %08x: Y = %d, X = %d, patsrc = %02x, srcmap = %d, dstmap = %d, py = %d, "
"sy = %d, dy = %d, width0 = %d, width1 = %d, width2 = %d, width3 = %d\n",
"sy = %d, dy = %d, width0 = %d, width1 = %d, width2 = %d, width3 = %d, bkgdcol = %02x\n",
xga->accel.command, xga->accel.y, xga->accel.x, xga->accel.pat_src,
xga->accel.src_map, xga->accel.dst_map, xga->accel.py, xga->accel.sy, xga->accel.dy,
xga->accel.px_map_width[0], xga->accel.px_map_width[1],
xga->accel.px_map_width[2], xga->accel.px_map_width[3]);
xga->accel.px_map_width[2], xga->accel.px_map_width[3], bkgdcol);
while (xga->accel.y >= 0) {
mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, xga->accel.pat_src, patbase, patwidth + 1);
if (((xga->accel.command >> 24) & 0x0f) == 0x0a) {
while (xga->accel.y >= 0) {
mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, xga->accel.pat_src, patbase, patwidth + 1);
if (mix)
area_state ^= 1;
if (xga->accel.command & 0xc0) {
if ((xga->accel.dx >= xga->accel.mask_map_origin_x_off) && (xga->accel.dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (xga->accel.dy >= xga->accel.mask_map_origin_y_off) && (xga->accel.dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) {
if (xga->accel.command & 0xc0) {
if ((xga->accel.dx >= xga->accel.mask_map_origin_x_off) && (xga->accel.dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (xga->accel.dy >= xga->accel.mask_map_origin_y_off) && (xga->accel.dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) {
if (area_state)
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol;
else
src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol;
if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) <= 3)
src_dat &= 0xff;
dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(area_state, dest_dat, src_dat);
dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask);
xga_log("1SRCDat=%02x, DSTDat=%02x, Old=%02x, MIX=%d.\n", src_dat, dest_dat, old_dest_dat, area_state);
xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1);
}
}
} else {
if (area_state)
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol;
else
src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol;
if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) <= 3)
src_dat &= 0xff;
dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(area_state, dest_dat, src_dat);
dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask);
xga_log("2Fill: NumXY(%d,%d): DXY(%d,%d): SRCDat=%02x, DSTDat=%02x, Old=%02x, frgdcol=%02x, bkgdcol=%02x, MIX=%d, frgdmix=%02x, bkgdmix=%02x, dstmapfmt=%02x, srcmapfmt=%02x, srcmapnum=%d.\n", x, y, xga->accel.dx, xga->accel.dy, src_dat, dest_dat, old_dest_dat, frgdcol, bkgdcol, area_state, xga->accel.frgd_mix & 0x1f, xga->accel.bkgd_mix & 0x1f, xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, xga->accel.px_map_format[xga->accel.src_map] & 0x0f, xga->accel.src_map);
xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1);
}
}
xga->accel.sx = ((xga->accel.sx + 1) & srcwidth) | (xga->accel.sx & ~srcwidth);
xga->accel.px = ((xga->accel.px + 1) & patwidth) | (xga->accel.px & ~patwidth);
xga->accel.dx++;
xga->accel.x--;
x++;
if (xga->accel.x < 0) {
area_state = 0;
x = 0;
xga->accel.y--;
xga->accel.x = xga->accel.blt_width & 0xfff;
xga->accel.dx = xga->accel.dst_map_x & 0x1fff;
if (xga->accel.dst_map_x >= 0x1800)
xga->accel.dx |= ~0x17ff;
xga->accel.sx = xga->accel.src_map_x & 0xfff;
xga->accel.px = xga->accel.pat_map_x & 0xfff;
xga->accel.sy = ((xga->accel.sy + ydir) & srcheight) | (xga->accel.sy & ~srcheight);
xga->accel.py += ydir;
xga->accel.dy += ydir;
y++;
if (xga->accel.y < 0) {
xga->accel.dst_map_x = xga->accel.dx;
xga->accel.dst_map_y = xga->accel.dy;
return;
}
}
}
} else {
while (xga->accel.y >= 0) {
mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, xga->accel.pat_src, patbase, patwidth + 1);
if (xga->accel.command & 0xc0) {
if ((xga->accel.dx >= xga->accel.mask_map_origin_x_off) && (xga->accel.dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (xga->accel.dy >= xga->accel.mask_map_origin_y_off) && (xga->accel.dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) {
if (mix) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol;
} else {
src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol;
}
dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(mix, dest_dat, src_dat);
dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask);
xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1);
}
}
} else {
if (mix) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol;
} else {
@@ -1580,49 +1761,36 @@ xga_bitblt(svga_t *svga)
xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1);
}
}
} else {
if (mix) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol;
} else {
src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol;
}
dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(mix, dest_dat, src_dat);
dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask);
xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1);
}
}
xga->accel.sx += xdir;
if (xga->accel.pattern)
xga->accel.px = ((xga->accel.px + xdir) & patwidth) | (xga->accel.px & ~patwidth);
else
xga->accel.px += xdir;
xga->accel.dx += xdir;
xga->accel.x--;
if (xga->accel.x < 0) {
xga->accel.y--;
xga->accel.x = (xga->accel.blt_width & 0xfff);
xga->accel.dx = xga->accel.dst_map_x & 0x1fff;
if (xga->accel.dst_map_x >= 0x1800)
xga->accel.dx |= ~0x17ff;
xga->accel.sx = xga->accel.src_map_x & 0xfff;
xga->accel.px = xga->accel.pat_map_x & 0xfff;
xga->accel.sy += ydir;
xga->accel.sx += xdir;
if (xga->accel.pattern)
xga->accel.py = ((xga->accel.py + ydir) & patheight) | (xga->accel.py & ~patheight);
xga->accel.px = ((xga->accel.px + xdir) & patwidth) | (xga->accel.px & ~patwidth);
else
xga->accel.py += ydir;
xga->accel.dy += ydir;
xga->accel.px += xdir;
xga->accel.dx += xdir;
xga->accel.x--;
if (xga->accel.x < 0) {
xga->accel.y--;
xga->accel.x = (xga->accel.blt_width & 0xfff);
if (xga->accel.y < 0) {
xga->accel.dst_map_x = xga->accel.dx;
xga->accel.dst_map_y = xga->accel.dy;
return;
xga->accel.dx = xga->accel.dst_map_x & 0x1fff;
if (xga->accel.dst_map_x >= 0x1800)
xga->accel.dx |= ~0x17ff;
xga->accel.sx = xga->accel.src_map_x & 0xfff;
xga->accel.px = xga->accel.pat_map_x & 0xfff;
xga->accel.sy += ydir;
if (xga->accel.pattern)
xga->accel.py = ((xga->accel.py + ydir) & patheight) | (xga->accel.py & ~patheight);
else
xga->accel.py += ydir;
xga->accel.dy += ydir;
if (xga->accel.y < 0) {
xga->accel.dst_map_x = xga->accel.dx;
xga->accel.dst_map_y = xga->accel.dy;
return;
}
}
}
}
@@ -2054,24 +2222,29 @@ exec_command:
#endif
switch ((xga->accel.command >> 24) & 0x0f) {
case 2: /*Short Stroke Vectors Read */
xga_log("Short Stroke Vectors Read.\n");
break;
case 3: /*Bresenham Line Draw Read*/
xga_log("Line Draw Read\n");
break;
case 4: /*Short Stroke Vectors*/
xga_log("Short Stroke Vectors.\n");
case 4: /*Short Stroke Vectors Write*/
xga_log("Short Stroke Vectors Write.\n");
break;
case 5: /*Bresenham Line Draw Write*/
xga_log("Line Draw Write.\n");
xga_line_draw_write(svga);
break;
case 8: /*BitBLT*/
xga_log("BitBLT.\n");
xga_bitblt(svga);
break;
case 9: /*Inverting BitBLT*/
xga_log("Inverting BitBLT\n");
break;
case 0x0a: /*Area Fill*/
xga_log("Area Fill.\n");
xga_log("Area Fill BitBLT.\n");
xga_bitblt(svga);
break;
default:
@@ -2355,6 +2528,47 @@ xga_render_overscan_right(xga_t *xga, svga_t *svga)
*line_ptr++ = svga->overscan_color;
}
static void
xga_render_4bpp(svga_t *svga)
{
xga_t *xga = &svga->xga;
uint32_t *p;
uint32_t dat;
if ((xga->displine + svga->y_add) < 0)
return;
if (xga->changedvram[xga->ma >> 12] || xga->changedvram[(xga->ma >> 12) + 1] || svga->fullchange) {
p = &svga->monitor->target_buffer->line[xga->displine + svga->y_add][svga->x_add];
if (xga->firstline_draw == 2000)
xga->firstline_draw = xga->displine;
xga->lastline_draw = xga->displine;
for (int x = 0; x <= xga->h_disp; x += 16) {
dat = *(uint32_t *) (&xga->vram[xga->ma & xga->vram_mask]);
p[0] = xga->pallook[(dat >> 4) & 0x0f];
p[1] = xga->pallook[dat & 0x0f];
p[2] = xga->pallook[(dat >> 12) & 0x0f];
p[3] = xga->pallook[(dat >> 8) & 0x0f];
p[4] = xga->pallook[(dat >> 20) & 0x0f];
p[5] = xga->pallook[(dat >> 16) & 0x0f];
p[6] = xga->pallook[(dat >> 28) & 0x0f];
p[7] = xga->pallook[(dat >> 24) & 0x0f];
dat = *(uint32_t *) (&xga->vram[(xga->ma + 4) & xga->vram_mask]);
p[9] = xga->pallook[dat & 0x0f];
p[11] = xga->pallook[(dat >> 8) & 0x0f];
p[13] = xga->pallook[(dat >> 16) & 0x0f];
p[15] = xga->pallook[(dat >> 24) & 0x0f];
xga->ma += 8;
p += 16;
}
xga->ma &= xga->vram_mask;
}
}
static void
xga_render_8bpp(svga_t *svga)
{
@@ -2449,7 +2663,7 @@ xga_write(uint32_t addr, uint8_t val, void *priv)
if (addr >= xga->vram_size)
return;
cycles -= video_timing_write_b;
cycles -= svga->monitor->mon_video_timing_write_b;
if (xga->access_mode & 8) {
if ((xga->access_mode & 7) == 4)
@@ -2510,7 +2724,7 @@ xga_read(uint32_t addr, void *priv)
if (addr >= xga->vram_size)
return ret;
cycles -= video_timing_read_b;
cycles -= svga->monitor->mon_video_timing_read_b;
if (xga->access_mode & 8) {
if ((xga->access_mode & 7) == 4)
@@ -2695,6 +2909,9 @@ xga_do_render(svga_t *svga)
xga_log("DISPCNTL = %d, vga = %d.\n", xga->disp_cntl_2 & 7, vga_on);
switch (xga->disp_cntl_2 & 7) {
case 2:
xga_render_4bpp(svga);
break;
case 3:
xga_render_8bpp(svga);
break;
@@ -2773,15 +2990,9 @@ xga_poll(xga_t *xga, svga_t *svga)
if (xga->sc == xga->rowcount) {
xga->sc = 0;
if ((xga->disp_cntl_2 & 7) == 4) {
xga->maback += (xga->rowoffset << 4);
if (xga->interlace)
xga->maback += (xga->rowoffset << 4);
} else {
xga->maback += (xga->rowoffset << 3);
if (xga->interlace)
xga->maback += (xga->rowoffset << 3);
}
xga->maback += (xga->rowoffset << (xga->disp_cntl_2 & 7));
if (xga->interlace)
xga->maback += (xga->rowoffset << (xga->disp_cntl_2 & 7));
xga->maback &= xga->vram_mask;
xga->ma = xga->maback;
} else {