From 2955a5d824093a6a701cef6289fc8ed97ea4c664 Mon Sep 17 00:00:00 2001 From: waltje Date: Sun, 5 Nov 2017 20:43:01 -0500 Subject: [PATCH] Fixed video card init order. Re-added the TI CF62011 SVGA controller, used by PS/1 and some PS/2 machines. --- src/floppy/fdc.c | 22 +- src/floppy/fdd.c | 21 +- src/machine/m_ps1.c | 663 +++++++++++++++++++------------------ src/machine/m_ps2_isa.c | 2 + src/machine/m_ps2_mca.c | 7 + src/machine/machine.c | 12 +- src/video/vid_table.c | 22 +- src/video/vid_ti_cf62011.c | 300 +++++++++++++++++ src/video/vid_ti_cf62011.h | 2 + src/video/video.c | 4 +- src/video/video.h | 3 +- src/win/Makefile.mingw | 3 +- 12 files changed, 683 insertions(+), 378 deletions(-) create mode 100644 src/video/vid_ti_cf62011.c create mode 100644 src/video/vid_ti_cf62011.h 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