diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c
index cf6c53eea..1ba420a29 100644
--- a/src/floppy/fdc.c
+++ b/src/floppy/fdc.c
@@ -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,
* Miran Grca,
@@ -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;
diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c
index 6837486d1..a4fb557f9 100644
--- a/src/floppy/fdd.c
+++ b/src/floppy/fdd.c
@@ -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;
diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c
index 514a9b719..3fee72cb9 100644
--- a/src/machine/m_ps1.c
+++ b/src/machine/m_ps1.c
@@ -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,
+ * Miran Grca,
+ * Fred N. van Kempen,
+ *
+ * Copyright 2008-2017 Sarah Walker.
+ * Copyright 2016,2017 Miran Grca.
+ * Copyright 2017 Fred N. van Kempen.
+ */
#include
#include
+#include
#include
#include
#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);
}
diff --git a/src/machine/m_ps2_isa.c b/src/machine/m_ps2_isa.c
index 96959a65a..89c5c7665 100644
--- a/src/machine/m_ps2_isa.c
+++ b/src/machine/m_ps2_isa.c
@@ -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);
}
diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c
index aa4ab1429..2e0da9137 100644
--- a/src/machine/m_ps2_mca.c
+++ b/src/machine/m_ps2_mca.c
@@ -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);
}
diff --git a/src/machine/machine.c b/src/machine/machine.c
index dfc5c890c..822540341 100644
--- a/src/machine/machine.c
+++ b/src/machine/machine.c
@@ -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,
* Miran Grca,
@@ -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]);
}
diff --git a/src/video/vid_table.c b/src/video/vid_table.c
index a67f452bf..e500c40b0 100644
--- a/src/video/vid_table.c
+++ b/src/video/vid_table.c
@@ -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,
* Fred N. van Kempen,
@@ -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", ¶dise_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
}
diff --git a/src/video/vid_ti_cf62011.c b/src/video/vid_ti_cf62011.c
new file mode 100644
index 000000000..a9278c523
--- /dev/null
+++ b/src/video/vid_ti_cf62011.c
@@ -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,
+ * Miran Grca,
+ * Fred N. van Kempen,
+ *
+ * Copyright 2008-2017 Sarah Walker.
+ * Copyright 2016,2017 Miran Grca.
+ * Copyright 2017 Fred N. van Kempen.
+ */
+#include
+#include
+#include
+#include
+#include
+#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
+};
diff --git a/src/video/vid_ti_cf62011.h b/src/video/vid_ti_cf62011.h
new file mode 100644
index 000000000..97a4de996
--- /dev/null
+++ b/src/video/vid_ti_cf62011.h
@@ -0,0 +1,2 @@
+extern device_t ti_cf62011_device;
+extern device_t ibm_ps1_2121_device;
diff --git a/src/video/video.c b/src/video/video.c
index c4fb591ab..c76ab4bf5 100644
--- a/src/video/video.c
+++ b/src/video/video.c
@@ -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,
* Miran Grca,
@@ -477,8 +477,6 @@ video_init(void)
{
int c, d, e;
- pclog("VIDEO: initializing..\n");
-
/* Account for overscan. */
buffer32 = create_bitmap(2048, 2048);
diff --git a/src/video/video.h b/src/video/video.h
index 7e3546677..a7b9d8760 100644
--- a/src/video/video.h
+++ b/src/video/video.h
@@ -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,
* Miran Grca,
@@ -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
};
diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw
index 8ba0997d0..72a5aca71 100644
--- a/src/win/Makefile.mingw
+++ b/src/win/Makefile.mingw
@@ -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,
# Fred N. van Kempen,
@@ -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