@@ -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;
|
||||
|
@@ -36,7 +36,7 @@ SettingsDisplay::SettingsDisplay(QWidget *parent)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
videoCard[0] = gfxcard[0];
|
||||
videoCard[0] = gfxcard[0];
|
||||
videoCard[1] = gfxcard[1];
|
||||
onCurrentMachineChanged(machine);
|
||||
}
|
||||
@@ -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,10 +128,12 @@ SettingsDisplay::on_pushButtonConfigureVoodoo_clicked()
|
||||
void
|
||||
SettingsDisplay::on_pushButtonConfigureXga_clicked()
|
||||
{
|
||||
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));
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
ibm8514_recalctimings(svga);
|
||||
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;
|
||||
|
||||
disptime = svga->htotal;
|
||||
_dispontime = svga->hdisp_time;
|
||||
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);
|
||||
return;
|
||||
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,8 +805,14 @@ 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) {
|
||||
svga->linecountff = 1;
|
||||
/*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) {
|
||||
svga->linecountff = 0;
|
||||
@@ -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 (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);
|
||||
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;
|
||||
} else
|
||||
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;
|
||||
addr <<= 2;
|
||||
} else
|
||||
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)) {
|
||||
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);
|
||||
mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000);
|
||||
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;
|
||||
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);
|
||||
}
|
||||
if (xga->a5_test && (xga->access_mode & 8) && !xga->linear_endian_reverse) {
|
||||
xga->on = 0;
|
||||
vga_on = !xga->on;
|
||||
}
|
||||
}
|
||||
} 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) {
|
||||
temp = xga->bios_rom.rom[addr];
|
||||
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;
|
||||
|
||||
right = (overscan_x >> 1);
|
||||
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,12 +3021,16 @@ 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 {
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_xga_isa);
|
||||
xga->pos_regs[2] = 1 | 0x0c | 0xf0;
|
||||
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 | (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);
|
||||
xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xf0) >> 4) * 0x2000);
|
||||
xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xf0) >> 4) * 0x2000);
|
||||
}
|
||||
|
||||
mem_mapping_add(&xga->video_mapping, 0, 0, xga_readb, xga_readw, xga_readl,
|
||||
@@ -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