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:
parent
f56f5e76e6
commit
5c8e1aecc2
12 changed files with 499 additions and 37 deletions
|
|
@ -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 \
|
||||||
|
|
|
||||||
|
|
@ -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 \
|
||||||
|
|
|
||||||
|
|
@ -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 \
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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
230
src/scamp.c
Normal 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
1
src/scamp.h
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
void scamp_init(void);
|
||||||
258
src/vid_cl5429.c
258
src/vid_cl5429.c
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
15
src/video.c
15
src/video.c
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue