Added Cirrus Logic GD5428 emulation.

As part of this, added emulation of the GD5428-based IBM 1MB SVGA Adapter/A,
along with support for external graphics cards on MCA platforms, adding the
ability to override the onboard VGA controller.
This commit is contained in:
SarahW 2020-02-01 16:30:34 +00:00
commit 68a2d8cb3c
14 changed files with 342 additions and 43 deletions

View file

@ -917,7 +917,7 @@ static void *esdi_init()
timer_add(&esdi->callback_timer, esdi_callback, esdi, 0);
mca_add(esdi_mca_read, esdi_mca_write, esdi);
mca_add(esdi_mca_read, esdi_mca_write, NULL, esdi);
esdi->pos_regs[0] = 0xff;
esdi->pos_regs[1] = 0xdd;

View file

@ -165,7 +165,7 @@ int driveempty[2];
#define PCJR (romset == ROM_IBMPCJR)
int GAMEBLASTER, GUS, SSI2001, voodoo_enabled;
extern int AMSTRAD, AT, is386, PCI, TANDY;
extern int AMSTRAD, AT, is386, PCI, TANDY, MCA;
enum
{
@ -304,6 +304,8 @@ enum
GFX_EGAWONDER800, /*ATI EGA Wonder 800+*/
GFX_MYSTIQUE, /*Matrox Mystique*/
GFX_AVGA2, /*Acumos AVGA2 / Cirrus Logic CL-GD5402*/
GFX_CL_GD5428, /*Cirrus Logic CL-GD5428*/
GFX_IBM_GD5428, /*IBM 1MB SVGA Adapter/A*/
GFX_MAX
};

View file

@ -6,6 +6,7 @@
void (*mca_card_write[8])(int addr, uint8_t val, void *priv);
uint8_t (*mca_card_read[8])(int addr, void *priv);
void (*mca_card_reset[8])(void *priv);
void *mca_priv[8];
static int mca_index;
static int mca_nr_cards;
@ -14,10 +15,13 @@ void mca_init(int nr_cards)
{
int c;
MCA = 1;
for (c = 0; c < 8; c++)
{
mca_card_read[c] = NULL;
mca_card_write[c] = NULL;
mca_card_reset[c] = NULL;
mca_priv[c] = NULL;
}
@ -47,7 +51,18 @@ void mca_write(uint16_t port, uint8_t val)
mca_card_write[mca_index](port, val, mca_priv[mca_index]);
}
void mca_add(uint8_t (*read)(int addr, void *priv), void (*write)(int addr, uint8_t val, void *priv), void *priv)
void mca_reset(void)
{
int c;
for (c = 0; c < 8; c++)
{
if (mca_card_reset[c])
mca_card_reset[c](mca_priv[c]);
}
}
void mca_add(uint8_t (*read)(int addr, void *priv), void (*write)(int addr, uint8_t val, void *priv), void (*reset)(void *priv), void *priv)
{
int c;
@ -57,6 +72,7 @@ void mca_add(uint8_t (*read)(int addr, void *priv), void (*write)(int addr, uint
{
mca_card_read[c] = read;
mca_card_write[c] = write;
mca_card_reset[c] = reset;
mca_priv[c] = priv;
return;
}

View file

@ -1,5 +1,6 @@
void mca_init(int nr_cards);
void mca_add(uint8_t (*read)(int addr, void *priv), void (*write)(int addr, uint8_t val, void *priv), void *priv);
void mca_add(uint8_t (*read)(int addr, void *priv), void (*write)(int addr, uint8_t val, void *priv), void (*reset)(void *priv), void *priv);
void mca_set_index(int index);
uint8_t mca_read(uint16_t port);
void mca_write(uint16_t port, uint8_t val);
void mca_reset(void);

View file

@ -127,7 +127,7 @@ void xt_zenith_init();
void at_mvp3_init();
int model;
int AMSTRAD, AT, PCI, TANDY;
int AMSTRAD, AT, PCI, TANDY, MCA;
MODEL models[] =
{
@ -174,7 +174,7 @@ MODEL models[] =
{"[286] IBM AT", ROM_IBMAT, "ibmat", { {"", cpus_ibmat}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 256,15872, 128, ibm_at_init, NULL},
{"[286] IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { {"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2, 512,16384, 512, ps1_m2011_init, NULL},
{"[286] IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { {"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2, 1, 16, 1, ps2_m30_286_init, NULL},
{"[286] IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", { {"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 16, 1, ps2_model_50_init, NULL},
{"[286] IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", { {"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 16, 1, ps2_model_50_init, NULL},
{"[286] IBM XT Model 286", ROM_IBMXT286, "ibmxt286", { {"", cpus_ibmxt286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 256,15872, 128, ibm_at_init, NULL},
{"[286] Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 512, 2048, 128, at_scat_init, NULL},
{"[286] Samsung SPC-4216P", ROM_SPC4216P, "spc4216p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 5, 1, at_scat_init, NULL},
@ -190,21 +190,21 @@ MODEL models[] =
{"[386SX] DTK 386SX clone", ROM_DTK386, "dtk386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_neat_init, NULL},
{"[386SX] Epson PC AX3", ROM_EPSON_PCAX3, "epson_pcax3", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT, 256,15872, 128, at_init, NULL},
{"[386SX] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL},
{"[386SX] IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 8, 1, ps2_model_55sx_init, NULL},
{"[386SX] IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 8, 1, ps2_model_55sx_init, NULL},
{"[386SX] KMX-C-02", ROM_KMXC02, "kmxc02", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT, 512,16384, 512, at_scatsx_init, NULL},
{"[386SX] Packard Bell Legend 300SX", ROM_PB_L300SX, "pb_l300sx", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, pb_l300sx_init, NULL},
{"[386DX] AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL},
{"[386DX] Compaq Deskpro 386", ROM_DESKPRO_386, "deskpro386", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE|MODEL_AT, 1, 15, 1, deskpro386_init, NULL},
{"[386DX] IBM PS/2 Model 70 (type 3)", ROM_IBMPS2_M70_TYPE3, "ibmps2_m70_type3", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_MCA, 2, 16, 2, ps2_model_70_init, NULL},
{"[386DX] IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 12, 1, ps2_model_80_init, NULL},
{"[386DX] IBM PS/2 Model 70 (type 3)", ROM_IBMPS2_M70_TYPE3, "ibmps2_m70_type3", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_MCA, 2, 16, 2, ps2_model_70_init, NULL},
{"[386DX] IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 12, 1, ps2_model_80_init, NULL},
{"[386DX] MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL},
{"[486] AMI 486 clone", ROM_AMI486, "ami486", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL},
{"[486] AMI WinBIOS 486", ROM_WIN486, "win486", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL},
{"[486] Award SiS 496/497", ROM_SIS496, "sis496", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_HAS_IDE, 1, 256, 1, at_sis496_init, NULL},
{"[486] Elonex PC-425X", ROM_ELX_PC425X, "elx_pc425x", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_sl82c460_init, NULL},
{"[486] IBM PS/2 Model 70 (type 4)", ROM_IBMPS2_M70_TYPE4, "ibmps2_m70_type4", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_MCA, 2, 16, 2, ps2_model_70_init, NULL},
{"[486] IBM PS/2 Model 70 (type 4)", ROM_IBMPS2_M70_TYPE4, "ibmps2_m70_type4", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_MCA, 2, 16, 2, ps2_model_70_init, NULL},
{"[486] Packard Bell PB410A", ROM_PB410A, "pb410a", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 64, 1, at_pb410a_init, NULL},
{"[Socket 4] Intel Premiere/PCI", ROM_REVENGE, "revenge", { {"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_batman_init, NULL},
@ -788,7 +788,7 @@ void at_mvp3_init()
void model_init()
{
pclog("Initting as %s\n", model_getname());
AMSTRAD = AT = PCI = TANDY = 0;
AMSTRAD = AT = PCI = TANDY = MCA = 0;
ide_set_bus_master(NULL, NULL, NULL, NULL);
models[model].init();

View file

@ -9,6 +9,7 @@
#include "ps2_nvr.h"
#include "rom.h"
#include "serial.h"
#include "vid_vga.h"
#include "x86.h"
//static uint8_t ps2_92, ps2_94, ps2_102, ps2_103, ps2_104, ps2_105, ps2_190;
@ -652,6 +653,8 @@ static void ps2_mca_write(uint16_t port, uint8_t val, void *p)
ps2.setup = val;
break;
case 0x96:
if ((val & 0x80) && !(ps2.adapter_setup & 0x80))
mca_reset();
ps2.adapter_setup = val;
mca_set_index(val & 7);
break;
@ -671,7 +674,15 @@ static void ps2_mca_write(uint16_t port, uint8_t val, void *p)
if (!(ps2.setup & PS2_SETUP_IO))
ps2.planar_write(port, val);
else if (!(ps2.setup & PS2_SETUP_VGA))
{
if (mb_vga)
{
vga_disable(mb_vga);
if (val & 1)
vga_enable(mb_vga);
}
ps2.pos_vga = val;
}
else if (ps2.adapter_setup & PS2_ADAPTER_SETUP)
mca_write(port, val);
break;
@ -1018,7 +1029,7 @@ void ps2_mca_board_model_70_type34_init(int is_type4)
break;
}
mca_add(ps2_mem_expansion_read, ps2_mem_expansion_write, NULL);
mca_add(ps2_mem_expansion_read, ps2_mem_expansion_write, NULL, NULL);
mem_mapping_add(&ps2.expansion_mapping,
0x800000,
(mem_size - 8192)*1024,
@ -1119,7 +1130,7 @@ void ps2_mca_board_model_80_type2_init()
break;
}
mca_add(ps2_mem_expansion_read, ps2_mem_expansion_write, NULL);
mca_add(ps2_mem_expansion_read, ps2_mem_expansion_write, NULL, NULL);
mem_mapping_add(&ps2.expansion_mapping,
0x400000,
(mem_size - 4096)*1024,

View file

@ -76,7 +76,7 @@ void *adlib_mca_init()
adlib_t *adlib = adlib_init();
io_removehandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &adlib->opl);
mca_add(adlib_mca_read, adlib_mca_write, adlib);
mca_add(adlib_mca_read, adlib_mca_write, NULL, adlib);
adlib->pos_regs[0] = 0xd7;
adlib->pos_regs[1] = 0x70;

View file

@ -999,7 +999,7 @@ void *sb_mcv_init()
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
sound_add_handler(sb_get_buffer_sb2, sb);
/* I/O handlers activated in sb_mcv_write */
mca_add(sb_mcv_read, sb_mcv_write, sb);
mca_add(sb_mcv_read, sb_mcv_write, NULL, sb);
sb->pos_regs[0] = 0x84;
sb->pos_regs[1] = 0x50;
return sb;
@ -1124,7 +1124,7 @@ void *sb_pro_mcv_init()
sound_add_handler(sb_get_buffer_sbpro, sb);
/* I/O handlers activated in sb_pro_mcv_write */
mca_add(sb_pro_mcv_read, sb_pro_mcv_write, sb);
mca_add(sb_pro_mcv_read, sb_pro_mcv_write, NULL, sb);
sb->pos_regs[0] = 0x03;
sb->pos_regs[1] = 0x51;

View file

@ -4,6 +4,7 @@
#include "cpu.h"
#include "device.h"
#include "io.h"
#include "mca.h"
#include "mem.h"
#include "pci.h"
#include "rom.h"
@ -11,11 +12,13 @@
#include "vid_cl5429.h"
#include "vid_svga.h"
#include "vid_svga_render.h"
#include "vid_vga.h"
#include "vid_unk_ramdac.h"
enum
{
CL_TYPE_AVGA2 = 0,
CL_TYPE_GD5428,
CL_TYPE_GD5429,
CL_TYPE_GD5430,
CL_TYPE_GD5434
@ -25,6 +28,10 @@ enum
#define BLIT_DEPTH_16 1
#define BLIT_DEPTH_32 3
#define CL_GD5428_SYSTEM_BUS_MCA 5
#define CL_GD5428_SYSTEM_BUS_VESA 6
#define CL_GD5428_SYSTEM_BUS_ISA 7
#define CL_GD5429_SYSTEM_BUS_VESA 5
#define CL_GD5429_SYSTEM_BUS_ISA 7
@ -51,6 +58,7 @@ typedef struct gd5429_t
struct
{
uint32_t bg_col, fg_col;
uint16_t trans_col, trans_mask;
uint16_t width, height;
uint16_t dst_pitch, src_pitch;
uint32_t dst_addr, src_addr;
@ -60,6 +68,9 @@ typedef struct gd5429_t
uint16_t width_backup, height_internal;
int x_count, y_count;
int depth;
int mem_word_sel;
uint16_t mem_word_save;
} blt;
uint8_t hidden_dac_reg;
@ -69,6 +80,9 @@ typedef struct gd5429_t
uint8_t int_line;
int card;
uint8_t pos_regs[8];
svga_t *mb_vga;
uint32_t lfb_base;
int mmio_vram_overlap;
@ -76,6 +90,8 @@ typedef struct gd5429_t
uint8_t sr10_read, sr11_read;
uint8_t latch_ext[4];
int vidsys_ena;
} gd5429_t;
#define GRB_X8_ADDRESSING (1 << 1)
@ -97,6 +113,8 @@ void gd5429_recalc_mapping(gd5429_t *gd5429);
uint8_t gd5429_read_linear(uint32_t addr, void *p);
static void ibm_gd5428_mapping_update(gd5429_t *gd5429);
void gd5429_out(uint16_t addr, uint8_t val, void *p)
{
gd5429_t *gd5429 = (gd5429_t *)p;
@ -110,6 +128,14 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p)
switch (addr)
{
case 0x3c3:
if (MCA)
{
gd5429->vidsys_ena = val & 1;
ibm_gd5428_mapping_update(gd5429);
}
break;
case 0x3c4:
svga->seqaddr = val;
break;
@ -206,7 +232,7 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p)
if (svga->gdcaddr > 8)
{
svga->gdcreg[svga->gdcaddr & 0x3f] = val;
if (gd5429->type < CL_TYPE_GD5429 && (svga->gdcaddr > 0xb))
if (gd5429->type < CL_TYPE_GD5428 && (svga->gdcaddr > 0xb))
return;
switch (svga->gdcaddr)
{
@ -296,6 +322,23 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p)
case 0x31:
gd5429_mmio_write(0xb8040, val, gd5429);
break;
case 0x34:
if (gd5429->type <= CL_TYPE_GD5428)
gd5429->blt.trans_col = (gd5429->blt.trans_col & 0xff00) | val;
break;
case 0x35:
if (gd5429->type <= CL_TYPE_GD5428)
gd5429->blt.trans_col = (gd5429->blt.trans_col & 0x00ff) | (val << 8);
break;
case 0x36:
if (gd5429->type <= CL_TYPE_GD5428)
gd5429->blt.trans_mask = (gd5429->blt.trans_mask & 0xff00) | val;
break;
case 0x37:
if (gd5429->type <= CL_TYPE_GD5428)
gd5429->blt.trans_mask = (gd5429->blt.trans_mask & 0x00ff) | (val << 8);
break;
}
return;
}
@ -337,6 +380,11 @@ uint8_t gd5429_in(uint16_t addr, void *p)
switch (addr)
{
case 0x3c3:
if (MCA)
return gd5429->vidsys_ena;
break;
case 0x3c4:
if ((svga->seqaddr & 0x1f) == 0x10)
return (svga->seqaddr & 0x1f) | gd5429->sr10_read;
@ -355,11 +403,20 @@ uint8_t gd5429_in(uint16_t addr, void *p)
return ((svga->seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f;
case 0x17:
if (gd5429->type < CL_TYPE_GD5429)
if (gd5429->type < CL_TYPE_GD5428)
break;
temp = svga->seqregs[0x17];
temp &= ~(7 << 3);
if (gd5429->type == CL_TYPE_GD5429)
if (gd5429->type == CL_TYPE_GD5428)
{
if (MCA)
temp |= (CL_GD5428_SYSTEM_BUS_MCA << 3);
else if (has_vlb)
temp |= (CL_GD5428_SYSTEM_BUS_VESA << 3);
else
temp |= (CL_GD5428_SYSTEM_BUS_ISA << 3);
}
else if (gd5429->type == CL_TYPE_GD5429)
{
if (has_vlb)
temp |= (CL_GD5429_SYSTEM_BUS_VESA << 3);
@ -411,6 +468,8 @@ uint8_t gd5429_in(uint16_t addr, void *p)
{
case CL_TYPE_AVGA2:
return 0x18; /*AVGA2*/
case CL_TYPE_GD5428:
return 0x98; /*GD5428*/
case CL_TYPE_GD5429:
return 0x9c; /*GD5429*/
case CL_TYPE_GD5430:
@ -453,7 +512,8 @@ void gd5429_recalc_mapping(gd5429_t *gd5429)
{
svga_t *svga = &gd5429->svga;
if (PCI && gd5429->type >= CL_TYPE_GD5430 && !(gd5429->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))
if ((PCI && gd5429->type >= CL_TYPE_GD5430 && !(gd5429->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) ||
(MCA && (!(gd5429->pos_regs[2] & 0x01) || !gd5429->vidsys_ena)))
{
mem_mapping_disable(&svga->mapping);
mem_mapping_disable(&gd5429->linear_mapping);
@ -487,7 +547,7 @@ void gd5429_recalc_mapping(gd5429_t *gd5429)
gd5429->mmio_vram_overlap = 1;
break;
}
if (svga->seqregs[0x17] & 0x04)
if (gd5429->type >= CL_TYPE_GD5429 && svga->seqregs[0x17] & 0x04)
mem_mapping_set_addr(&gd5429->mmio_mapping, 0xb8000, 0x00100);
else
mem_mapping_disable(&gd5429->mmio_mapping);
@ -516,7 +576,7 @@ void gd5429_recalc_mapping(gd5429_t *gd5429)
}
mem_mapping_disable(&svga->mapping);
mem_mapping_set_addr(&gd5429->linear_mapping, base, size);
if (svga->seqregs[0x17] & 0x04)
if (gd5429->type >= CL_TYPE_GD5429 && svga->seqregs[0x17] & 0x04)
mem_mapping_set_addr(&gd5429->mmio_mapping, 0xb8000, 0x00100);
else
mem_mapping_disable(&gd5429->mmio_mapping);
@ -1448,9 +1508,18 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p)
}
//pclog("%02X %02X\n", dst, mask);
if ((gd5429->blt.width_backup - gd5429->blt.width) >= blt_mask &&
!((gd5429->blt.mode & 0x08) && !mask))
svga->vram[gd5429->blt.dst_addr & svga->vram_mask] = dst;
if (gd5429->type <= CL_TYPE_GD5428)
{
if ((gd5429->blt.width_backup - gd5429->blt.width) >= blt_mask &&
(!(gd5429->blt.mode & 0x08) || (dst & gd5429->blt.trans_mask) != gd5429->blt.trans_col))
svga->vram[gd5429->blt.dst_addr & svga->vram_mask] = dst;
}
else
{
if ((gd5429->blt.width_backup - gd5429->blt.width) >= blt_mask &&
!((gd5429->blt.mode & 0x08) && !mask))
svga->vram[gd5429->blt.dst_addr & svga->vram_mask] = dst;
}
gd5429->blt.dst_addr += ((gd5429->blt.mode & 0x01) ? -1 : 1);
@ -1708,14 +1777,22 @@ static uint32_t gd5429_mmio_readl(uint32_t addr, void *p)
void gd5429_blt_write_w(uint32_t addr, uint16_t val, void *p)
{
gd5429_t *gd5429 = (gd5429_t *)p;
// pclog("gd5429_blt_write_w %08X %08X\n", addr, val);
gd5429_start_blit(val, 16, p);
if (!gd5429->blt.mem_word_sel)
gd5429->blt.mem_word_save = val;
else
gd5429_start_blit(gd5429->blt.mem_word_save | (val << 16), 32, p);
gd5429->blt.mem_word_sel = !gd5429->blt.mem_word_sel;
}
void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *p)
{
gd5429_t *gd5429 = (gd5429_t *)p;
gd5429->blt.mem_word_sel = 0;
// pclog("gd5429_blt_write_l %08X %08X %04X %04X\n", addr, val, ((val >> 8) & 0x00ff) | ((val << 8) & 0xff00), ((val >> 24) & 0x00ff) | ((val >> 8) & 0xff00));
if ((gd5429->blt.mode & 0x84) == 0x84)
{
@ -1728,6 +1805,78 @@ void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *p)
gd5429_start_blit(val, 32, p);
}
uint8_t ibm_gd5428_mca_read(int port, void *p)
{
gd5429_t *gd5429 = (gd5429_t *)p;
// pclog("gd5429_pro_mcv_read: port=%04x %02x %04x:%04x\n", port, gd5429->pos_regs[port & 7], CS, cpu_state.pc);
return gd5429->pos_regs[port & 7];
}
static void ibm_gd5428_mapping_update(gd5429_t *gd5429)
{
gd5429_recalc_mapping(gd5429);
io_removehandler(0x03a0, 0x0023, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429);
io_removehandler(0x03c4, 0x001c, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429);
if ((gd5429->pos_regs[2] & 0x01) && gd5429->vidsys_ena)
{
// pclog(" GD5429 enable registers\n");
io_sethandler(0x03c0, 0x0003, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429);
io_sethandler(0x03c4, 0x001c, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429);
if (!(gd5429->svga.miscout & 1))
io_sethandler(0x03a0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429);
gd5429->svga.override = 0;
if (mb_vga)
svga_set_override(mb_vga, 1);
}
else
{
// pclog(" GD5429 disable registers\n");
gd5429->svga.override = 1;
if (mb_vga)
svga_set_override(mb_vga, 0);
}
}
void ibm_gd5428_mca_write(int port, uint8_t val, void *p)
{
// svga_set_override(voodoo->svga, val & 1);
gd5429_t *gd5429 = (gd5429_t *)p;
// pclog("gd5429_pro_mcv_write: port=%04x val=%02x\n", port, val);
if (port < 0x102)
return;
gd5429->pos_regs[port & 7] = val;
if ((port & 7) == 2)
{
mem_mapping_disable(&gd5429->bios_rom.mapping);
io_removehandler(0x03c3, 0x0001, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429);
if (gd5429->pos_regs[2] & 0x01)
{
// pclog("Enable BIOS mapping\n");
mem_mapping_enable(&gd5429->bios_rom.mapping);
io_sethandler(0x03c3, 0x0001, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429);
}
// else
// pclog("Disable BIOS mapping\n");
}
ibm_gd5428_mapping_update(gd5429);
}
static void ibm_gd5428_mca_reset(void *p)
{
gd5429_t *gd5429 = (gd5429_t *)p;
// pclog("ibm_gd5428_mca_reset\n");
gd5429->vidsys_ena = 0;
ibm_gd5428_mca_write(0x102, 0, gd5429);
}
static uint8_t cl_pci_read(int func, int addr, void *p)
{
gd5429_t *gd5429 = (gd5429_t *)p;
@ -1813,14 +1962,17 @@ static void cl_pci_write(int func, int addr, uint8_t val, void *p)
}
}
static void *cl_init(int type, char *fn, int pci_card)
static void *cl_init(int type, char *fn, int pci_card, uint32_t force_vram_size)
{
gd5429_t *gd5429 = malloc(sizeof(gd5429_t));
svga_t *svga = &gd5429->svga;
int vram_size;
memset(gd5429, 0, sizeof(gd5429_t));
vram_size = device_get_config_int("memory");
if (force_vram_size)
vram_size = force_vram_size;
else
vram_size = device_get_config_int("memory");
if (vram_size >= 256)
gd5429->vram_mask = (vram_size << 10) - 1;
else
@ -1849,6 +2001,8 @@ static void *cl_init(int type, char *fn, int pci_card)
io_sethandler(0x46e8, 0x0002, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429);
svga->decode_mask = svga->vram_mask;
}
if (type == CL_TYPE_GD5428)
svga->decode_mask = svga->vram_mask;
svga->hwcursor.yoff = 32;
svga->hwcursor.xoff = 0;
@ -1888,37 +2042,70 @@ static void *cl_init(int type, char *fn, int pci_card)
static void *avga2_init()
{
return cl_init(CL_TYPE_AVGA2, "avga2vram.vbi", -1);
return cl_init(CL_TYPE_AVGA2, "avga2vram.vbi", -1, 0);
}
static void *avga2_cbm_sl386sx_init()
{
return cl_init(CL_TYPE_AVGA2, "cbm_sl386sx25/c000.rom", -1);
return cl_init(CL_TYPE_AVGA2, "cbm_sl386sx25/c000.rom", -1, 0);
}
static void *gd5428_init()
{
return cl_init(CL_TYPE_GD5428, "Machspeed_VGA_GUI_2100_VLB.vbi", -1, 0);
}
static void *ibm_gd5428_init()
{
gd5429_t *gd5429;
svga_t *mb_vga = svga_get_pri();
gd5429 = cl_init(CL_TYPE_GD5428, "SVGA141.ROM", -1, 1); /*Only supports 1MB*/
gd5429->mb_vga = mb_vga;
mca_add(ibm_gd5428_mca_read, ibm_gd5428_mca_write, ibm_gd5428_mca_reset, gd5429);
gd5429->pos_regs[0] = 0x7b;
gd5429->pos_regs[1] = 0x91;
gd5429->pos_regs[2] = 0;
gd5429_recalc_mapping(gd5429);
io_removehandler(0x03a0, 0x0040, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429);
gd5429->svga.override = 1;
mem_mapping_disable(&gd5429->bios_rom.mapping);
io_sethandler(0x46e8, 0x0001, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429);
return gd5429;
}
static void *gd5429_init()
{
return cl_init(CL_TYPE_GD5429, "5429.vbi", -1);
return cl_init(CL_TYPE_GD5429, "5429.vbi", -1, 0);
}
static void *gd5430_init()
{
return cl_init(CL_TYPE_GD5430, "gd5430/pci.bin", -1);
return cl_init(CL_TYPE_GD5430, "gd5430/pci.bin", -1, 0);
}
static void *gd5430_pb570_init()
{
return cl_init(CL_TYPE_GD5430, "pb570/gd5430.bin", 8);
return cl_init(CL_TYPE_GD5430, "pb570/gd5430.bin", 8, 0);
}
static void *gd5434_init()
{
return cl_init(CL_TYPE_GD5434, "gd5434.bin", -1);
return cl_init(CL_TYPE_GD5434, "gd5434.bin", -1, 0);
}
static void *gd5434_pb520r_init()
{
return cl_init(CL_TYPE_GD5434, "pb520r/gd5434.bin", 3);
return cl_init(CL_TYPE_GD5434, "pb520r/gd5434.bin", 3, 0);
}
static int avga2_available()
{
return rom_present("avga2vram.vbi");
}
static int gd5428_available()
{
return rom_present("Machspeed_VGA_GUI_2100_VLB.vbi");
}
static int ibm_gd5428_available()
{
return rom_present(/*"FILE.ROM"*/"SVGA141.ROM");
}
static int gd5429_available()
{
return rom_present("5429.vbi");
@ -2068,6 +2255,32 @@ device_t avga2_cbm_sl386sx_device =
avga2_config
};
device_t gd5428_device =
{
"Cirrus Logic GD5428",
0,
gd5428_init,
gd5429_close,
gd5428_available,
gd5429_speed_changed,
gd5429_force_redraw,
gd5429_add_status_info,
gd5429_config
};
device_t ibm_gd5428_device =
{
"IBM 1MB SVGA Adapter/A (Cirrus Logic GD5428)",
DEVICE_MCA,
ibm_gd5428_init,
gd5429_close,
ibm_gd5428_available,
gd5429_speed_changed,
gd5429_force_redraw,
gd5429_add_status_info,
NULL
};
device_t gd5429_device =
{
"Cirrus Logic GD5429",

View file

@ -1,5 +1,7 @@
extern device_t avga2_device;
extern device_t avga2_cbm_sl386sx_device;
extern device_t gd5428_device;
extern device_t ibm_gd5428_device;
extern device_t gd5429_device;
extern device_t gd5430_device;
extern device_t gd5430_pb570_device;

View file

@ -9,6 +9,8 @@
#include "vid_svga.h"
#include "vid_vga.h"
svga_t *mb_vga = NULL;
typedef struct vga_t
{
svga_t svga;
@ -84,6 +86,30 @@ uint8_t vga_in(uint16_t addr, void *p)
return temp;
}
void vga_disable(void *p)
{
vga_t *vga = (vga_t *)p;
svga_t *svga = &vga->svga;
// pclog("vga_disable\n");
io_removehandler(0x03a0, 0x0040, vga_in, NULL, NULL, vga_out, NULL, NULL, vga);
mem_mapping_disable(&svga->mapping);
}
void vga_enable(void *p)
{
vga_t *vga = (vga_t *)p;
svga_t *svga = &vga->svga;
// pclog("vga_enable\n");
io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga);
if (!(svga->miscout & 1))
io_sethandler(0x03a0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga);
mem_mapping_enable(&svga->mapping);
}
void *vga_init()
{
vga_t *vga = malloc(sizeof(vga_t));
@ -122,6 +148,8 @@ void *ps1vga_init()
vga->svga.bpp = 8;
vga->svga.miscout = 1;
mb_vga = &vga->svga;
return vga;
}
@ -134,6 +162,8 @@ void vga_close(void *p)
{
vga_t *vga = (vga_t *)p;
mb_vga = NULL;
svga_close(&vga->svga);
free(vga);

View file

@ -1,2 +1,8 @@
extern device_t vga_device;
extern device_t ps1vga_device;
void vga_disable(void *p);
void vga_enable(void *p);
struct svga_t;
extern struct svga_t *mb_vga;

View file

@ -90,6 +90,7 @@ static VIDEO_CARD video_cards[] =
{"ATI VGA Charger (ATI-28800)", "ati28800", &ati28800_device, GFX_VGACHARGER, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}},
{"ATI VGA Edge-16 (ATI-18800)", "ati18800", &ati18800_device, GFX_VGAEDGE16, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
{"CGA", "cga", &cga_device, GFX_CGA, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
{"Cirrus Logic CL-GD5428", "cl_gd5428", &gd5428_device, GFX_CL_GD5428, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}},
{"Cirrus Logic CL-GD5429", "cl_gd5429", &gd5429_device, GFX_CL_GD5429, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}},
{"Cirrus Logic CL-GD5430", "cl_gd5430", &gd5430_device, GFX_CL_GD5430, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}},
{"Cirrus Logic CL-GD5434", "cl_gd5434", &gd5434_device, GFX_CL_GD5434, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}},
@ -99,6 +100,7 @@ static VIDEO_CARD video_cards[] =
{"EGA", "ega", &ega_device, GFX_EGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
{"Hercules", "hercules", &hercules_device, GFX_HERCULES, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
{"Hercules InColor", "incolor", &incolor_device, GFX_INCOLOR, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
{"IBM 1MB SVGA Adapter/A (CL GD5428)", "ibm1mbsvga", &ibm_gd5428_device, GFX_IBM_GD5428, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}},
{"Image Manager 1024", "im1024", &im1024_device, GFX_IM1024, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
{"Matrox Mystique", "mystique", &mystique_device, GFX_MYSTIQUE, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}},
{"MDA", "mda", &mda_device, GFX_MDA, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
@ -218,12 +220,16 @@ device_t *video_card_getdevice(int card, int romset)
case ROM_IBMPS1_2011:
case ROM_IBMPS2_M30_286:
return &ps1vga_device;
case ROM_IBMPS2_M50:
case ROM_IBMPS2_M55SX:
case ROM_IBMPS2_M70_TYPE3:
case ROM_IBMPS2_M70_TYPE4:
case ROM_IBMPS2_M80:
return &ps1vga_device;
if (card == GFX_BUILTIN)
return &ps1vga_device;
break;
case ROM_IBMPS1_2121:
return &ps1_m2121_svga_device;
@ -588,12 +594,16 @@ void video_updatetiming()
case ROM_IBMPS1_2011:
case ROM_IBMPS2_M30_286:
timing = &timing_vga;
break;
case ROM_IBMPS2_M50:
case ROM_IBMPS2_M55SX:
case ROM_IBMPS2_M70_TYPE3:
case ROM_IBMPS2_M70_TYPE4:
case ROM_IBMPS2_M80:
timing = &timing_vga;
if (gfxcard == GFX_BUILTIN)
timing = &timing_vga;
break;
case ROM_IBMPS1_2121:
@ -776,13 +786,18 @@ void video_init()
case ROM_IBMPS1_2011:
case ROM_IBMPS2_M30_286:
device_add(&ps1vga_device);
return;
case ROM_IBMPS2_M50:
case ROM_IBMPS2_M55SX:
case ROM_IBMPS2_M70_TYPE3:
case ROM_IBMPS2_M70_TYPE4:
case ROM_IBMPS2_M80:
device_add(&ps1vga_device);
return;
if (gfxcard == GFX_BUILTIN)
return;
break;
case ROM_IBMPS1_2121:
device_add(&ps1_m2121_svga_device);

View file

@ -147,7 +147,10 @@ static void recalc_vid_list(void* hdlg, int model, int force_builtin_video)
break;
if (video_card_available(c) && gfx_present[video_new_to_old(c)] &&
((models[model].flags & MODEL_PCI) || !(video_card_getdevice(c, romset)->flags & DEVICE_PCI)))
((models[model].flags & MODEL_PCI) || !(video_card_getdevice(c, romset)->flags & DEVICE_PCI)) &&
((models[model].flags & MODEL_MCA) || !(video_card_getdevice(c, romset)->flags & DEVICE_MCA)) &&
(!(models[model].flags & MODEL_MCA) || (video_card_getdevice(c, romset)->flags & DEVICE_MCA))
)
{
wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s);
if (video_new_to_old(c) == gfxcard && !found_card)