Added PS/1 model 2011 emulation.

This commit is contained in:
TomW 2015-06-21 16:03:33 +01:00
commit 9f09e9c370
13 changed files with 320 additions and 71 deletions

BIN
ibmps1_2011.nvr Normal file

Binary file not shown.

View file

@ -8,7 +8,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad
device.o disc.o disc_fdi.o disc_img.o dma.o fdc.o fdi2raw.o gameport.o headland.o i430lx.o i430fx.o \ device.o disc.o disc_fdi.o disc_img.o dma.o fdc.o fdi2raw.o gameport.o headland.o i430lx.o i430fx.o \
i430vx.o ide.o intel.o intel_flash.o io.o jim.o keyboard.o keyboard_amstrad.o keyboard_at.o \ i430vx.o ide.o intel.o intel_flash.o io.o jim.o keyboard.o keyboard_amstrad.o keyboard_at.o \
keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o model.o mouse.o mouse_ps2.o \ keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o model.o mouse.o mouse_ps2.o \
mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti.o pc.o pci.o pic.o piix.o pit.o ppi.o rom.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o \
serial.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ serial.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \
sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_resid.o \ sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_resid.o \
sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o \ sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o \

View file

@ -38,6 +38,8 @@ typedef struct FDC
int data_ready; int data_ready;
int inread; int inread;
int dskchg_activelow;
} FDC; } FDC;
static FDC fdc; static FDC fdc;
@ -374,7 +376,12 @@ uint8_t fdc_read(uint16_t addr, void *priv)
switch (addr&7) switch (addr&7)
{ {
case 1: /*???*/ case 1: /*???*/
temp=0x50; // temp=0x50;
temp = 0x70;
if (fdc.dor & 1)
temp &= ~0x40;
else
temp &= ~0x20;
break; break;
case 3: case 3:
temp = 0x20; temp = 0x20;
@ -426,7 +433,7 @@ uint8_t fdc_read(uint16_t addr, void *priv)
temp = (disc_changed[fdc.dor & 1] || drive_empty[fdc.dor & 1])?0x80:0; temp = (disc_changed[fdc.dor & 1] || drive_empty[fdc.dor & 1])?0x80:0;
else else
temp = 0; temp = 0;
if (AMSTRADIO) /*PC2086/3086 seem to reverse this bit*/ if (fdc.dskchg_activelow) /*PC2086/3086 seem to reverse this bit*/
temp ^= 0x80; temp ^= 0x80;
// printf("- DC %i %02X %02X %i %i - ",fdc.dor & 1, fdc.dor, 0x10 << (fdc.dor & 1), discchanged[fdc.dor & 1], driveempty[fdc.dor & 1]); // printf("- DC %i %02X %02X %i %i - ",fdc.dor & 1, fdc.dor, 0x10 << (fdc.dor & 1), discchanged[fdc.dor & 1], driveempty[fdc.dor & 1]);
// discchanged[fdc.dor&1]=0; // discchanged[fdc.dor&1]=0;
@ -942,6 +949,7 @@ void fdc_indexpulse()
void fdc_init() void fdc_init()
{ {
timer_add(fdc_callback, &disctime, &disctime, NULL); timer_add(fdc_callback, &disctime, &disctime, NULL);
fdc.dskchg_activelow = 0;
} }
void fdc_add() void fdc_add()
@ -968,3 +976,8 @@ void fdc_discchange_clear(int drive)
{ {
disc_changed[drive] = 0; disc_changed[drive] = 0;
} }
void fdc_set_dskchg_activelow()
{
fdc.dskchg_activelow = 1;
}

View file

@ -6,3 +6,4 @@ void fdc_reset();
void fdc_poll(); void fdc_poll();
void fdc_abort(); void fdc_abort();
void fdc_discchange_clear(int drive); void fdc_discchange_clear(int drive);
void fdc_set_dskchg_activelow();

View file

@ -321,6 +321,7 @@ enum
ROM_430VX, ROM_430VX,
ROM_ENDEAVOR, ROM_ENDEAVOR,
ROM_REVENGE, ROM_REVENGE,
ROM_IBMPS1_2011,
ROM_MAX ROM_MAX
}; };

View file

@ -452,6 +452,31 @@ int loadbios()
biosmask = 0x1ffff; biosmask = 0x1ffff;
//is486=1; //is486=1;
return 1; return 1;
case ROM_IBMPS1_2011:
#if 0
f=romfopen("roms/ibmps1es/ibm_1057757_24-05-90.bin","rb");
ff=romfopen("roms/ibmps1es/ibm_1057757_29-15-90.bin","rb");
fseek(f, 0x10000, SEEK_SET);
fseek(ff, 0x10000, SEEK_SET);
if (!f || !ff) break;
for (c = 0x0000; c < 0x20000; c += 2)
{
rom[c] = getc(f);
rom[c+1] = getc(ff);
}
fclose(ff);
fclose(f);
#endif
//#if 0
f = romfopen("roms/ibmps1es/f80000.bin", "rb");
if (!f) break;
fseek(f, 0x60000, SEEK_SET);
fread(rom, 0x20000, 1, f);
fclose(f);
//#endif
biosmask = 0x1ffff;
return 1;
} }
printf("Failed to load ROM!\n"); printf("Failed to load ROM!\n");
if (f) fclose(f); if (f) fclose(f);

View file

@ -34,6 +34,7 @@
#include "pic.h" #include "pic.h"
#include "piix.h" #include "piix.h"
#include "pit.h" #include "pit.h"
#include "ps1.h"
#include "serial.h" #include "serial.h"
#include "sis496.h" #include "sis496.h"
#include "sound_sn76489.h" #include "sound_sn76489.h"
@ -49,6 +50,7 @@ void ams_init();
void europc_init(); void europc_init();
void olim24_init(); void olim24_init();
void at_init(); void at_init();
void ps1_init();
void at_neat_init(); void at_neat_init();
void at_acer386sx_init(); void at_acer386sx_init();
void at_wd76c10_init(); void at_wd76c10_init();
@ -81,6 +83,7 @@ MODEL models[] =
{"Commodore PC 30 III", ROM_CMDPC30, { "", cpus_286, "", NULL, "", NULL}, 0, at_init}, {"Commodore PC 30 III", ROM_CMDPC30, { "", cpus_286, "", NULL, "", NULL}, 0, at_init},
{"AMI 286 clone", ROM_AMI286, { "", cpus_286, "", NULL, "", NULL}, 0, at_neat_init}, {"AMI 286 clone", ROM_AMI286, { "", cpus_286, "", NULL, "", NULL}, 0, at_neat_init},
{"DELL System 200", ROM_DELL200, { "", cpus_286, "", NULL, "", NULL}, 0, at_init}, {"DELL System 200", ROM_DELL200, { "", cpus_286, "", NULL, "", NULL}, 0, at_init},
{"IBM PS/1 model 2011", ROM_IBMPS1_2011, { "", cpus_286, "", NULL, "", NULL}, 1, ps1_init},
{"Acer 386SX25/N", ROM_ACER386, { "Intel", cpus_acer, "", NULL, "", NULL}, 1, at_acer386sx_init}, {"Acer 386SX25/N", ROM_ACER386, { "Intel", cpus_acer, "", NULL, "", NULL}, 1, at_acer386sx_init},
{"Amstrad MegaPC", ROM_MEGAPC, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 1, at_wd76c10_init}, {"Amstrad MegaPC", ROM_MEGAPC, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 1, at_wd76c10_init},
{"AMI 386 clone", ROM_AMI386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, at_headland_init}, {"AMI 386 clone", ROM_AMI386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, at_headland_init},
@ -180,6 +183,7 @@ void ams_init()
nvr_init(); nvr_init();
xtide_init(); xtide_init();
nmi_init(); nmi_init();
fdc_set_dskchg_activelow();
} }
void europc_init() void europc_init()
@ -215,6 +219,20 @@ void at_init()
pic2_init(); pic2_init();
} }
void ps1_init()
{
common_init();
pit_set_out_func(1, pit_refresh_timer_at);
dma16_init();
ide_init();
keyboard_at_init();
mouse_ps2_init();
nvr_init();
pic2_init();
ps1mb_init();
fdc_set_dskchg_activelow();
}
void at_neat_init() void at_neat_init()
{ {
at_init(); at_init();

View file

@ -136,6 +136,7 @@ void loadnvr()
case ROM_PC2086: f = romfopen("pc2086.nvr", "rb"); break; case ROM_PC2086: f = romfopen("pc2086.nvr", "rb"); break;
case ROM_PC3086: f = romfopen("pc3086.nvr", "rb"); break; case ROM_PC3086: f = romfopen("pc3086.nvr", "rb"); break;
case ROM_IBMAT: f = romfopen("at.nvr", "rb"); break; case ROM_IBMAT: f = romfopen("at.nvr", "rb"); break;
case ROM_IBMPS1_2011: f = romfopen("ibmps1_2011.nvr", "rb"); /*nvrmask = 127; */break;
case ROM_CMDPC30: f = romfopen("cmdpc30.nvr", "rb"); nvrmask = 127; break; case ROM_CMDPC30: f = romfopen("cmdpc30.nvr", "rb"); nvrmask = 127; break;
case ROM_AMI286: f = romfopen("ami286.nvr", "rb"); nvrmask = 127; break; case ROM_AMI286: f = romfopen("ami286.nvr", "rb"); nvrmask = 127; break;
case ROM_DELL200: f = romfopen("dell200.nvr", "rb"); nvrmask = 127; break; case ROM_DELL200: f = romfopen("dell200.nvr", "rb"); nvrmask = 127; break;
@ -175,6 +176,7 @@ void savenvr()
case ROM_PC2086: f = romfopen("pc2086.nvr", "wb"); break; case ROM_PC2086: f = romfopen("pc2086.nvr", "wb"); break;
case ROM_PC3086: f = romfopen("pc3086.nvr", "wb"); break; case ROM_PC3086: f = romfopen("pc3086.nvr", "wb"); break;
case ROM_IBMAT: f = romfopen("at.nvr", "wb"); break; case ROM_IBMAT: f = romfopen("at.nvr", "wb"); break;
case ROM_IBMPS1_2011: f = romfopen("ibmps1_2011.nvr", "wb"); break;
case ROM_CMDPC30: f = romfopen("cmdpc30.nvr", "wb"); break; case ROM_CMDPC30: f = romfopen("cmdpc30.nvr", "wb"); break;
case ROM_AMI286: f = romfopen("ami286.nvr", "wb"); break; case ROM_AMI286: f = romfopen("ami286.nvr", "wb"); break;
case ROM_DELL200: f = romfopen("dell200.nvr", "wb"); break; case ROM_DELL200: f = romfopen("dell200.nvr", "wb"); break;

152
src/ps1.c Normal file
View file

@ -0,0 +1,152 @@
#include "ibm.h"
#include "mem.h"
#include "ps1.h"
#include "rom.h"
#include "lpt.h"
static rom_t ps1_high_rom;
static uint8_t ps1_92, ps1_94, ps1_102, ps1_103, ps1_104, ps1_105, ps1_190;
static struct
{
uint8_t status, int_status;
uint8_t attention, ctrl;
} ps1_hd;
uint8_t ps1_read(uint16_t port, void *p)
{
uint8_t temp;
switch (port)
{
case 0x91:
return 0;
case 0x92:
return ps1_92;
case 0x94:
return ps1_94;
case 0x102:
return ps1_102 | 8;
case 0x103:
return ps1_103;
case 0x104:
return ps1_104;
case 0x105:
return ps1_105;
case 0x190:
return ps1_190;
case 0x322:
temp = ps1_hd.status;
break;
case 0x324:
temp = ps1_hd.int_status;
ps1_hd.int_status &= ~0x02;
break;
default:
temp = 0xff;
break;
}
return temp;
}
void ps1_write(uint16_t port, uint8_t val, void *p)
{
switch (port)
{
case 0x0092:
ps1_92 = val;
mem_a20_alt = val & 2;
mem_a20_recalc();
break;
case 0x94:
ps1_94 = val;
break;
case 0x102:
lpt1_remove();
if (val & 0x04)
serial1_init(0x3f8, 4);
else
serial1_remove();
if (val & 0x10)
{
switch ((val >> 5) & 3)
{
case 0:
lpt1_init(0x3bc);
break;
case 1:
lpt1_init(0x378);
break;
case 2:
lpt1_init(0x278);
break;
}
}
ps1_102 = val;
break;
case 0x103:
ps1_103 = val;
break;
case 0x104:
ps1_104 = val;
break;
case 0x105:
ps1_105 = val;
break;
case 0x190:
ps1_190 = val;
break;
case 0x322:
ps1_hd.ctrl = val;
if (val & 0x80)
ps1_hd.status |= 0x02;
break;
case 0x324:
ps1_hd.attention = val & 0xf0;
if (ps1_hd.attention)
ps1_hd.status = 0x14;
break;
}
}
void ps1mb_init()
{
io_sethandler(0x0091, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL);
io_sethandler(0x0092, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL);
io_sethandler(0x0094, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL);
io_sethandler(0x0102, 0x0004, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL);
io_sethandler(0x0190, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL);
io_sethandler(0x0320, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL);
io_sethandler(0x0322, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL);
io_sethandler(0x0324, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL);
rom_init(&ps1_high_rom,
"roms/ibmps1es/f80000.bin",
0xf80000,
0x80000,
0x7ffff,
0,
MEM_MAPPING_EXTERNAL);
/* rom_init_interleaved(&ps1_high_rom,
"roms/ibmps1es/ibm_1057757_24-05-90.bin",
"roms/ibmps1es/ibm_1057757_29-15-90.bin",
0xfc0000,
0x40000,
0x3ffff,
0,
MEM_MAPPING_EXTERNAL);*/
ps1_190 = 0;
lpt1_remove();
lpt2_remove();
lpt1_init(0x3bc);
serial1_remove();
serial2_remove();
memset(&ps1_hd, 0, sizeof(ps1_hd));
}

1
src/ps1.h Normal file
View file

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

View file

@ -100,6 +100,26 @@ void *vga_init()
return vga; return vga;
} }
/*PS/1 uses a standard VGA controller, but with no option ROM*/
void *ps1vga_init()
{
vga_t *vga = malloc(sizeof(vga_t));
memset(vga, 0, sizeof(vga_t));
svga_init(&vga->svga, vga, 1 << 18, /*256kb*/
NULL,
vga_in, vga_out,
NULL,
NULL);
io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga);
vga->svga.bpp = 8;
vga->svga.miscout = 1;
return vga;
}
static int vga_available() static int vga_available()
{ {
return rom_present("roms/ibm_vga.bin"); return rom_present("roms/ibm_vga.bin");
@ -146,3 +166,14 @@ device_t vga_device =
vga_force_redraw, vga_force_redraw,
vga_add_status_info vga_add_status_info
}; };
device_t ps1vga_device =
{
"PS/1 VGA",
0,
ps1vga_init,
vga_close,
vga_available,
vga_speed_changed,
vga_force_redraw,
vga_add_status_info
};

View file

@ -1 +1,2 @@
extern device_t vga_device; extern device_t vga_device;
extern device_t ps1vga_device;

View file

@ -257,6 +257,10 @@ void video_init()
case ROM_ACER386: case ROM_ACER386:
device_add(&oti067_device); device_add(&oti067_device);
return; return;
case ROM_IBMPS1_2011:
device_add(&ps1vga_device);
return;
} }
device_add(video_cards[video_old_to_new(gfxcard)].device); device_add(video_cards[video_old_to_new(gfxcard)].device);
} }