Merge pull request #3543 from 86Box/tc1995

Video changes: (see below)
This commit is contained in:
Miran Grča
2023-08-12 00:30:57 +02:00
committed by GitHub
20 changed files with 2660 additions and 2119 deletions

View File

@@ -19,7 +19,16 @@
#ifndef VIDEO_8514A_H
#define VIDEO_8514A_H
typedef struct {
int ena,
x, y, xoff, yoff, cur_xsize, cur_ysize,
v_acc, h_acc;
uint32_t addr, pitch;
} hwcursor8514_t;
typedef struct ibm8514_t {
hwcursor8514_t hwcursor;
hwcursor8514_t hwcursor_latch;
uint8_t pos_regs[8];
int force_old_addr;
@@ -29,8 +38,10 @@ typedef struct ibm8514_t {
uint32_t vram_size;
uint32_t vram_mask;
uint32_t pallook[512];
PALETTE vgapal;
uint8_t hwcursor_oddeven;
uint8_t dac_mask;
uint8_t dac_status;
uint32_t *map8;
@@ -38,7 +49,9 @@ typedef struct ibm8514_t {
int dac_pos;
int dac_r;
int dac_g;
int dac_b;
int internal_pitch;
int hwcursor_on;
struct {
uint16_t subsys_cntl;

View File

@@ -89,6 +89,7 @@ typedef struct svga_t {
int dac_pos;
int dac_r;
int dac_g;
int dac_b;
int vtotal;
int dispend;
int vsyncstart;
@@ -341,6 +342,9 @@ extern void ati68860_ramdac_set_render(void *priv, svga_t *svga);
extern void ati68860_ramdac_set_pallook(void *priv, int i, uint32_t col);
extern void ati68860_hwcursor_draw(svga_t *svga, int displine);
extern void ati68875_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svga_t *svga);
extern uint8_t ati68875_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga);
extern void att49x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga);
extern uint8_t att49x_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga);
@@ -396,6 +400,7 @@ extern float tvp3026_getclock(int clock, void *priv);
# ifdef EMU_DEVICE_H
extern const device_t ati68860_ramdac_device;
extern const device_t ati68875_ramdac_device;
extern const device_t att490_ramdac_device;
extern const device_t att491_ramdac_device;
extern const device_t att492_ramdac_device;
@@ -409,6 +414,9 @@ extern const device_t bt485a_ramdac_device;
extern const device_t gendac_ramdac_device;
extern const device_t ibm_rgb528_ramdac_device;
extern const device_t ics2494an_305_device;
extern const device_t ati18810_device;
extern const device_t ati18811_0_device;
extern const device_t ati18811_1_device;
extern const device_t ics2595_device;
extern const device_t icd2061_device;
extern const device_t ics9161_device;

View File

@@ -73,6 +73,15 @@ void svga_render_ABGR8888_highres(svga_t *svga);
void svga_render_RGBA8888_lowres(svga_t *svga);
void svga_render_RGBA8888_highres(svga_t *svga);
void ibm8514_render_8bpp(svga_t *svga);
void ibm8514_render_15bpp(svga_t *svga);
void ibm8514_render_16bpp(svga_t *svga);
void ibm8514_render_24bpp(svga_t *svga);
void ibm8514_render_BGR(svga_t *svga);
void ibm8514_render_32bpp(svga_t *svga);
void ibm8514_render_ABGR8888(svga_t *svga);
void ibm8514_render_RGBA8888(svga_t *svga);
extern void (*svga_render)(svga_t *svga);
#endif /*VID_SVGA_RENDER_H*/

View File

@@ -302,7 +302,9 @@ extern void ibm8514_device_add(void);
extern const device_t mach8_isa_device;
extern const device_t mach32_isa_device;
extern const device_t mach32_vlb_device;
extern const device_t mach32_mca_device;
extern const device_t mach32_pci_device;
extern const device_t mach32_onboard_pci_device;
/* ATi Mach64 */
extern const device_t mach64gx_isa_device;

View File

@@ -269,6 +269,7 @@ machine_at_valuepointp60_init(const machine_t *model)
pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x01, PCI_CARD_IDE, 0, 0, 0, 0);
pci_register_slot(0x03, PCI_CARD_VIDEO, 3, 3, 3, 3);
pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 2, 1, 4);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4);
@@ -280,6 +281,9 @@ machine_at_valuepointp60_init(const machine_t *model)
device_add(&i430lx_device);
if (gfxcard[0] == VID_INTERNAL)
device_add(&mach32_onboard_pci_device);
return ret;
}

View File

@@ -7754,7 +7754,7 @@ const machine_t machines[] = {
.max_multi = MACHINE_MULTIPLIER_FIXED
},
.bus_flags = MACHINE_PS2_PCI,
.flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI,
.flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI,
.ram = {
.min = 2048,
.max = 131072,
@@ -7764,7 +7764,7 @@ const machine_t machines[] = {
.kbc_device = NULL,
.kbc_p1 = 0,
.gpio = 0,
.device = NULL,
.device = &mach32_onboard_pci_device,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,

View File

@@ -102,11 +102,17 @@ SettingsDisplay::onCurrentMachineChanged(int machineId)
ui->comboBoxVideoSecondary->setEnabled(true);
ui->pushButtonConfigureSecondary->setEnabled(true);
}
if (video_card_get_flags(gfxcard[0]) != VIDEO_FLAG_TYPE_8514)
ibm8514_has_vga = 0;
if (video_card_get_flags(gfxcard[0]) != VIDEO_FLAG_TYPE_XGA)
xga_has_vga = 0;
if (gfxcard[0] == VID_INTERNAL) {
if (video_get_type_monitor(0) != VIDEO_FLAG_TYPE_8514)
ibm8514_has_vga = 0;
if (video_get_type_monitor(0) != VIDEO_FLAG_TYPE_XGA)
xga_has_vga = 0;
} else {
if (video_card_get_flags(gfxcard[0]) != VIDEO_FLAG_TYPE_8514)
ibm8514_has_vga = 0;
if (video_card_get_flags(gfxcard[0]) != VIDEO_FLAG_TYPE_XGA)
xga_has_vga = 0;
}
ui->comboBoxVideo->setCurrentIndex(selectedRow);
if (gfxcard[1] == 0)
ui->pushButtonConfigureSecondary->setEnabled(false);

View File

@@ -18,7 +18,8 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c
vid_incolor.c vid_colorplus.c vid_genius.c vid_pgc.c vid_im1024.c
vid_sigma.c vid_wy700.c vid_ega.c vid_ega_render.c vid_svga.c vid_8514a.c
vid_svga_render.c vid_ddc.c vid_vga.c vid_ati_eeprom.c vid_ati18800.c
vid_ati28800.c vid_ati_mach8.c vid_ati_mach64.c vid_ati68860_ramdac.c vid_bt48x_ramdac.c
vid_ati28800.c vid_ati_mach8.c vid_ati_mach64.c vid_ati68875_ramdac.c
vid_ati68860_ramdac.c vid_bt48x_ramdac.c
vid_av9194.c vid_icd2061.c vid_ics2494.c vid_ics2595.c vid_cl54xx.c
vid_et3000.c vid_et4000.c vid_sc1148x_ramdac.c vid_sc1502x_ramdac.c
vid_et4000w32.c vid_stg_ramdac.c vid_ht216.c vid_oak_oti.c vid_paradise.c

View File

@@ -63,30 +63,16 @@ ibm8514_log(const char *fmt, ...)
#define READ_PIXTRANS_WORD(cx, n) \
if ((cmd <= 1) || (cmd == 5)) { \
if (dev->local) { \
temp = svga->vram[((dev->accel.cy * dev->pitch) + (cx) + (n)) & svga->vram_mask]; \
temp |= (svga->vram[((dev->accel.cy * dev->pitch) + (cx) + (n + 1)) & svga->vram_mask] << 8); \
} else { \
temp = dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n)) & dev->vram_mask]; \
temp |= (dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n + 1)) & dev->vram_mask] << 8); \
} \
temp = dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n)) & dev->vram_mask]; \
temp |= (dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n + 1)) & dev->vram_mask] << 8); \
} else { \
if (dev->local) { \
temp = svga->vram[(dev->accel.dest + (cx) + (n)) & svga->vram_mask]; \
temp |= (svga->vram[(dev->accel.dest + (cx) + (n + 1)) & svga->vram_mask] << 8); \
} else { \
temp = dev->vram[(dev->accel.dest + (cx) + (n)) & dev->vram_mask]; \
temp |= (dev->vram[(dev->accel.dest + (cx) + (n + 1)) & dev->vram_mask] << 8); \
} \
temp = dev->vram[(dev->accel.dest + (cx) + (n)) & dev->vram_mask]; \
temp |= (dev->vram[(dev->accel.dest + (cx) + (n + 1)) & dev->vram_mask] << 8); \
}
#define READ(addr, dat) \
if (dev->local) { \
if ((svga->bpp == 15) || (svga->bpp == 16)) { \
dat = vram_w[(addr) & (svga->vram_mask >> 1)]; \
} else { \
dat = (svga->vram[(addr) & (svga->vram_mask)]); \
} \
if (dev->bpp) { \
dat = vram_w[(addr) & (dev->vram_mask >> 1)]; \
} else { \
dat = (dev->vram[(addr) & (dev->vram_mask)]); \
}
@@ -194,14 +180,9 @@ ibm8514_log(const char *fmt, ...)
}
#define WRITE(addr, dat) \
if (dev->local) { \
if ((svga->bpp == 15) || (svga->bpp == 16)) { \
vram_w[((addr)) & (svga->vram_mask >> 1)] = dat; \
svga->changedvram[(((addr)) & (svga->vram_mask >> 1)) >> 11] = changeframecount; \
} else { \
svga->vram[((addr)) & (svga->vram_mask)] = dat; \
svga->changedvram[(((addr)) & (svga->vram_mask)) >> 12] = changeframecount; \
} \
if (dev->bpp) { \
vram_w[((addr)) & (dev->vram_mask >> 1)] = dat; \
dev->changedvram[(((addr)) & (dev->vram_mask >> 1)) >> 11] = changeframecount; \
} else { \
dev->vram[((addr)) & (dev->vram_mask)] = dat; \
dev->changedvram[(((addr)) & (dev->vram_mask)) >> 12] = changeframecount; \
@@ -212,7 +193,7 @@ int ibm8514_has_vga = 0;
int
ibm8514_cpu_src(svga_t *svga)
{
const ibm8514_t *dev = &svga->dev8514;
ibm8514_t *dev = &svga->dev8514;
if (!(dev->accel.cmd & 0x100))
return 0;
@@ -226,7 +207,7 @@ ibm8514_cpu_src(svga_t *svga)
int
ibm8514_cpu_dest(svga_t *svga)
{
const ibm8514_t *dev = &svga->dev8514;
ibm8514_t *dev = &svga->dev8514;
if (!(dev->accel.cmd & 0x100))
return 0;
@@ -579,8 +560,10 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len)
dev->data_available = 0;
dev->data_available2 = 0;
dev->accel.cmd = val;
if (dev->accel.cmd & 0x100)
dev->accel.cmd_back = 0;
if (port == 0xdae8) {
if (dev->accel.cmd & 0x100)
dev->accel.cmd_back = 0;
}
ibm8514_accel_start(-1, 0, -1, 0, svga, len);
}
break;
@@ -978,9 +961,9 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len)
case 0x4ae8:
if (!val)
break;
dev->accel.advfunc_cntl = val & 7;
ibm8514_on = (dev->accel.advfunc_cntl & 1);
vga_on = !ibm8514_on;
dev->accel.advfunc_cntl = val & 0x0f;
ibm8514_on = val & 0x01;
vga_on = !ibm8514_on;
ibm8514_log("IBM 8514/A: VGA ON = %i, val = %02x\n", vga_on, val);
svga_recalctimings(svga);
break;
@@ -1011,14 +994,14 @@ ibm8514_accel_in(uint16_t port, svga_t *svga, int len)
ibm8514_t *dev = &svga->dev8514;
uint32_t temp = 0;
int cmd;
int vpos = dev->displine + svga->y_add;
int vpos = 0;
int vblankend = svga->vblankstart + svga->crtc[0x16];
switch (port) {
case 0x2e8:
vpos = dev->displine + svga->y_add;
if (vblankend > dev->vtotal) {
vblankend -= dev->vtotal;
vpos = dev->vc & 0x7ff;
if (vblankend > dev->v_total) {
vblankend -= dev->v_total;
if (vpos >= svga->vblankstart || vpos <= vblankend)
temp |= 2;
} else {
@@ -1051,13 +1034,13 @@ ibm8514_accel_in(uint16_t port, svga_t *svga, int len)
break;
case 0x42e8:
vpos = dev->displine + svga->y_add;
if (vblankend > dev->vtotal) {
vblankend -= dev->vtotal;
vpos = dev->vc & 0x7ff;
if (vblankend > dev->v_total) {
vblankend -= dev->v_total;
if (vpos >= svga->vblankstart || vpos <= vblankend)
dev->subsys_stat |= 1;
} else {
if (vpos >= svga->vblankstart && vpos <= vblankend)
if (vpos >= svga->vblankstart && vpos <= vblankend)
dev->subsys_stat |= 1;
}
if (len != 1) {
@@ -1172,7 +1155,7 @@ void
ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, UNUSED(int len))
{
ibm8514_t *dev = &svga->dev8514;
uint16_t *vram_w = (uint16_t *) svga->vram;
uint16_t *vram_w = (uint16_t *) dev->vram;
uint16_t src_dat = 0;
uint16_t dest_dat;
uint16_t old_dest_dat;
@@ -1181,7 +1164,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
uint16_t clip_b = dev->accel.multifunc[3];
uint16_t clip_r = dev->accel.multifunc[4];
int pixcntl = (dev->accel.multifunc[0x0a] >> 6) & 3;
uint16_t mix_mask = ((svga->bpp == 8) || (svga->bpp == 24)) ? 0x80 : 0x8000;
uint16_t mix_mask = dev->bpp ? 0x8000 : 0x80;
uint16_t compare = dev->accel.color_cmp;
int compare_mode = dev->accel.multifunc[0x0a] & 0x38;
int cmd = dev->accel.cmd >> 13;
@@ -1194,7 +1177,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
int and3 = dev->accel.cur_x & 3;
uint16_t poly_src = 0;
if ((svga->bpp == 8) || (svga->bpp == 24)) {
if (!dev->bpp) {
compare &= 0xff;
frgd_color &= 0xff;
bkgd_color &= 0xff;
@@ -1225,7 +1208,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
count >>= 3;
}
if ((svga->bpp == 15) || (svga->bpp == 16)) {
if (dev->bpp) {
if ((dev->accel.cmd & 0x200) && (count == 2))
count >>= 1;
}
@@ -1312,6 +1295,8 @@ 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, ssvdraw=%x.\n", cmd, dev->accel.cmd, dev->accel.ssv_draw);
switch (cmd) {
case 0: /*NOP (Short Stroke Vectors)*/
if (dev->accel.ssv_state == 0)
@@ -1356,7 +1341,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
mix_dat <<= 1;
mix_dat |= 1;
if ((svga->bpp == 15) || (svga->bpp == 16))
if (dev->bpp)
cpu_dat >>= 16;
else
cpu_dat >>= 8;
@@ -1441,7 +1426,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
mix_dat <<= 1;
mix_dat |= 1;
if ((svga->bpp == 15) || (svga->bpp == 16))
if (dev->bpp)
cpu_dat >>= 16;
else
cpu_dat >>= 8;
@@ -1693,7 +1678,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
mix_dat <<= 1;
mix_dat |= 1;
if ((svga->bpp == 15) || (svga->bpp == 16))
if (dev->bpp)
cpu_dat >>= 16;
else
cpu_dat >>= 8;
@@ -1786,7 +1771,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
dev->accel.temp_cnt--;
mix_dat >>= 1;
if ((svga->bpp == 15) || (svga->bpp == 16))
if (dev->bpp)
cpu_dat >>= 16;
else
cpu_dat >>= 8;
@@ -1914,7 +1899,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
mix_dat <<= 1;
mix_dat |= 1;
if ((svga->bpp == 15) || (svga->bpp == 16))
if (dev->bpp)
cpu_dat >>= 16;
else
cpu_dat >>= 8;
@@ -2020,7 +2005,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
if (dev->accel.cur_y >= 0x600)
dev->accel.cy |= ~0x5ff;
if (dev->local && dev->accel.ge_offset && (svga->bpp == 24))
if ((dev->local >= 2) && dev->accel.ge_offset && (svga->bpp == 24))
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
else
dev->accel.dest = dev->accel.cy * dev->pitch;
@@ -2072,7 +2057,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
if (!(dev->accel.cmd & 0x40) && (frgd_mix == 2) && (bkgd_mix == 2) && (pixcntl == 0) && (cmd == 2)) {
if (!(dev->accel.sx & 1)) {
dev->accel.output = 1;
if (dev->local && dev->accel.ge_offset && (svga->bpp == 24))
if ((dev->local >= 2) && dev->accel.ge_offset && (svga->bpp == 24))
dev->accel.newdest_out = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch);
else
dev->accel.newdest_out = (dev->accel.cy + 1) * dev->pitch;
@@ -2195,7 +2180,7 @@ rect_fill_pix:
mix_dat <<= 1;
mix_dat |= 1;
if ((svga->bpp == 15) || (svga->bpp == 16))
if (dev->bpp)
cpu_dat >>= 16;
else
cpu_dat >>= 8;
@@ -2320,7 +2305,7 @@ rect_fill_pix:
mix_dat <<= 1;
mix_dat |= 1;
if ((svga->bpp == 15) || (svga->bpp == 16))
if (dev->bpp)
cpu_dat >>= 16;
else
cpu_dat >>= 8;
@@ -2348,7 +2333,7 @@ rect_fill_pix:
else
dev->accel.cy--;
if (dev->local && dev->accel.ge_offset && (svga->bpp == 24))
if ((dev->local >= 2) && dev->accel.ge_offset && (svga->bpp == 24))
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
else
dev->accel.dest = dev->accel.cy * dev->pitch;
@@ -2403,7 +2388,7 @@ rect_fill_pix:
}
}
mix_dat >>= 1;
if ((svga->bpp == 15) || (svga->bpp == 16))
if (dev->bpp)
cpu_dat >>= 16;
else
cpu_dat >>= 8;
@@ -2440,7 +2425,7 @@ rect_fill_pix:
else
dev->accel.cy--;
if (dev->local && dev->accel.ge_offset && (svga->bpp == 24))
if ((dev->local >= 2) && dev->accel.ge_offset && (svga->bpp == 24))
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
else
dev->accel.dest = dev->accel.cy * dev->pitch;
@@ -2547,7 +2532,7 @@ rect_fill_pix:
}
mix_dat <<= 1;
mix_dat |= 1;
if ((svga->bpp == 15) || (svga->bpp == 16))
if (dev->bpp)
cpu_dat >>= 16;
else
cpu_dat >>= 8;
@@ -2649,7 +2634,7 @@ rect_fill_pix:
mix_dat <<= 1;
mix_dat |= 1;
if ((svga->bpp == 15) || (svga->bpp == 16))
if (dev->bpp)
cpu_dat >>= 16;
else
cpu_dat >>= 8;
@@ -2854,7 +2839,7 @@ rect_fill:
}
if (poly_src) {
dev->accel.fill_state = !dev->accel.fill_state;
dev->accel.fill_state ^= 1;
}
if (dev->accel.fill_state) {
@@ -3036,7 +3021,7 @@ rect_fill:
mix_dat <<= 1;
mix_dat |= 1;
if ((svga->bpp == 15) || (svga->bpp == 16))
if (dev->bpp)
cpu_dat >>= 16;
else
cpu_dat >>= 8;
@@ -3222,7 +3207,7 @@ bitblt_pix:
mix_dat <<= 1;
mix_dat |= 1;
if ((svga->bpp == 15) || (svga->bpp == 16))
if (dev->bpp)
cpu_dat >>= 16;
else
cpu_dat >>= 8;
@@ -3312,7 +3297,7 @@ bitblt_pix:
}
}
mix_dat >>= 1;
if ((svga->bpp == 15) || (svga->bpp == 16))
if (dev->bpp)
cpu_dat >>= 16;
else
cpu_dat >>= 8;
@@ -3423,7 +3408,7 @@ bitblt_pix:
}
mix_dat <<= 1;
mix_dat |= 1;
if ((svga->bpp == 15) || (svga->bpp == 16))
if (dev->bpp)
cpu_dat >>= 16;
else
cpu_dat >>= 8;
@@ -3622,7 +3607,7 @@ bitblt:
}
}
} else {
if ((svga->bpp == 24) && dev->local && (dev->accel.cmd == 0xc2b5)) {
if ((svga->bpp == 24) && (dev->local >= 2) && (dev->accel.cmd == 0xc2b5)) {
int64_t cx;
int64_t dx;
@@ -3753,10 +3738,11 @@ bitblt:
}
}
static void
void
ibm8514_render_8bpp(svga_t *svga)
{
ibm8514_t *dev = &svga->dev8514;
int x;
uint32_t *p;
uint32_t dat;
@@ -3771,18 +3757,18 @@ ibm8514_render_8bpp(svga_t *svga)
dev->firstline_draw = dev->displine;
dev->lastline_draw = dev->displine;
for (int x = 0; x <= dev->h_disp; x += 8) {
for (x = 0; x <= dev->h_disp; x += 8) {
dat = *(uint32_t *) (&dev->vram[dev->ma & dev->vram_mask]);
p[0] = dev->map8[dat & 0xff];
p[1] = dev->map8[(dat >> 8) & 0xff];
p[2] = dev->map8[(dat >> 16) & 0xff];
p[3] = dev->map8[(dat >> 24) & 0xff];
p[0] = dev->pallook[dat & 0xff];
p[1] = dev->pallook[(dat >> 8) & 0xff];
p[2] = dev->pallook[(dat >> 16) & 0xff];
p[3] = dev->pallook[(dat >> 24) & 0xff];
dat = *(uint32_t *) (&dev->vram[(dev->ma + 4) & dev->vram_mask]);
p[4] = dev->map8[dat & 0xff];
p[5] = dev->map8[(dat >> 8) & 0xff];
p[6] = dev->map8[(dat >> 16) & 0xff];
p[7] = dev->map8[(dat >> 24) & 0xff];
p[4] = dev->pallook[dat & 0xff];
p[5] = dev->pallook[(dat >> 8) & 0xff];
p[6] = dev->pallook[(dat >> 16) & 0xff];
p[7] = dev->pallook[(dat >> 24) & 0xff];
dev->ma += 8;
p += 8;
@@ -3791,6 +3777,216 @@ ibm8514_render_8bpp(svga_t *svga)
}
}
void
ibm8514_render_15bpp(svga_t *svga)
{
ibm8514_t *dev = &svga->dev8514;
int x;
uint32_t *p;
uint32_t dat;
if ((dev->displine + svga->y_add) < 0) {
return;
}
if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) {
p = &buffer32->line[dev->displine + svga->y_add][svga->x_add];
if (dev->firstline_draw == 2000)
dev->firstline_draw = dev->displine;
dev->lastline_draw = dev->displine;
for (x = 0; x <= dev->h_disp; x += 8) {
dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1)) & dev->vram_mask]);
p[x] = video_15to32[dat & 0xffff];
p[x + 1] = video_15to32[dat >> 16];
dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1) + 4) & dev->vram_mask]);
p[x + 2] = video_15to32[dat & 0xffff];
p[x + 3] = video_15to32[dat >> 16];
dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1) + 8) & dev->vram_mask]);
p[x + 4] = video_15to32[dat & 0xffff];
p[x + 5] = video_15to32[dat >> 16];
dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1) + 12) & dev->vram_mask]);
p[x + 6] = video_15to32[dat & 0xffff];
p[x + 7] = video_15to32[dat >> 16];
}
dev->ma += (x << 1);
dev->ma &= dev->vram_mask;
}
}
void
ibm8514_render_16bpp(svga_t *svga)
{
ibm8514_t *dev = &svga->dev8514;
int x;
uint32_t *p;
uint32_t dat;
if ((dev->displine + svga->y_add) < 0) {
return;
}
if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) {
p = &buffer32->line[dev->displine + svga->y_add][svga->x_add];
if (dev->firstline_draw == 2000)
dev->firstline_draw = dev->displine;
dev->lastline_draw = dev->displine;
for (x = 0; x <= dev->h_disp; x += 8) {
dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1)) & dev->vram_mask]);
p[x] = video_16to32[dat & 0xffff];
p[x + 1] = video_16to32[dat >> 16];
dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1) + 4) & dev->vram_mask]);
p[x + 2] = video_16to32[dat & 0xffff];
p[x + 3] = video_16to32[dat >> 16];
dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1) + 8) & dev->vram_mask]);
p[x + 4] = video_16to32[dat & 0xffff];
p[x + 5] = video_16to32[dat >> 16];
dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1) + 12) & dev->vram_mask]);
p[x + 6] = video_16to32[dat & 0xffff];
p[x + 7] = video_16to32[dat >> 16];
}
dev->ma += (x << 1);
dev->ma &= dev->vram_mask;
}
}
void
ibm8514_render_24bpp(svga_t *svga)
{
ibm8514_t *dev = &svga->dev8514;
int x;
uint32_t *p;
uint32_t dat;
if ((dev->displine + svga->y_add) < 0)
return;
if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) {
p = &buffer32->line[dev->displine + svga->y_add][svga->x_add];
if (dev->firstline_draw == 2000)
dev->firstline_draw = dev->displine;
dev->lastline_draw = dev->displine;
for (x = 0; x <= dev->h_disp; x += 4) {
dat = *(uint32_t *) (&dev->vram[dev->ma & dev->vram_mask]);
p[x] = dat & 0xffffff;
dat = *(uint32_t *) (&dev->vram[(dev->ma + 3) & dev->vram_mask]);
p[x + 1] = dat & 0xffffff;
dat = *(uint32_t *) (&dev->vram[(dev->ma + 6) & dev->vram_mask]);
p[x + 2] = dat & 0xffffff;
dat = *(uint32_t *) (&dev->vram[(dev->ma + 9) & dev->vram_mask]);
p[x + 3] = dat & 0xffffff;
dev->ma += 12;
}
dev->ma &= dev->vram_mask;
}
}
void
ibm8514_render_BGR(svga_t *svga)
{
ibm8514_t *dev = &svga->dev8514;
int x;
uint32_t *p;
uint32_t dat;
if ((dev->displine + svga->y_add) < 0)
return;
if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) {
p = &buffer32->line[dev->displine + svga->y_add][svga->x_add];
if (dev->firstline_draw == 2000)
dev->firstline_draw = dev->displine;
dev->lastline_draw = dev->displine;
for (x = 0; x <= dev->h_disp; x += 4) {
dat = *(uint32_t *) (&dev->vram[dev->ma & dev->vram_mask]);
p[x] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
dat = *(uint32_t *) (&dev->vram[(dev->ma + 3) & dev->vram_mask]);
p[x + 1] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
dat = *(uint32_t *) (&dev->vram[(dev->ma + 6) & dev->vram_mask]);
p[x + 2] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
dat = *(uint32_t *) (&dev->vram[(dev->ma + 9) & dev->vram_mask]);
p[x + 3] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
dev->ma += 12;
}
dev->ma &= dev->vram_mask;
}
}
void
ibm8514_render_ABGR8888(svga_t *svga)
{
ibm8514_t *dev = &svga->dev8514;
int x;
uint32_t *p;
uint32_t dat;
if ((dev->displine + svga->y_add) < 0)
return;
if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) {
p = &buffer32->line[dev->displine + svga->y_add][svga->x_add];
if (dev->firstline_draw == 2000)
dev->firstline_draw = dev->displine;
dev->lastline_draw = dev->displine;
for (x = 0; x <= dev->h_disp; x++) {
dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 2)) & dev->vram_mask]);
*p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
}
dev->ma += (x * 4);
dev->ma &= dev->vram_mask;
}
}
void
ibm8514_render_RGBA8888(svga_t *svga)
{
ibm8514_t *dev = &svga->dev8514;
int x;
uint32_t *p;
uint32_t dat;
if ((dev->displine + svga->y_add) < 0)
return;
if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) {
p = &buffer32->line[dev->displine + svga->y_add][svga->x_add];
if (dev->firstline_draw == 2000)
dev->firstline_draw = dev->displine;
dev->lastline_draw = dev->displine;
for (x = 0; x <= dev->h_disp; x++) {
dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 2)) & dev->vram_mask]);
*p++ = dat >> 8;
}
dev->ma += (x * 4);
dev->ma &= dev->vram_mask;
}
}
static void
ibm8514_render_overscan_left(ibm8514_t *dev, svga_t *svga)
{
@@ -3828,7 +4024,18 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga)
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 == (svga->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) {
@@ -3841,6 +4048,9 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga)
video_wait_for_buffer();
}
if (dev->hwcursor_on)
dev->changedvram[dev->ma >> 12] = dev->changedvram[(dev->ma >> 12) + 1] = dev->interlace ? 3 : 2;
svga->render(svga);
svga->x_add = (overscan_x >> 1);
@@ -3848,6 +4058,14 @@ ibm8514_poll(ibm8514_t *dev, svga_t *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;
}
@@ -3855,10 +4073,15 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga)
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;
dev->linepos = 0;
@@ -3872,13 +4095,13 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga)
dev->ma = dev->maback;
} else {
dev->sc++;
dev->sc &= 31;
dev->sc &= 0x1f;
dev->ma = dev->maback;
}
}
dev->vc++;
dev->vc &= 2047;
dev->vc &= 0x7ff;
if (dev->vc == dev->dispend) {
dev->dispon = 0;
@@ -3893,6 +4116,7 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga)
}
if (dev->vc == dev->v_syncstart) {
dev->dispon = 0;
svga->cgastat |= 8;
x = dev->h_disp;
if (dev->interlace && !dev->oddeven)
@@ -3914,6 +4138,7 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga)
dev->oddeven ^= 1;
changeframecount = dev->interlace ? 3 : 2;
svga->vslines = 0;
if (dev->interlace && dev->oddeven)
dev->ma = dev->maback = (dev->rowoffset << 1);
@@ -3930,6 +4155,9 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga)
dev->displine = (dev->interlace && dev->oddeven) ? 1 : 0;
svga->x_add = (overscan_x >> 1);
dev->hwcursor_on = 0;
dev->hwcursor_latch = dev->hwcursor;
}
}
}
@@ -3948,19 +4176,17 @@ ibm8514_recalctimings(svga_t *svga)
dev->rowcount = !!(dev->disp_cntl & 0x08);
dev->dispend = ((dev->vdisp >> 1) + 1);
if (dev->dispend == 766)
dev->dispend = 768;
dev->dispend += 2;
if (dev->dispend == 598)
dev->dispend = 600;
dev->dispend += 2;
if (dev->accel.advfunc_cntl & 4) {
if (!vga_on && dev->ibm_mode) {
if (dev->h_disp == 8) {
dev->h_disp = 1024;
dev->dispend = 768;
dev->v_total = 1536;
dev->v_syncstart = 1536;
}
if (dev->h_disp == 8) {
dev->h_disp = 1024;
dev->dispend = 768;
dev->v_total = 1536;
dev->v_syncstart = 1536;
}
if (dev->dispend == 598)
@@ -3975,20 +4201,14 @@ ibm8514_recalctimings(svga_t *svga)
dev->v_total >>= 1;
}
if (ibm8514_has_vga) {
dev->pitch = dev->ext_pitch;
dev->rowoffset = dev->ext_crt_pitch;
} else
dev->rowoffset = 128;
dev->rowoffset = 0x80;
ibm8514_log("1024x768 clock mode, hdisp = %d, htotal = %d, vtotal = %d, vsyncstart = %d, interlace = %02x\n", dev->h_disp, dev->h_total, dev->v_total, dev->v_syncstart, dev->interlace);
svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
} else {
if (!vga_on && dev->ibm_mode) {
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 (dev->interlace) {
@@ -4000,11 +4220,7 @@ ibm8514_recalctimings(svga_t *svga)
dev->v_total >>= 1;
}
if (ibm8514_has_vga) {
dev->pitch = dev->ext_pitch;
dev->rowoffset = dev->ext_crt_pitch;
} else
dev->rowoffset = 128;
dev->rowoffset = 0x80;
svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
}
@@ -4059,15 +4275,14 @@ ibm8514_init(const device_t *info)
dev->vram = calloc(dev->vram_size, 1);
dev->changedvram = calloc(dev->vram_size >> 12, 1);
dev->vram_mask = dev->vram_size - 1;
dev->map8 = svga->pallook;
dev->map8 = dev->pallook;
dev->type = info->flags;
dev->ibm_mode = 1;
dev->bpp = 8;
dev->bpp = 0;
ibm8514_io_set(svga);
if (info->flags & DEVICE_MCA) {
if (dev->type & DEVICE_MCA) {
dev->pos_regs[0] = 0x7f;
dev->pos_regs[1] = 0xef;
mca_add(ibm8514_mca_read, ibm8514_mca_write, ibm8514_mca_feedb, NULL, svga);

View File

@@ -65,22 +65,22 @@ typedef struct ati68860_ramdac_t {
} ati68860_ramdac_t;
void
ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga)
ati68860_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga)
{
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv;
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p;
switch (addr) {
case 0:
svga_out(0x3c8, val, svga);
svga_out(ibm8514_on ? 0x2ec : 0x3c8, val, svga);
break;
case 1:
svga_out(0x3c9, val, svga);
svga_out(ibm8514_on ? 0x2ed : 0x3c9, val, svga);
break;
case 2:
svga_out(0x3c6, val, svga);
svga_out(ibm8514_on ? 0x2ea : 0x3c6, val, svga);
break;
case 3:
svga_out(0x3c7, val, svga);
svga_out(ibm8514_on ? 0x2eb : 0x3c7, val, svga);
break;
default:
ramdac->regs[addr & 0xf] = val;
@@ -168,23 +168,23 @@ ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga)
}
uint8_t
ati68860_ramdac_in(uint16_t addr, void *priv, svga_t *svga)
ati68860_ramdac_in(uint16_t addr, void *p, svga_t *svga)
{
const ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv;
uint8_t temp = 0;
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p;
uint8_t temp = 0;
switch (addr) {
case 0:
temp = svga_in(0x3c8, svga);
temp = svga_in(ibm8514_on ? 0x2ec : 0x3c8, svga);
break;
case 1:
temp = svga_in(0x3c9, svga);
temp = svga_in(ibm8514_on ? 0x2ed : 0x3c9, svga);
break;
case 2:
temp = svga_in(0x3c6, svga);
temp = svga_in(ibm8514_on ? 0x2ea : 0x3c6, svga);
break;
case 3:
temp = svga_in(0x3c7, svga);
temp = svga_in(ibm8514_on ? 0x2eb : 0x3c7, svga);
break;
case 4:
case 8:
@@ -207,9 +207,9 @@ ati68860_ramdac_in(uint16_t addr, void *priv, svga_t *svga)
}
void
ati68860_set_ramdac_type(void *priv, int type)
ati68860_set_ramdac_type(void *p, int type)
{
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv;
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p;
if (ramdac->ramdac_type != type) {
ramdac->ramdac_type = type;
@@ -237,17 +237,17 @@ ati68860_ramdac_init(UNUSED(const device_t *info))
}
void
ati68860_ramdac_set_render(void *priv, svga_t *svga)
ati68860_ramdac_set_render(void *p, svga_t *svga)
{
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv;
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p;
svga->render = ramdac->render;
}
void
ati68860_ramdac_set_pallook(void *priv, int i, uint32_t col)
ati68860_ramdac_set_pallook(void *p, int i, uint32_t col)
{
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv;
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p;
ramdac->pallook[i] = col;
}
@@ -255,11 +255,11 @@ ati68860_ramdac_set_pallook(void *priv, int i, uint32_t col)
void
ati68860_hwcursor_draw(svga_t *svga, int displine)
{
const ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac;
int offset;
uint8_t dat;
uint32_t col0 = ramdac->pallook[0];
uint32_t col1 = ramdac->pallook[1];
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac;
int offset;
uint8_t dat;
uint32_t col0 = ramdac->pallook[0];
uint32_t col1 = ramdac->pallook[1];
offset = svga->dac_hwcursor_latch.xoff;
for (uint32_t x = 0; x < 64 - svga->dac_hwcursor_latch.xoff; x += 4) {

View File

@@ -0,0 +1,219 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Emulation of the Mach32-compatible ATI 68875 RAMDAC and clones.
*
*
*
* Authors: TheCollector1995.
*
* Copyright 2022-2023 TheCollector1995.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/timer.h>
#include <86box/video.h>
#include <86box/vid_svga.h>
#include <86box/vid_svga_render.h>
typedef struct ati68875_ramdac_t {
uint8_t gen_cntl;
uint8_t in_clk_sel;
uint8_t out_clk_sel;
uint8_t mux_cntl;
uint8_t palette_page_sel;
uint8_t test_reg;
} ati68875_ramdac_t;
static void
ati68875_set_bpp(ati68875_ramdac_t *ramdac, svga_t *svga)
{
if (ramdac->mux_cntl == 0xff)
return;
if (ramdac->mux_cntl & 0x20)
svga->bpp = 8;
else {
svga->bpp = 24;
}
svga_recalctimings(svga);
}
void
ati68875_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t *svga)
{
ati68875_ramdac_t *ramdac = (ati68875_ramdac_t *) p;
uint8_t rs = (addr & 0x03);
rs |= (!!rs2 << 2);
rs |= (!!rs3 << 3);
switch (rs) {
case 0x00: /* Palette Write Index Register (RS value = 0000) */
case 0x01: /* Palette Data Register (RS value = 0001) */
case 0x02: /* Pixel Read Mask Register (RS value = 0010) */
case 0x03:
svga_out(addr, val, svga);
break;
case 0x08: /* General Control Register (RS value = 1000) */
ramdac->gen_cntl = val;
break;
case 0x09: /* Input Clock Selection Register (RS value = 1001) */
ramdac->in_clk_sel = val;
break;
case 0x0a: /* Output Clock Selection Register (RS value = 1010) */
ramdac->out_clk_sel = val;
break;
case 0x0b: /* MUX Control Register (RS value = 1011) */
ramdac->mux_cntl = val;
ati68875_set_bpp(ramdac, svga);
break;
case 0x0c: /* Palette Page Register (RS value = 1100) */
ramdac->palette_page_sel = val;
break;
case 0x0e: /* Test Register (RS value = 1110) */
ramdac->test_reg = val;
break;
case 0x0f: /* Reset State (RS value = 1111) */
ramdac->mux_cntl = 0x2d;
svga->bpp = 8;
svga_recalctimings(svga);
break;
}
return;
}
uint8_t
ati68875_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga)
{
ati68875_ramdac_t *ramdac = (ati68875_ramdac_t *) p;
ibm8514_t *dev = &svga->dev8514;
uint8_t rs = (addr & 0x03);
uint8_t temp = 0;
rs |= (!!rs2 << 2);
rs |= (!!rs3 << 3);
switch (rs) {
case 0x00: /* Palette Write Index Register (RS value = 0000) */
case 0x01: /* Palette Data Register (RS value = 0001) */
case 0x02: /* Pixel Read Mask Register (RS value = 0010) */
case 0x03:
temp = svga_in(addr, svga);
break;
case 0x08: /* General Control Register (RS value = 1000) */
temp = ramdac->gen_cntl;
break;
case 0x09: /* Input Clock Selection Register (RS value = 1001) */
temp = ramdac->in_clk_sel;
break;
case 0x0a: /* Output Clock Selection Register (RS value = 1010) */
temp = ramdac->out_clk_sel;
break;
case 0x0b: /* MUX Control Register (RS value = 1011) */
temp = ramdac->mux_cntl;
break;
case 0x0c: /* Palette Page Register (RS value = 1100) */
temp = ramdac->palette_page_sel;
break;
case 0x0e: /* Test Register (RS value = 1110) */
switch (ramdac->test_reg & 0x07) {
case 0x00:
temp = ibm8514_on ? dev->dac_r : svga->dac_r;
break;
case 0x01:
temp = ibm8514_on ? dev->dac_g : svga->dac_g;
break;
case 0x02:
temp = ibm8514_on ? dev->dac_b : svga->dac_b;
break;
case 0x03:
temp = 0x75;
break;
case 0x04:
if (ibm8514_on) {
dev->dac_r++;
temp = dev->dac_r;
} else {
svga->dac_r++;
temp = svga->dac_r;
}
break;
case 0x05:
if (ibm8514_on) {
dev->dac_g++;
temp = dev->dac_g;
} else {
svga->dac_g++;
temp = svga->dac_g;
}
break;
case 0x06:
if (ibm8514_on) {
dev->dac_b++;
temp = dev->dac_b;
} else {
svga->dac_b++;
temp = svga->dac_b;
}
break;
case 0x07:
if (ramdac->test_reg & 0x80)
temp = ibm8514_on ? dev->dac_r : svga->dac_r;
else if (ramdac->test_reg & 0x40)
temp = ibm8514_on ? dev->dac_g : svga->dac_g;
else if (ramdac->test_reg & 0x20)
temp = ibm8514_on ? dev->dac_b : svga->dac_b;
break;
}
break;
}
return temp;
}
static void *
ati68875_ramdac_init(const device_t *info)
{
ati68875_ramdac_t *ramdac = (ati68875_ramdac_t *) malloc(sizeof(ati68875_ramdac_t));
memset(ramdac, 0, sizeof(ati68875_ramdac_t));
ramdac->mux_cntl = 0x2d;
return ramdac;
}
static void
ati68875_ramdac_close(void *priv)
{
ati68875_ramdac_t *ramdac = (ati68875_ramdac_t *) priv;
if (ramdac)
free(ramdac);
}
const device_t ati68875_ramdac_device = {
.name = "ATI 68875 RAMDAC",
.internal_name = "ati68875_ramdac",
.flags = 0,
.local = 0,
.init = ati68875_ramdac_init,
.close = ati68875_ramdac_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -439,12 +439,12 @@ mach64_out(uint16_t addr, uint8_t val, void *priv)
svga->crtcreg = val & 0x3f;
return;
case 0x3D5:
if (svga->crtcreg > 0x20)
return;
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80))
return;
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80))
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
if (svga->crtcreg > 0x18)
return;
old = svga->crtc[svga->crtcreg];
svga->crtc[svga->crtcreg] = val;
@@ -454,7 +454,7 @@ mach64_out(uint16_t addr, uint8_t val, void *priv)
svga->fullchange = 3;
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
} else {
svga->fullchange = changeframecount;
svga->fullchange = svga->monitor->mon_changeframecount;
svga_recalctimings(svga);
}
}
@@ -493,7 +493,7 @@ mach64_in(uint16_t addr, void *priv)
case 0x3D4:
return svga->crtcreg;
case 0x3D5:
if (svga->crtcreg > 0x18)
if (svga->crtcreg > 0x20)
return 0xff;
return svga->crtc[svga->crtcreg];
@@ -1521,13 +1521,13 @@ mach64_start_line(mach64_t *mach64)
#define WRITE(addr, width) \
if (width == 0) { \
svga->vram[(addr) &mach64->vram_mask] = dest_dat; \
svga->changedvram[((addr) &mach64->vram_mask) >> 12] = changeframecount; \
svga->changedvram[((addr) &mach64->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \
} else if (width == 1) { \
*(uint16_t *) &svga->vram[((addr) << 1) & mach64->vram_mask] = dest_dat; \
svga->changedvram[(((addr) << 1) & mach64->vram_mask) >> 12] = changeframecount; \
svga->changedvram[(((addr) << 1) & mach64->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \
} else if (width == 2) { \
*(uint32_t *) &svga->vram[((addr) << 2) & mach64->vram_mask] = dest_dat; \
svga->changedvram[(((addr) << 2) & mach64->vram_mask) >> 12] = changeframecount; \
svga->changedvram[(((addr) << 2) & mach64->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \
} else { \
if (dest_dat & 1) { \
if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) \
@@ -1540,7 +1540,7 @@ mach64_start_line(mach64_t *mach64)
else \
svga->vram[((addr) >> 3) & mach64->vram_mask] &= ~(1 << (7 - ((addr) &7))); \
} \
svga->changedvram[(((addr) >> 3) & mach64->vram_mask) >> 12] = changeframecount; \
svga->changedvram[(((addr) >> 3) & mach64->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \
}
void
@@ -3069,7 +3069,7 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv)
case 0x17:
WRITE8(addr, mach64->crtc_off_pitch, val);
svga_recalctimings(&mach64->svga);
svga->fullchange = changeframecount;
svga->fullchange = svga->monitor->mon_changeframecount;
break;
case 0x18:
@@ -4541,7 +4541,7 @@ mach64_force_redraw(void *priv)
{
mach64_t *mach64 = (mach64_t *) priv;
mach64->svga.fullchange = changeframecount;
mach64->svga.fullchange = mach64->svga.monitor->mon_changeframecount;
}
// clang-format off

File diff suppressed because it is too large Load Diff

View File

@@ -500,7 +500,8 @@ et4000w32p_recalctimings(svga_t *svga)
switch (svga->bpp) {
case 15:
case 16:
svga->hdisp >>= 1;
if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1))
svga->hdisp >>= 1;
if (et4000->type <= ET4000W32P_REVC) {
if (et4000->type == ET4000W32P_REVC) {
if (svga->hdisp != 1024)
@@ -513,7 +514,7 @@ et4000w32p_recalctimings(svga_t *svga)
svga->hdisp /= 3;
if (et4000->type <= ET4000W32P_REVC)
et4000->adjust_cursor = 2;
if (et4000->type == ET4000W32P_DIAMOND && (svga->hdisp == 640 / 2 || svga->hdisp == 1232)) {
if ((et4000->type == ET4000W32P_DIAMOND) && ((svga->hdisp == (640 / 2)) || (svga->hdisp == 1232))) {
svga->hdisp = 640;
}
break;
@@ -1072,8 +1073,7 @@ et4000w32p_mmu_read(uint32_t addr, void *priv)
case 0x8e:
if (et4000->type >= ET4000W32P_REVC)
return et4000->acl.internal.pixel_depth;
else
return et4000->acl.internal.vbus;
return et4000->acl.internal.vbus;
case 0x8f:
return et4000->acl.internal.xy_dir;
case 0x90:

View File

@@ -49,9 +49,9 @@ ics2494_log(const char *fmt, ...)
#endif
float
ics2494_getclock(int clock, void *priv)
ics2494_getclock(int clock, void *p)
{
const ics2494_t *ics2494 = (ics2494_t *) priv;
ics2494_t *ics2494 = (ics2494_t *) p;
if (clock > 15)
clock = 15;
@@ -66,6 +66,63 @@ ics2494_init(const device_t *info)
memset(ics2494, 0, sizeof(ics2494_t));
switch (info->local) {
case 10:
/* ATI 18810 for ATI 28800 */
ics2494->freq[0x0] = 30240000.0;
ics2494->freq[0x1] = 32000000.0;
ics2494->freq[0x2] = 37500000.0;
ics2494->freq[0x3] = 39000000.0;
ics2494->freq[0x4] = 42954000.0;
ics2494->freq[0x5] = 48771000.0;
ics2494->freq[0x6] = 16657000.0;
ics2494->freq[0x7] = 36000000.0;
ics2494->freq[0x8] = 40000000.0;
ics2494->freq[0x9] = 56644000.0;
ics2494->freq[0xa] = 75000000.0;
ics2494->freq[0xb] = 65000000.0;
ics2494->freq[0xc] = 50350000.0;
ics2494->freq[0xd] = 56640000.0;
ics2494->freq[0xe] = 28322000.0;
ics2494->freq[0xf] = 44900000.0;
break;
case 110:
/* ATI 18811-0 for ATI Mach32 */
ics2494->freq[0x0] = 30240000.0;
ics2494->freq[0x1] = 32000000.0;
ics2494->freq[0x2] = 110000000.0;
ics2494->freq[0x3] = 80000000.0;
ics2494->freq[0x4] = 42954000.0;
ics2494->freq[0x5] = 48771000.0;
ics2494->freq[0x6] = 92400000.0;
ics2494->freq[0x7] = 36000000.0;
ics2494->freq[0x8] = 39910000.0;
ics2494->freq[0x9] = 44900000.0;
ics2494->freq[0xa] = 75000000.0;
ics2494->freq[0xb] = 65000000.0;
ics2494->freq[0xc] = 50350000.0;
ics2494->freq[0xd] = 56640000.0;
ics2494->freq[0xe] = 0.0;
ics2494->freq[0xf] = 44900000.0;
break;
case 111:
/* ATI 18811-1 for ATI Mach32 MCA */
ics2494->freq[0x0] = 135000000.0;
ics2494->freq[0x1] = 32000000.0;
ics2494->freq[0x2] = 110000000.0;
ics2494->freq[0x3] = 80000000.0;
ics2494->freq[0x4] = 100000000.0;
ics2494->freq[0x5] = 126000000.0;
ics2494->freq[0x6] = 92400000.0;
ics2494->freq[0x7] = 36000000.0;
ics2494->freq[0x8] = 39910000.0;
ics2494->freq[0x9] = 44900000.0;
ics2494->freq[0xa] = 75000000.0;
ics2494->freq[0xb] = 65000000.0;
ics2494->freq[0xc] = 50350000.0;
ics2494->freq[0xd] = 56640000.0;
ics2494->freq[0xe] = 0.0;
ics2494->freq[0xf] = 44900000.0;
break;
case 305:
/* ICS2494A(N)-205 for S3 86C924 */
ics2494->freq[0x0] = 25175000.0;
@@ -85,9 +142,6 @@ ics2494_init(const device_t *info)
ics2494->freq[0xe] = 75000000.0;
ics2494->freq[0xf] = 94500000.0;
break;
default:
break;
}
return ics2494;
@@ -115,3 +169,45 @@ const device_t ics2494an_305_device = {
.force_redraw = NULL,
.config = NULL
};
const device_t ati18810_device = {
.name = "ATI 18810 Clock Generator",
.internal_name = "ati18810",
.flags = 0,
.local = 10,
.init = ics2494_init,
.close = ics2494_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t ati18811_0_device = {
.name = "ATI 18811-0 Clock Generator",
.internal_name = "ati18811_0",
.flags = 0,
.local = 110,
.init = ics2494_init,
.close = ics2494_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t ati18811_1_device = {
.name = "ATI 18811-1 Clock Generator",
.internal_name = "ati18811_1",
.flags = 0,
.local = 111,
.init = ics2494_init,
.close = ics2494_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -84,8 +84,9 @@ oti_out(uint16_t addr, uint8_t val, void *priv)
if (!oti->chip_id) {
oti->enable_register = val & 1;
return;
} else
break;
}
svga_out(addr, val, svga);
return;
case 0x3c6:
case 0x3c7:

View File

@@ -111,10 +111,48 @@ void
svga_out(uint16_t addr, uint8_t val, void *priv)
{
svga_t *svga = (svga_t *) priv;
ibm8514_t *dev = &svga->dev8514;
xga_t *xga = &svga->xga;
uint8_t o;
uint8_t index;
switch (addr) {
case 0x2ea:
dev->dac_mask = val;
break;
case 0x2eb:
case 0x2ec:
dev->dac_pos = 0;
dev->dac_status = addr & 0x03;
dev->dac_addr = (val + (addr & 0x01)) & 0xff;
break;
case 0x2ed:
svga->fullchange = svga->monitor->mon_changeframecount;
switch (dev->dac_pos) {
case 0:
dev->dac_r = val;
dev->dac_pos++;
break;
case 1:
dev->dac_g = val;
dev->dac_pos++;
break;
case 2:
index = dev->dac_addr & 0xff;
dev->dac_b = val;
svga->vgapal[index].r = dev->dac_r;
svga->vgapal[index].g = dev->dac_g;
svga->vgapal[index].b = dev->dac_b;
if (svga->ramdac_type == RAMDAC_8BIT)
dev->pallook[index] = makecol32(svga->vgapal[index].r, svga->vgapal[index].g, svga->vgapal[index].b);
else
dev->pallook[index] = makecol32(video_6to8[svga->vgapal[index].r & 0x3f], video_6to8[svga->vgapal[index].g & 0x3f], video_6to8[svga->vgapal[index].b & 0x3f]);
dev->dac_pos = 0;
dev->dac_addr = (dev->dac_addr + 1) & 0xff;
break;
}
break;
case 0x3c0:
case 0x3c1:
if (!svga->attrff) {
@@ -167,10 +205,12 @@ svga_out(uint16_t addr, uint8_t val, void *priv)
svga_recalctimings(svga);
break;
case 0x3c3:
if (xga_enabled) {
svga->xga.on = (val & 0x01) ? 0 : 1;
vga_on = !svga->xga.on;
}
if (xga_enabled)
xga->on = (val & 0x01) ? 0 : 1;
if (ibm8514_enabled)
ibm8514_on = (val & 0x01) ? 0 : 1;
vga_on = val & 0x01;
break;
case 0x3c4:
svga->seqaddr = val;
@@ -210,19 +250,15 @@ svga_out(uint16_t addr, uint8_t val, void *priv)
break;
}
break;
case 0x2ea:
case 0x3c6:
svga->dac_mask = val;
break;
case 0x2eb:
case 0x2ec:
case 0x3c7:
case 0x3c8:
svga->dac_pos = 0;
svga->dac_status = addr & 0x03;
svga->dac_addr = (val + (addr & 0x01)) & 255;
break;
case 0x2ed:
case 0x3c9:
if (svga->adv_flags & FLAG_RAMDAC_SHIFT)
val <<= 2;
@@ -238,9 +274,10 @@ svga_out(uint16_t addr, uint8_t val, void *priv)
break;
case 2:
index = svga->dac_addr & 255;
svga->dac_b = val;
svga->vgapal[index].r = svga->dac_r;
svga->vgapal[index].g = svga->dac_g;
svga->vgapal[index].b = val;
svga->vgapal[index].b = svga->dac_b;
if (svga->ramdac_type == RAMDAC_8BIT)
svga->pallook[index] = makecol32(svga->vgapal[index].r, svga->vgapal[index].g, svga->vgapal[index].b);
else
@@ -317,10 +354,51 @@ uint8_t
svga_in(uint16_t addr, void *priv)
{
svga_t *svga = (svga_t *) priv;
ibm8514_t *dev = &svga->dev8514;
uint8_t index;
uint8_t ret = 0xff;
switch (addr) {
case 0x2ea:
ret = dev->dac_mask;
break;
case 0x2eb:
ret = dev->dac_status;
break;
case 0x2ec:
ret = dev->dac_addr;
break;
case 0x2ed:
index = (dev->dac_addr - 1) & 0xff;
switch (dev->dac_pos) {
case 0:
dev->dac_pos++;
if (svga->ramdac_type == RAMDAC_8BIT)
ret = svga->vgapal[index].r;
else
ret = svga->vgapal[index].r & 0x3f;
break;
case 1:
dev->dac_pos++;
if (svga->ramdac_type == RAMDAC_8BIT)
ret = svga->vgapal[index].g;
else
ret = svga->vgapal[index].g & 0x3f;
break;
case 2:
dev->dac_pos = 0;
dev->dac_addr = (dev->dac_addr + 1) & 0xff;
if (svga->ramdac_type == RAMDAC_8BIT)
ret = svga->vgapal[index].b;
else
ret = svga->vgapal[index].b & 0x3f;
break;
default:
break;
}
break;
case 0x3c0:
ret = svga->attraddr | svga->attr_palette_enable;
break;
@@ -333,25 +411,24 @@ svga_in(uint16_t addr, void *priv)
else
ret = 0x10;
break;
case 0x3c3:
ret = vga_on;
break;
case 0x3c4:
ret = svga->seqaddr;
break;
case 0x3c5:
ret = svga->seqregs[svga->seqaddr & 0x0f];
break;
case 0x2ea:
case 0x3c6:
ret = svga->dac_mask;
break;
case 0x2eb:
case 0x3c7:
ret = svga->dac_status;
break;
case 0x2ec:
case 0x3c8:
ret = svga->dac_addr;
break;
case 0x2ed:
case 0x3c9:
index = (svga->dac_addr - 1) & 255;
switch (svga->dac_pos) {
@@ -432,16 +509,27 @@ svga_in(uint16_t addr, void *priv)
void
svga_set_ramdac_type(svga_t *svga, int type)
{
ibm8514_t *dev = &svga->dev8514;
if (svga->ramdac_type != type) {
svga->ramdac_type = type;
for (int c = 0; c < 256; c++) {
if (svga->ramdac_type == RAMDAC_8BIT)
svga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b);
else
svga->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4,
(svga->vgapal[c].g & 0x3f) * 4,
(svga->vgapal[c].b & 0x3f) * 4);
if (ibm8514_on) {
if (svga->ramdac_type == RAMDAC_8BIT)
dev->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b);
else
dev->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4,
(svga->vgapal[c].g & 0x3f) * 4,
(svga->vgapal[c].b & 0x3f) * 4);
} else {
if (svga->ramdac_type == RAMDAC_8BIT)
svga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b);
else
svga->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4,
(svga->vgapal[c].g & 0x3f) * 4,
(svga->vgapal[c].b & 0x3f) * 4);
}
}
}
}
@@ -449,6 +537,8 @@ svga_set_ramdac_type(svga_t *svga, int type)
void
svga_recalctimings(svga_t *svga)
{
ibm8514_t *dev = &svga->dev8514;
xga_t *xga = &svga->xga;
double crtcconst;
double _dispontime;
double _dispofftime;
@@ -495,7 +585,7 @@ svga_recalctimings(svga_t *svga)
svga->htotal = svga->crtc[0];
/* +5 has been verified by Sergi to be correct - +6 must have been an off by one error. */
svga->htotal += 5; /*+6 is required for Tyrian*/
svga->htotal += 5; /*+5 is required for Tyrian*/
svga->rowoffset = svga->crtc[0x13];
@@ -612,23 +702,18 @@ svga_recalctimings(svga_t *svga)
} else
svga->monitor->mon_overscan_x = 16;
if (vga_on) {
if (svga->recalctimings_ex) {
svga->recalctimings_ex(svga);
}
} else {
if (ibm8514_enabled) {
if (svga->dev8514.local) {
if (svga->recalctimings_ex) {
svga->recalctimings_ex(svga);
}
} else
ibm8514_recalctimings(svga);
}
if (xga_enabled)
xga_recalctimings(svga);
if (svga->recalctimings_ex) {
svga->recalctimings_ex(svga);
}
if (ibm8514_enabled) {
if (!dev->local)
ibm8514_recalctimings(svga);
}
if (xga_enabled)
xga_recalctimings(svga);
if (svga->hdisp >= 2048)
svga->monitor->mon_overscan_x = 0;
@@ -640,9 +725,9 @@ svga_recalctimings(svga_t *svga)
crtcconst = svga->clock * svga->char_width;
if (ibm8514_on && !svga->dev8514.local) {
disptime = svga->dev8514.h_total;
_dispontime = svga->dev8514.h_disp;
if (ibm8514_on) {
disptime = dev->h_total;
_dispontime = dev->h_disp;
} else {
disptime = svga->htotal;
_dispontime = svga->hdisp_time;
@@ -727,21 +812,19 @@ svga_poll(void *priv)
{
svga_t *svga = (svga_t *) priv;
ibm8514_t *dev = &svga->dev8514;
xga_t *xga = &svga->xga;
uint32_t x;
uint32_t blink_delay;
int wx;
int wy;
int ret;
int old_ma;
int linecountff = 0;
if (!vga_on && ibm8514_enabled && ibm8514_on) {
if (!dev->local) {
ibm8514_poll(dev, svga);
return;
}
} else if (!vga_on && xga_enabled && svga->xga.on) {
xga_poll(&svga->xga, svga);
if (ibm8514_enabled && ibm8514_on) {
ibm8514_poll(dev, svga);
return;
} else if (xga_enabled && xga->on) {
xga_poll(xga, svga);
return;
}
@@ -835,14 +918,8 @@ svga_poll(void *priv)
if ((svga->sc == (svga->crtc[11] & 31)) || (svga->sc == svga->rowcount))
svga->con = 0;
if (svga->dispon) {
/*Real IBM 8514/A or compatibility mode doesn't have linedbl, so skip those.*/
if (dev->local && ibm8514_on) {
svga->linedbl = 0;
svga->linecountff = 0;
linecountff = 1;
}
if (svga->linedbl && !svga->linecountff && !linecountff) {
svga->linecountff = 1;
if (svga->linedbl && !svga->linecountff) {
svga->linecountff = 1;
svga->ma = svga->maback;
} else if (svga->sc == svga->rowcount) {
svga->linecountff = 0;
@@ -949,17 +1026,11 @@ svga_poll(void *priv)
svga->monitor->mon_changeframecount = svga->interlace ? 3 : 2;
svga->vslines = 0;
if ((dev->local && vga_on) || !dev->local) {
if (svga->interlace && svga->oddeven)
svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5);
else
svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[5] & 0x60) >> 5);
} else if (dev->local && ibm8514_on) {
if (svga->interlace && svga->oddeven)
svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1);
else
svga->ma = svga->maback = svga->ma_latch;
}
if (svga->interlace && svga->oddeven)
svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5);
else
svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[5] & 0x60) >> 5);
svga->ca = ((svga->crtc[0xe] << 8) | svga->crtc[0xf]) + ((svga->crtc[0xb] & 0x60) >> 5) + svga->ca_adj;
svga->ma = (svga->ma << 2);
svga->maback = (svga->maback << 2);
@@ -974,24 +1045,22 @@ svga_poll(void *priv)
svga->dispon = 1;
svga->displine = (svga->interlace && svga->oddeven) ? 1 : 0;
if (!ibm8514_on) {
svga->scrollcache = (svga->attrregs[0x13] & 0x0f);
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/
if (svga->seqregs[1] & 1)
svga->scrollcache &= 0x07;
else {
svga->scrollcache++;
if (svga->scrollcache > 8)
svga->scrollcache = 0;
}
} else if ((svga->render == svga_render_2bpp_lowres) || (svga->render == svga_render_2bpp_highres) || (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres))
svga->scrollcache = (svga->attrregs[0x13] & 0x0f);
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/
if (svga->seqregs[1] & 1)
svga->scrollcache &= 0x07;
else
svga->scrollcache = (svga->scrollcache & 0x06) >> 1;
else {
svga->scrollcache++;
if (svga->scrollcache > 8)
svga->scrollcache = 0;
}
} else if ((svga->render == svga_render_2bpp_lowres) || (svga->render == svga_render_2bpp_highres) || (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres))
svga->scrollcache &= 0x07;
else
svga->scrollcache = (svga->scrollcache & 0x06) >> 1;
if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres))
svga->scrollcache <<= 1;
}
if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres))
svga->scrollcache <<= 1;
svga->x_add = (svga->monitor->mon_overscan_x >> 1) - svga->scrollcache;
@@ -1152,7 +1221,7 @@ static __inline void
svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv)
{
svga_t *svga = (svga_t *) priv;
xga_t *xga = &svga->xga;
int writemask2 = svga->writemask;
int reset_wm = 0;
latch_t vall;
@@ -1167,23 +1236,23 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv)
if (!linear) {
if (xga_enabled) {
if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl >= 1)) {
if (((xga->op_mode & 7) >= 4) && (xga->aperture_cntl >= 1)) {
if (val == 0xa5) { /*Memory size test of XGA*/
svga->xga.test = val;
svga->xga.a5_test = 1;
xga->test = val;
xga->a5_test = 1;
return;
} else if (val == 0x5a) {
svga->xga.test = val;
xga->test = val;
return;
} else if ((val == 0x12) || (val == 0x34)) {
addr += svga->xga.write_bank;
svga->xga.vram[addr & svga->xga.vram_mask] = val;
svga->xga.linear_endian_reverse = 1;
addr += xga->write_bank;
xga->vram[addr & xga->vram_mask] = val;
xga->linear_endian_reverse = 1;
return;
}
} else {
svga->xga.on = 0;
vga_on = !svga->xga.on;
xga->on = 0;
vga_on = 1;
}
}
addr = svga_decode_addr(svga, addr, 1);
@@ -1368,6 +1437,7 @@ static __inline uint8_t
svga_read_common(uint32_t addr, uint8_t linear, void *priv)
{
svga_t *svga = (svga_t *) priv;
xga_t *xga = &svga->xga;
uint32_t latch_addr = 0;
int readplane = svga->readplane;
uint8_t count;
@@ -1381,22 +1451,22 @@ svga_read_common(uint32_t addr, uint8_t linear, void *priv)
if (!linear) {
if (xga_enabled) {
if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl >= 1)) {
if (svga->xga.test == 0xa5) { /*Memory size test of XGA*/
svga->xga.on = 1;
vga_on = !svga->xga.on;
return svga->xga.test;
} else if (svga->xga.test == 0x5a) {
svga->xga.on = 1;
vga_on = !svga->xga.on;
return svga->xga.test;
if (((xga->op_mode & 7) >= 4) && (xga->aperture_cntl >= 1)) {
if (xga->test == 0xa5) { /*Memory size test of XGA*/
xga->on = 1;
vga_on = 0;
return xga->test;
} else if (xga->test == 0x5a) {
xga->on = 1;
vga_on = 0;
return xga->test;
} else if ((addr == 0xa0000) || (addr == 0xa0010)) {
addr += svga->xga.read_bank;
return svga->xga.vram[addr & svga->xga.vram_mask];
addr += xga->read_bank;
return xga->vram[addr & xga->vram_mask];
}
} else {
svga->xga.on = 0;
vga_on = !svga->xga.on;
xga->on = 0;
vga_on = 1;
}
}
addr = svga_decode_addr(svga, addr, 0);
@@ -1617,7 +1687,7 @@ svga_writeb_linear(uint32_t addr, uint8_t val, void *priv)
return;
addr &= svga->vram_mask;
svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount;
*&svga->vram[addr] = val;
svga->vram[addr] = val;
}
void
@@ -1752,7 +1822,7 @@ svga_readb_linear(uint32_t addr, void *priv)
if (addr >= svga->vram_max)
return 0xff;
return *&svga->vram[addr & svga->vram_mask];
return svga->vram[addr & svga->vram_mask];
}
uint16_t

View File

@@ -154,6 +154,7 @@ video_cards[] = {
{ &vga_device },
{ &v7_vga_1024i_device },
{ &wy700_device },
{ &mach32_mca_device, VIDEO_FLAG_TYPE_8514 },
{ &gd5426_mca_device },
{ &gd5428_mca_device },
{ &et4000_mca_device },
@@ -343,9 +344,9 @@ video_reset(int card)
monitor_index_global = 0;
loadfont("roms/video/mda/mda.rom", 0);
if (!(card == VID_NONE)
if ((card != VID_NONE)
&& !machine_has_flags(machine, MACHINE_VIDEO_ONLY)
&& gfxcard[1] != 0
&& (gfxcard[1] != 0)
&& device_is_valid(video_card_getdevice(gfxcard[1]), machine)) {
video_monitor_init(1);
monitor_index_global = 1;
@@ -354,7 +355,7 @@ video_reset(int card)
}
/* Do not initialize internal cards here. */
if (!(card == VID_NONE) && !(card == VID_INTERNAL) && !machine_has_flags(machine, MACHINE_VIDEO_ONLY)) {
if ((card != VID_NONE) && (card != VID_INTERNAL) && !machine_has_flags(machine, MACHINE_VIDEO_ONLY)) {
vid_table_log("VIDEO: initializing '%s'\n", video_cards[card].device->name);
video_prepare();
@@ -369,14 +370,24 @@ video_reset(int card)
void
video_post_reset(void)
{
if (gfxcard[0] != VID_NONE) {
if (ibm8514_enabled) {
if (gfxcard[0] == VID_INTERNAL)
ibm8514_has_vga = (video_get_type_monitor(0) == VIDEO_FLAG_TYPE_8514);
else if (gfxcard[0] != VID_NONE)
ibm8514_has_vga = (video_card_get_flags(gfxcard[0]) == VIDEO_FLAG_TYPE_8514);
else
ibm8514_has_vga = 0;
if (ibm8514_has_vga)
ibm8514_enabled = 1;
if (ibm8514_enabled) {
if (!ibm8514_has_vga)
ibm8514_device_add();
}
if (xga_enabled)
xga_device_add();
}
if (xga_enabled)
xga_device_add();
/* Reset the graphics card (or do nothing if it was already done
by the machine's init function). */
video_reset(gfxcard[0]);

View File

@@ -6,7 +6,7 @@
*
* This file is part of the 86Box distribution.
*
* Trident TGUI9400CXi and TGUI9440 emulation.
* Trident TGUI9400CXi and TGUI9440/96x0 emulation.
*
* TGUI9400CXi has extended write modes, controlled by extended
* GDC registers :
@@ -223,11 +223,10 @@ tgui_update_irqs(tgui_t *tgui)
if (!tgui->pci)
return;
if (!(tgui->oldctrl1 & 0x40)) {
if (!(tgui->oldctrl1 & 0x40))
pci_set_irq(tgui->pci_slot, PCI_INTA, &tgui->irq_state);
} else {
else
pci_clear_irq(tgui->pci_slot, PCI_INTA, &tgui->irq_state);
}
}
static void
@@ -500,7 +499,7 @@ tgui_out(uint16_t addr, uint8_t val, void *priv)
svga->fullchange = 3;
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
} else {
svga->fullchange = changeframecount;
svga->fullchange = svga->monitor->mon_changeframecount;
svga_recalctimings(svga);
}
}
@@ -629,7 +628,6 @@ void
tgui_recalctimings(svga_t *svga)
{
tgui_t *tgui = (tgui_t *) svga->priv;
uint8_t ger22lower = tgui->accel.ger22 & 0xff;
uint8_t ger22upper = (tgui->accel.ger22 >> 8);
if (!svga->rowoffset)
@@ -638,13 +636,8 @@ tgui_recalctimings(svga_t *svga)
if (svga->crtc[0x29] & 0x10)
svga->rowoffset |= 0x100;
if ((tgui->type >= TGUI_9440) && (svga->bpp >= 24)) {
if ((tgui->accel.bpp == 0) && (ger22lower != 14) && (svga->bpp == 24))
svga->hdisp = (svga->crtc[1] + 1) * 8;
if ((tgui->accel.bpp == 3) && (ger22lower == 14) && (svga->bpp == 32) && (tgui->type == TGUI_9440))
svga->rowoffset <<= 1;
// pclog("Accelbpp = %d, ger22lower = %02x, ger22upper = %02x, bpp = %d, rowoffset = %d.\n", tgui->accel.bpp, ger22lower, ger22upper, svga->bpp, svga->rowoffset);
}
if ((tgui->type >= TGUI_9440) && (svga->bpp >= 24))
svga->hdisp = (svga->crtc[1] + 1) * 8;
if ((svga->crtc[0x1e] & 0xA0) == 0xA0)
svga->ma_latch |= 0x10000;
@@ -750,14 +743,14 @@ tgui_recalctimings(svga_t *svga)
else if ((svga->dispend == 600) && (svga->hdisp == 800) && svga->interlace)
svga->hdisp = 1600;
if (ger22upper & 0x80) {
svga->htotal <<= 1;
svga->hdisp <<= 1;
svga->hdisp_time <<= 1;
}
switch (svga->hdisp) {
case 640:
if (ger22upper & 0x01)
svga->rowoffset = 0x50;
break;
case 1600:
if (svga->rowoffset != 0x100)
svga->rowoffset = 0x100;
svga->rowoffset = 80;
break;
}
}
@@ -780,9 +773,8 @@ tgui_recalctimings(svga_t *svga)
case 32:
svga->render = svga_render_32bpp_highres;
if (tgui->type >= TGUI_9660) {
if (svga->hdisp == 1024) {
if (svga->hdisp == 1024)
svga->rowoffset <<= 1;
}
}
break;
}
@@ -1079,15 +1071,20 @@ tgui_ext_linear_read(uint32_t addr, void *priv)
if (addr >= svga->vram_max)
return 0xff;
addr &= ~0xf;
addr &= svga->vram_mask;
addr &= (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) ? ~0x0f : ~0x07;
addr = dword_remap(svga, addr);
for (uint8_t c = 0; c < 16; c++) {
tgui->copy_latch[c] = svga->vram[addr + c];
addr += ((c & 3) == 3) ? 13 : 1;
if (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) {
for (int c = 0; c < 16; c++) {
tgui->copy_latch[c] = svga->vram[addr];
addr += (c & 3) ? 1 : 13;
addr &= svga->vram_mask;
}
return svga->vram[addr];
}
return svga->vram[addr & svga->vram_mask];
return svga_read_linear(addr, svga);
}
static uint8_t
@@ -1105,7 +1102,8 @@ tgui_ext_linear_write(uint32_t addr, uint8_t val, void *priv)
{
svga_t *svga = (svga_t *) priv;
tgui_t *tgui = (tgui_t *) svga->priv;
int c;
int c;
int bpp = (tgui->ext_gdc_regs[0] & EXT_CTRL_16BIT);
uint8_t fg[2] = { tgui->ext_gdc_regs[4], tgui->ext_gdc_regs[5] };
uint8_t bg[2] = { tgui->ext_gdc_regs[1], tgui->ext_gdc_regs[2] };
uint8_t mask = tgui->ext_gdc_regs[7];
@@ -1116,62 +1114,53 @@ tgui_ext_linear_write(uint32_t addr, uint8_t val, void *priv)
if (addr >= svga->vram_max)
return;
addr &= svga->vram_mask;
addr &= (tgui->ext_gdc_regs[0] & 8) ? ~0xf : ~0x7;
addr &= (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) ? ~0x0f : ~0x07;
addr = dword_remap(svga, addr);
svga->changedvram[addr >> 12] = changeframecount;
svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount;
switch (tgui->ext_gdc_regs[0] & 0xf) {
/*8-bit mono->colour expansion, unmasked*/
case 2:
for (c = 7; c >= 0; c--) {
if (mask & (1 << c))
*(uint8_t *) &svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0];
addr += (c == 4) ? 13 : 1;
if (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) {
for (c = 0; c < 16; c++) {
svga->vram[addr] = tgui->copy_latch[c];
addr += ((c & 3) == 3) ? 13 : 1;
addr &= svga->vram_mask;
}
} else if (tgui->ext_gdc_regs[0] & (EXT_CTRL_MONO_EXPANSION | EXT_CTRL_MONO_TRANSPARENT)) {
if (tgui->ext_gdc_regs[0] & EXT_CTRL_MONO_TRANSPARENT) {
if (bpp) {
for (c = 7; c >= 0; c--) {
if ((val & mask) & (1 << c))
svga->vram[addr] = fg[(c & 1) ^ 1];
addr += (c & 3) ? 1 : 13;
addr &= svga->vram_mask;
}
} else {
for (c = 7; c >= 0; c--) {
if ((val & mask) & (1 << c))
svga->vram[addr] = tgui->ext_gdc_regs[4];
addr += (c == 4) ? 13 : 1;
addr &= svga->vram_mask;
}
}
break;
/*16-bit mono->colour expansion, unmasked*/
case 3:
for (c = 7; c >= 0; c--) {
if (mask & (1 << c))
*(uint8_t *) &svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1];
addr += (c == 4) ? 13 : 1;
} else {
if (bpp) {
for (c = 7; c >= 0; c--) {
if (mask & (1 << c))
svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1];
addr += (c & 3) ? 1 : 13;
addr &= svga->vram_mask;
}
} else {
for (c = 7; c >= 0; c--) {
if (mask & (1 << c))
svga->vram[addr] = (val & (1 << c)) ? tgui->ext_gdc_regs[4] : tgui->ext_gdc_regs[1];
addr += (c == 4) ? 13 : 1;
addr &= svga->vram_mask;
}
}
break;
/*8-bit mono->colour expansion, masked*/
case 6:
for (c = 7; c >= 0; c--) {
if ((val & mask) & (1 << c))
*(uint8_t *) &svga->vram[addr] = fg[0];
addr += (c == 4) ? 13 : 1;
}
break;
/*16-bit mono->colour expansion, masked*/
case 7:
for (c = 7; c >= 0; c--) {
if ((val & mask) & (1 << c))
*(uint8_t *) &svga->vram[addr] = fg[(c & 1) ^ 1];
addr += (c == 4) ? 13 : 1;
}
break;
case 0x8:
case 0x9:
case 0xa:
case 0xb:
case 0xc:
case 0xd:
case 0xe:
case 0xf:
for (c = 0; c < 16; c++) {
*(uint8_t *) &svga->vram[addr] = tgui->copy_latch[c];
addr += ((c & 3) == 3) ? 13 : 1;
}
break;
}
}
} else
svga_write_linear(addr, val, svga);
}
static void
@@ -1179,7 +1168,8 @@ tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *priv)
{
svga_t *svga = (svga_t *) priv;
tgui_t *tgui = (tgui_t *) svga->priv;
int c;
int c;
int bpp = (tgui->ext_gdc_regs[0] & EXT_CTRL_16BIT);
uint8_t fg[2] = { tgui->ext_gdc_regs[4], tgui->ext_gdc_regs[5] };
uint8_t bg[2] = { tgui->ext_gdc_regs[1], tgui->ext_gdc_regs[2] };
uint16_t mask = (tgui->ext_gdc_regs[7] << 8) | tgui->ext_gdc_regs[8];
@@ -1190,70 +1180,81 @@ tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *priv)
if (addr >= svga->vram_max)
return;
addr &= svga->vram_mask;
addr &= ~0xf;
addr &= (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) ? ~0x0f : ~0x07;
addr = dword_remap(svga, addr);
svga->changedvram[addr >> 12] = changeframecount;
svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount;
val = (val >> 8) | (val << 8);
switch (tgui->ext_gdc_regs[0] & 0xf) {
/*8-bit mono->colour expansion, unmasked*/
case 2:
for (c = 15; c >= 0; c--) {
if (mask & (1 << c))
*(uint8_t *) &svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0];
addr += (c & 3) ? 1 : 13;
}
break;
if (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) {
for (c = 0; c < 16; c++) {
svga->vram[addr] = tgui->copy_latch[c];
addr += (c & 3) ? 1 : 13;
addr &= svga->vram_mask;
}
} else if (tgui->ext_gdc_regs[0] & (EXT_CTRL_MONO_EXPANSION | EXT_CTRL_MONO_TRANSPARENT)) {
if (tgui->ext_gdc_regs[0] & EXT_CTRL_MONO_TRANSPARENT) {
if (bpp) {
for (c = 15; c >= 0; c--) {
if ((val & mask) & (1 << c))
svga->vram[addr] = fg[(c & 1) ^ 1];
addr += (c & 3) ? 1 : 13;
addr &= svga->vram_mask;
}
} else {
for (c = 15; c >= 0; c--) {
if ((val & mask) & (1 << c))
svga->vram[addr] = tgui->ext_gdc_regs[4];
/*16-bit mono->colour expansion, unmasked*/
case 3:
for (c = 15; c >= 0; c--) {
if (mask & (1 << c))
*(uint8_t *) &svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1];
addr += (c & 3) ? 1 : 13;
addr += (c & 3) ? 1 : 13;
addr &= svga->vram_mask;
}
}
break;
} else {
if (bpp) {
for (c = 15; c >= 0; c--) {
if (mask & (1 << c))
svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1];
addr += (c & 3) ? 1 : 13;
addr &= svga->vram_mask;
}
} else {
for (c = 15; c >= 0; c--) {
if (mask & (1 << c))
svga->vram[addr] = (val & (1 << c)) ? tgui->ext_gdc_regs[4] : tgui->ext_gdc_regs[1];
/*8-bit mono->colour expansion, masked*/
case 6:
for (c = 15; c >= 0; c--) {
if ((val & mask) & (1 << c))
*(uint8_t *) &svga->vram[addr] = fg[0];
addr += (c & 3) ? 1 : 13;
addr += (c & 3) ? 1 : 13;
addr &= svga->vram_mask;
}
}
break;
/*16-bit mono->colour expansion, masked*/
case 7:
for (c = 15; c >= 0; c--) {
if ((val & mask) & (1 << c))
*(uint8_t *) &svga->vram[addr] = fg[(c & 1) ^ 1];
addr += (c & 3) ? 1 : 13;
}
break;
case 0x8:
case 0x9:
case 0xa:
case 0xb:
case 0xc:
case 0xd:
case 0xe:
case 0xf:
for (c = 0; c < 16; c++) {
*(uint8_t *) &svga->vram[addr + c] = tgui->copy_latch[c];
addr += ((c & 3) == 3) ? 13 : 1;
}
break;
}
}
} else
svga_writew_linear(addr, val, svga);
}
static void
tgui_ext_linear_writel(uint32_t addr, uint32_t val, void *priv)
{
tgui_ext_linear_writew(addr, val, priv);
svga_t *svga = (svga_t *) priv;
tgui_t *tgui = (tgui_t *) svga->priv;
cycles -= video_timing_write_l;
addr &= svga->decode_mask;
if (addr >= svga->vram_max)
return;
addr &= svga->vram_mask;
addr &= (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) ? ~0x0f : ~0x07;
addr = dword_remap(svga, addr);
svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount;
if (tgui->ext_gdc_regs[0] & (EXT_CTRL_MONO_EXPANSION | EXT_CTRL_MONO_TRANSPARENT | EXT_CTRL_LATCH_COPY)) {
tgui_ext_linear_writew(addr, val & 0xffff, priv);
tgui_ext_linear_writew(addr + 2, val >> 16, priv);
} else {
svga_writel_linear(addr, val, svga);
}
}
static void
@@ -1261,7 +1262,7 @@ tgui_ext_write(uint32_t addr, uint8_t val, void *priv)
{
svga_t *svga = (svga_t *) priv;
addr = (addr & svga->banked_mask) + svga->read_bank;
addr = (addr & svga->banked_mask) + svga->write_bank;
tgui_ext_linear_write(addr, val, svga);
}
@@ -1270,7 +1271,7 @@ tgui_ext_writew(uint32_t addr, uint16_t val, void *priv)
{
svga_t *svga = (svga_t *) priv;
addr = (addr & svga->banked_mask) + svga->read_bank;
addr = (addr & svga->banked_mask) + svga->write_bank;
tgui_ext_linear_writew(addr, val, svga);
}
@@ -1279,7 +1280,7 @@ tgui_ext_writel(uint32_t addr, uint32_t val, void *priv)
{
svga_t *svga = (svga_t *) priv;
addr = (addr & svga->banked_mask) + svga->read_bank;
addr = (addr & svga->banked_mask) + svga->write_bank;
tgui_ext_linear_writel(addr, val, svga);
}
@@ -1329,13 +1330,13 @@ enum {
#define WRITE(addr, dat) \
if (tgui->accel.bpp == 0) { \
svga->vram[(addr) &tgui->vram_mask] = dat; \
svga->changedvram[((addr) & (tgui->vram_mask)) >> 12] = changeframecount; \
svga->changedvram[((addr) & (tgui->vram_mask)) >> 12] = svga->monitor->mon_changeframecount; \
} else if (tgui->accel.bpp == 1) { \
vram_w[(addr) & (tgui->vram_mask >> 1)] = dat; \
svga->changedvram[((addr) & (tgui->vram_mask >> 1)) >> 11] = changeframecount; \
svga->changedvram[((addr) & (tgui->vram_mask >> 1)) >> 11] = svga->monitor->mon_changeframecount; \
} else { \
vram_l[(addr) & (tgui->vram_mask >> 2)] = dat; \
svga->changedvram[((addr) & (tgui->vram_mask >> 2)) >> 10] = changeframecount; \
svga->changedvram[((addr) & (tgui->vram_mask >> 2)) >> 10] = svga->monitor->mon_changeframecount; \
}
static void
@@ -1365,7 +1366,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
trans_col &= 0xffff;
}
if (count != -1 && !tgui->accel.x && (tgui->accel.flags & TGUI_SRCMONO)) {
if ((count != -1) && !tgui->accel.x && (tgui->accel.flags & TGUI_SRCMONO)) {
count -= (tgui->accel.flags >> 24) & 7;
cpu_dat <<= (tgui->accel.flags >> 24) & 7;
}
@@ -1413,38 +1414,6 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
}
}
switch (svga->hdisp) {
case 640:
case 1024:
case 1280:
tgui->accel.pitch = svga->hdisp;
break;
case 800: /*Disassembly of the TGUI9440/96x0 drivers shows that 800x600 is treated as 832 in the acceleration pitch (0x340 as horizontal display)*/
tgui->accel.pitch = svga->hdisp + 32;
break;
case 1600:
tgui->accel.pitch = 2048;
break;
}
switch (ger22lower) {
case 4: /*8-bit mode for modes up to 1024x768.*/
case 9: /*15-bit and 16-bit modes.*/
if (!(ger22upper & 0x01)) {
if (ger22upper == 0x00)
tgui->accel.pitch = 1024;
}
break;
case 8: /*8-bit mode for modes greater than 1024x768 and 24-bit mode for 640x480 (latter is TGUI9440AGi only).*/
if (!(ger22upper & 0x01)) {
if (ger22upper == 0x00) {
if (svga->bpp == 24)
tgui->accel.pitch = 2048;
}
}
break;
}
// 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);
switch (tgui->accel.command) {
@@ -2002,49 +1971,40 @@ static void
tgui_accel_out(uint16_t addr, uint8_t val, void *priv)
{
tgui_t *tgui = (tgui_t *) priv;
svga_t *svga = &tgui->svga;
switch (addr) {
case 0x2122:
tgui->accel.ger22 = (tgui->accel.ger22 & 0xff00) | val;
switch (val & 0xff) {
case 4:
tgui->accel.pitch = 0x200 << ((val >> 2) & 3);
switch (svga->bpp) {
case 8:
case 24:
tgui->accel.bpp = 0;
break;
case 9:
switch (tgui->svga.bpp) {
case 32:
tgui->accel.bpp = 3;
break;
default:
tgui->accel.bpp = 1;
break;
}
case 15:
case 16:
tgui->accel.bpp = 1;
break;
case 13:
case 14:
switch (tgui->svga.bpp) {
case 15:
case 16:
tgui->accel.bpp = 1;
break;
case 24:
tgui->accel.bpp = 0;
break;
case 32:
tgui->accel.bpp = 3;
break;
}
case 32:
tgui->accel.bpp = 3;
break;
}
break;
case 0x2123:
tgui->accel.ger22 = (tgui->accel.ger22 & 0xff) | (val << 8);
if ((val & 0x80) || (((val & 0xc0) == 0x40)))
tgui->accel.pitch = svga->rowoffset << 3;
else if (tgui->accel.pitch <= 1024)
tgui->accel.pitch = svga->rowoffset << 3;
if (tgui->accel.bpp == 1)
tgui->accel.pitch >>= 1;
else if (tgui->accel.bpp == 3)
tgui->accel.pitch >>= 2;
svga_recalctimings(svga);
break;
case 0x2124: /*Command*/
@@ -2656,45 +2616,35 @@ tgui_accel_write(uint32_t addr, uint8_t val, void *priv)
switch (addr & 0xff) {
case 0x22:
tgui->accel.ger22 = (tgui->accel.ger22 & 0xff00) | val;
switch (val & 0xff) {
case 4:
tgui->accel.pitch = 0x200 << ((val >> 2) & 3);
switch (svga->bpp) {
case 8:
case 24:
tgui->accel.bpp = 0;
break;
case 9:
switch (tgui->svga.bpp) {
case 32:
tgui->accel.bpp = 3;
break;
default:
tgui->accel.bpp = 1;
break;
}
case 15:
case 16:
tgui->accel.bpp = 1;
break;
case 13:
case 14:
switch (tgui->svga.bpp) {
case 15:
case 16:
tgui->accel.bpp = 1;
break;
case 24:
tgui->accel.bpp = 0;
break;
case 32:
tgui->accel.bpp = 3;
break;
}
case 32:
tgui->accel.bpp = 3;
break;
}
break;
case 0x23:
tgui->accel.ger22 = (tgui->accel.ger22 & 0xff) | (val << 8);
if ((val & 0x80) || (((val & 0xc0) == 0x40)))
tgui->accel.pitch = svga->rowoffset << 3;
else if (tgui->accel.pitch <= 1024)
tgui->accel.pitch = svga->rowoffset << 3;
if (tgui->accel.bpp == 1)
tgui->accel.pitch >>= 1;
else if (tgui->accel.bpp == 3)
tgui->accel.pitch >>= 2;
svga_recalctimings(svga);
break;
case 0x24: /*Command*/
@@ -3516,6 +3466,9 @@ tgui_init(const device_t *info)
mem_mapping_disable(&tgui->accel_mapping);
mem_mapping_disable(&tgui->mmio_mapping);
if (tgui->vram_size == (2 << 20))
svga->crtc[0x21] |= 0x10;
tgui_set_io(tgui);
if (tgui->pci && (tgui->type >= TGUI_9440)) {
@@ -3589,7 +3542,7 @@ tgui_force_redraw(void *priv)
{
tgui_t *tgui = (tgui_t *) priv;
tgui->svga.fullchange = changeframecount;
tgui->svga.fullchange = tgui->svga.monitor->mon_changeframecount;
}
// clang-format off

View File

@@ -738,6 +738,7 @@ VIDOBJ := agpgart.o video.o \
vid_ati_eeprom.o \
vid_ati18800.o vid_ati28800.o \
vid_ati_mach8.o \
vid_ati68875_ramdac.o \
vid_ati_mach64.o vid_ati68860_ramdac.o \
vid_bt48x_ramdac.o \
vid_av9194.o vid_icd2061.o vid_ics2494.o vid_ics2595.o \