This commit is contained in:
OBattler
2017-11-06 02:43:42 +01:00
12 changed files with 683 additions and 378 deletions

View File

@@ -9,7 +9,7 @@
* Implementation of the NEC uPD-765 and compatible floppy disk
* controller.
*
* Version: @(#)fdc.c 1.0.8 2017/11/04
* Version: @(#)fdc.c 1.0.8 2017/11/05
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -40,8 +40,6 @@
extern int64_t motoron[FDD_NUM];
int ui_writeprot[FDD_NUM] = {0, 0, 0, 0};
int command_has_drivesel[256] = {
0, 0,
1, /* READ TRACK */
@@ -1332,16 +1330,24 @@ uint8_t fdc_read(uint16_t addr, void *priv)
drive = real_drive(fdc.dor & 3);
if (fdc.ps1)
{
/*PS/1 Model 2121 seems return drive type in port 0x3f3,
despite the 82077AA FDC not implementing this. This is
presumably implemented outside the FDC on one of the
motherboard's support chips.*/
/* PS/1 Model 2121 seems return drive type in port
* 0x3f3, despite the 82077AA FDC not implementing
* this. This is presumably implemented outside the
* FDC on one of the motherboard's support chips.
*
* Confirmed: 00=1.44M 3.5
* 10=2.88M 3.5
* 20=1.2M 5.25
* 30=1.2M 5.25
*
* as reported by Configur.exe.
*/
if (fdd_is_525(drive))
temp = 0x20;
else if (fdd_is_ed(drive))
temp = 0x10;
else
temp = 0x00;
temp = 0x30;
}
else if (!fdc.enh_mode)
temp = 0x20;

View File

@@ -26,20 +26,19 @@
#include "fdd.h"
static struct
{
int type;
int track;
typedef struct {
int type;
int track;
int densel;
int head;
int turbo;
int check_bpb;
} fdd_t;
int densel;
int head;
fdd_t fdd[FDD_NUM];
int ui_writeprot[FDD_NUM] = {0, 0, 0, 0};
int turbo;
int check_bpb;
} fdd[FDD_NUM];
/* Flags:
Bit 0: 300 rpm supported;

View File

@@ -1,8 +1,38 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Emulation of the IBM PS/1 models 2011, 2121 and 2133.
*
* Model 2121: This is similar to model 2011 but some of the functionality
* has moved to a chip at ports 0xe0 (index)/0xe1 (data). The
* only functions I have identified are enables for the first
* 512K and next 128K of RAM, in bits 0 of registers 0 and 1
* respectively.
*
* Port 0x105 has bit 7 forced high. Without this 128K of
* memory will be missed by the BIOS on cold boots.
*
* The reserved 384K is remapped to the top of extended memory.
* If this is not done then you get an error on startup.
*
* Version: @(#)m_ps1.c 1.0.2 2017/11/05
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016,2017 Miran Grca.
* Copyright 2017 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include "../86box.h"
@@ -25,366 +55,339 @@
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "../sound/snd_ps1.h"
#include "../video/video.h"
#include "../video/vid_vga.h"
#include "../video/vid_ti_cf62011.h"
#include "machine.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 int ps1_e0_addr;
static uint8_t ps1_e0_regs[256];
typedef struct {
int model;
rom_t high_rom;
uint8_t ps1_92,
ps1_94,
ps1_102,
ps1_103,
ps1_104,
ps1_105,
ps1_190;
int ps1_e0_addr;
uint8_t ps1_e0_regs[256];
struct {
uint8_t status, int_status;
uint8_t attention, ctrl;
} hd;
} ps1_t;
static struct
static void
recalc_memory(ps1_t *ps)
{
uint8_t status, int_status;
uint8_t attention, ctrl;
} ps1_hd;
/* Enable first 512K */
mem_set_mem_state(0x00000, 0x80000,
(ps->ps1_e0_regs[0] & 0x01) ?
(MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) :
(MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL));
static 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;
}
static 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)
serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ);
else
serial_remove(1);
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(void)
{
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);
#if 0
if (!enable_xtide)
{
rom_init(&ps1_high_rom,
L"roms/machines/ibmps1es/f80000_shell.bin",
0xf80000,
0x80000,
0x7ffff,
0,
MEM_MAPPING_EXTERNAL);
}
#endif
ps1_190 = 0;
lpt1_remove();
lpt2_remove();
lpt1_init(0x3bc);
serial_remove(1);
serial_remove(2);
memset(&ps1_hd, 0, sizeof(ps1_hd));
}
/*PS/1 Model 2121.
This is similar to the model 2011 but some of the functionality has moved to a
chip at ports 0xe0 (index)/0xe1 (data). The only functions I have identified
are enables for the first 512kb and next 128kb of RAM, in bits 0 of registers
0 and 1 respectively.
Port 0x105 has bit 7 forced high. Without this 128kb of memory will be missed
by the BIOS on cold boots.
The reserved 384kb is remapped to the top of extended memory. If this is not
done then you get an error on startup.
*/
static uint8_t ps1_m2121_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 0xe1:
return ps1_e0_regs[ps1_e0_addr];
case 0x102:
return ps1_102;
case 0x103:
return ps1_103;
case 0x104:
return ps1_104;
case 0x105:
return ps1_105 | 0x80;
case 0x190:
return ps1_190;
default:
temp = 0xff;
break;
}
return temp;
}
static void ps1_m2121_recalc_memory(void)
{
/*Enable first 512kb*/
mem_set_mem_state(0x00000, 0x80000, (ps1_e0_regs[0] & 0x01) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL));
/*Enable 512-640kb*/
mem_set_mem_state(0x80000, 0x20000, (ps1_e0_regs[1] & 0x01) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL));
}
void ps1_m2121_write(uint16_t port, uint8_t val, void *p)
{
switch (port)
{
case 0x0092:
if (val & 1)
{
softresetx86();
cpu_set_edx();
}
ps1_92 = val & ~1;
mem_a20_alt = val & 2;
mem_a20_recalc();
break;
case 0x94:
ps1_94 = val;
break;
case 0xe0:
ps1_e0_addr = val;
break;
case 0xe1:
ps1_e0_regs[ps1_e0_addr] = val;
ps1_m2121_recalc_memory();
break;
case 0x102:
lpt1_remove();
if (val & 0x04)
serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ);
else
serial_remove(1);
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;
}
}
static void ps1mb_m2121_init(void)
{
io_sethandler(0x0091, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL);
io_sethandler(0x0092, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL);
io_sethandler(0x0094, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL);
io_sethandler(0x00e0, 0x0002, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL);
io_sethandler(0x0102, 0x0004, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL);
io_sethandler(0x0190, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL);
rom_init(&ps1_high_rom,
L"roms/machines/ibmps1_2121/fc0000_shell.bin",
0xfc0000,
0x40000,
0x3ffff,
0,
MEM_MAPPING_EXTERNAL);
ps1_92 = 0;
ps1_190 = 0;
lpt1_init(0x3bc);
mem_remap_top_384k();
}
static void ps1mb_m2133_init(void)
{
io_sethandler(0x0091, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL);
io_sethandler(0x0092, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL);
io_sethandler(0x0094, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL);
io_sethandler(0x0102, 0x0004, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL);
io_sethandler(0x0190, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL);
ps1_92 = 0;
ps1_190 = 0;
lpt1_init(0x3bc);
mem_remap_top_384k();
/* Enable 512-640K */
mem_set_mem_state(0x80000, 0x20000,
(ps->ps1_e0_regs[1] & 0x01) ?
(MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) :
(MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL));
}
static void
machine_ps1_common_init(machine_t *model)
ps1_write(uint16_t port, uint8_t val, void *priv)
{
machine_common_init(model);
ps1_t *ps = (ps1_t *)priv;
pit_set_out_func(&pit, 1, pit_refresh_timer_at);
dma16_init();
if (romset != ROM_IBMPS1_2011)
{
ide_init();
}
device_add(&keyboard_at_device);
nvr_at_init(8);
pic2_init();
if (romset != ROM_IBMPS1_2133)
{
fdc_set_dskchg_activelow();
device_add(&ps1_audio_device);
}
switch (port) {
case 0x0092:
if (ps->model != 2011) {
if (val & 1) {
softresetx86();
cpu_set_edx();
}
ps->ps1_92 = val & ~1;
} else {
ps->ps1_92 = val;
}
mem_a20_alt = val & 2;
mem_a20_recalc();
break;
/*PS/1 audio uses ports 200h and 202-207h, so only initialise gameport on 201h*/
if (joystick_type != 7)
device_add(&gameport_201_device);
case 0x0094:
ps->ps1_94 = val;
break;
case 0x00e0:
if (ps->model != 2011) {
ps->ps1_e0_addr = val;
}
break;
case 0x00e1:
if (ps->model != 2011) {
ps->ps1_e0_regs[ps->ps1_e0_addr] = val;
recalc_memory(ps);
}
break;
case 0x0102:
lpt1_remove();
if (val & 0x04)
serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ);
else
serial_remove(1);
if (val & 0x10) {
switch ((val >> 5) & 3) {
case 0:
lpt1_init(0x03bc);
break;
case 1:
lpt1_init(0x0378);
break;
case 2:
lpt1_init(0x0278);
break;
}
}
ps->ps1_102 = val;
break;
case 0x0103:
ps->ps1_103 = val;
break;
case 0x0104:
ps->ps1_104 = val;
break;
case 0x0105:
ps->ps1_105 = val;
break;
case 0x0190:
ps->ps1_190 = val;
break;
case 0x0322:
if (ps->model == 2011) {
ps->hd.ctrl = val;
if (val & 0x80)
ps->hd.status |= 0x02;
}
break;
case 0x0324:
if (ps->model == 2011) {
ps->hd.attention = val & 0xf0;
if (ps->hd.attention)
ps->hd.status = 0x14;
}
break;
}
}
static uint8_t
ps1_read(uint16_t port, void *priv)
{
ps1_t *ps = (ps1_t *)priv;
uint8_t ret = 0xff;
switch (port) {
case 0x0091:
ret = 0;
break;
case 0x0092:
ret = ps->ps1_92;
break;
case 0x0094:
ret = ps->ps1_94;
break;
case 0x00e1:
if (ps->model != 2011) {
ret = ps->ps1_e0_regs[ps->ps1_e0_addr];
}
break;
case 0x0102:
if (ps->model == 2011)
ret = ps->ps1_102 | 0x08;
else
ret = ps->ps1_102;
break;
case 0x0103:
ret = ps->ps1_103;
break;
case 0x0104:
ret = ps->ps1_104;
break;
case 0x0105:
if (ps->model == 2011)
ret = ps->ps1_105;
else
ret = ps->ps1_105 | 0x80;
break;
case 0x0190:
ret = ps->ps1_190;
break;
case 0x0322:
if (ps->model == 2011) {
ret = ps->hd.status;
}
break;
case 0x0324:
if (ps->model == 2011) {
ret = ps->hd.int_status;
ps->hd.int_status &= ~0x02;
}
break;
default:
break;
}
return(ret);
}
static void
ps1_setup(int model)
{
ps1_t *ps;
ps = (ps1_t *)malloc(sizeof(ps1_t));
memset(ps, 0x00, sizeof(ps1_t));
ps->model = model;
io_sethandler(0x0091, 1,
ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps);
io_sethandler(0x0092, 1,
ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps);
io_sethandler(0x0094, 1,
ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps);
io_sethandler(0x0102, 4,
ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps);
io_sethandler(0x0190, 1,
ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps);
if (model == 2011) {
io_sethandler(0x0320, 1,
ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps);
io_sethandler(0x0322, 1,
ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps);
io_sethandler(0x0324, 1,
ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps);
#if 0
rom_init(&ps->high_rom,
L"roms/machines/ibmps1es/f80000_shell.bin",
0xf80000, 0x80000, 0x7ffff, 0, MEM_MAPPING_EXTERNAL);
#endif
lpt1_remove();
lpt2_remove();
lpt1_init(0x03bc);
serial_remove(1);
serial_remove(2);
/* Enable the PS/1 VGA controller. */
device_add(&ps1vga_device);
}
if (model == 2121) {
io_sethandler(0x00e0, 2,
ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps);
#if 0
rom_init(&ps->high_rom,
L"roms/machines/ibmps1_2121/fc0000_shell.bin",
0xfc0000, 0x40000, 0x3ffff, 0, MEM_MAPPING_EXTERNAL);
#endif
lpt1_init(0x03bc);
/* Initialize the video controller. */
if (gfxcard == GFX_INTERNAL)
device_add(&ibm_ps1_2121_device);
}
if (model == 2133) {
lpt1_init(0x03bc);
}
}
static void
ps1_common_init(machine_t *model)
{
machine_common_init(model);
mem_remap_top_384k();
pit_set_out_func(&pit, 1, pit_refresh_timer_at);
dma16_init();
pic2_init();
nvr_at_init(8);
// if (romset != ROM_IBMPS1_2011)
ide_init();
device_add(&keyboard_at_device);
if (romset != ROM_IBMPS1_2133) {
fdc_set_dskchg_activelow();
device_add(&ps1_audio_device);
}
/* Audio uses ports 200h and 202-207h, so only initialize gameport on 201h. */
if (joystick_type != 7)
device_add(&gameport_201_device);
}
void
machine_ps1_m2011_init(machine_t *model)
{
machine_ps1_common_init(model);
ps1_common_init(model);
ps1mb_init();
mem_remap_top_384k();
ps1_setup(2011);
}
void
machine_ps1_m2121_init(machine_t *model)
{
machine_ps1_common_init(model);
ps1_common_init(model);
ps1mb_m2121_init();
fdc_set_ps1();
ps1_setup(2121);
fdc_set_ps1();
}
void
machine_ps1_m2133_init(machine_t *model)
{
machine_ps1_common_init(model);
ps1_common_init(model);
ps1mb_m2133_init();
ps1_setup(2133);
}

View File

@@ -18,6 +18,7 @@
#include "../floppy/floppy.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "../video/vid_ti_cf62011.h"
#include "machine.h"
@@ -165,4 +166,5 @@ machine_ps2_m30_286_init(machine_t *model)
ps2board_init();
fdc_set_dskchg_activelow();
fdc_set_ps1();
device_add(&ti_cf62011_device);
}

View File

@@ -19,6 +19,7 @@
#include "../lpt.h"
#include "../mouse.h"
#include "../serial.h"
#include "../video/vid_ti_cf62011.h"
#include "machine.h"
@@ -574,6 +575,8 @@ static void ps2_mca_board_model_50_init()
ps2.planar_read = model_50_read;
ps2.planar_write = model_50_write;
device_add(&ti_cf62011_device);
}
static void ps2_mca_board_model_55sx_init()
@@ -636,6 +639,8 @@ static void ps2_mca_board_model_55sx_init()
ps2.planar_read = model_55sx_read;
ps2.planar_write = model_55sx_write;
device_add(&ti_cf62011_device);
}
static void mem_encoding_update()
@@ -799,6 +804,8 @@ static void ps2_mca_board_model_80_type2_init()
NULL);
mem_mapping_disable(&ps2.expansion_mapping);
}
device_add(&ti_cf62011_device);
}

View File

@@ -8,7 +8,7 @@
*
* Handling of the emulated machines.
*
* Version: @(#)machine.c 1.0.25 2017/11/04
* Version: @(#)machine.c 1.0.26 2017/11/05
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -83,8 +83,8 @@ machine_t machines[] =
{"[386SX ISA] Amstrad MegaPC", ROM_MEGAPC, "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 1, 16, 1, 127, machine_at_wd76c10_init, NULL },
{"[386SX ISA] Award 386SX clone", ROM_AWARD386SX_OPTI495, "award386sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_init, NULL },
{"[386SX ISA] DTK 386SX clone", ROM_DTK386, "dtk386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_neat_init, NULL },
{"[386SX ISA] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 1, 16, 1, 127, machine_ps1_m2121_init, NULL },
{"[386SX ISA] IBM PS/1 m.2121+ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 1, 16, 1, 127, machine_ps1_m2121_init, NULL },
{"[386SX ISA] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 6, 1, 127, machine_ps1_m2121_init, NULL },
{"[386SX ISA] IBM PS/1 m.2121+ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 6, 1, 127, machine_ps1_m2121_init, NULL },
{"[386SX MCA] IBM PS/2 model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 8, 1, 63, machine_ps2_model_55sx_init, NULL },
@@ -147,12 +147,12 @@ machine_init(void)
rom_load_bios(romset);
mem_add_bios();
/* All good, boot the machine! */
machines[machine].init(&machines[machine]);
/* Add video card unless its their internal one. */
if (! machines[machine].fixed_gfxcard)
video_reset_card(gfxcard);
/* All good, boot the machine! */
machines[machine].init(&machines[machine]);
}

View File

@@ -8,7 +8,7 @@
*
* Define all known video cards.
*
* Version: @(#)vid_table.c 1.0.5 2017/11/04
* Version: @(#)vid_table.c 1.0.6 2017/11/05
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
@@ -62,6 +62,7 @@
#include "vid_tgui9440.h"
#include "vid_tvga.h"
#include "vid_vga.h"
#include "vid_ti_cf62011.h"
#include "vid_wy700.h"
@@ -112,6 +113,8 @@ video_cards[] = {
{ "[ISA] OAK OTI-077", "oti077", &oti077_device, GFX_OTI077 },
{ "[ISA] Paradise WD90C11", "wd90c11", &paradise_wd90c11_device, GFX_WD90C11 },
{ "[ISA] Plantronics ColorPlus", "plantronics", &colorplus_device, GFX_COLORPLUS },
{"[ISA] TI CF62011 SVGA", "ti_cf62011",
&ti_cf62011_device, GFX_TICF62011 },
{ "[ISA] Trident TVGA8900D", "tvga8900d", &tvga8900d_device, GFX_TVGA },
{ "[ISA] Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000 },
{"[ISA] VGA", "vga", &vga_device, GFX_VGA },
@@ -170,9 +173,6 @@ video_reset_card(int card)
device_add(video_cards[video_old_to_new(card)].device);
#if 0
switch (rs) {
case ROM_IBMPCJR:
case ROM_OLIM24:
case ROM_PC1512:
device_add(&pc1512_device);
case ROM_PC1640:
@@ -190,20 +190,6 @@ video_reset_card(int card)
device_add(&tandy_device);
case ROM_TANDY1000SL2:
device_add(&tandysl_device);
case ROM_IBMPS1_2011:
device_add(&ps1vga_device);
case ROM_IBMPS1_2121:
case ROM_IBMPS2_M30_286:
case ROM_IBMPS2_M50:
case ROM_IBMPS2_M55SX:
case ROM_IBMPS2_M80:
device_add(&ps1_m2121_svga_device);
/* Handled by the machine. */
break;
default:
device_add(video_cards[video_old_to_new(gc)].device);
}
#endif
}

300
src/video/vid_ti_cf62011.c Normal file
View File

@@ -0,0 +1,300 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Emulation of the TI CF62011 SVGA chip.
*
* This chip was used in several of IBM's later machines, such
* as the PS/1 Model 2121, and a number of PS/2 models. As noted
* in an article on Usenet:
*
* "In the early 90s IBM looked for some cheap VGA card to
* substitute the (relatively) expensive XGA-2 adapter for
* *servers*, where the primary purpose is supervision of the
* machine rather than real *work* with it in Hi-Res. It was
* just to supply a base video, where a XGA-2 were a waste of
* potential. They had a contract with TI for some DSPs in
* multimedia already (the MWave for instance is based on
* TI-DSPs as well as many Thinkpad internal chipsets) and TI
* offered them a rather cheap and inexpensive chipset
* and combined it with a cheap clock oscillator and an Inmos
* RAMDAC. That chipset was already pretty much outdated at
* that time but IBM decided it would suffice for that low
* end purpose.
*
* Driver support was given under DOS and OS/2 only for base
* functions like selection of the vertical refresh and few
* different modes only. Not even the Win 3.x support has
* been finalized. Technically the adapter could do better
* than VGA, but its video BIOS is largely undocumented and
* intentionally crippled down to a few functions."
*
* This chip is reportedly the same one as used in the MCA
* IBM SVGA Adapter/A (ID 090EEh), which mostly had faster
* VRAM and RAMDAC. The VESA DOS graphics driver for that
* card can be used: m95svga.exe
*
* The controller responds at ports in the range 0x2100-0x210F,
* which are the same as the XGA. It supports up to 1MB of VRAM,
* but we lock it down to 512K. The PS/1 2122 had 256K.
*
* Version: @(#)vid_ti_cf62011.c 1.0.2 2017/11/05
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016,2017 Miran Grca.
* Copyright 2017 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include "../86box.h"
#include "../config.h"
#include "../io.h"
#include "../mem.h"
#include "../rom.h"
#include "../device.h"
#include "../video/video.h"
#include "../video/vid_vga.h"
#include "../video/vid_svga.h"
#include "vid_ti_cf62011.h"
typedef struct {
svga_t svga;
rom_t bios_rom;
uint32_t vram_size;
uint8_t banking;
uint8_t reg_2100;
uint8_t reg_210a;
} tivga_t;
static void
vid_out(uint16_t addr, uint8_t val, void *priv)
{
tivga_t *ti = (tivga_t *)priv;
svga_t *svga = &ti->svga;
uint8_t old;
if (((addr & 0xfff0) == 0x3d0 ||
(addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60;
switch (addr) {
case 0x3D4:
svga->crtcreg = val & 0x1f;
return;
case 0x3D5:
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80))
return;
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80))
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
old = svga->crtc[svga->crtcreg];
svga->crtc[svga->crtcreg] = val;
if (old != val) {
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
break;
case 0x2100:
ti->reg_2100 = val;
if ((val & 7) < 4)
svga->write_bank = 0;
else
svga->write_bank = (ti->banking & 0x7) * 0x10000;
svga->read_bank = svga->write_bank;
break;
case 0x2108:
if ((ti->reg_2100 & 7) >= 4)
svga->write_bank = (val & 0x7) * 0x10000;
svga->read_bank = svga->write_bank;
ti->banking = val;
break;
case 0x210a:
ti->reg_210a = val;
break;
}
svga_out(addr, val, svga);
}
static uint8_t
vid_in(uint16_t addr, void *priv)
{
tivga_t *ti = (tivga_t *)priv;
svga_t *svga = &ti->svga;
uint8_t ret;
if (((addr & 0xfff0) == 0x3d0 ||
(addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60;
switch (addr) {
case 0x100:
ret = 0xfe;
break;
case 0x101:
ret = 0xe8;
break;
case 0x3D4:
ret = svga->crtcreg;
break;
case 0x3D5:
ret = svga->crtc[svga->crtcreg];
break;
case 0x2108:
ret = ti->banking;
break;
case 0x210a:
ret = ti->reg_210a;
break;
default:
ret = svga_in(addr, svga);
break;
}
return(ret);
}
static void
vid_speed_changed(void *priv)
{
tivga_t *ti = (tivga_t *)priv;
svga_recalctimings(&ti->svga);
}
static void
vid_force_redraw(void *priv)
{
tivga_t *ti = (tivga_t *)priv;
ti->svga.fullchange = changeframecount;
}
static void
vid_add_status_info(char *s, int max_len, void *priv)
{
tivga_t *ti = (tivga_t *)priv;
svga_add_status_info(s, max_len, &ti->svga);
}
static void
vid_close(void *priv)
{
tivga_t *ti = (tivga_t *)priv;
svga_close(&ti->svga);
free(ti);
}
static void *
vid_init(device_t *info)
{
tivga_t *ti;
/* Allocate control block and initialize. */
ti = (tivga_t *)malloc(sizeof(tivga_t));
memset(ti, 0x00, sizeof(tivga_t));
/* Set amount of VRAM in KB. */
if (info->local == 0)
ti->vram_size = device_get_config_int("vram_size");
else
ti->vram_size = info->local;
pclog("VIDEO: initializing %s, %dK VRAM\n", info->name, ti->vram_size);
svga_init(&ti->svga, ti, ti->vram_size<<10, NULL, vid_in, vid_out, NULL, NULL);
io_sethandler(0x0100, 2, vid_in, NULL, NULL, vid_out, NULL, NULL, ti);
io_sethandler(0x03c0, 32, vid_in, NULL, NULL, vid_out, NULL, NULL, ti);
io_sethandler(0x2100, 16, vid_in, NULL, NULL, vid_out, NULL, NULL, ti);
ti->svga.bpp = 8;
ti->svga.miscout = 1;
return(ti);
}
static device_config_t vid_config[] =
{
{
"vram_size", "Memory Size", CONFIG_SELECTION, "", 256,
{
{
"256K", 256
},
{
"512K", 512
},
{
"1024K", 1024
},
{
""
}
}
},
{
"", "", -1
}
};
device_t ti_cf62011_device = {
"TI CF62011 SVGA",
0,
0,
vid_init, vid_close, NULL,
NULL,
vid_speed_changed,
vid_force_redraw,
vid_add_status_info,
vid_config
};
device_t ibm_ps1_2121_device = {
"IBM PS/1 Model 2121 SVGA",
0,
256,
vid_init, vid_close, NULL,
NULL,
vid_speed_changed,
vid_force_redraw,
vid_add_status_info,
NULL
};

View File

@@ -0,0 +1,2 @@
extern device_t ti_cf62011_device;
extern device_t ibm_ps1_2121_device;

View File

@@ -40,7 +40,7 @@
* W = 3 bus clocks
* L = 4 bus clocks
*
* Version: @(#)video.c 1.0.8 2017/11/04
* Version: @(#)video.c 1.0.9 2017/11/05
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -477,8 +477,6 @@ video_init(void)
{
int c, d, e;
pclog("VIDEO: initializing..\n");
/* Account for overscan. */
buffer32 = create_bitmap(2048, 2048);

View File

@@ -8,7 +8,7 @@
*
* Definitions for the video controller module.
*
* Version: @(#)video.h 1.0.2 2017/11/04
* Version: @(#)video.h 1.0.3 2017/11/05
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -91,6 +91,7 @@ enum {
GFX_CL_GD5434, /* Cirrus Logic CL-GD5434 */
GFX_CL_GD5436, /* Cirrus Logic CL-GD5436 */
GFX_CL_GD5440, /* Cirrus Logic CL-GD5440 */
GFX_TICF62011, /* TI CF62011 */
GFX_MAX
};

View File

@@ -8,7 +8,7 @@
#
# Makefile for Win32 (MinGW32) environment.
#
# Version: @(#)Makefile.mingw 1.0.71 2017/11/04
# Version: @(#)Makefile.mingw 1.0.72 2017/11/05
#
# Authors: Miran Grca, <mgrca8@gmail.com>
# Fred N. van Kempen, <decwiz@yahoo.com>
@@ -383,6 +383,7 @@ VIDOBJ := video.o \
vid_sc1502x_ramdac.o \
vid_sdac_ramdac.o \
vid_stg_ramdac.o \
vid_ti_cf62011.o \
vid_wy700.o \
vid_voodoo.o