Added emulation of Commodore SL386SX-25 (PC Player II).

As part of this, added emulation of the onboard AVGA2, and fixed a couple of
bugs in the Cirrus Logic extended write modes.
Currently chipset (VLSI SCAMP) is missing EMS emulation.
This commit is contained in:
SarahW 2019-12-20 17:19:25 +00:00
commit 5c8e1aecc2
12 changed files with 499 additions and 37 deletions

View file

@ -38,7 +38,7 @@ jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c joysti
keyboard_amstrad.c keyboard_at.c keyboard_olim24.c keyboard_pcjr.c keyboard_xt.c laserxt.c lpt.c lpt_dac.c lpt_dss.c \ keyboard_amstrad.c keyboard_at.c keyboard_olim24.c keyboard_pcjr.c keyboard_xt.c laserxt.c lpt.c lpt_dac.c lpt_dss.c \
mca.c mcr.c mem.c mem_bios.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c mvp3.c \ mca.c mcr.c mem.c mem_bios.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c mvp3.c \
neat.c nmi.c nvr.c olivetti_m24.c opti495.c paths.c pc.c pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c \ neat.c nmi.c nvr.c olivetti_m24.c opti495.c paths.c pc.c pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c \
ps2_nvr.c nvr_tc8521.c pzx.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c \ ps2_nvr.c nvr_tc8521.c pzx.c rom.c rtc.c rtc_tc8521.c scamp.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c \
scsi_zip.c serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_audiopci.c \ scsi_zip.c serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_audiopci.c \
sound_cms.c sound_emu8k.c sound_gus.c sound_mpu401_uart.c sound_opl.c sound_pas16.c sound_ps1.c sound_pssj.c \ sound_cms.c sound_emu8k.c sound_gus.c sound_mpu401_uart.c sound_opl.c sound_pas16.c sound_ps1.c sound_pssj.c \
sound_sb.c sound_sb_dsp.c sound_sn76489.c sound_speaker.c sound_ssi2001.c sound_wss.c sound_ym7128.c soundopenal.c \ sound_sb.c sound_sb_dsp.c sound_sn76489.c sound_speaker.c sound_ssi2001.c sound_wss.c sound_ym7128.c soundopenal.c \

View file

@ -24,7 +24,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203
keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o \ keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o \
mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o \ mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o \
mvp3.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o \ mvp3.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o \
piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o pzx.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o \ piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o pzx.o rom.o rtc.o rtc_tc8521.o scamp.o scat.o scsi.o \
scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o \ scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o \
sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \ sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \
sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o \ sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o \

View file

@ -24,7 +24,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203
keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o \ keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o \
mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o \ mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o \
mvp3.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o \ mvp3.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o \
piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o pzx.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o \ piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o pzx.o rom.o rtc.o rtc_tc8521.o scamp.o scat.o scsi.o \
scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o \ scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o \
sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \ sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \
sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o \ sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o \

View file

@ -252,6 +252,7 @@ enum
ROM_PPC512, ROM_PPC512,
ROM_BULL_MICRAL_45, ROM_BULL_MICRAL_45,
ROM_FIC_VA503P, ROM_FIC_VA503P,
ROM_CBM_SL386SX25,
ROM_MAX ROM_MAX
}; };

View file

@ -1008,6 +1008,13 @@ int loadbios()
fclose(f); fclose(f);
biosmask = 0x1ffff; biosmask = 0x1ffff;
return 1; return 1;
case ROM_CBM_SL386SX25:
f = romfopen("cbm_sl386sx25/f000.rom", "rb");
if (!f) break;
romfread(rom, 0x10000, 1, f);
fclose(f);
return 1;
} }
printf("Failed to load ROM!\n"); printf("Failed to load ROM!\n");
if (f) fclose(f); if (f) fclose(f);

View file

@ -54,6 +54,7 @@
#include "ps1.h" #include "ps1.h"
#include "ps2.h" #include "ps2.h"
#include "ps2_mca.h" #include "ps2_mca.h"
#include "scamp.h"
#include "scat.h" #include "scat.h"
#include "serial.h" #include "serial.h"
#include "sio.h" #include "sio.h"
@ -96,6 +97,7 @@ void ps2_model_55sx_init();
void ps2_model_70_init(); void ps2_model_70_init();
void ps2_model_80_init(); void ps2_model_80_init();
void at_neat_init(); void at_neat_init();
void at_scamp_init();
void at_scat_init(); void at_scat_init();
void at_scatsx_init(); void at_scatsx_init();
void at_acer386sx_init(); void at_acer386sx_init();
@ -184,6 +186,7 @@ MODEL models[] =
{"[386SX] AMA-932J", ROM_AMA932J, "ama932j", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_HAS_IDE, 512, 8192, 128, at_headland_init, NULL}, {"[386SX] AMA-932J", ROM_AMA932J, "ama932j", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_HAS_IDE, 512, 8192, 128, at_headland_init, NULL},
{"[386SX] AMI 386SX clone", ROM_AMI386SX, "ami386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_headland_init, NULL}, {"[386SX] AMI 386SX clone", ROM_AMI386SX, "ami386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_headland_init, NULL},
{"[386SX] Amstrad MegaPC", ROM_MEGAPC, "megapc", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_DISABLE_HW|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, {"[386SX] Amstrad MegaPC", ROM_MEGAPC, "megapc", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_DISABLE_HW|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL},
{"[386SX] Commodore SL386SX-25", ROM_CBM_SL386SX25, "cbm_sl386sx25", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1024,16384, 512, at_scamp_init, NULL},
{"[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] 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] 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/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},
@ -567,6 +570,12 @@ void at_neat_init()
neat_init(); neat_init();
} }
void at_scamp_init()
{
at_init();
scamp_init();
}
void at_scat_init() void at_scat_init()
{ {
at_init(); at_init();

View file

@ -347,6 +347,7 @@ void loadnvr()
case ROM_PB410A: f = nvrfopen("pb410a.nvr", "rb"); nvrmask = 127; break; case ROM_PB410A: f = nvrfopen("pb410a.nvr", "rb"); nvrmask = 127; break;
case ROM_BULL_MICRAL_45: f = nvrfopen("bull_micral_45.nvr", "rb"); break; case ROM_BULL_MICRAL_45: f = nvrfopen("bull_micral_45.nvr", "rb"); break;
case ROM_FIC_VA503P: f = nvrfopen("fic_va503p.nvr", "rb"); nvrmask = 127; break; case ROM_FIC_VA503P: f = nvrfopen("fic_va503p.nvr", "rb"); nvrmask = 127; break;
case ROM_CBM_SL386SX25: f = nvrfopen("cbm_sl386sx25.nvr", "rb"); nvrmask = 127; break;
default: return; default: return;
} }
@ -445,6 +446,7 @@ void savenvr()
case ROM_PB410A: f = nvrfopen("pb410a.nvr", "wb"); break; case ROM_PB410A: f = nvrfopen("pb410a.nvr", "wb"); break;
case ROM_BULL_MICRAL_45: f = nvrfopen("bull_micral_45.nvr", "wb"); break; case ROM_BULL_MICRAL_45: f = nvrfopen("bull_micral_45.nvr", "wb"); break;
case ROM_FIC_VA503P: f = nvrfopen("fic_va503p.nvr", "wb"); break; case ROM_FIC_VA503P: f = nvrfopen("fic_va503p.nvr", "wb"); break;
case ROM_CBM_SL386SX25: f = nvrfopen("cbm_sl386sx25.nvr", "wb"); break;
default: return; default: return;
} }

230
src/scamp.c Normal file
View file

@ -0,0 +1,230 @@
#include "ibm.h"
#include "io.h"
#include "mem.h"
#include "scamp.h"
static struct
{
int cfg_index;
uint8_t cfg_regs[256];
int cfg_enable;
uint8_t port_92;
} scamp;
#define CFG_ID 0x00
#define CFG_SLTPTR 0x02
#define CFG_RAMMAP 0x03
#define CFG_ABAXS 0x0e
#define CFG_CAXS 0x0f
#define CFG_DAXS 0x10
#define CFG_FEAXS 0x11
#define ID_VL82C311 0xd6
#define RAMMAP_REMP386 (1 << 4)
static void shadow_control(uint32_t addr, uint32_t size, int state)
{
// pclog("shadow_control: addr=%08x size=%04x state=%i\n", addr, size, state);
switch (state)
{
case 0:
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
break;
case 1:
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
break;
case 2:
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
break;
case 3:
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
break;
}
flushmmucache_nopc();
}
void scamp_write(uint16_t addr, uint8_t val, void *p)
{
// pclog("scamp_write: addr=%04x val=%02x\n", addr, val);
switch (addr)
{
case 0x92:
if ((mem_a20_alt ^ val) & 2)
{
mem_a20_alt = val & 2;
mem_a20_recalc();
}
if ((~scamp.port_92 & val) & 1)
{
softresetx86();
cpu_set_edx();
}
scamp.port_92 = val;
break;
case 0xec:
if (scamp.cfg_enable)
scamp.cfg_index = val;
break;
case 0xed:
if (scamp.cfg_enable)
{
if (scamp.cfg_index >= 0x02 && scamp.cfg_index <= 0x16)
{
scamp.cfg_regs[scamp.cfg_index] = val;
// pclog("SCAMP CFG[%02x]=%02x\n", scamp.cfg_index, val);
switch (scamp.cfg_index)
{
case CFG_SLTPTR:
#if 0
if (!val)
{
/*Disable all RAM*/
mem_mapping_disable(&ram_low_mapping);
mem_mapping_disable(&ram_high_mapping);
}
else if (val < 0x10)
{
mem_mapping_set_addr(&ram_low_mapping, 0, (val > 9) ? 0xa0000 : (val << 16));
mem_mapping_disable(&ram_high_mapping);
}
else
{
mem_mapping_enable(&ram_low_mapping);
mem_mapping_enable(&ram_high_mapping);
}
#endif
break;
case CFG_RAMMAP:
mem_mapping_disable(&ram_remapped_mapping);
if (scamp.cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)
{
/*Enabling remapping will disable all shadowing*/
mem_remap_top_384k();
shadow_control(0xa0000, 0x60000, 0);
}
else
{
shadow_control(0xa0000, 0x8000, scamp.cfg_regs[CFG_ABAXS] & 3);
shadow_control(0xa8000, 0x8000, (scamp.cfg_regs[CFG_ABAXS] >> 2) & 3);
shadow_control(0xb0000, 0x8000, (scamp.cfg_regs[CFG_ABAXS] >> 4) & 3);
shadow_control(0xb8000, 0x8000, (scamp.cfg_regs[CFG_ABAXS] >> 6) & 3);
shadow_control(0xc0000, 0x4000, scamp.cfg_regs[CFG_ABAXS] & 3);
shadow_control(0xc4000, 0x4000, (scamp.cfg_regs[CFG_ABAXS] >> 2) & 3);
shadow_control(0xc8000, 0x4000, (scamp.cfg_regs[CFG_ABAXS] >> 4) & 3);
shadow_control(0xcc000, 0x4000, (scamp.cfg_regs[CFG_ABAXS] >> 6) & 3);
shadow_control(0xd0000, 0x4000, scamp.cfg_regs[CFG_ABAXS] & 3);
shadow_control(0xd4000, 0x4000, (scamp.cfg_regs[CFG_ABAXS] >> 2) & 3);
shadow_control(0xd8000, 0x4000, (scamp.cfg_regs[CFG_ABAXS] >> 4) & 3);
shadow_control(0xdc000, 0x4000, (scamp.cfg_regs[CFG_ABAXS] >> 6) & 3);
shadow_control(0xe0000, 0x8000, scamp.cfg_regs[CFG_ABAXS] & 3);
shadow_control(0xe8000, 0x8000, (scamp.cfg_regs[CFG_ABAXS] >> 2) & 3);
shadow_control(0xf0000, 0x8000, (scamp.cfg_regs[CFG_ABAXS] >> 4) & 3);
shadow_control(0xf8000, 0x8000, (scamp.cfg_regs[CFG_ABAXS] >> 6) & 3);
}
break;
case CFG_ABAXS:
if (!(scamp.cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386))
{
shadow_control(0xa0000, 0x8000, val & 3);
shadow_control(0xa8000, 0x8000, (val >> 2) & 3);
shadow_control(0xb0000, 0x8000, (val >> 4) & 3);
shadow_control(0xb8000, 0x8000, (val >> 6) & 3);
}
break;
case CFG_CAXS:
if (!(scamp.cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386))
{
shadow_control(0xc0000, 0x4000, val & 3);
shadow_control(0xc4000, 0x4000, (val >> 2) & 3);
shadow_control(0xc8000, 0x4000, (val >> 4) & 3);
shadow_control(0xcc000, 0x4000, (val >> 6) & 3);
}
break;
case CFG_DAXS:
if (!(scamp.cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386))
{
shadow_control(0xd0000, 0x4000, val & 3);
shadow_control(0xd4000, 0x4000, (val >> 2) & 3);
shadow_control(0xd8000, 0x4000, (val >> 4) & 3);
shadow_control(0xdc000, 0x4000, (val >> 6) & 3);
}
break;
case CFG_FEAXS:
if (!(scamp.cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386))
{
shadow_control(0xe0000, 0x8000, val & 3);
shadow_control(0xe8000, 0x8000, (val >> 2) & 3);
shadow_control(0xf0000, 0x8000, (val >> 4) & 3);
shadow_control(0xf8000, 0x8000, (val >> 6) & 3);
}
break;
}
}
}
break;
case 0xee:
if (scamp.cfg_enable && mem_a20_alt)
{
scamp.port_92 &= ~2;
mem_a20_alt = 0;
mem_a20_recalc();
}
break;
}
}
uint8_t scamp_read(uint16_t addr, void *p)
{
uint8_t ret = 0xff;
switch (addr)
{
case 0x92:
ret = scamp.port_92;
break;
case 0xee:
if (!mem_a20_alt)
{
scamp.port_92 |= 2;
mem_a20_alt = 1;
mem_a20_recalc();
}
break;
case 0xef:
softresetx86();
cpu_set_edx();
break;
}
// pclog("scamp_read: addr=%04x ret=%02x\n", addr, ret);
return ret;
}
void scamp_init(void)
{
memset(&scamp, 0, sizeof(scamp));
scamp.cfg_regs[CFG_ID] = ID_VL82C311;
scamp.cfg_enable = 1;
io_sethandler(0x0092, 0x0001, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL);
io_sethandler(0x00e8, 0x0001, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL);
io_sethandler(0x00ea, 0x0006, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL);
io_sethandler(0x00f4, 0x0002, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL);
io_sethandler(0x00f9, 0x0001, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL);
io_sethandler(0x00fb, 0x0001, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL);
}

1
src/scamp.h Normal file
View file

@ -0,0 +1 @@
void scamp_init(void);

View file

@ -15,7 +15,8 @@
enum enum
{ {
CL_TYPE_GD5429 = 0, CL_TYPE_AVGA2 = 0,
CL_TYPE_GD5429,
CL_TYPE_GD5430, CL_TYPE_GD5430,
CL_TYPE_GD5434 CL_TYPE_GD5434
}; };
@ -73,8 +74,14 @@ typedef struct gd5429_t
int mmio_vram_overlap; int mmio_vram_overlap;
uint8_t sr10_read, sr11_read; uint8_t sr10_read, sr11_read;
uint8_t latch_ext[4];
} gd5429_t; } gd5429_t;
#define GRB_X8_ADDRESSING (1 << 1)
#define GRB_WRITEMODE_EXT (1 << 2)
#define GRB_8B_LATCHES (1 << 3)
static void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p); static void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p);
static void gd5429_mmio_writew(uint32_t addr, uint16_t val, void *p); static void gd5429_mmio_writew(uint32_t addr, uint16_t val, void *p);
static void gd5429_mmio_writel(uint32_t addr, uint32_t val, void *p); static void gd5429_mmio_writel(uint32_t addr, uint32_t val, void *p);
@ -88,6 +95,8 @@ void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *p);
void gd5429_recalc_banking(gd5429_t *gd5429); void gd5429_recalc_banking(gd5429_t *gd5429);
void gd5429_recalc_mapping(gd5429_t *gd5429); void gd5429_recalc_mapping(gd5429_t *gd5429);
uint8_t gd5429_read_linear(uint32_t addr, void *p);
void gd5429_out(uint16_t addr, uint8_t val, void *p) void gd5429_out(uint16_t addr, uint8_t val, void *p)
{ {
gd5429_t *gd5429 = (gd5429_t *)p; gd5429_t *gd5429 = (gd5429_t *)p;
@ -143,7 +152,8 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p)
case 0x07: case 0x07:
svga->set_reset_disabled = svga->seqregs[7] & 1; svga->set_reset_disabled = svga->seqregs[7] & 1;
case 0x17: case 0x17:
gd5429_recalc_mapping(gd5429); if (gd5429->type >= CL_TYPE_GD5429)
gd5429_recalc_mapping(gd5429);
break; break;
} }
return; return;
@ -196,6 +206,8 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p)
if (svga->gdcaddr > 8) if (svga->gdcaddr > 8)
{ {
svga->gdcreg[svga->gdcaddr & 0x3f] = val; svga->gdcreg[svga->gdcaddr & 0x3f] = val;
if (gd5429->type < CL_TYPE_GD5429 && (svga->gdcaddr > 0xb))
return;
switch (svga->gdcaddr) switch (svga->gdcaddr)
{ {
case 0x09: case 0x0a: case 0x0b: case 0x09: case 0x0a: case 0x0b:
@ -318,7 +330,7 @@ uint8_t gd5429_in(uint16_t addr, void *p)
gd5429_t *gd5429 = (gd5429_t *)p; gd5429_t *gd5429 = (gd5429_t *)p;
svga_t *svga = &gd5429->svga; svga_t *svga = &gd5429->svga;
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3d0) && !(svga->miscout & 1)) if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
addr ^= 0x60; addr ^= 0x60;
// if (addr != 0x3da) pclog("IN gd5429 %04X\n", addr); // if (addr != 0x3da) pclog("IN gd5429 %04X\n", addr);
@ -343,6 +355,8 @@ uint8_t gd5429_in(uint16_t addr, void *p)
return ((svga->seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f; return ((svga->seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f;
case 0x17: case 0x17:
if (gd5429->type < CL_TYPE_GD5429)
break;
temp = svga->seqregs[0x17]; temp = svga->seqregs[0x17];
temp &= ~(7 << 3); temp &= ~(7 << 3);
if (gd5429->type == CL_TYPE_GD5429) if (gd5429->type == CL_TYPE_GD5429)
@ -395,6 +409,8 @@ uint8_t gd5429_in(uint16_t addr, void *p)
case 0x27: /*ID*/ case 0x27: /*ID*/
switch (gd5429->type) switch (gd5429->type)
{ {
case CL_TYPE_AVGA2:
return 0x18; /*AVGA2*/
case CL_TYPE_GD5429: case CL_TYPE_GD5429:
return 0x9c; /*GD5429*/ return 0x9c; /*GD5429*/
case CL_TYPE_GD5430: case CL_TYPE_GD5430:
@ -654,10 +670,10 @@ static void gd5429_write(uint32_t addr, uint8_t val, void *p)
{ {
gd5429_t *gd5429 = (gd5429_t *)p; gd5429_t *gd5429 = (gd5429_t *)p;
svga_t *svga = &gd5429->svga; svga_t *svga = &gd5429->svga;
// pclog("gd5429_write : %05X %02X ", addr, val);
addr &= svga->banked_mask; addr &= svga->banked_mask;
addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1];
// pclog("%08X\n", addr);
gd5429_write_linear(addr, val, p); gd5429_write_linear(addr, val, p);
} }
static void gd5429_writew(uint32_t addr, uint16_t val, void *p) static void gd5429_writew(uint32_t addr, uint16_t val, void *p)
@ -668,7 +684,7 @@ static void gd5429_writew(uint32_t addr, uint16_t val, void *p)
addr &= svga->banked_mask; addr &= svga->banked_mask;
addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1];
if (svga->writemode < 4) if ((svga->writemode < 4) && !(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES)))
svga_writew_linear(addr, val, svga); svga_writew_linear(addr, val, svga);
else else
{ {
@ -684,7 +700,7 @@ static void gd5429_writel(uint32_t addr, uint32_t val, void *p)
addr &= svga->banked_mask; addr &= svga->banked_mask;
addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1];
if (svga->writemode < 4) if ((svga->writemode < 4) && !(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES)))
svga_writel_linear(addr, val, svga); svga_writel_linear(addr, val, svga);
else else
{ {
@ -699,13 +715,10 @@ static uint8_t gd5429_read(uint32_t addr, void *p)
{ {
gd5429_t *gd5429 = (gd5429_t *)p; gd5429_t *gd5429 = (gd5429_t *)p;
svga_t *svga = &gd5429->svga; svga_t *svga = &gd5429->svga;
uint8_t ret;
// pclog("gd5429_read : %05X ", addr);
addr &= svga->banked_mask; addr &= svga->banked_mask;
addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1];
ret = svga_read_linear(addr, &gd5429->svga); return gd5429_read_linear(addr, gd5429);
// pclog("%08X %02X\n", addr, ret);
return ret;
} }
static uint16_t gd5429_readw(uint32_t addr, void *p) static uint16_t gd5429_readw(uint32_t addr, void *p)
{ {
@ -714,7 +727,10 @@ static uint16_t gd5429_readw(uint32_t addr, void *p)
addr &= svga->banked_mask; addr &= svga->banked_mask;
addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1];
return svga_readw_linear(addr, &gd5429->svga);
if (!(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES)))
return svga_readw_linear(addr, &gd5429->svga);
return gd5429_read_linear(addr, gd5429) | (gd5429_read_linear(addr+1, gd5429) << 8);
} }
static uint32_t gd5429_readl(uint32_t addr, void *p) static uint32_t gd5429_readl(uint32_t addr, void *p)
{ {
@ -723,7 +739,11 @@ static uint32_t gd5429_readl(uint32_t addr, void *p)
addr &= svga->banked_mask; addr &= svga->banked_mask;
addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1];
return svga_readl_linear(addr, &gd5429->svga);
if (!(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES)))
return svga_readl_linear(addr, &gd5429->svga);
return gd5429_read_linear(addr, gd5429) | (gd5429_read_linear(addr+1, gd5429) << 8) |
(gd5429_read_linear(addr+2, gd5429) << 16) | (gd5429_read_linear(addr+3, gd5429) << 24);
} }
void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) void gd5429_write_linear(uint32_t addr, uint8_t val, void *p)
@ -731,7 +751,7 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p)
gd5429_t *gd5429 = (gd5429_t *)p; gd5429_t *gd5429 = (gd5429_t *)p;
svga_t *svga = &gd5429->svga; svga_t *svga = &gd5429->svga;
uint8_t vala, valb, valc, vald, wm = svga->writemask; uint8_t vala, valb, valc, vald, wm = svga->writemask;
int writemask2 = svga->writemask; int writemask2 = svga->seqregs[2];
cycles -= video_timing_write_b; cycles -= video_timing_write_b;
cycles_lost += video_timing_write_b; cycles_lost += video_timing_write_b;
@ -741,7 +761,9 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p)
// if (svga_output) pclog("Write LFB %08X %02X ", addr, val); // if (svga_output) pclog("Write LFB %08X %02X ", addr, val);
if (!(svga->gdcreg[6] & 1)) if (!(svga->gdcreg[6] & 1))
svga->fullchange = 2; svga->fullchange = 2;
if ((svga->chain4 || svga->fb_only) && (svga->writemode < 4)) if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING)
addr <<= 3;
else if ((svga->chain4 || svga->fb_only) && (svga->writemode < 4))
{ {
writemask2 = 1 << (addr & 3); writemask2 = 1 << (addr & 3);
addr &= ~3; addr &= ~3;
@ -818,7 +840,6 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p)
else else
{ {
// pclog("Writemode 4 : %X ", addr); // pclog("Writemode 4 : %X ", addr);
addr <<= 1;
svga->changedvram[addr >> 12] = changeframecount; svga->changedvram[addr >> 12] = changeframecount;
// pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); // pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]);
if (val & svga->seqregs[2] & 0x80) if (val & svga->seqregs[2] & 0x80)
@ -891,7 +912,6 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p)
else else
{ {
// pclog("Writemode 5 : %X ", addr); // pclog("Writemode 5 : %X ", addr);
addr <<= 1;
svga->changedvram[addr >> 12] = changeframecount; svga->changedvram[addr >> 12] = changeframecount;
// pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); // pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]);
if (svga->seqregs[2] & 0x80) if (svga->seqregs[2] & 0x80)
@ -914,10 +934,27 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p)
break; break;
case 1: case 1:
if (writemask2 & 1) svga->vram[addr] = svga->la; if (svga->gdcreg[0xb] & GRB_WRITEMODE_EXT)
if (writemask2 & 2) svga->vram[addr | 0x1] = svga->lb; {
if (writemask2 & 4) svga->vram[addr | 0x2] = svga->lc; if (writemask2 & 0x80) svga->vram[addr] = svga->la;
if (writemask2 & 8) svga->vram[addr | 0x3] = svga->ld; if (writemask2 & 0x40) svga->vram[addr | 0x1] = svga->lb;
if (writemask2 & 0x20) svga->vram[addr | 0x2] = svga->lc;
if (writemask2 & 0x10) svga->vram[addr | 0x3] = svga->ld;
if (svga->gdcreg[0xb] & GRB_8B_LATCHES)
{
if (writemask2 & 0x08) svga->vram[addr | 0x4] = gd5429->latch_ext[0];
if (writemask2 & 0x04) svga->vram[addr | 0x5] = gd5429->latch_ext[1];
if (writemask2 & 0x02) svga->vram[addr | 0x6] = gd5429->latch_ext[2];
if (writemask2 & 0x01) svga->vram[addr | 0x7] = gd5429->latch_ext[3];
}
}
else
{
if (writemask2 & 1) svga->vram[addr] = svga->la;
if (writemask2 & 2) svga->vram[addr | 0x1] = svga->lb;
if (writemask2 & 4) svga->vram[addr | 0x2] = svga->lc;
if (writemask2 & 8) svga->vram[addr | 0x3] = svga->ld;
}
break; break;
case 0: case 0:
if (svga->gdcreg[3] & 7) if (svga->gdcreg[3] & 7)
@ -1055,13 +1092,92 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p)
} }
} }
uint8_t gd5429_read_linear(uint32_t addr, void *p)
{
gd5429_t *gd5429 = (gd5429_t *)p;
svga_t *svga = &gd5429->svga;
uint8_t temp, temp2, temp3, temp4;
int readplane = svga->readplane;
uint32_t latch_addr = (addr << 2) & svga->decode_mask;
cycles -= video_timing_read_b;
cycles_lost += video_timing_read_b;
egareads++;
if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING)
addr <<= 3;
else if (svga->chain4 || svga->fb_only)
{
addr &= svga->decode_mask;
if (addr >= svga->vram_max)
return 0xff;
return svga->vram[addr & svga->vram_mask];
}
else if (svga->chain2_read)
{
readplane = (readplane & 2) | (addr & 1);
addr &= ~1;
addr <<= 2;
}
else
addr<<=2;
addr &= svga->decode_mask;
if (latch_addr >= svga->vram_max)
{
svga->la = svga->lb = svga->lc = svga->ld = 0xff;
if (svga->gdcreg[0xb] & GRB_8B_LATCHES)
gd5429->latch_ext[0] = gd5429->latch_ext[1] = gd5429->latch_ext[2] = gd5429->latch_ext[3] = 0xff;
}
else
{
latch_addr &= svga->vram_mask;
svga->la = svga->vram[latch_addr];
svga->lb = svga->vram[latch_addr | 0x1];
svga->lc = svga->vram[latch_addr | 0x2];
svga->ld = svga->vram[latch_addr | 0x3];
if (svga->gdcreg[0xb] & GRB_8B_LATCHES)
{
gd5429->latch_ext[0] = svga->vram[latch_addr | 0x4];
gd5429->latch_ext[1] = svga->vram[latch_addr | 0x5];
gd5429->latch_ext[2] = svga->vram[latch_addr | 0x6];
gd5429->latch_ext[3] = svga->vram[latch_addr | 0x7];
}
}
if (addr >= svga->vram_max)
return 0xff;
addr &= svga->vram_mask;
if (svga->readmode)
{
temp = svga->la;
temp ^= (svga->colourcompare & 1) ? 0xff : 0;
temp &= (svga->colournocare & 1) ? 0xff : 0;
temp2 = svga->lb;
temp2 ^= (svga->colourcompare & 2) ? 0xff : 0;
temp2 &= (svga->colournocare & 2) ? 0xff : 0;
temp3 = svga->lc;
temp3 ^= (svga->colourcompare & 4) ? 0xff : 0;
temp3 &= (svga->colournocare & 4) ? 0xff : 0;
temp4 = svga->ld;
temp4 ^= (svga->colourcompare & 8) ? 0xff : 0;
temp4 &= (svga->colournocare & 8) ? 0xff : 0;
return ~(temp | temp2 | temp3 | temp4);
}
//printf("Read %02X %04X %04X\n",vram[addr|svga->readplane],addr,svga->readplane);
return svga->vram[addr | readplane];
}
static void gd5429_writeb_linear(uint32_t addr, uint8_t val, void *p) static void gd5429_writeb_linear(uint32_t addr, uint8_t val, void *p)
{ {
svga_t *svga = (svga_t *)p; svga_t *svga = (svga_t *)p;
gd5429_t *gd5429 = (gd5429_t *)svga->p; gd5429_t *gd5429 = (gd5429_t *)svga->p;
// pclog("gd5429_writeb : %08X %02X\n", addr, val); if ((svga->writemode < 4) && !(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES)))
if (svga->writemode < 4)
svga_write_linear(addr, val, svga); svga_write_linear(addr, val, svga);
else else
gd5429_write_linear(addr, val & 0xff, gd5429); gd5429_write_linear(addr, val & 0xff, gd5429);
@ -1071,8 +1187,7 @@ static void gd5429_writew_linear(uint32_t addr, uint16_t val, void *p)
svga_t *svga = (svga_t *)p; svga_t *svga = (svga_t *)p;
gd5429_t *gd5429 = (gd5429_t *)svga->p; gd5429_t *gd5429 = (gd5429_t *)svga->p;
// pclog("gd5429_writew : %08X %04X\n", addr, val); if ((svga->writemode < 4) && !(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES)))
if (svga->writemode < 4)
svga_writew_linear(addr, val, svga); svga_writew_linear(addr, val, svga);
else else
{ {
@ -1085,8 +1200,7 @@ static void gd5429_writel_linear(uint32_t addr, uint32_t val, void *p)
svga_t *svga = (svga_t *)p; svga_t *svga = (svga_t *)p;
gd5429_t *gd5429 = (gd5429_t *)svga->p; gd5429_t *gd5429 = (gd5429_t *)svga->p;
// pclog("gd5429_writel : %08X %08X %i\n", addr, val, svga->writemode); if ((svga->writemode < 4) && !(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES)))
if (svga->writemode < 4)
svga_writel_linear(addr, val, svga); svga_writel_linear(addr, val, svga);
else else
{ {
@ -1097,6 +1211,35 @@ static void gd5429_writel_linear(uint32_t addr, uint32_t val, void *p)
} }
} }
static uint8_t gd5429_readb_linear(uint32_t addr, void *p)
{
gd5429_t *gd5429 = (gd5429_t *)p;
svga_t *svga = &gd5429->svga;
if (!(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES)))
return svga_read_linear(addr, &gd5429->svga);
return gd5429_read_linear(addr, gd5429);
}
static uint16_t gd5429_readw_linear(uint32_t addr, void *p)
{
gd5429_t *gd5429 = (gd5429_t *)p;
svga_t *svga = &gd5429->svga;
if (!(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES)))
return svga_readw_linear(addr, &gd5429->svga);
return gd5429_read_linear(addr, gd5429) | (gd5429_read_linear(addr+1, gd5429) << 8);
}
static uint32_t gd5429_readl_linear(uint32_t addr, void *p)
{
gd5429_t *gd5429 = (gd5429_t *)p;
svga_t *svga = &gd5429->svga;
if (!(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES)))
return svga_readl_linear(addr, &gd5429->svga);
return gd5429_read_linear(addr, gd5429) | (gd5429_read_linear(addr+1, gd5429) << 8) |
(gd5429_read_linear(addr+2, gd5429) << 16) | (gd5429_read_linear(addr+3, gd5429) << 24);
}
void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) void gd5429_start_blit(uint32_t cpu_dat, int count, void *p)
{ {
@ -1685,13 +1828,16 @@ static void *cl_init(int type, char *fn, int pci_card)
memset(gd5429, 0, sizeof(gd5429_t)); memset(gd5429, 0, sizeof(gd5429_t));
vram_size = device_get_config_int("memory"); vram_size = device_get_config_int("memory");
gd5429->vram_mask = (vram_size << 20) - 1; if (vram_size >= 256)
gd5429->vram_mask = (vram_size << 10) - 1;
else
gd5429->vram_mask = (vram_size << 20) - 1;
gd5429->type = type; gd5429->type = type;
rom_init(&gd5429->bios_rom, fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); rom_init(&gd5429->bios_rom, fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
svga_init(&gd5429->svga, gd5429, vram_size << 20, svga_init(&gd5429->svga, gd5429, (vram_size >= 256) ? (vram_size << 10) : (vram_size << 20),
gd5429_recalctimings, gd5429_recalctimings,
gd5429_in, gd5429_out, gd5429_in, gd5429_out,
gd5429_hwcursor_draw, gd5429_hwcursor_draw,
@ -1701,9 +1847,15 @@ static void *cl_init(int type, char *fn, int pci_card)
mem_mapping_set_p(&gd5429->svga.mapping, gd5429); mem_mapping_set_p(&gd5429->svga.mapping, gd5429);
mem_mapping_add(&gd5429->mmio_mapping, 0, 0, gd5429_mmio_read, gd5429_mmio_readw, gd5429_mmio_readl, gd5429_mmio_write, gd5429_mmio_writew, gd5429_mmio_writel, NULL, 0, gd5429); mem_mapping_add(&gd5429->mmio_mapping, 0, 0, gd5429_mmio_read, gd5429_mmio_readw, gd5429_mmio_readl, gd5429_mmio_write, gd5429_mmio_writew, gd5429_mmio_writel, NULL, 0, gd5429);
mem_mapping_add(&gd5429->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, gd5429_writeb_linear, gd5429_writew_linear, gd5429_writel_linear, NULL, 0, svga); mem_mapping_add(&gd5429->linear_mapping, 0, 0, gd5429_readb_linear, gd5429_readw_linear, gd5429_readl_linear, gd5429_writeb_linear, gd5429_writew_linear, gd5429_writel_linear, NULL, 0, svga);
io_sethandler(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); io_sethandler(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429);
if (type == CL_TYPE_AVGA2)
{
io_sethandler(0x0102, 0x0001, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429);
io_sethandler(0x46e8, 0x0002, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429);
svga->decode_mask = svga->vram_mask;
}
svga->hwcursor.yoff = 32; svga->hwcursor.yoff = 32;
svga->hwcursor.xoff = 0; svga->hwcursor.xoff = 0;
@ -1741,6 +1893,10 @@ static void *cl_init(int type, char *fn, int pci_card)
} }
static void *avga2_cbm_sl386sx_init()
{
return cl_init(CL_TYPE_AVGA2, "cbm_sl386sx25/c000.rom", -1);
}
static void *gd5429_init() static void *gd5429_init()
{ {
return cl_init(CL_TYPE_GD5429, "5429.vbi", -1); return cl_init(CL_TYPE_GD5429, "5429.vbi", -1);
@ -1805,6 +1961,33 @@ void gd5429_add_status_info(char *s, int max_len, void *p)
svga_add_status_info(s, max_len, &gd5429->svga); svga_add_status_info(s, max_len, &gd5429->svga);
} }
static device_config_t avga2_config[] =
{
{
.name = "memory",
.description = "Memory size",
.type = CONFIG_SELECTION,
.selection =
{
{
.description = "256 kB",
.value = 256
},
{
.description = "512 kB",
.value = 512
},
{
.description = ""
}
},
.default_int = 512
},
{
.type = -1
}
};
static device_config_t gd5429_config[] = static device_config_t gd5429_config[] =
{ {
{ {
@ -1858,6 +2041,19 @@ static device_config_t gd5434_config[] =
} }
}; };
device_t avga2_cbm_sl386sx_device =
{
"AVGA2 (Commodore SL386SX-25)",
0,
avga2_cbm_sl386sx_init,
gd5429_close,
gd5430_available,
gd5429_speed_changed,
gd5429_force_redraw,
gd5429_add_status_info,
avga2_config
};
device_t gd5429_device = device_t gd5429_device =
{ {
"Cirrus Logic GD5429", "Cirrus Logic GD5429",

View file

@ -1,3 +1,4 @@
extern device_t avga2_cbm_sl386sx_device;
extern device_t gd5429_device; extern device_t gd5429_device;
extern device_t gd5430_device; extern device_t gd5430_device;
extern device_t gd5430_pb570_device; extern device_t gd5430_pb570_device;

View file

@ -130,6 +130,7 @@ static video_timings_t timing_pc200 = {VIDEO_ISA, 8,16,32, 8,16,32};
static video_timings_t timing_m24 = {VIDEO_ISA, 8,16,32, 8,16,32}; static video_timings_t timing_m24 = {VIDEO_ISA, 8,16,32, 8,16,32};
static video_timings_t timing_pvga1a = {VIDEO_ISA, 6, 8,16, 6, 8,16}; static video_timings_t timing_pvga1a = {VIDEO_ISA, 6, 8,16, 6, 8,16};
static video_timings_t timing_wd90c11 = {VIDEO_ISA, 3, 3, 6, 5, 5,10}; static video_timings_t timing_wd90c11 = {VIDEO_ISA, 3, 3, 6, 5, 5,10};
static video_timings_t timing_avga2 = {VIDEO_ISA, 3, 3, 6, 5, 5,10};
static video_timings_t timing_oti067 = {VIDEO_ISA, 6, 8,16, 6, 8,16}; static video_timings_t timing_oti067 = {VIDEO_ISA, 6, 8,16, 6, 8,16};
static video_timings_t timing_vga = {VIDEO_ISA, 8,16,32, 8,16,32}; static video_timings_t timing_vga = {VIDEO_ISA, 8,16,32, 8,16,32};
static video_timings_t timing_ps1_svga = {VIDEO_ISA, 6, 8,16, 6, 8,16}; static video_timings_t timing_ps1_svga = {VIDEO_ISA, 6, 8,16, 6, 8,16};
@ -242,6 +243,9 @@ device_t *video_card_getdevice(int card, int romset)
case ROM_PB520R: case ROM_PB520R:
return &gd5434_pb520r_device; return &gd5434_pb520r_device;
case ROM_CBM_SL386SX25:
return &avga2_cbm_sl386sx_device;
} }
return video_cards[card].device; return video_cards[card].device;
} }
@ -365,6 +369,7 @@ int video_is_mda()
case ROM_PB410A: case ROM_PB410A:
case ROM_PB570: case ROM_PB570:
case ROM_PB520R: case ROM_PB520R:
case ROM_CBM_SL386SX25:
return 0; return 0;
} }
return (video_cards[video_old_to_new(gfxcard)].flags & VIDEO_FLAG_TYPE_MASK) == VIDEO_FLAG_TYPE_MDA; return (video_cards[video_old_to_new(gfxcard)].flags & VIDEO_FLAG_TYPE_MASK) == VIDEO_FLAG_TYPE_MDA;
@ -411,6 +416,7 @@ int video_is_cga()
case ROM_PB410A: case ROM_PB410A:
case ROM_PB570: case ROM_PB570:
case ROM_PB520R: case ROM_PB520R:
case ROM_CBM_SL386SX25:
return 0; return 0;
} }
return (video_cards[video_old_to_new(gfxcard)].flags & VIDEO_FLAG_TYPE_MASK) == VIDEO_FLAG_TYPE_CGA; return (video_cards[video_old_to_new(gfxcard)].flags & VIDEO_FLAG_TYPE_MASK) == VIDEO_FLAG_TYPE_CGA;
@ -449,6 +455,7 @@ int video_is_ega_vga()
case ROM_PB410A: case ROM_PB410A:
case ROM_PB570: case ROM_PB570:
case ROM_PB520R: case ROM_PB520R:
case ROM_CBM_SL386SX25:
return 1; return 1;
} }
return (video_cards[video_old_to_new(gfxcard)].flags & VIDEO_FLAG_TYPE_MASK) == VIDEO_FLAG_TYPE_SPECIAL; return (video_cards[video_old_to_new(gfxcard)].flags & VIDEO_FLAG_TYPE_MASK) == VIDEO_FLAG_TYPE_SPECIAL;
@ -614,6 +621,10 @@ void video_updatetiming()
case ROM_PB520R: case ROM_PB520R:
timing = &timing_pb520r; timing = &timing_pb520r;
break; break;
case ROM_CBM_SL386SX25:
timing = &timing_avga2;
break;
} }
@ -813,6 +824,10 @@ void video_init()
break; break;
} }
return; return;
case ROM_CBM_SL386SX25:
device_add(&avga2_cbm_sl386sx_device);
return;
} }
device_add(video_cards[video_old_to_new(gfxcard)].device); device_add(video_cards[video_old_to_new(gfxcard)].device);
} }