Video features and fixes:
Added the Mach8 and Mach32 ISA/VLB/PCI cards (initial implementation and MCA coming soon for the Mach32) and their corresponding EEPROM's. Added INMOS XGA ISA card and updated the SVGA core to reflect its mapping as well as the Mach8/32 mapping when in 8514 monitor mode. Mark the XGA button as already checked and locked when a standalone XGA BIOS card is present like the INMOS one. (QT only) Same concept as above, but applies to the Mach8 and 32 for the 8514 option as well. (QT only)
This commit is contained in:
@@ -24,6 +24,8 @@ typedef struct ibm8514_t {
|
||||
|
||||
int force_old_addr;
|
||||
int type;
|
||||
int local;
|
||||
int bpp;
|
||||
|
||||
uint32_t vram_size;
|
||||
uint32_t vram_mask;
|
||||
@@ -32,6 +34,7 @@ typedef struct ibm8514_t {
|
||||
uint8_t dac_mask, dac_status;
|
||||
uint32_t *map8;
|
||||
int dac_addr, dac_pos, dac_r, dac_g;
|
||||
int internal_pitch;
|
||||
|
||||
struct {
|
||||
uint16_t subsys_cntl;
|
||||
@@ -58,7 +61,7 @@ typedef struct ibm8514_t {
|
||||
uint8_t pix_trans[2];
|
||||
int poly_draw;
|
||||
int ssv_state;
|
||||
int x1, x2, y1, y2;
|
||||
int16_t x1, x2, x3, y1, y2;
|
||||
int sys_cnt, sys_cnt2;
|
||||
int temp_cnt;
|
||||
int16_t cx, cy, oldcy;
|
||||
@@ -80,6 +83,7 @@ typedef struct ibm8514_t {
|
||||
|
||||
uint16_t scratch;
|
||||
int fill_state, xdir, ydir;
|
||||
uint32_t ge_offset;
|
||||
} accel;
|
||||
|
||||
uint16_t test;
|
||||
@@ -90,7 +94,7 @@ typedef struct ibm8514_t {
|
||||
dispon, hdisp_on, linecountff,
|
||||
vc, linepos, oddeven, cursoron, blink, scrollcache,
|
||||
firstline, lastline, firstline_draw, lastline_draw,
|
||||
displine, fullchange, x_add, y_add;
|
||||
displine, fullchange;
|
||||
uint32_t ma, maback;
|
||||
|
||||
uint8_t *vram, *changedvram, linedbl;
|
||||
@@ -103,11 +107,13 @@ typedef struct ibm8514_t {
|
||||
int disp_cntl, interlace;
|
||||
uint8_t subsys_cntl, subsys_stat;
|
||||
|
||||
volatile int force_busy, force_busy2;
|
||||
atomic_int force_busy, force_busy2;
|
||||
|
||||
int blitter_busy;
|
||||
uint64_t blitter_time;
|
||||
uint64_t status_time;
|
||||
int pitch;
|
||||
int ext_pitch;
|
||||
int ext_crt_pitch;
|
||||
} ibm8514_t;
|
||||
#endif /*VIDEO_8514A_H*/
|
||||
|
||||
@@ -43,6 +43,7 @@ typedef struct ati_eeprom_t {
|
||||
} ati_eeprom_t;
|
||||
|
||||
void ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type);
|
||||
void ati_eeprom_load_mach8(ati_eeprom_t *eeprom, char *fn);
|
||||
void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat);
|
||||
int ati_eeprom_read(ati_eeprom_t *eeprom);
|
||||
|
||||
|
||||
@@ -31,8 +31,9 @@
|
||||
# define FLAG_NOSKEW 16
|
||||
# define FLAG_ADDR_BY16 32
|
||||
# define FLAG_RAMDAC_SHIFT 64
|
||||
# define FLAG_128K_MASK 128
|
||||
|
||||
# define FLAG_ATI 128
|
||||
# define FLAG_S3_911_16BIT 256
|
||||
# define FLAG_512K_MASK 512
|
||||
struct monitor_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -36,6 +36,7 @@ typedef struct xga_t {
|
||||
mem_mapping_t linear_mapping;
|
||||
mem_mapping_t video_mapping;
|
||||
rom_t bios_rom;
|
||||
rom_t vga_bios_rom;
|
||||
xga_hwcursor_t hwcursor, hwcursor_latch;
|
||||
PALETTE extpal;
|
||||
|
||||
@@ -57,7 +58,7 @@ typedef struct xga_t {
|
||||
uint8_t clk_sel_1, clk_sel_2;
|
||||
uint8_t hwc_control;
|
||||
uint8_t bus_arb;
|
||||
uint8_t select_pos_isa;
|
||||
uint8_t isa_pos_enable;
|
||||
uint8_t hwcursor_oddeven;
|
||||
uint8_t cfg_reg_instance;
|
||||
uint8_t rowcount;
|
||||
@@ -70,6 +71,8 @@ typedef struct xga_t {
|
||||
uint8_t sprite_data[1024];
|
||||
uint8_t scrollcache;
|
||||
uint8_t direct_color;
|
||||
uint8_t dma_channel;
|
||||
uint8_t instance_isa, instance_num, ext_mem_addr;
|
||||
uint8_t *vram, *changedvram;
|
||||
|
||||
int16_t hwc_pos_x;
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
|
||||
#ifndef VIDEO_XGA_DEVICE_H
|
||||
#define VIDEO_XGA_DEVICE_H
|
||||
extern int xga_has_vga;
|
||||
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t xga_device;
|
||||
extern const device_t xga_isa_device;
|
||||
extern const device_t inmos_isa_device;
|
||||
#endif
|
||||
#endif /*VIDEO_XGA_DEVICE_H*/
|
||||
|
||||
@@ -60,8 +60,10 @@ enum {
|
||||
#define VIDEO_FLAG_TYPE_CGA 0
|
||||
#define VIDEO_FLAG_TYPE_MDA 1
|
||||
#define VIDEO_FLAG_TYPE_SPECIAL 2
|
||||
#define VIDEO_FLAG_TYPE_NONE 3
|
||||
#define VIDEO_FLAG_TYPE_MASK 3
|
||||
#define VIDEO_FLAG_TYPE_8514 3
|
||||
#define VIDEO_FLAG_TYPE_XGA 4
|
||||
#define VIDEO_FLAG_TYPE_NONE 5
|
||||
#define VIDEO_FLAG_TYPE_MASK 7
|
||||
|
||||
typedef struct video_timings_t {
|
||||
int type;
|
||||
@@ -206,6 +208,7 @@ extern double cpuclock;
|
||||
extern int emu_fps;
|
||||
extern int frames;
|
||||
extern int readflash;
|
||||
extern int ibm8514_has_vga;
|
||||
|
||||
/* Function handler pointers. */
|
||||
extern void (*video_recalctimings)(void);
|
||||
@@ -232,6 +235,8 @@ extern int video_card_get_flags(int card);
|
||||
extern int video_is_mda(void);
|
||||
extern int video_is_cga(void);
|
||||
extern int video_is_ega_vga(void);
|
||||
extern int video_is_8514(void);
|
||||
extern int video_is_xga(void);
|
||||
extern void video_inform_monitor(int type, const video_timings_t *ptr, int monitor_index);
|
||||
extern int video_get_type_monitor(int monitor_index);
|
||||
|
||||
@@ -290,8 +295,12 @@ extern uint32_t video_color_transform(uint32_t color);
|
||||
/* IBM XGA */
|
||||
extern void xga_device_add(void);
|
||||
|
||||
/* IBM 8514/A and generic clones*/
|
||||
/* IBM 8514/A and clones*/
|
||||
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_pci_device;
|
||||
|
||||
/* ATi Mach64 */
|
||||
extern const device_t mach64gx_isa_device;
|
||||
|
||||
@@ -102,6 +102,11 @@ 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;
|
||||
|
||||
ui->comboBoxVideo->setCurrentIndex(selectedRow);
|
||||
if (gfxcard[1] == 0)
|
||||
ui->pushButtonConfigureSecondary->setEnabled(false);
|
||||
@@ -123,11 +128,13 @@ SettingsDisplay::on_pushButtonConfigureVoodoo_clicked()
|
||||
void
|
||||
SettingsDisplay::on_pushButtonConfigureXga_clicked()
|
||||
{
|
||||
if (!xga_has_vga) {
|
||||
if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) {
|
||||
DeviceConfig::ConfigureDevice(&xga_device, 0, qobject_cast<Settings *>(Settings::settings));
|
||||
} else {
|
||||
DeviceConfig::ConfigureDevice(&xga_isa_device, 0, qobject_cast<Settings *>(Settings::settings));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -139,7 +146,6 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index)
|
||||
auto curVideoCard_2 = videoCard[1];
|
||||
videoCard[0] = ui->comboBoxVideo->currentData().toInt();
|
||||
ui->pushButtonConfigure->setEnabled(video_card_has_config(videoCard[0]) > 0);
|
||||
|
||||
bool machineHasPci = machine_has_bus(machineId, MACHINE_BUS_PCI) > 0;
|
||||
ui->checkBoxVoodoo->setEnabled(machineHasPci);
|
||||
if (machineHasPci) {
|
||||
@@ -149,16 +155,16 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index)
|
||||
|
||||
bool hasIsa16 = machine_has_bus(machineId, MACHINE_BUS_ISA16) > 0;
|
||||
bool has_MCA = machine_has_bus(machineId, MACHINE_BUS_MCA) > 0;
|
||||
ui->checkBox8514->setEnabled(hasIsa16 || has_MCA);
|
||||
ui->checkBox8514->setEnabled((hasIsa16 || has_MCA) && !ibm8514_has_vga);
|
||||
if (hasIsa16 || has_MCA) {
|
||||
ui->checkBox8514->setChecked(ibm8514_enabled);
|
||||
}
|
||||
|
||||
ui->checkBoxXga->setEnabled(hasIsa16 || has_MCA);
|
||||
ui->checkBoxXga->setEnabled((hasIsa16 || has_MCA) && !xga_has_vga);
|
||||
if (hasIsa16 || has_MCA)
|
||||
ui->checkBoxXga->setChecked(xga_enabled);
|
||||
|
||||
ui->pushButtonConfigureXga->setEnabled((hasIsa16 || has_MCA) && ui->checkBoxXga->isChecked());
|
||||
ui->pushButtonConfigureXga->setEnabled((hasIsa16 || has_MCA) && ui->checkBoxXga->isChecked() && !xga_has_vga);
|
||||
|
||||
int c = 2;
|
||||
|
||||
@@ -187,7 +193,7 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index)
|
||||
c++;
|
||||
}
|
||||
|
||||
if (videoCard[1] == 0 || (machine_has_flags(machineId, MACHINE_VIDEO_ONLY) > 0)) {
|
||||
if ((videoCard[1] == 0) || (machine_has_flags(machineId, MACHINE_VIDEO_ONLY) > 0)) {
|
||||
ui->comboBoxVideoSecondary->setCurrentIndex(0);
|
||||
ui->pushButtonConfigureSecondary->setEnabled(false);
|
||||
}
|
||||
@@ -202,7 +208,7 @@ SettingsDisplay::on_checkBoxVoodoo_stateChanged(int state)
|
||||
void
|
||||
SettingsDisplay::on_checkBoxXga_stateChanged(int state)
|
||||
{
|
||||
ui->pushButtonConfigureXga->setEnabled(state == Qt::Checked);
|
||||
ui->pushButtonConfigureXga->setEnabled((state == Qt::Checked) && !xga_has_vga);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -18,7 +18,7 @@ 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_mach64.c vid_ati68860_ramdac.c vid_bt48x_ramdac.c
|
||||
vid_ati28800.c vid_ati_mach8.c vid_ati_mach64.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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -45,6 +45,26 @@ ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type)
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void
|
||||
ati_eeprom_load_mach8(ati_eeprom_t *eeprom, char *fn)
|
||||
{
|
||||
FILE *f;
|
||||
int size;
|
||||
eeprom->type = 0;
|
||||
strncpy(eeprom->fn, fn, sizeof(eeprom->fn) - 1);
|
||||
f = nvr_fopen(eeprom->fn, "rb");
|
||||
size = 128;
|
||||
if (!f) { /*The ATI Graphics Ultra bios expects an immediate write to nvram if none is present at boot time otherwise
|
||||
it would hang the machine.*/
|
||||
memset(eeprom->data, 0, size);
|
||||
f = nvr_fopen(eeprom->fn, "wb");
|
||||
fwrite(eeprom->data, 1, size, f);
|
||||
}
|
||||
if (fread(eeprom->data, 1, size, f) != size)
|
||||
memset(eeprom->data, 0, size);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void
|
||||
ati_eeprom_save(ati_eeprom_t *eeprom)
|
||||
{
|
||||
|
||||
5568
src/video/vid_ati_mach8.c
Normal file
5568
src/video/vid_ati_mach8.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -41,6 +41,7 @@
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_svga.h>
|
||||
#include <86box/vid_svga_render.h>
|
||||
#include <86box/vid_xga_device.h>
|
||||
|
||||
void svga_doblit(int wx, int wy, svga_t *svga);
|
||||
|
||||
@@ -131,7 +132,7 @@ svga_out(uint16_t addr, uint8_t val, void *p)
|
||||
if (svga->attraddr < 16)
|
||||
svga->fullchange = svga->monitor->mon_changeframecount;
|
||||
if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) {
|
||||
for (uint8_t c = 0; c < 16; c++) {
|
||||
for (int c = 0; c < 16; c++) {
|
||||
if (svga->attrregs[0x10] & 0x80) {
|
||||
svga->egapal[c] = (svga->attrregs[c] & 0xf) | ((svga->attrregs[0x14] & 0xf) << 4);
|
||||
} else {
|
||||
@@ -165,6 +166,12 @@ svga_out(uint16_t addr, uint8_t val, void *p)
|
||||
io_sethandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p);
|
||||
svga_recalctimings(svga);
|
||||
break;
|
||||
case 0x3c3:
|
||||
if (xga_enabled) {
|
||||
svga->xga.on = (val & 0x01) ? 0 : 1;
|
||||
vga_on = !svga->xga.on;
|
||||
}
|
||||
break;
|
||||
case 0x3c4:
|
||||
svga->seqaddr = val;
|
||||
break;
|
||||
@@ -407,7 +414,7 @@ svga_set_ramdac_type(svga_t *svga, int type)
|
||||
if (svga->ramdac_type != type) {
|
||||
svga->ramdac_type = type;
|
||||
|
||||
for (uint16_t c = 0; c < 256; c++) {
|
||||
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
|
||||
@@ -583,8 +590,14 @@ svga_recalctimings(svga_t *svga)
|
||||
svga->recalctimings_ex(svga);
|
||||
}
|
||||
} else {
|
||||
if (ibm8514_enabled)
|
||||
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);
|
||||
}
|
||||
@@ -597,8 +610,13 @@ 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;
|
||||
} else {
|
||||
disptime = svga->htotal;
|
||||
_dispontime = svga->hdisp_time;
|
||||
}
|
||||
|
||||
if (svga->seqregs[1] & 8) {
|
||||
disptime *= 2;
|
||||
@@ -678,16 +696,20 @@ void
|
||||
svga_poll(void *p)
|
||||
{
|
||||
svga_t *svga = (svga_t *) p;
|
||||
ibm8514_t *dev = &svga->dev8514;
|
||||
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) {
|
||||
ibm8514_poll(&svga->dev8514, svga);
|
||||
if (!dev->local) {
|
||||
ibm8514_poll(dev, svga);
|
||||
return;
|
||||
}
|
||||
} else if (!vga_on && xga_enabled && svga->xga.on) {
|
||||
xga_poll(&svga->xga, svga);
|
||||
return;
|
||||
@@ -695,22 +717,22 @@ svga_poll(void *p)
|
||||
|
||||
if (!svga->linepos) {
|
||||
if (svga->displine == svga->hwcursor_latch.y && svga->hwcursor_latch.ena) {
|
||||
svga->hwcursor_on = svga->hwcursor.cur_ysize - svga->hwcursor_latch.yoff;
|
||||
svga->hwcursor_on = svga->hwcursor_latch.cur_ysize - svga->hwcursor_latch.yoff;
|
||||
svga->hwcursor_oddeven = 0;
|
||||
}
|
||||
|
||||
if (svga->displine == (svga->hwcursor_latch.y + 1) && svga->hwcursor_latch.ena && svga->interlace) {
|
||||
svga->hwcursor_on = svga->hwcursor.cur_ysize - (svga->hwcursor_latch.yoff + 1);
|
||||
svga->hwcursor_on = svga->hwcursor_latch.cur_ysize - (svga->hwcursor_latch.yoff + 1);
|
||||
svga->hwcursor_oddeven = 1;
|
||||
}
|
||||
|
||||
if (svga->displine == svga->dac_hwcursor_latch.y && svga->dac_hwcursor_latch.ena) {
|
||||
svga->dac_hwcursor_on = svga->dac_hwcursor.cur_ysize - svga->dac_hwcursor_latch.yoff;
|
||||
svga->dac_hwcursor_on = svga->dac_hwcursor_latch.cur_ysize - svga->dac_hwcursor_latch.yoff;
|
||||
svga->dac_hwcursor_oddeven = 0;
|
||||
}
|
||||
|
||||
if (svga->displine == (svga->dac_hwcursor_latch.y + 1) && svga->dac_hwcursor_latch.ena && svga->interlace) {
|
||||
svga->dac_hwcursor_on = svga->dac_hwcursor.cur_ysize - (svga->dac_hwcursor_latch.yoff + 1);
|
||||
svga->dac_hwcursor_on = svga->dac_hwcursor_latch.cur_ysize - (svga->dac_hwcursor_latch.yoff + 1);
|
||||
svga->dac_hwcursor_oddeven = 1;
|
||||
}
|
||||
|
||||
@@ -783,7 +805,13 @@ svga_poll(void *p)
|
||||
if ((svga->sc == (svga->crtc[11] & 31)) || (svga->sc == svga->rowcount))
|
||||
svga->con = 0;
|
||||
if (svga->dispon) {
|
||||
if (svga->linedbl && !svga->linecountff) {
|
||||
/*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;
|
||||
svga->ma = svga->maback;
|
||||
} else if (svga->sc == svga->rowcount) {
|
||||
@@ -793,23 +821,24 @@ svga_poll(void *p)
|
||||
svga->maback += (svga->rowoffset << 3);
|
||||
if (svga->interlace)
|
||||
svga->maback += (svga->rowoffset << 3);
|
||||
|
||||
svga->maback &= svga->vram_display_mask;
|
||||
svga->ma = svga->maback;
|
||||
} else {
|
||||
svga->linecountff = 0;
|
||||
svga->sc++;
|
||||
svga->sc &= 31;
|
||||
svga->sc &= 0x1f;
|
||||
svga->ma = svga->maback;
|
||||
}
|
||||
}
|
||||
|
||||
svga->hsync_divisor = !svga->hsync_divisor;
|
||||
svga->hsync_divisor ^= 1;
|
||||
|
||||
if (svga->hsync_divisor && (svga->crtc[0x17] & 4))
|
||||
return;
|
||||
|
||||
svga->vc++;
|
||||
svga->vc &= 2047;
|
||||
svga->vc &= 0x7ff;
|
||||
|
||||
if (svga->vc == svga->split) {
|
||||
ret = 1;
|
||||
@@ -835,6 +864,7 @@ svga_poll(void *p)
|
||||
if (svga->vc == svga->dispend) {
|
||||
if (svga->vblank_start)
|
||||
svga->vblank_start(svga);
|
||||
|
||||
svga->dispon = 0;
|
||||
blink_delay = (svga->crtc[11] & 0x60) >> 5;
|
||||
if (svga->crtc[10] & 0x20)
|
||||
@@ -846,6 +876,7 @@ svga_poll(void *p)
|
||||
|
||||
if (!(svga->gdcreg[6] & 1) && !(svga->blink & 15))
|
||||
svga->fullchange = 2;
|
||||
|
||||
svga->blink = (svga->blink + 1) & 0x7f;
|
||||
|
||||
for (x = 0; x < ((svga->vram_mask + 1) >> 12); x++) {
|
||||
@@ -888,12 +919,18 @@ svga_poll(void *p)
|
||||
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;
|
||||
}
|
||||
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);
|
||||
svga->ca = (svga->ca << 2);
|
||||
@@ -958,9 +995,9 @@ svga_init(const device_t *info, svga_t *svga, void *p, int memsize,
|
||||
svga->monitor_index = monitor_index_global;
|
||||
svga->monitor = &monitors[svga->monitor_index];
|
||||
|
||||
for (uint16_t c = 0; c < 256; c++) {
|
||||
for (int c = 0; c < 256; c++) {
|
||||
e = c;
|
||||
for (uint8_t d = 0; d < 8; d++) {
|
||||
for (int d = 0; d < 8; d++) {
|
||||
svga_rotate[d][c] = e;
|
||||
e = (e >> 1) | ((e & 1) ? 0x80 : 0);
|
||||
}
|
||||
@@ -1100,7 +1137,7 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
|
||||
|
||||
if (!linear) {
|
||||
if (xga_enabled) {
|
||||
if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl == 1)) {
|
||||
if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl >= 1)) {
|
||||
if (val == 0xa5) { /*Memory size test of XGA*/
|
||||
svga->xga.test = val;
|
||||
svga->xga.a5_test = 1;
|
||||
@@ -1108,7 +1145,7 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
|
||||
} else if (val == 0x5a) {
|
||||
svga->xga.test = val;
|
||||
return;
|
||||
} else if (val == 0x12 || val == 0x34) {
|
||||
} 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;
|
||||
@@ -1145,10 +1182,18 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
|
||||
if (addr & 1)
|
||||
writemask2 <<= 1;
|
||||
addr &= ~1;
|
||||
addr <<= 2;
|
||||
if (linear && ibm8514_on && (svga->adv_flags & FLAG_ATI)) {
|
||||
addr &= svga->vram_mask;
|
||||
} else
|
||||
addr <<= 2;
|
||||
|
||||
} else {
|
||||
if (linear && ibm8514_on && (svga->adv_flags & FLAG_ATI)) {
|
||||
writemask2 = 1 << (addr & 3);
|
||||
addr &= ~3;
|
||||
addr &= svga->vram_mask;
|
||||
} else
|
||||
addr <<= 2;
|
||||
}
|
||||
addr &= svga->decode_mask;
|
||||
|
||||
if (svga->translate_address)
|
||||
@@ -1303,7 +1348,7 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
|
||||
|
||||
if (!linear) {
|
||||
if (xga_enabled) {
|
||||
if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl == 1)) {
|
||||
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;
|
||||
@@ -1312,7 +1357,7 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
|
||||
svga->xga.on = 1;
|
||||
vga_on = !svga->xga.on;
|
||||
return svga->xga.test;
|
||||
} else if (addr == 0xa0000 || addr == 0xa0010) {
|
||||
} else if ((addr == 0xa0000) || (addr == 0xa0010)) {
|
||||
addr += svga->xga.read_bank;
|
||||
return svga->xga.vram[addr & svga->xga.vram_mask];
|
||||
}
|
||||
@@ -1354,11 +1399,24 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
|
||||
} else if (svga->chain2_read) {
|
||||
readplane = (readplane & 2) | (addr & 1);
|
||||
addr &= ~1;
|
||||
if (linear && ibm8514_on && (svga->adv_flags & FLAG_ATI))
|
||||
addr &= svga->vram_mask;
|
||||
else
|
||||
addr <<= 2;
|
||||
} else {
|
||||
if (linear && ibm8514_on && (svga->adv_flags & FLAG_ATI)) {
|
||||
addr &= svga->decode_mask;
|
||||
if (addr >= svga->vram_max)
|
||||
return 0xff;
|
||||
latch_addr = (addr & svga->vram_mask) & ~3;
|
||||
for (uint8_t i = 0; i < count; i++)
|
||||
svga->latch.b[i] = svga->vram[latch_addr | i];
|
||||
return svga->vram[addr & svga->vram_mask];
|
||||
} else
|
||||
addr <<= 2;
|
||||
|
||||
}
|
||||
addr &= svga->decode_mask;
|
||||
|
||||
if (svga->translate_address) {
|
||||
latch_addr = svga->translate_address(latch_addr, p);
|
||||
addr = svga->translate_address(addr, p);
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <86box/vid_ega.h>
|
||||
#include <86box/vid_colorplus.h>
|
||||
#include <86box/vid_mda.h>
|
||||
#include <86box/vid_xga_device.h>
|
||||
|
||||
typedef struct {
|
||||
const device_t *device;
|
||||
@@ -79,6 +80,8 @@ video_cards[] = {
|
||||
{ &vid_none_device },
|
||||
{ &vid_internal_device },
|
||||
{ &atiega_device },
|
||||
{ &mach8_isa_device, VIDEO_FLAG_TYPE_8514 },
|
||||
{ &mach32_isa_device, VIDEO_FLAG_TYPE_8514 },
|
||||
{ &mach64gx_isa_device },
|
||||
{ &ati28800k_device },
|
||||
{ &ati18800_vga88_device },
|
||||
@@ -112,6 +115,7 @@ video_cards[] = {
|
||||
{ &hercules_device, VIDEO_FLAG_TYPE_MDA },
|
||||
{ &herculesplus_device, VIDEO_FLAG_TYPE_MDA },
|
||||
{ &incolor_device },
|
||||
{ &inmos_isa_device, VIDEO_FLAG_TYPE_XGA },
|
||||
{ &im1024_device },
|
||||
{ &iskra_ega_device },
|
||||
{ &et4000_kasan_isa_device },
|
||||
@@ -154,6 +158,7 @@ video_cards[] = {
|
||||
{ &gd5428_mca_device },
|
||||
{ &et4000_mca_device },
|
||||
{ &radius_svga_multiview_mca_device },
|
||||
{ &mach32_pci_device, VIDEO_FLAG_TYPE_8514 },
|
||||
{ &mach64gx_pci_device },
|
||||
{ &mach64vt2_device },
|
||||
{ &et4000w32p_videomagic_revb_pci_device },
|
||||
@@ -211,6 +216,7 @@ video_cards[] = {
|
||||
{ &voodoo_3_1000_device },
|
||||
{ &voodoo_3_2000_device },
|
||||
{ &voodoo_3_3000_device },
|
||||
{ &mach32_vlb_device, VIDEO_FLAG_TYPE_8514 },
|
||||
{ &mach64gx_vlb_device },
|
||||
{ &et4000w32i_vlb_device },
|
||||
{ &et4000w32p_videomagic_revb_vlb_device },
|
||||
@@ -431,3 +437,15 @@ video_is_ega_vga(void)
|
||||
{
|
||||
return (video_get_type() == VIDEO_FLAG_TYPE_SPECIAL);
|
||||
}
|
||||
|
||||
int
|
||||
video_is_8514(void)
|
||||
{
|
||||
return (video_get_type() == VIDEO_FLAG_TYPE_8514);
|
||||
}
|
||||
|
||||
int
|
||||
video_is_xga(void)
|
||||
{
|
||||
return (video_get_type() == VIDEO_FLAG_TYPE_XGA);
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
#define XGA_BIOS_PATH "roms/video/xga/XGA_37F9576_Ver200.BIN"
|
||||
#define XGA2_BIOS_PATH "roms/video/xga/xga2_v300.bin"
|
||||
#define INMOS_XGA_BIOS_PATH "roms/video/xga/InMOS XGA - Fairchild NM27C256Q-150.BIN"
|
||||
|
||||
static video_timings_t timing_xga_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 };
|
||||
static video_timings_t timing_xga_mca = { .type = VIDEO_MCA, .write_b = 4, .write_w = 5, .write_l = 10, .read_b = 5, .read_w = 5, .read_l = 10 };
|
||||
@@ -44,16 +45,86 @@ static video_timings_t timing_xga_mca = { .type = VIDEO_MCA, .write_b = 4, .writ
|
||||
static void xga_ext_outb(uint16_t addr, uint8_t val, void *p);
|
||||
static uint8_t xga_ext_inb(uint16_t addr, void *p);
|
||||
|
||||
int xga_has_vga = 0;
|
||||
|
||||
void
|
||||
svga_xga_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
svga_t *svga = (svga_t *)p;
|
||||
uint8_t old;
|
||||
|
||||
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3D4:
|
||||
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);
|
||||
old = svga->crtc[svga->crtcreg];
|
||||
svga->crtc[svga->crtcreg] = val;
|
||||
if (old != val) {
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
|
||||
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
svga_xga_in(uint16_t addr, void *p)
|
||||
{
|
||||
svga_t *svga = (svga_t *)p;
|
||||
uint8_t temp;
|
||||
|
||||
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3D4:
|
||||
temp = svga->crtcreg;
|
||||
break;
|
||||
case 0x3D5:
|
||||
if (svga->crtcreg & 0x20)
|
||||
temp = 0xff;
|
||||
else
|
||||
temp = svga->crtc[svga->crtcreg];
|
||||
break;
|
||||
default:
|
||||
temp = svga_in(addr, svga);
|
||||
break;
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
void
|
||||
xga_updatemapping(svga_t *svga)
|
||||
{
|
||||
xga_t *xga = &svga->xga;
|
||||
|
||||
//pclog("OpMode = %x, linear base = %08x, aperture cntl = %d, opmodereset1 = %d, access mode = %x, map = %x.\n", xga->op_mode, xga->linear_base, xga->aperture_cntl, xga->op_mode_reset, xga->access_mode, svga->gdcreg[6] & 0x0c);
|
||||
//pclog("OpMode = %x, linear base = %08x, aperture cntl = %d, access mode = %x, map = %x, endian reverse = %d, a5test = %d, XGA on = %d.\n", xga->op_mode, xga->linear_base, xga->aperture_cntl, xga->access_mode, svga->gdcreg[6] & 0x0c, xga->linear_endian_reverse, xga->a5_test, xga->on);
|
||||
if (((xga->op_mode & 7) >= 4) || ((xga->op_mode & 7) == 0)) {
|
||||
if (xga->aperture_cntl == 1) {
|
||||
if ((xga->aperture_cntl == 1) || (xga->aperture_cntl == 2)) {
|
||||
mem_mapping_disable(&svga->mapping);
|
||||
if (xga->aperture_cntl == 1)
|
||||
mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000);
|
||||
else
|
||||
mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000);
|
||||
|
||||
mem_mapping_enable(&xga->video_mapping);
|
||||
xga->banked_mask = 0xffff;
|
||||
if (!xga->linear_endian_reverse)
|
||||
@@ -63,38 +134,23 @@ xga_updatemapping(svga_t *svga)
|
||||
mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000);
|
||||
mem_mapping_enable(&xga->video_mapping);
|
||||
xga->banked_mask = 0xffff;
|
||||
if (xga->pos_regs[4] & 1)
|
||||
mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000);
|
||||
else if (xga->base_addr_1mb)
|
||||
if (xga->base_addr_1mb)
|
||||
mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000);
|
||||
else
|
||||
mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000);
|
||||
if (((xga->op_mode & 7) == 4) && ((svga->gdcreg[6] & 0x0c) == 0x0c) && !xga->a5_test && xga->on)
|
||||
xga->linear_endian_reverse = 1;
|
||||
else if (((xga->op_mode & 7) == 0) && ((svga->gdcreg[6] & 0x0c) == 0x0c) && !xga->a5_test && !xga->on)
|
||||
else if (((xga->op_mode & 7) == 0) && ((svga->gdcreg[6] & 0x0c) == 0x0c) && !xga->a5_test && !xga->on) {
|
||||
xga->linear_endian_reverse = 1;
|
||||
}
|
||||
if (xga->a5_test && (xga->access_mode & 8) && !xga->linear_endian_reverse) {
|
||||
xga->on = 0;
|
||||
vga_on = !xga->on;
|
||||
} else {
|
||||
mem_mapping_disable(&svga->mapping);
|
||||
mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000);
|
||||
mem_mapping_enable(&xga->video_mapping);
|
||||
xga->banked_mask = 0xffff;
|
||||
mem_mapping_disable(&xga->linear_mapping);
|
||||
}
|
||||
} else {
|
||||
xga->on = 0;
|
||||
vga_on = !xga->on;
|
||||
mem_mapping_disable(&svga->mapping);
|
||||
if (xga->aperture_cntl == 2)
|
||||
mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000);
|
||||
else
|
||||
mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000);
|
||||
mem_mapping_enable(&xga->video_mapping);
|
||||
xga->banked_mask = 0xffff;
|
||||
mem_mapping_disable(&xga->linear_mapping);
|
||||
//pclog("XGA opmode (not extended) = %d, disp mode = %d, aperture = %d.\n", xga->op_mode & 7, xga->disp_cntl_2 & 7, xga->aperture_cntl);
|
||||
}
|
||||
//pclog("XGA opmode (extended) = %d, disp mode = %d, aperture = %d.\n", xga->op_mode & 7, xga->disp_cntl_2 & 7, xga->aperture_cntl);
|
||||
}
|
||||
//pclog("VGA on = %d.\n", vga_on);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -126,19 +182,19 @@ xga_recalctimings(svga_t *svga)
|
||||
|
||||
xga->ma_latch = xga->disp_start_addr;
|
||||
|
||||
switch (xga->clk_sel_1 & 0x0c) {
|
||||
switch ((xga->clk_sel_1 >> 2) & 3) {
|
||||
case 0:
|
||||
if (xga->clk_sel_2 & 0x80) {
|
||||
svga->clock = (cpuclock * (double) (1ULL << 32)) / 41539000.0;
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 41539000.0;
|
||||
} else {
|
||||
svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 25175000.0;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
svga->clock = (cpuclock * (double) (1ULL << 32)) / 28322000.0;
|
||||
case 1:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 28322000.0;
|
||||
break;
|
||||
case 0x0c:
|
||||
svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
|
||||
case 3:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 44900000.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -309,7 +365,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)
|
||||
else if ((xga->sprite_pos >= 1) || ((xga->disp_cntl_2 & 7) > 3))
|
||||
xga->cursor_data_on = 1;
|
||||
else if (xga->aperture_cntl == 0) {
|
||||
if (xga->linear_endian_reverse && !(xga->access_mode & 8))
|
||||
@@ -474,7 +530,10 @@ xga_ext_inb(uint16_t addr, void *p)
|
||||
case 0x0f:
|
||||
switch (xga->regs_idx) {
|
||||
case 4:
|
||||
ret = (xga->bus & DEVICE_MCA) ? 1 : 0;
|
||||
if (xga->bus & DEVICE_MCA)
|
||||
ret = 0x01; /*32-bit MCA*/
|
||||
else
|
||||
ret = 0x10; /*16-bit ISA*/
|
||||
break;
|
||||
case 0x10:
|
||||
ret = xga->htotal & 0xff;
|
||||
@@ -653,6 +712,16 @@ xga_ext_inb(uint16_t addr, void *p)
|
||||
ret = xga->clk_sel_2;
|
||||
break;
|
||||
|
||||
case 0x74:
|
||||
if (xga->bus & DEVICE_MCA)
|
||||
ret = xga->regs[xga->regs_idx];
|
||||
else {
|
||||
ret = (xga->dma_channel << 1);
|
||||
if (xga->dma_channel)
|
||||
ret |= 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = xga->regs[xga->regs_idx];
|
||||
break;
|
||||
@@ -678,15 +747,35 @@ xga_ext_inb(uint16_t addr, void *p)
|
||||
dat = xga->vram[(addr + 1) & (xga->vram_mask - 1)] & 0xff; \
|
||||
dat |= (xga->vram[(addr) & (xga->vram_mask - 1)] << 8);
|
||||
|
||||
#define READL(addr, dat) \
|
||||
dat = *(uint32_t *) &xga->vram[(addr) & (xga->vram_mask)];
|
||||
|
||||
#define READL_REVERSE(addr, dat) \
|
||||
dat = xga->vram[(addr + 3) & (xga->vram_mask - 3)] & 0xff; \
|
||||
dat |= (xga->vram[(addr + 2) & (xga->vram_mask - 3)] << 8); \
|
||||
dat |= (xga->vram[(addr + 1) & (xga->vram_mask - 3)] << 16); \
|
||||
dat |= (xga->vram[(addr) & (xga->vram_mask - 3)] << 24);
|
||||
|
||||
#define WRITEW(addr, dat) \
|
||||
*(uint16_t *) &xga->vram[((addr)) & (xga->vram_mask)] = dat; \
|
||||
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount;
|
||||
|
||||
#define WRITEL(addr, dat) \
|
||||
*(uint32_t *) &xga->vram[((addr)) & (xga->vram_mask)] = dat; \
|
||||
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount;
|
||||
|
||||
#define WRITEW_REVERSE(addr, dat) \
|
||||
xga->vram[((addr + 1)) & (xga->vram_mask - 1)] = dat & 0xff; \
|
||||
xga->vram[((addr)) & (xga->vram_mask - 1)] = dat >> 8; \
|
||||
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount;
|
||||
|
||||
#define WRITEL_REVERSE(addr, dat) \
|
||||
xga->vram[((addr + 3)) & (xga->vram_mask - 3)] = dat & 0xff; \
|
||||
xga->vram[((addr + 2)) & (xga->vram_mask - 3)] = dat >> 8; \
|
||||
xga->vram[((addr + 1)) & (xga->vram_mask - 3)] = dat >> 16; \
|
||||
xga->vram[((addr)) & (xga->vram_mask - 3)] = dat >> 24; \
|
||||
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount;
|
||||
|
||||
#define ROP(mix, d, s) \
|
||||
{ \
|
||||
switch ((mix) ? (xga->accel.frgd_mix & 0x1f) : (xga->accel.bkgd_mix & 0x1f)) { \
|
||||
@@ -859,6 +948,23 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int
|
||||
byte = mem_readw_phys(addr);
|
||||
}
|
||||
return byte;
|
||||
case 5: /*24-bit*/
|
||||
addr += (y * (width << 2));
|
||||
addr += (x << 2);
|
||||
if (!skip) {
|
||||
if ((xga->accel.px_map_format[map] & 8)) {
|
||||
if (xga->linear_endian_reverse) {
|
||||
READL(addr, byte);
|
||||
} else {
|
||||
READL_REVERSE(addr, byte);
|
||||
}
|
||||
} else {
|
||||
READL(addr, byte);
|
||||
}
|
||||
} else {
|
||||
byte = mem_readl_phys(addr);
|
||||
}
|
||||
return byte;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -936,6 +1042,22 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui
|
||||
}
|
||||
mem_writew_phys(addr, pixel);
|
||||
break;
|
||||
case 5: /*24-bit*/
|
||||
addr += (y * (width) << 2);
|
||||
addr += (x << 2);
|
||||
if (!skip) {
|
||||
if ((xga->accel.px_map_format[map] & 8)) {
|
||||
if (xga->linear_endian_reverse) {
|
||||
WRITEL(addr, pixel);
|
||||
} else {
|
||||
WRITEL_REVERSE(addr, pixel);
|
||||
}
|
||||
} else {
|
||||
WRITEL(addr, pixel);
|
||||
}
|
||||
}
|
||||
mem_writel_phys(addr, pixel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1447,6 +1569,10 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len)
|
||||
|
||||
if (addr >= 0x1800) {
|
||||
switch (addr & 0x7f) {
|
||||
case 0x11:
|
||||
xga->accel.control = val;
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
xga->accel.px_map_idx = val & 3;
|
||||
break;
|
||||
@@ -1923,11 +2049,21 @@ xga_mem_read(uint32_t addr, xga_t *xga, svga_t *svga)
|
||||
uint8_t temp = 0;
|
||||
|
||||
addr &= 0x1fff;
|
||||
|
||||
if (addr < 0x1800) {
|
||||
if (!xga_has_vga)
|
||||
temp = xga->bios_rom.rom[addr];
|
||||
else
|
||||
temp = xga->vga_bios_rom.rom[addr];
|
||||
} else {
|
||||
switch (addr & 0x7f) {
|
||||
case 0x11:
|
||||
temp = xga->accel.control;
|
||||
if (xga->accel.control & 0x08)
|
||||
temp |= 0x10;
|
||||
else
|
||||
temp &= ~0x10;
|
||||
break;
|
||||
|
||||
case 0x20:
|
||||
temp = xga->accel.bres_err_term & 0xff;
|
||||
break;
|
||||
@@ -2092,8 +2228,9 @@ xga_render_overscan_left(xga_t *xga, svga_t *svga)
|
||||
if (svga->scrblank || (xga->h_disp == 0))
|
||||
return;
|
||||
|
||||
uint32_t *line_ptr = svga->monitor->target_buffer->line[xga->displine + svga->y_add];
|
||||
for (int i = 0; i < svga->x_add; i++)
|
||||
buffer32->line[xga->displine + svga->y_add][i] = svga->overscan_color;
|
||||
*line_ptr++ = svga->overscan_color;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2107,9 +2244,10 @@ xga_render_overscan_right(xga_t *xga, svga_t *svga)
|
||||
if (svga->scrblank || (xga->h_disp == 0))
|
||||
return;
|
||||
|
||||
uint32_t *line_ptr = &svga->monitor->target_buffer->line[xga->displine + svga->y_add][svga->x_add + xga->h_disp];
|
||||
right = (overscan_x >> 1);
|
||||
for (int i = 0; i < right; i++)
|
||||
buffer32->line[xga->displine + svga->y_add][svga->x_add + xga->h_disp + i] = svga->overscan_color;
|
||||
*line_ptr++ = svga->overscan_color;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2122,7 +2260,7 @@ xga_render_8bpp(xga_t *xga, svga_t *svga)
|
||||
return;
|
||||
|
||||
if (xga->changedvram[xga->ma >> 12] || xga->changedvram[(xga->ma >> 12) + 1] || svga->fullchange) {
|
||||
p = &buffer32->line[xga->displine + svga->y_add][svga->x_add];
|
||||
p = &svga->monitor->target_buffer->line[xga->displine + svga->y_add][svga->x_add];
|
||||
|
||||
if (xga->firstline_draw == 2000)
|
||||
xga->firstline_draw = xga->displine;
|
||||
@@ -2159,7 +2297,7 @@ xga_render_16bpp(xga_t *xga, svga_t *svga)
|
||||
return;
|
||||
|
||||
if (xga->changedvram[xga->ma >> 12] || xga->changedvram[(xga->ma >> 12) + 1] || svga->fullchange) {
|
||||
p = &buffer32->line[xga->displine + svga->y_add][svga->x_add];
|
||||
p = &svga->monitor->target_buffer->line[xga->displine + svga->y_add][svga->x_add];
|
||||
|
||||
if (xga->firstline_draw == 2000)
|
||||
xga->firstline_draw = xga->displine;
|
||||
@@ -2524,7 +2662,7 @@ xga_poll(xga_t *xga, svga_t *svga)
|
||||
}
|
||||
|
||||
xga->vc++;
|
||||
xga->vc &= 2047;
|
||||
xga->vc &= 0x7ff;
|
||||
|
||||
if (xga->vc == xga->split) {
|
||||
if (xga->interlace && xga->oddeven)
|
||||
@@ -2683,8 +2821,149 @@ static uint8_t
|
||||
xga_pos_in(uint16_t addr, void *priv)
|
||||
{
|
||||
svga_t *svga = (svga_t *) priv;
|
||||
xga_t *xga = &svga->xga;
|
||||
uint8_t ret;
|
||||
|
||||
return (xga_mca_read(addr, svga));
|
||||
if (xga_has_vga) {
|
||||
switch (addr) {
|
||||
case 0x0100:
|
||||
case 0x0101:
|
||||
if (xga->instance_isa == xga->instance_num)
|
||||
ret = xga->pos_regs[addr & 7];
|
||||
else
|
||||
ret = 0xff;
|
||||
break;
|
||||
case 0x0102:
|
||||
case 0x0105:
|
||||
ret = xga->pos_regs[addr & 7];
|
||||
break;
|
||||
case 0x0106:
|
||||
ret = xga->pos_idx >> 8;
|
||||
break;
|
||||
case 0x0107:
|
||||
ret = xga->pos_idx & 0xff;
|
||||
break;
|
||||
case 0x0103:
|
||||
if (!(xga->pos_idx & 3)) {
|
||||
ret = xga->pos_regs[3];
|
||||
} else
|
||||
ret = 0;
|
||||
//pclog("POS IDX for 0103 = %d, ret = %02x.\n", xga->pos_idx & 3, ret);
|
||||
break;
|
||||
case 0x0104:
|
||||
switch (xga->pos_idx & 3) {
|
||||
case 0:
|
||||
ret = xga->pos_regs[4];
|
||||
break;
|
||||
case 1:
|
||||
ret = xga->pos_regs[0];
|
||||
break;
|
||||
case 2:
|
||||
ret = xga->pos_regs[1];
|
||||
break;
|
||||
case 3:
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
//pclog("POS IDX for 0104 = %d, ret = %02x.\n", xga->pos_idx & 3, ret);
|
||||
break;
|
||||
case 0x0108:
|
||||
case 0x0109:
|
||||
case 0x010a:
|
||||
case 0x010b:
|
||||
case 0x010c:
|
||||
case 0x010d:
|
||||
case 0x010e:
|
||||
case 0x010f:
|
||||
xga->instance_num = addr & 7;
|
||||
if (xga->instance_isa == xga->instance_num)
|
||||
ret = xga->instance_isa;
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
ret |= xga->isa_pos_enable;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (addr) {
|
||||
case 0x0100:
|
||||
case 0x0101:
|
||||
ret = xga->pos_regs[addr & 7];
|
||||
break;
|
||||
case 0x0103:
|
||||
ret = xga->pos_regs[3] | 7;
|
||||
ret |= (xga->dma_channel << 3);
|
||||
break;
|
||||
case 0x0102:
|
||||
case 0x0104:
|
||||
case 0x0105:
|
||||
case 0x0106:
|
||||
case 0x0107:
|
||||
ret = (xga_mca_read(addr, svga));
|
||||
break;
|
||||
case 0x0108:
|
||||
case 0x0109:
|
||||
case 0x010a:
|
||||
case 0x010b:
|
||||
case 0x010c:
|
||||
case 0x010d:
|
||||
case 0x010e:
|
||||
case 0x010f:
|
||||
xga->instance_num = addr & 7;
|
||||
if (xga->instance_isa == xga->instance_num)
|
||||
ret = xga->instance_isa;
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
ret |= xga->isa_pos_enable;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
xga_pos_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
svga_t *svga = (svga_t *) priv;
|
||||
xga_t *xga = &svga->xga;
|
||||
|
||||
if (xga_has_vga) {
|
||||
switch (addr) {
|
||||
case 0x0106:
|
||||
xga->pos_idx = (xga->pos_idx & 0x00ff) | (val << 8);
|
||||
break;
|
||||
case 0x0107:
|
||||
xga->pos_idx = (xga->pos_idx & 0xff00) | (val);
|
||||
//pclog("POS IDX Write = %04x.\n", xga->pos_idx);
|
||||
break;
|
||||
case 0x0108:
|
||||
case 0x0109:
|
||||
case 0x010a:
|
||||
case 0x010b:
|
||||
case 0x010c:
|
||||
case 0x010d:
|
||||
case 0x010e:
|
||||
case 0x010f:
|
||||
xga->instance_num = addr & 7;
|
||||
xga->isa_pos_enable = val & 0x08;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (addr) {
|
||||
case 0x0108:
|
||||
case 0x0109:
|
||||
case 0x010a:
|
||||
case 0x010b:
|
||||
case 0x010c:
|
||||
case 0x010d:
|
||||
case 0x010e:
|
||||
case 0x010f:
|
||||
xga->instance_num = addr & 7;
|
||||
xga->isa_pos_enable = val & 0x08;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2700,7 +2979,10 @@ static void
|
||||
uint32_t temp;
|
||||
uint8_t *rom = NULL;
|
||||
|
||||
xga->ext_mem_addr = device_get_config_hex16("ext_mem_addr");
|
||||
xga->instance_isa = device_get_config_int("instance");
|
||||
xga->type = device_get_config_int("type");
|
||||
xga->dma_channel = device_get_config_int("dma");
|
||||
xga->bus = info->flags;
|
||||
|
||||
xga->vram_size = (1024 << 10);
|
||||
@@ -2739,8 +3021,12 @@ static void
|
||||
xga->rom_addr = 0;
|
||||
rom_init(&xga->bios_rom, xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, 0xc0000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
} else {
|
||||
if (xga_has_vga) {
|
||||
rom_init(&xga->vga_bios_rom, INMOS_XGA_BIOS_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
} else
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_xga_isa);
|
||||
xga->pos_regs[2] = 1 | 0x0c | 0xf0;
|
||||
|
||||
xga->pos_regs[2] = 1 | (xga->instance_isa << 1) | xga->ext_mem_addr;
|
||||
xga->instance = (xga->pos_regs[2] & 0x0e) >> 1;
|
||||
xga->pos_regs[4] = 1 | 2;
|
||||
xga->linear_base = ((xga->pos_regs[4] & 0xfe) * 0x1000000) + (xga->instance << 22);
|
||||
@@ -2755,7 +3041,7 @@ static void
|
||||
NULL, MEM_MAPPING_EXTERNAL, svga);
|
||||
mem_mapping_add(&xga->memio_mapping, 0, 0, xga_memio_readb, xga_memio_readw, xga_memio_readl,
|
||||
xga_memio_writeb, xga_memio_writew, xga_memio_writel,
|
||||
xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, svga);
|
||||
xga_has_vga ? xga->vga_bios_rom.rom : xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, svga);
|
||||
|
||||
mem_mapping_disable(&xga->video_mapping);
|
||||
mem_mapping_disable(&xga->linear_mapping);
|
||||
@@ -2768,13 +3054,41 @@ static void
|
||||
mca_add(xga_mca_read, xga_mca_write, xga_mca_feedb, xga_mca_reset, svga);
|
||||
} else {
|
||||
io_sethandler(0x0100, 0x0008, xga_pos_in, NULL, NULL, NULL, NULL, NULL, svga);
|
||||
if (xga_has_vga)
|
||||
io_sethandler(0x0106, 0x0002, NULL, NULL, NULL, xga_pos_out, NULL, NULL, svga);
|
||||
|
||||
io_sethandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga);
|
||||
io_sethandler(0x0108, 0x0008, xga_pos_in, NULL, NULL, xga_pos_out, NULL, NULL, svga);
|
||||
mem_mapping_set_addr(&xga->memio_mapping, xga->rom_addr + 0x1c00 + (xga->instance * 0x80), 0x80);
|
||||
}
|
||||
|
||||
return svga;
|
||||
}
|
||||
|
||||
static void
|
||||
*
|
||||
svga_xga_init(const device_t *info)
|
||||
{
|
||||
svga_t *svga = malloc(sizeof(svga_t));
|
||||
memset(svga, 0, sizeof(svga_t));
|
||||
|
||||
video_inform(VIDEO_FLAG_TYPE_XGA, &timing_xga_isa);
|
||||
|
||||
svga_init(info, svga, svga, 1 << 18, /*256kB*/
|
||||
NULL,
|
||||
svga_xga_in, svga_xga_out,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
io_sethandler(0x03c0, 0x0020, svga_xga_in, NULL, NULL, svga_xga_out, NULL, NULL, svga);
|
||||
|
||||
svga->bpp = 8;
|
||||
svga->miscout = 1;
|
||||
xga_has_vga = 1;
|
||||
xga_enabled = 1;
|
||||
|
||||
return xga_init(info);
|
||||
}
|
||||
|
||||
static void
|
||||
xga_close(void *p)
|
||||
{
|
||||
@@ -2793,6 +3107,12 @@ xga_available(void)
|
||||
return rom_present(XGA_BIOS_PATH) && rom_present(XGA2_BIOS_PATH);
|
||||
}
|
||||
|
||||
static int
|
||||
inmos_xga_available(void)
|
||||
{
|
||||
return rom_present(INMOS_XGA_BIOS_PATH);
|
||||
}
|
||||
|
||||
static void
|
||||
xga_speed_changed(void *p)
|
||||
{
|
||||
@@ -2809,7 +3129,7 @@ xga_force_redraw(void *p)
|
||||
svga->fullchange = svga->monitor->mon_changeframecount;
|
||||
}
|
||||
|
||||
static const device_config_t xga_configuration[] = {
|
||||
static const device_config_t xga_mca_configuration[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "type",
|
||||
@@ -2835,6 +3155,91 @@ static const device_config_t xga_configuration[] = {
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static const device_config_t xga_isa_configuration[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "type",
|
||||
.description = "XGA type",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = "",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{
|
||||
.description = "XGA-1",
|
||||
.value = 0
|
||||
},
|
||||
{
|
||||
.description = "XGA-2",
|
||||
.value = 1
|
||||
},
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
{
|
||||
.name = "instance",
|
||||
.description = "Instance",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = "",
|
||||
.default_int = 6,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "0 (2100h-210Fh)", .value = 0 },
|
||||
{ .description = "1 (2110h-211Fh)", .value = 1 },
|
||||
{ .description = "2 (2120h-212Fh)", .value = 2 },
|
||||
{ .description = "3 (2130h-213Fh)", .value = 3 },
|
||||
{ .description = "4 (2140h-214Fh)", .value = 4 },
|
||||
{ .description = "5 (2150h-215Fh)", .value = 5 },
|
||||
{ .description = "6 (2160h-216Fh)", .value = 6 },
|
||||
{ .description = "7 (2170h-217Fh)", .value = 7 },
|
||||
{ .description = "" }
|
||||
},
|
||||
},
|
||||
{
|
||||
.name = "ext_mem_addr",
|
||||
.description = "MMIO address",
|
||||
.type = CONFIG_HEX16,
|
||||
.default_string = "",
|
||||
.default_int = 0x00f0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "C800h", .value = 0x0040 },
|
||||
{ .description = "CA00h", .value = 0x0050 },
|
||||
{ .description = "CC00h", .value = 0x0060 },
|
||||
{ .description = "CE00h", .value = 0x0070 },
|
||||
{ .description = "D000h", .value = 0x0080 },
|
||||
{ .description = "D200h", .value = 0x0090 },
|
||||
{ .description = "D400h", .value = 0x00a0 },
|
||||
{ .description = "D600h", .value = 0x00b0 },
|
||||
{ .description = "D800h", .value = 0x00c0 },
|
||||
{ .description = "DA00h", .value = 0x00d0 },
|
||||
{ .description = "DC00h", .value = 0x00e0 },
|
||||
{ .description = "DE00h", .value = 0x00f0 },
|
||||
{ .description = "" }
|
||||
},
|
||||
},
|
||||
{
|
||||
.name = "dma",
|
||||
.description = "DMA channel",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = "",
|
||||
.default_int = 7,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "Disabled", .value = 0 },
|
||||
{ .description = "DMA 6", .value = 6 },
|
||||
{ .description = "DMA 7", .value = 7 },
|
||||
{ .description = "" }
|
||||
},
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t xga_device = {
|
||||
.name = "XGA (MCA)",
|
||||
.internal_name = "xga_mca",
|
||||
@@ -2846,7 +3251,7 @@ const device_t xga_device = {
|
||||
{ .available = xga_available },
|
||||
.speed_changed = xga_speed_changed,
|
||||
.force_redraw = xga_force_redraw,
|
||||
.config = xga_configuration
|
||||
.config = xga_mca_configuration
|
||||
};
|
||||
|
||||
const device_t xga_isa_device = {
|
||||
@@ -2860,13 +3265,27 @@ const device_t xga_isa_device = {
|
||||
{ .available = xga_available },
|
||||
.speed_changed = xga_speed_changed,
|
||||
.force_redraw = xga_force_redraw,
|
||||
.config = xga_configuration
|
||||
.config = xga_isa_configuration
|
||||
};
|
||||
|
||||
const device_t inmos_isa_device = {
|
||||
.name = "INMOS XGA (ISA)",
|
||||
.internal_name = "inmos_xga_isa",
|
||||
.flags = DEVICE_ISA | DEVICE_AT,
|
||||
.local = 0,
|
||||
.init = svga_xga_init,
|
||||
.close = xga_close,
|
||||
.reset = xga_reset,
|
||||
{ .available = inmos_xga_available },
|
||||
.speed_changed = xga_speed_changed,
|
||||
.force_redraw = xga_force_redraw,
|
||||
.config = xga_isa_configuration
|
||||
};
|
||||
|
||||
void
|
||||
xga_device_add(void)
|
||||
{
|
||||
if (!xga_enabled)
|
||||
if (!xga_enabled || (xga_has_vga && xga_enabled))
|
||||
return;
|
||||
|
||||
if (machine_has_bus(machine, MACHINE_BUS_MCA))
|
||||
|
||||
@@ -711,6 +711,7 @@ VIDOBJ := agpgart.o video.o \
|
||||
vid_vga.o \
|
||||
vid_ati_eeprom.o \
|
||||
vid_ati18800.o vid_ati28800.o \
|
||||
vid_ati_mach8.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 \
|
||||
|
||||
Reference in New Issue
Block a user