Add IBM PS/1 Model 2133 (EMEA 451) emulation. Currently displays a cache error
on boot, but otherwise seems to work fine.
This commit is contained in:
parent
adf4a2de93
commit
8870334114
14 changed files with 319 additions and 12 deletions
|
|
@ -49,7 +49,7 @@ vid_incolor.c vid_mda.c vid_mga.c vid_olivetti_m24.c vid_oti037.c vid_oti067.c v
|
|||
vid_pc1640.c vid_pcjr.c vid_pgc.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_sdac_ramdac.c vid_sigma.c \
|
||||
vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_t1000.c vid_t3100e.c vid_tandy.c vid_tandysl.c vid_tgui9440.c \
|
||||
vid_tkd8001_ramdac.c vid_tvga.c vid_unk_ramdac.c vid_vga.c vid_voodoo.c video.c wd76c10.c vid_wy700.c vt82c586b.c \
|
||||
w83877tf.c x86seg.c x87.c x87_timings.c xi8088.c xtide.c sound_dbopl.cc sound_resid.cc
|
||||
vl82c480.c w83877tf.c x86seg.c x87.c x87_timings.c xi8088.c xtide.c sound_dbopl.cc sound_resid.cc
|
||||
|
||||
# DOSBox
|
||||
pcem_SOURCES += dosbox/cdrom_image.cpp dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.c
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203
|
|||
vid_mga.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \
|
||||
vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o vid_stg_ramdac.o vid_svga.o \
|
||||
vid_svga_render.o vid_t1000.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \
|
||||
vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy700.o video.o \
|
||||
vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy700.o video.o vl82c480.o \
|
||||
vt82c586b.o w83877tf.o wd76c10.o x86seg.o x87.o x87_timings.o xi8088.c xtide.o win-midi.o wx-main.o \
|
||||
wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o \
|
||||
wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o \
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203
|
|||
vid_mga.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \
|
||||
vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o vid_stg_ramdac.o vid_svga.o \
|
||||
vid_svga_render.o vid_t1000.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \
|
||||
vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy700.o video.o \
|
||||
vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy700.o video.o vl82c480.o \
|
||||
vt82c586b.o w83877tf.o wd76c10.o x86seg.o x87.o x87_timings.o xi8088.c xtide.o win-midi.o wx-main.o \
|
||||
wx-config_sel.o wx-dialogbox.o wx-hostconfig.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o \
|
||||
wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o \
|
||||
|
|
|
|||
|
|
@ -253,6 +253,7 @@ enum
|
|||
ROM_BULL_MICRAL_45,
|
||||
ROM_FIC_VA503P,
|
||||
ROM_CBM_SL386SX25,
|
||||
ROM_IBMPS1_2133_451,
|
||||
|
||||
ROM_MAX
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1015,6 +1015,14 @@ int loadbios()
|
|||
romfread(rom, 0x10000, 1, f);
|
||||
fclose(f);
|
||||
return 1;
|
||||
|
||||
case ROM_IBMPS1_2133_451:
|
||||
f = romfopen("ibmps1_2133/PS1_2133_52G2974_ROM.bin", "rb");
|
||||
if (!f) break;
|
||||
romfread(rom, 0x20000, 1, f);
|
||||
fclose(f);
|
||||
biosmask = 0x1ffff;
|
||||
return 1;
|
||||
}
|
||||
printf("Failed to load ROM!\n");
|
||||
if (f) fclose(f);
|
||||
|
|
|
|||
10
src/model.c
10
src/model.c
|
|
@ -70,6 +70,7 @@
|
|||
#include "vid_pcjr.h"
|
||||
#include "vid_tandy.h"
|
||||
#include "vid_t1000.h"
|
||||
#include "vl82c480.h"
|
||||
#include "vt82c586b.h"
|
||||
#include "w83877tf.h"
|
||||
#include "wd76c10.h"
|
||||
|
|
@ -91,6 +92,7 @@ void deskpro386_init();
|
|||
void pb_l300sx_init();
|
||||
void ps1_m2011_init();
|
||||
void ps1_m2121_init();
|
||||
void ps1_m2133_init(void);
|
||||
void ps2_m30_286_init();
|
||||
void ps2_model_50_init();
|
||||
void ps2_model_55sx_init();
|
||||
|
|
@ -204,6 +206,7 @@ MODEL models[] =
|
|||
{"[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/1 Model 2133 (EMEA 451)",ROM_IBMPS1_2133_451, "ibmps1_2133", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2, 2, 64, 2, ps1_m2133_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},
|
||||
|
||||
|
|
@ -507,6 +510,13 @@ void ps1_m2121_init()
|
|||
fdc_set_ps1();
|
||||
}
|
||||
|
||||
void ps1_m2133_init(void)
|
||||
{
|
||||
at_init();
|
||||
vl82c480_init();
|
||||
ps1mb_m2133_init();
|
||||
}
|
||||
|
||||
void ps2_m30_286_init()
|
||||
{
|
||||
AT = 1;
|
||||
|
|
|
|||
|
|
@ -348,6 +348,7 @@ void loadnvr()
|
|||
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_CBM_SL386SX25: f = nvrfopen("cbm_sl386sx25.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_IBMPS1_2133_451: f = nvrfopen("ibmps1_2133.nvr", "rb"); nvrmask = 127; break;
|
||||
|
||||
default: return;
|
||||
}
|
||||
|
|
@ -447,6 +448,7 @@ void savenvr()
|
|||
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_CBM_SL386SX25: f = nvrfopen("cbm_sl386sx25.nvr", "wb"); break;
|
||||
case ROM_IBMPS1_2133_451: f = nvrfopen("ibmps1_2133.nvr", "wb"); break;
|
||||
|
||||
default: return;
|
||||
}
|
||||
|
|
|
|||
62
src/ps1.c
62
src/ps1.c
|
|
@ -301,3 +301,65 @@ void ps1mb_m2121_init()
|
|||
|
||||
mem_remap_top_384k();
|
||||
}
|
||||
|
||||
|
||||
/*Not sure what this SuperIO chip is, so define it here for now*/
|
||||
static struct
|
||||
{
|
||||
int idx;
|
||||
uint8_t regs[3];
|
||||
} ps1_m2133_superio;
|
||||
|
||||
static uint16_t ps1_lpt_io[4] = {0x378, 0x3bc, 0x278, 0x378};
|
||||
static uint16_t ps1_com_io[4] = {0x3f8, 0x2f8, 0x3e8, 0x2e8};
|
||||
|
||||
static uint8_t ps1_m2133_read(uint16_t port, void *p)
|
||||
{
|
||||
uint8_t ret = 0xff;
|
||||
switch (port)
|
||||
{
|
||||
case 0x398:
|
||||
ret = ps1_m2133_superio.idx;
|
||||
break;
|
||||
|
||||
case 0x399:
|
||||
if (ps1_m2133_superio.idx < 3)
|
||||
ret = ps1_m2133_superio.regs[ps1_m2133_superio.idx];
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ps1_m2133_write(uint16_t port, uint8_t val, void *p)
|
||||
{
|
||||
// pclog("ps1_m2133_write: port=%04x val=%02x\n", port, val);
|
||||
switch (port)
|
||||
{
|
||||
case 0x398:
|
||||
ps1_m2133_superio.idx = val;
|
||||
break;
|
||||
|
||||
case 0x399:
|
||||
if (ps1_m2133_superio.idx < 3)
|
||||
{
|
||||
ps1_m2133_superio.regs[ps1_m2133_superio.idx] = val;
|
||||
|
||||
lpt1_remove();
|
||||
serial1_remove();
|
||||
serial2_remove();
|
||||
|
||||
if (ps1_m2133_superio.regs[0] & 1)
|
||||
lpt1_init(ps1_lpt_io[ps1_m2133_superio.regs[1] & 3]);
|
||||
if (ps1_m2133_superio.regs[0] & 2)
|
||||
serial1_set(ps1_com_io[(ps1_m2133_superio.regs[1] >> 2) & 3], 4);
|
||||
if (ps1_m2133_superio.regs[0] & 4)
|
||||
serial2_set(ps1_com_io[(ps1_m2133_superio.regs[1] >> 4) & 3], 3);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ps1mb_m2133_init(void)
|
||||
{
|
||||
io_sethandler(0x0398, 0x0002, ps1_m2133_read, NULL, NULL, ps1_m2133_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
void ps1mb_init();
|
||||
void ps1mb_m2121_init();
|
||||
void ps1mb_m2133_init(void);
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
enum
|
||||
{
|
||||
CL_TYPE_AVGA2 = 0,
|
||||
CL_TYPE_GD5426,
|
||||
CL_TYPE_GD5428,
|
||||
CL_TYPE_GD5429,
|
||||
CL_TYPE_GD5430,
|
||||
|
|
@ -226,13 +227,27 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p)
|
|||
svga->gdcreg[6] = val;
|
||||
gd5429_recalc_mapping(gd5429);
|
||||
}
|
||||
|
||||
/*Hack - the Windows 3.x drivers for the GD5426/8 require VRAM wraparound
|
||||
for pattern & cursor writes to work correctly, but the BIOSes require
|
||||
no wrapping to detect memory size - albeit with odd/even mode enabled.
|
||||
This may be a quirk of address mapping. So change wrapping mode based on
|
||||
odd/even mode for now*/
|
||||
if (gd5429->type == CL_TYPE_GD5426 || gd5429->type == CL_TYPE_GD5428)
|
||||
{
|
||||
if (val & 2) /*Odd/Even*/
|
||||
svga->decode_mask = 0x1fffff;
|
||||
else
|
||||
svga->decode_mask = svga->vram_mask;
|
||||
}
|
||||
|
||||
svga->gdcreg[6] = val;
|
||||
return;
|
||||
}
|
||||
if (svga->gdcaddr > 8)
|
||||
{
|
||||
svga->gdcreg[svga->gdcaddr & 0x3f] = val;
|
||||
if (gd5429->type < CL_TYPE_GD5428 && (svga->gdcaddr > 0xb))
|
||||
if (gd5429->type < CL_TYPE_GD5426 && (svga->gdcaddr > 0xb))
|
||||
return;
|
||||
switch (svga->gdcaddr)
|
||||
{
|
||||
|
|
@ -403,11 +418,11 @@ uint8_t gd5429_in(uint16_t addr, void *p)
|
|||
return ((svga->seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f;
|
||||
|
||||
case 0x17:
|
||||
if (gd5429->type < CL_TYPE_GD5428)
|
||||
if (gd5429->type < CL_TYPE_GD5426)
|
||||
break;
|
||||
temp = svga->seqregs[0x17];
|
||||
temp &= ~(7 << 3);
|
||||
if (gd5429->type == CL_TYPE_GD5428)
|
||||
if (gd5429->type == CL_TYPE_GD5426 || gd5429->type == CL_TYPE_GD5428)
|
||||
{
|
||||
if (MCA)
|
||||
temp |= (CL_GD5428_SYSTEM_BUS_MCA << 3);
|
||||
|
|
@ -468,6 +483,8 @@ uint8_t gd5429_in(uint16_t addr, void *p)
|
|||
{
|
||||
case CL_TYPE_AVGA2:
|
||||
return 0x18; /*AVGA2*/
|
||||
case CL_TYPE_GD5426:
|
||||
return 0x90; /*GD5426*/
|
||||
case CL_TYPE_GD5428:
|
||||
return 0x98; /*GD5428*/
|
||||
case CL_TYPE_GD5429:
|
||||
|
|
@ -645,7 +662,11 @@ void gd5429_recalctimings(svga_t *svga)
|
|||
d = (svga->seqregs[0x1b + clock] >> 1) & 0x1f;
|
||||
p = svga->seqregs[0x1b + clock] & 1;
|
||||
|
||||
/*Prevent divide by zero during clock setup*/
|
||||
if (d && n)
|
||||
vclk = (14318184.0 * ((float)n / (float)d)) / (float)(1 + p);
|
||||
else
|
||||
vclk = 14318184.0;
|
||||
switch (svga->seqregs[7] & ((gd5429->type >= CL_TYPE_GD5434) ? 0xe : 0x6))
|
||||
{
|
||||
case 2:
|
||||
|
|
@ -1980,6 +2001,7 @@ static void *cl_init(int type, char *fn, int pci_card, uint32_t force_vram_size)
|
|||
|
||||
gd5429->type = type;
|
||||
|
||||
if (fn)
|
||||
rom_init(&gd5429->bios_rom, fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
svga_init(&gd5429->svga, gd5429, (vram_size >= 256) ? (vram_size << 10) : (vram_size << 20),
|
||||
|
|
@ -2001,8 +2023,6 @@ static void *cl_init(int type, char *fn, int pci_card, uint32_t force_vram_size)
|
|||
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;
|
||||
|
|
@ -2048,6 +2068,10 @@ static void *avga2_cbm_sl386sx_init()
|
|||
{
|
||||
return cl_init(CL_TYPE_AVGA2, "cbm_sl386sx25/c000.rom", -1, 0);
|
||||
}
|
||||
static void *gd5426_ps1_init()
|
||||
{
|
||||
return cl_init(CL_TYPE_GD5426, NULL, -1, 1);
|
||||
}
|
||||
static void *gd5428_init()
|
||||
{
|
||||
return cl_init(CL_TYPE_GD5428, "Machspeed_VGA_GUI_2100_VLB.vbi", -1, 0);
|
||||
|
|
@ -2255,6 +2279,19 @@ device_t avga2_cbm_sl386sx_device =
|
|||
avga2_config
|
||||
};
|
||||
|
||||
device_t gd5426_ps1_device =
|
||||
{
|
||||
"Cirrus Logic GD5426 (IBM PS/1)",
|
||||
0,
|
||||
gd5426_ps1_init,
|
||||
gd5429_close,
|
||||
NULL,
|
||||
gd5429_speed_changed,
|
||||
gd5429_force_redraw,
|
||||
gd5429_add_status_info,
|
||||
NULL
|
||||
};
|
||||
|
||||
device_t gd5428_device =
|
||||
{
|
||||
"Cirrus Logic GD5428",
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
extern device_t avga2_device;
|
||||
extern device_t avga2_cbm_sl386sx_device;
|
||||
extern device_t gd5426_ps1_device;
|
||||
extern device_t gd5428_device;
|
||||
extern device_t ibm_gd5428_device;
|
||||
extern device_t gd5429_device;
|
||||
extern device_t gd5429_reply_m25_device;
|
||||
extern device_t gd5430_device;
|
||||
extern device_t gd5430_pb570_device;
|
||||
extern device_t gd5434_device;
|
||||
|
|
|
|||
14
src/video.c
14
src/video.c
|
|
@ -234,6 +234,9 @@ device_t *video_card_getdevice(int card, int romset)
|
|||
case ROM_IBMPS1_2121:
|
||||
return &ps1_m2121_svga_device;
|
||||
|
||||
case ROM_IBMPS1_2133_451:
|
||||
return &gd5426_ps1_device;
|
||||
|
||||
case ROM_T3100E:
|
||||
return &t3100e_device;
|
||||
|
||||
|
|
@ -372,6 +375,7 @@ int video_is_mda()
|
|||
case ROM_IBMPS2_M70_TYPE4:
|
||||
case ROM_IBMPS2_M80:
|
||||
case ROM_IBMPS1_2121:
|
||||
case ROM_IBMPS1_2133_451:
|
||||
case ROM_T3100E:
|
||||
case ROM_T1000:
|
||||
case ROM_ELX_PC425X:
|
||||
|
|
@ -421,6 +425,7 @@ int video_is_cga()
|
|||
case ROM_IBMPS2_M70_TYPE4:
|
||||
case ROM_IBMPS2_M80:
|
||||
case ROM_IBMPS1_2121:
|
||||
case ROM_IBMPS1_2133_451:
|
||||
case ROM_ELX_PC425X:
|
||||
case ROM_PB410A:
|
||||
case ROM_PB570:
|
||||
|
|
@ -460,6 +465,7 @@ int video_is_ega_vga()
|
|||
case ROM_IBMPS2_M70_TYPE4:
|
||||
case ROM_IBMPS2_M80:
|
||||
case ROM_IBMPS1_2121:
|
||||
case ROM_IBMPS1_2133_451:
|
||||
case ROM_ELX_PC425X:
|
||||
case ROM_PB410A:
|
||||
case ROM_PB570:
|
||||
|
|
@ -610,6 +616,10 @@ void video_updatetiming()
|
|||
timing = &timing_ps1_svga;
|
||||
break;
|
||||
|
||||
case ROM_IBMPS1_2133_451:
|
||||
timing = &timing_pb570;
|
||||
break;
|
||||
|
||||
case ROM_T3100E:
|
||||
timing = &timing_t3100e;
|
||||
break;
|
||||
|
|
@ -803,6 +813,10 @@ void video_init()
|
|||
device_add(&ps1_m2121_svga_device);
|
||||
return;
|
||||
|
||||
case ROM_IBMPS1_2133_451:
|
||||
device_add(&gd5426_ps1_device);
|
||||
return;
|
||||
|
||||
case ROM_T3100E:
|
||||
device_add(&t3100e_device);
|
||||
return;
|
||||
|
|
|
|||
169
src/vl82c480.c
Normal file
169
src/vl82c480.c
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "vl82c480.h"
|
||||
|
||||
static struct
|
||||
{
|
||||
int cfg_index;
|
||||
uint8_t cfg_regs[256];
|
||||
|
||||
uint8_t port_92;
|
||||
} vl82c480;
|
||||
|
||||
#define CFG_ID 0x00
|
||||
#define CFG_AAXS 0x0d
|
||||
#define CFG_BAXS 0x0e
|
||||
#define CFG_CAXS 0x0f
|
||||
#define CFG_DAXS 0x10
|
||||
#define CFG_EAXS 0x11
|
||||
#define CFG_FAXS 0x12
|
||||
|
||||
#define ID_VL82C480 0x90
|
||||
|
||||
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 vl82c480_write(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
// if (addr != 0x92) pclog("vl82c480_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 ((~vl82c480.port_92 & val) & 1)
|
||||
{
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
}
|
||||
vl82c480.port_92 = val;
|
||||
break;
|
||||
|
||||
case 0xec:
|
||||
vl82c480.cfg_index = val;
|
||||
break;
|
||||
|
||||
case 0xed:
|
||||
if (vl82c480.cfg_index >= 0x01 && vl82c480.cfg_index <= 0x24)
|
||||
{
|
||||
vl82c480.cfg_regs[vl82c480.cfg_index] = val;
|
||||
switch (vl82c480.cfg_index)
|
||||
{
|
||||
case CFG_AAXS:
|
||||
shadow_control(0xa0000, 0x4000, val & 3);
|
||||
shadow_control(0xa4000, 0x4000, (val >> 2) & 3);
|
||||
shadow_control(0xa8000, 0x4000, (val >> 4) & 3);
|
||||
shadow_control(0xac000, 0x4000, (val >> 6) & 3);
|
||||
break;
|
||||
case CFG_BAXS:
|
||||
shadow_control(0xb0000, 0x4000, val & 3);
|
||||
shadow_control(0xb4000, 0x4000, (val >> 2) & 3);
|
||||
shadow_control(0xb8000, 0x4000, (val >> 4) & 3);
|
||||
shadow_control(0xbc000, 0x4000, (val >> 6) & 3);
|
||||
break;
|
||||
case CFG_CAXS:
|
||||
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:
|
||||
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_EAXS:
|
||||
shadow_control(0xe0000, 0x4000, val & 3);
|
||||
shadow_control(0xe4000, 0x4000, (val >> 2) & 3);
|
||||
shadow_control(0xe8000, 0x4000, (val >> 4) & 3);
|
||||
shadow_control(0xec000, 0x4000, (val >> 6) & 3);
|
||||
break;
|
||||
case CFG_FAXS:
|
||||
shadow_control(0xf0000, 0x4000, val & 3);
|
||||
shadow_control(0xf4000, 0x4000, (val >> 2) & 3);
|
||||
shadow_control(0xf8000, 0x4000, (val >> 4) & 3);
|
||||
shadow_control(0xfc000, 0x4000, (val >> 6) & 3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xee:
|
||||
if (mem_a20_alt)
|
||||
{
|
||||
vl82c480.port_92 &= ~2;
|
||||
mem_a20_alt = 0;
|
||||
mem_a20_recalc();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t vl82c480_read(uint16_t addr, void *p)
|
||||
{
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x92:
|
||||
ret = vl82c480.port_92;
|
||||
break;
|
||||
|
||||
case 0xec:
|
||||
ret = vl82c480.cfg_index;
|
||||
break;
|
||||
|
||||
case 0xed:
|
||||
ret = vl82c480.cfg_regs[vl82c480.cfg_index];
|
||||
break;
|
||||
|
||||
case 0xee:
|
||||
if (!mem_a20_alt)
|
||||
{
|
||||
vl82c480.port_92 |= 2;
|
||||
mem_a20_alt = 1;
|
||||
mem_a20_recalc();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xef:
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
break;
|
||||
}
|
||||
|
||||
// pclog("vl82c480_read: addr=%04x ret=%02x\n", addr, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void vl82c480_init(void)
|
||||
{
|
||||
memset(&vl82c480, 0, sizeof(vl82c480));
|
||||
vl82c480.cfg_regs[CFG_ID] = ID_VL82C480;
|
||||
|
||||
io_sethandler(0x0092, 0x0001, vl82c480_read, NULL, NULL, vl82c480_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x00ec, 0x0004, vl82c480_read, NULL, NULL, vl82c480_write, NULL, NULL, NULL);
|
||||
}
|
||||
1
src/vl82c480.h
Normal file
1
src/vl82c480.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
void vl82c480_init(void);
|
||||
Loading…
Reference in a new issue