Merge branch '86Box:master' into master

This commit is contained in:
starfrost
2025-06-09 23:05:04 +01:00
committed by GitHub
33 changed files with 1323 additions and 772 deletions

View File

@@ -57,6 +57,7 @@ add_library(dev OBJECT
smbus_ali7101.c
smbus_piix4.c
smbus_sis5595.c
tulip_jumper.c
unittester.c
)

File diff suppressed because it is too large Load Diff

103
src/device/tulip_jumper.c Normal file
View File

@@ -0,0 +1,103 @@
/*
* 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.
*
* Implementation of the Tulip Jumper Readout.
*
* Bits 7-5 = board number, 0-5 valid, 6, 7 invalid.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2025 Miran Grca.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include "cpu.h"
#include <86box/timer.h>
#include <86box/io.h>
#include <86box/device.h>
#include <86box/machine.h>
#include <86box/sound.h>
#include <86box/chipset.h>
#include <86box/plat.h>
#include <86box/plat_unused.h>
typedef struct tulip_jumper_t {
uint8_t jumper;
} tulip_jumper_t;
#ifdef ENABLE_TULIP_JUMPER_LOG
int tulip_jumper_do_log = ENABLE_TULIP_JUMPER_LOG;
static void
tulip_jumper_log(const char *fmt, ...)
{
va_list ap;
if (tulip_jumper_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define tulip_jumper_log(fmt, ...)
#endif
static uint8_t
tulip_jumper_read(uint16_t addr, void *priv)
{
const tulip_jumper_t *dev = (tulip_jumper_t *) priv;
uint8_t ret = 0xff;
tulip_jumper_log("Tulip Jumper: Read %02x\n", dev->jumper);
ret = dev->jumper;
return ret;
}
static void
tulip_jumper_close(void *priv)
{
tulip_jumper_t *dev = (tulip_jumper_t *) priv;
free(dev);
}
static void *
tulip_jumper_init(const device_t *info)
{
tulip_jumper_t *dev = (tulip_jumper_t *) calloc(1, sizeof(tulip_jumper_t));
/* Return board number 05. */
dev->jumper = 0xbf;
io_sethandler(0x0d80, 0x0001, tulip_jumper_read, NULL, NULL, NULL, NULL, NULL, dev);
return dev;
}
const device_t tulip_jumper_device = {
.name = "Tulip Jumper Readout",
.internal_name = "tulip_jumper",
.flags = 0,
.local = 0,
.init = tulip_jumper_init,
.close = tulip_jumper_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -187,10 +187,18 @@ fdc_ctrl_reset(void *priv)
fdc->stat = 0x80;
fdc->pnum = fdc->ptot = 0;
fdc->st0 = 0;
fdc->lock = 0;
fdc->head = 0;
fdc->step = 0;
fdc->power_down = 0;
if (!fdc->lock) {
fdc->fifo = 0;
fdc->tfifo = 1;
fifo_reset(fdc->fifo_p);
fifo_set_len(fdc->fifo_p, fdc->tfifo + 1);
fifo_set_trigger_len(fdc->fifo_p, fdc->tfifo + 1);
}
}
sector_id_t
@@ -2374,6 +2382,8 @@ fdc_reset(void *priv)
fdc->swwp = 0;
fdc->disable_write = 0;
fdc->lock = 0;
fdc_ctrl_reset(fdc);
if (!(fdc->flags & FDC_FLAG_AT))

View File

@@ -201,6 +201,8 @@ extern const device_t vlsi_scamp_device;
extern const device_t wd76c10_device;
/* Miscellaneous Hardware */
extern const device_t tulip_jumper_device;
extern const device_t dell_jumper_device;
extern const device_t nec_mate_unk_device;

View File

@@ -473,7 +473,9 @@ extern int machine_at_spc4216p_init(const machine_t *);
extern int machine_at_spc4620p_init(const machine_t *);
extern int machine_at_kmxc02_init(const machine_t *);
extern int machine_at_deskmaster286_init(const machine_t *);
extern int machine_at_dells200_init(const machine_t *);
extern int machine_at_tuliptc7_init(const machine_t *);
extern int machine_at_pc8_init(const machine_t *);
extern int machine_at_3302_init(const machine_t *);
@@ -546,6 +548,7 @@ extern int machine_at_exp4349_init(const machine_t *);
extern int machine_at_vect486vl_init(const machine_t *);
extern int machine_at_d824_init(const machine_t *);
extern int machine_at_tuliptc38_init(const machine_t *);
extern int machine_at_martin_init(const machine_t *);
extern int machine_at_403tg_init(const machine_t *);
@@ -610,6 +613,7 @@ extern int machine_at_iach488_init(const machine_t *);
extern int machine_at_pcm9340_init(const machine_t *);
extern int machine_at_pcm5330_init(const machine_t *);
extern int machine_at_84xxuuda_init(const machine_t *);
extern int machine_at_ecs486_init(const machine_t *);
extern int machine_at_hot433a_init(const machine_t *);
extern int machine_at_pl4600c_init(const machine_t *);

View File

@@ -102,4 +102,6 @@ extern int picinterrupt(void);
extern uint8_t pic_irq_ack(void);
extern void pic_toggle_latch(int is_ps2);
#endif /*EMU_PIC_H*/

View File

@@ -24,6 +24,19 @@
#define INT_FIFO_EMP (1 << 3)
#define INT_MASK 0xf
typedef enum {
IBM_8514A_TYPE = 0,
ATI_38800_TYPE,
ATI_68800_TYPE,
TYPE_MAX
} ibm8514_card_type;
typedef enum {
IBM = 0,
ATI,
EXTENSIONS_MAX
} ibm8514_extensions_t;
typedef struct hwcursor8514_t {
int ena;
int x;
@@ -58,7 +71,7 @@ typedef struct ibm8514_t {
int force_old_addr;
int type;
int local;
ibm8514_card_type local;
int bpp;
int on;
int accel_bpp;
@@ -246,7 +259,8 @@ typedef struct ibm8514_t {
int pitch;
int ext_pitch;
int ext_crt_pitch;
int extensions;
ibm8514_extensions_t extensions;
int onboard;
int linear;
uint32_t vram_amount;
int vram_512k_8514;
@@ -263,9 +277,9 @@ typedef struct ibm8514_t {
} ibm8514_t;
#define IBM_8514A (((dev->local & 0xff) == 0x00) && (dev->extensions == 0x00))
#define ATI_8514A_ULTRA (((dev->local & 0xff) == 0x00) && (dev->extensions == 0x01))
#define ATI_GRAPHICS_ULTRA ((dev->local & 0xff) == 0x01)
#define ATI_MACH32 ((dev->local & 0xff) == 0x02)
#define IBM_8514A (((dev->local & 0xff) == IBM_8514A_TYPE) && (dev->extensions == IBM))
#define ATI_8514A_ULTRA (((dev->local & 0xff) == IBM_8514A_TYPE) && (dev->extensions == ATI))
#define ATI_GRAPHICS_ULTRA ((dev->local & 0xff) == ATI_38800_TYPE)
#define ATI_MACH32 ((dev->local & 0xff) == ATI_68800_TYPE)
#endif /*VIDEO_8514A_H*/

View File

@@ -15,16 +15,65 @@
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
* Copyright 2025 starfrost (refactoring)
*/
#ifndef VIDEO_CGA_H
#define VIDEO_CGA_H
// Mode flags for the CGA.
// Set by writing to 3D8
typedef enum cga_mode_flags_e
{
CGA_MODE_FLAG_HIGHRES = 1 << 0, // 80-column text mode
CGA_MODE_FLAG_GRAPHICS = 1 << 1, // Graphics mode
CGA_MODE_FLAG_BW = 1 << 2, // Black and white
CGA_MODE_FLAG_VIDEO_ENABLE = 1 << 3, // 0 = no video (as if the video was 0)
CGA_MODE_FLAG_HIGHRES_GRAPHICS = 1 << 4, // 640*200 mode. Corrupts text mode if CGA_MODE_FLAG_GRAPHICS not set.
CGA_MODE_FLAG_BLINK = 1 << 5, // If this is set, bit 5 of textmode characters blinks. Otherwise it is a high-intensity bg mode.
} cga_mode_flags;
// Motorola MC6845 CRTC registers
typedef enum cga_crtc_registers_e
{
CGA_CRTC_HTOTAL = 0x0, // Horizontal total (total number of characters incl. hsync)
CGA_CRTC_HDISP = 0x1, // Horizontal display
CGA_CRTC_HSYNC_POS = 0x2, // Horizontal position of horizontal ysnc
CGA_CRTC_HSYNC_WIDTH = 0x3, // Width of horizontal sync
CGA_CRTC_VTOTAL = 0x4, // Vertical total (total number of scanlines incl. vsync)
CGA_CRTC_VTOTAL_ADJUST = 0x5, // Vertical total adjust value
CGA_CRTC_VDISP = 0x6, // Vertical display (total number of displayed scanline)
CGA_CRTC_VSYNC = 0x7, // Vertical sync scanline number
CGA_CRTC_INTERLACE = 0x8, // Interlacing mode
CGA_CRTC_MAX_SCANLINE_ADDR = 0x9, // Maximum scanline address
CGA_CRTC_CURSOR_START = 0xA, // Cursor start scanline
CGA_CRTC_CURSOR_END = 0xB, // Cursor end scanline
CGA_CRTC_START_ADDR_HIGH = 0xC, // Screen start address high 8 bits
CGA_CRTC_START_ADDR_LOW = 0xD, // Screen start address low 8 bits
CGA_CRTC_CURSOR_ADDR_HIGH = 0xE, // Cursor address high 8 bits
CGA_CRTC_CURSOR_ADDR_LOW = 0xF, // Cursor address low 8 bits
CGA_CRTC_LIGHT_PEN_ADDR_HIGH = 0x10, // Light pen address high 8 bits (not currently supported)
CGA_CRTC_LIGHT_PEN_ADDR_LOW = 0x11, // Light pen address low 8 bits (not currently supported)
} cga_crtc_registers;
typedef enum cga_registers_e
{
CGA_REGISTER_CRTC_INDEX = 0x3D4,
CGA_REGISTER_CRTC_DATA = 0x3D5,
CGA_REGISTER_MODE_CONTROL = 0x3D8,
CGA_REGISTER_COLOR_SELECT = 0x3D9,
CGA_REGISTER_STATUS = 0x3DA,
CGA_REGISTER_CLEAR_LIGHT_PEN_LATCH = 0x3DB,
CGA_REGISTER_SET_LIGHT_PEN_LATCH = 0x3DC,
} cga_registers;
#define CGA_NUM_CRTC_REGS 32
typedef struct cga_t {
mem_mapping_t mapping;
int crtcreg;
uint8_t crtc[32];
uint8_t crtc[CGA_NUM_CRTC_REGS];
uint8_t cgastat;
@@ -40,7 +89,6 @@ typedef struct cga_t {
int vc;
int cgadispon;
int con;
int coff;
int cursoron;
int cgablink;
int vsynctime;

View File

@@ -47,7 +47,6 @@ typedef struct {
uint16_t ma;
uint16_t maback;
int con;
int coff;
int cursoron;
int dispon;
int blink;

View File

@@ -29,7 +29,6 @@ typedef struct mda_t {
uint16_t ma;
uint16_t maback;
int con;
int coff;
int cursoron;
int dispon;
int blink;

View File

@@ -116,7 +116,6 @@ typedef struct pgc {
int vc;
int cgadispon;
int con;
int coff;
int cursoron;
int cgablink;
int vsynctime;

View File

@@ -117,7 +117,6 @@ typedef struct amsvid_t {
int vc;
int cgadispon;
int con;
int coff;
int cursoron;
int cgablink;
int vsynctime;
@@ -515,7 +514,6 @@ vid_poll_1512(void *priv)
}
if (vid->sc == (vid->crtc[11] & 31)) {
vid->con = 0;
vid->coff = 1;
}
if (vid->vadj) {
vid->sc++;
@@ -1319,7 +1317,6 @@ lcdm_poll(amsvid_t *vid)
}
if (mda->sc == (mda->crtc[11] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[11] & 31) >> 1))) {
mda->con = 0;
mda->coff = 1;
}
if (mda->vadj) {
mda->sc++;
@@ -1483,7 +1480,6 @@ lcdc_poll(amsvid_t *vid)
}
if (cga->sc == (cga->crtc[11] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[11] & 31) >> 1))) {
cga->con = 0;
cga->coff = 1;
}
if ((cga->crtc[8] & 3) == 3 && cga->sc == (cga->crtc[9] >> 1))
cga->maback = cga->ma;

View File

@@ -262,6 +262,19 @@ machine_at_px286_init(const machine_t *model)
return ret;
}
static void
machine_at_ctat_common_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&cs8220_device);
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&keyboard_at_phoenix_device);
}
int
machine_at_dells200_init(const machine_t *model)
{
@@ -274,14 +287,24 @@ machine_at_dells200_init(const machine_t *model)
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
machine_at_ctat_common_init(model);
device_add(&cs8220_device);
return ret;
}
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
int
machine_at_tuliptc7_init(const machine_t *model)
{
int ret;
device_add(&keyboard_at_phoenix_device);
ret = bios_load_interleavedr("roms/machines/tuliptc7/tc7be.bin",
"roms/machines/tuliptc7/tc7bo.bin",
0x000f8000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_ctat_common_init(model);
return ret;
}

View File

@@ -413,7 +413,7 @@ machine_at_vect486vl_init(const machine_t *model) // has HDC problems
return ret;
if (gfxcard[0] == VID_INTERNAL)
device_add(&gd5428_onboard_device);
device_add(machine_get_vid_device(machine));
machine_at_common_init_ex(model, 2);
@@ -439,7 +439,7 @@ machine_at_d824_init(const machine_t *model)
return ret;
if (gfxcard[0] == VID_INTERNAL)
device_add(&gd5428_onboard_device);
device_add(machine_get_vid_device(machine));
machine_at_common_init_ex(model, 2);
@@ -457,6 +457,41 @@ machine_at_d824_init(const machine_t *model)
return ret;
}
int
machine_at_tuliptc38_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/tuliptc38/TULIP1.BIN",
0x000f0000, 262144, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init_ex(model, 2);
device_add(&vl82c486_device);
device_add(&tulip_jumper_device);
device_add(&vl82c113_device);
device_add(&ide_isa_device);
device_add(&fdc37c651_ide_device);
if (gfxcard[0] == VID_INTERNAL) {
bios_load_aux_linear("roms/machines/tuliptc38/VBIOS.BIN",
0x000c0000, 32768, 0);
device_add(machine_get_vid_device(machine));
} else for (uint16_t i = 0; i < 32768; i++)
rom[i] = mem_readb_phys(0x000c0000 + i);
mem_mapping_set_addr(&bios_mapping, 0x0c0000, 0x40000);
mem_mapping_set_exec(&bios_mapping, rom);
return ret;
}
int
machine_at_martin_init(const machine_t *model)
{
@@ -2197,18 +2232,66 @@ machine_at_ecs486_init(const machine_t *model)
return ret;
}
static const device_config_t hot433a_config[] = {
// clang-format off
{
.name = "bios",
.description = "BIOS Version",
.type = CONFIG_BIOS,
.default_string = "hot433a",
.default_int = 0,
.file_filter = "",
.spinner = { 0 },
.bios = {
{ .name = "AMI", .internal_name = "hot433a", .bios_type = BIOS_NORMAL,
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/hot433/433AUS33.ROM", "" } },
{ .name = "Award (eSupport update)", .internal_name = "hot433a_award", .bios_type = BIOS_NORMAL,
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/hot433/2A4X5H21.BIN", "" } },
{ .files_no = 0 }
},
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
const device_t hot433a_device = {
.name = "Shuttle HOT-433A",
.internal_name = "hot433a_device",
.flags = 0,
.local = 0,
.init = NULL,
.close = NULL,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = hot433a_config
};
int
machine_at_hot433a_init(const machine_t *model)
{
int ret;
int ret = 0;
const char* fn;
ret = bios_load_linear("roms/machines/hot433/433AUS33.ROM",
0x000e0000, 131072, 0);
/* No ROMs available */
if (!device_available(model->device))
return ret;
device_context(model->device);
int is_award = !strcmp(device_get_config_bios("bios"), "hot433a_award");
fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0);
ret = bios_load_linear(fn, 0x000e0000, 131072, 0);
device_context_restore();
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
machine_at_common_init_ex(model, 2);
if (is_award)
device_add(&amstrad_megapc_nvr_device);
else
device_add(&ami_1994_nvr_device);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
@@ -2220,9 +2303,46 @@ machine_at_hot433a_init(const machine_t *model)
device_add(&umc_hb4_device);
device_add(&umc_8886bf_device);
device_add(&um8669f_device);
if (is_award)
device_add(&um8663af_device);
else
device_add(&um8669f_device);
device_add(&winbond_flash_w29c010_device);
device_add(&keyboard_at_ami_device);
if (is_award)
device_add(&keyboard_ps2_ami_device);
else
device_add(&keyboard_at_ami_device);
pic_toggle_latch(is_award);
return ret;
}
int
machine_at_84xxuuda_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/84xxuuda/uud0520s.bin",
0x000e0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2);
device_add(&umc_hb4_device);
device_add(&umc_8886bf_device);
device_add(&um8663bf_device);
device_add(&winbond_flash_w29c010_device);
device_add(&keyboard_ps2_ami_device);
return ret;
}

View File

@@ -646,6 +646,7 @@ europc_boot(UNUSED(const device_t *info))
* (JS9) can be used to "move" it to 0x0350, to get it out of
* the way of other cards that need this range.
*/
sys->jim = device_get_config_hex16("js9");
io_sethandler(sys->jim, 16,
jim_read, NULL, NULL, jim_write, NULL, NULL, sys);
@@ -680,14 +681,14 @@ static const device_config_t europc_config[] = {
{
.name = "js9",
.description = "JS9 Jumper (JIM)",
.type = CONFIG_INT,
.type = CONFIG_HEX16,
.default_string = "",
.default_int = 0,
.default_int = 0x0250,
.file_filter = "",
.spinner = { 0 },
.selection = {
{ .description = "Disabled (250h)", .value = 0 },
{ .description = "Enabled (350h)", .value = 1 },
{ .description = "Disabled (250h)", .value = 0x0250 },
{ .description = "Enabled (350h)", .value = 0x0350 },
{ .description = "" }
},
},

View File

@@ -82,7 +82,6 @@ typedef struct pcjr_t {
int vc;
int dispon;
int con;
int coff;
int cursoron;
int blink;
int vsynctime;
@@ -1167,7 +1166,6 @@ vid_poll(void *priv)
}
if (pcjr->sc == (pcjr->crtc[11] & 31) || ((pcjr->crtc[8] & 3) == 3 && pcjr->sc == ((pcjr->crtc[11] & 31) >> 1))) {
pcjr->con = 0;
pcjr->coff = 1;
}
if (pcjr->vadj) {
pcjr->sc++;

View File

@@ -92,7 +92,6 @@ typedef struct t1kvid_t {
int vc;
int dispon;
int con;
int coff;
int cursoron;
int blink;
int fullchange;
@@ -1212,7 +1211,6 @@ vid_poll(void *priv)
}
if (vid->sc == (vid->crtc[11] & 31) || ((vid->crtc[8] & 3) == 3 && vid->sc == ((vid->crtc[11] & 31) >> 1))) {
vid->con = 0;
vid->coff = 1;
}
if (vid->vadj) {
vid->sc++;

View File

@@ -69,6 +69,7 @@ extern const device_t ap5s_device;
extern const device_t d842_device;
extern const device_t d943_device;
extern const device_t dells333sl_device;
extern const device_t hot433a_device;
const machine_filter_t machine_types[] = {
{ "None", MACHINE_TYPE_NONE },
@@ -3415,6 +3416,47 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
/* No proper pictures of the KBC exist, though it seems to have the IBM AT KBC
firmware. */
{
.name = "[C&T PC/AT] Tulip AT Compact",
.internal_name = "tuliptc7",
.type = MACHINE_TYPE_286,
.chipset = MACHINE_CHIPSET_CT_AT,
.init = machine_at_tuliptc7_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_286,
.block = CPU_BLOCK_NONE,
.min_bus = 6000000,
.max_bus = 12000000,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
.max_multi = 0
},
.bus_flags = MACHINE_AT,
.flags = MACHINE_FLAGS_NONE,
.ram = {
.min = 640,
.max = 16384,
.step = 128
},
.nvrmask = 127,
.kbc_device = NULL,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
},
/* Has Quadtel KBC firmware. */
{
.name = "[GC103] Quadtel 286 clone",
@@ -6605,6 +6647,46 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
/* Has a VLSI VL82C113A SCAMP Combination I/O which holds the KBC. */
{
.name = "[VLSI 82C486] Tulip 486 DC/DT",
.internal_name = "tuliptc38",
.type = MACHINE_TYPE_486,
.chipset = MACHINE_CHIPSET_VLSI_VL82C486,
.init = machine_at_tuliptc38_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_SOCKET1,
.block = CPU_BLOCK_NONE,
.min_bus = 0,
.max_bus = 0,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
.max_multi = 0
},
.bus_flags = MACHINE_AT,
.flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM,
.ram = {
.min = 2048,
.max = 32768,
.step = 2048
},
.nvrmask = 127,
.kbc_device = NULL,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.fdc_device = NULL,
.sio_device = NULL, /*Has SIO (sorta): VLSI VL82C113A SCAMP Combination I/O*/
.vid_device = &gd5426_onboard_device,
.snd_device = NULL,
.net_device = NULL
},
/* Has IBM PS/2 Type 1 KBC firmware. */
{
.name = "[MCA] IBM PS/2 model 70 (type 4)",
@@ -9036,6 +9118,47 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
/* This has the UMC 88xx on-chip KBC. All the copies of the BIOS string I can find, end in
in -H, so the UMC on-chip KBC likely emulates the AMI 'H' KBC firmware. */
{
.name = "[UMC 8881] Biostar MB-84xxUUD-A",
.internal_name = "84xxuuda",
.type = MACHINE_TYPE_486_S3_PCI,
.chipset = MACHINE_CHIPSET_UMC_UM8881,
.init = machine_at_84xxuuda_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_SOCKET3,
.block = CPU_BLOCK_NONE,
.min_bus = 0,
.max_bus = 0,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
.max_multi = 0
},
.bus_flags = MACHINE_PS2_PCI,
.flags = MACHINE_IDE_DUAL | MACHINE_APM,
.ram = {
.min = 1024,
.max = 131072,
.step = 1024
},
.nvrmask = 255,
.kbc_device = NULL,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
},
/* This has an AMIKey-2, which is an updated version of type 'H'. */
{
.name = "[UMC 8881] ECS Elite UM8810P-AIO",
@@ -9259,7 +9382,7 @@ const machine_t machines[] = {
.min_multi = 0,
.max_multi = 0
},
.bus_flags = MACHINE_PCI,
.bus_flags = MACHINE_PS2_PCI,
.flags = MACHINE_IDE_DUAL | MACHINE_APM,
.ram = {
.min = 1024,
@@ -9271,7 +9394,7 @@ const machine_t machines[] = {
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.device = &hot433a_device,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,

View File

@@ -638,6 +638,25 @@ pic_reset_hard(void)
}
}
void
pic_toggle_latch(int is_ps2)
{
pic_kbd_latch(0x00);
pic_mouse_latch(0x00);
/* Explicitly reset the latches. */
kbd_latch = mouse_latch = 0;
latched_irqs = 0x0000;
/* The situation is as follows: There is a giant mess when it comes to these latches on real hardware,
to the point that there's even boards with board-level latched that get used in place of the latches
on the chipset, therefore, I'm just doing this here for the sake of simplicity. */
if (is_ps2) {
pic_kbd_latch(0x01);
pic_mouse_latch(0x01);
}
}
void
pic_init(void)
{

View File

@@ -214,7 +214,7 @@ emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
(GetForegroundWindow() == ((HWND) secondaryRenderer->winId())));
}
bool skip = ((nCode < 0) || (nCode != HC_ACTION) || !is_over_window);
bool skip = ((nCode < 0) || (nCode != HC_ACTION) || !is_over_window || (kbd_req_capture && !mouse_capture));
if (skip)
return CallNextHookEx(NULL, nCode, wParam, lParam);

View File

@@ -3693,10 +3693,10 @@ ibm8514_poll(void *priv)
svga->render8514(svga);
svga->x_add = (overscan_x >> 1);
svga->x_add = svga->left_overscan;
ibm8514_render_overscan_left(dev, svga);
ibm8514_render_overscan_right(dev, svga);
svga->x_add = (overscan_x >> 1);
svga->x_add = svga->left_overscan;
if (dev->hwcursor_on) {
if (svga->hwcursor_draw)
@@ -3796,7 +3796,7 @@ ibm8514_poll(void *priv)
dev->dispon = 1;
dev->displine = (dev->interlace && dev->oddeven) ? 1 : 0;
svga->x_add = (overscan_x >> 1);
svga->x_add = svga->left_overscan;
dev->hwcursor_on = 0;
dev->hwcursor_latch = dev->hwcursor;
@@ -3966,7 +3966,7 @@ ibm8514_init(const device_t *info)
bios_addr = 0xc6000;
switch (dev->extensions) {
case 1:
case ATI:
if (rom_present(BIOS_MACH8_ROM_PATH)) {
mach_t * mach = (mach_t *) calloc(1, sizeof(mach_t));
svga->ext8514 = mach;
@@ -3977,13 +3977,14 @@ ibm8514_init(const device_t *info)
0, MEM_MAPPING_EXTERNAL);
ati8514_init(svga, svga->ext8514, svga->dev8514);
mach->accel.scratch0 = ((((bios_addr >> 7) - 0x1000) >> 4));
mach->accel.scratch0 = ((bios_addr >> 7) - 0x1000) >> 4;
bios_rom_eeprom = mach->accel.scratch0;
if (dev->type & DEVICE_MCA) {
dev->pos_regs[0] = 0x88;
dev->pos_regs[1] = 0x80;
mach->eeprom.data[0] = 0x0000;
mach->eeprom.data[1] = bios_rom_eeprom | ((bios_rom_eeprom | 0x01) << 8);
ibm8514_log("EEPROM Data1=%04x.\n", mach->eeprom.data[1]);
mca_add(ati8514_mca_read, ati8514_mca_write, ibm8514_mca_feedb, ibm8514_mca_reset, svga);
ati_eeprom_load_mach8(&mach->eeprom, "ati8514_mca.nvr", 1);
mem_mapping_disable(&dev->bios_rom.mapping);
@@ -4067,12 +4068,12 @@ static const device_config_t isa_ext8514_config[] = {
.description = "Vendor",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 0,
.default_int = IBM,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "IBM", .value = 0 },
{ .description = "ATI", .value = 1 },
{ .description = "IBM", .value = IBM },
{ .description = "ATI", .value = ATI },
{ .description = "" }
},
.bios = { { 0 } }
@@ -4127,12 +4128,12 @@ static const device_config_t mca_ext8514_config[] = {
.description = "Vendor",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 0,
.default_int = IBM,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "IBM", .value = 0 },
{ .description = "ATI", .value = 1 },
{ .description = "IBM", .value = IBM },
{ .description = "ATI", .value = ATI },
{ .description = "" }
},
.bios = { { 0 } }
@@ -4145,7 +4146,7 @@ const device_t gen8514_isa_device = {
.name = "IBM 8514/A clone (ISA)",
.internal_name = "8514_isa",
.flags = DEVICE_ISA16,
.local = 0,
.local = IBM_8514A_TYPE,
.init = ibm8514_init,
.close = ibm8514_close,
.reset = NULL,
@@ -4159,7 +4160,7 @@ const device_t ibm8514_mca_device = {
.name = "IBM 8514/A (MCA)",
.internal_name = "8514_mca",
.flags = DEVICE_MCA,
.local = 0,
.local = IBM_8514A_TYPE,
.init = ibm8514_init,
.close = ibm8514_close,
.reset = NULL,

View File

@@ -7409,7 +7409,7 @@ const device_t mach8_vga_isa_device = {
.name = "ATI Mach8 (ATI Graphics Ultra) (ISA)",
.internal_name = "mach8_vga_isa",
.flags = DEVICE_ISA,
.local = 1,
.local = ATI_38800_TYPE,
.init = mach8_init,
.close = mach_close,
.reset = mach_reset,
@@ -7423,7 +7423,7 @@ const device_t mach32_isa_device = {
.name = "ATI Mach32 (ISA)",
.internal_name = "mach32_isa",
.flags = DEVICE_ISA,
.local = 2,
.local = ATI_68800_TYPE,
.init = mach8_init,
.close = mach_close,
.reset = mach_reset,
@@ -7437,7 +7437,7 @@ const device_t mach32_vlb_device = {
.name = "ATI Mach32 (VLB)",
.internal_name = "mach32_vlb",
.flags = DEVICE_VLB,
.local = 2,
.local = ATI_68800_TYPE,
.init = mach8_init,
.close = mach_close,
.reset = mach_reset,
@@ -7451,7 +7451,7 @@ const device_t mach32_mca_device = {
.name = "ATI Mach32 (MCA)",
.internal_name = "mach32_mca",
.flags = DEVICE_MCA,
.local = 2,
.local = ATI_68800_TYPE,
.init = mach8_init,
.close = mach_close,
.reset = mach_reset,
@@ -7465,7 +7465,7 @@ const device_t mach32_pci_device = {
.name = "ATI Mach32 (PCI)",
.internal_name = "mach32_pci",
.flags = DEVICE_PCI,
.local = 2,
.local = ATI_68800_TYPE,
.init = mach8_init,
.close = mach_close,
.reset = mach_reset,
@@ -7479,7 +7479,7 @@ const device_t mach32_onboard_pci_device = {
.name = "ATI Mach32 (PCI) On-Board",
.internal_name = "mach32_pci_onboard",
.flags = DEVICE_PCI,
.local = 2 | 0x100,
.local = ATI_68800_TYPE | 0x100,
.init = mach8_init,
.close = mach_close,
.reset = mach_reset,

View File

@@ -16,7 +16,7 @@
*
* Copyright 2008-2019 Sarah Walker.
* Copyright 2016-2019 Miran Grca.
* Copyright 2023 W. M. Martinez
* Copyright 2023 W. M. Martine
*/
#include <stdio.h>
#include <stdint.h>
@@ -73,10 +73,10 @@ void cga_recalctimings(cga_t *cga);
static void
cga_update_latch(cga_t *cga)
{
uint32_t lp_latch = cga->displine * cga->crtc[1];
uint32_t lp_latch = cga->displine * cga->crtc[CGA_CRTC_HDISP];
cga->crtc[0x10] = (lp_latch >> 8) & 0x3f;
cga->crtc[0x11] = lp_latch & 0xff;
cga->crtc[CGA_CRTC_LIGHT_PEN_ADDR_LOW] = lp_latch & 0xff;
}
void
@@ -89,20 +89,22 @@ cga_out(uint16_t addr, uint8_t val, void *priv)
addr = (addr & 0xff9) | 0x004;
switch (addr) {
case 0x3D4:
case CGA_REGISTER_CRTC_INDEX:
cga->crtcreg = val & 31;
return;
case 0x3D5:
case CGA_REGISTER_CRTC_DATA:
old = cga->crtc[cga->crtcreg];
cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg];
if (old != val) {
// Recalc the timings if we are writing any invalid CRTC register or a valid CRTC register
// except the CURSOR and LIGHT PEN registers
if ((cga->crtcreg < 0xe) || (cga->crtcreg > 0x11)) {
cga->fullchange = changeframecount;
cga_recalctimings(cga);
}
}
return;
case 0x3D8:
case CGA_REGISTER_MODE_CONTROL:
old = cga->cgamode;
cga->cgamode = val;
@@ -113,18 +115,18 @@ cga_out(uint16_t addr, uint8_t val, void *priv)
cga_recalctimings(cga);
}
return;
case 0x3D9:
case CGA_REGISTER_COLOR_SELECT:
old = cga->cgacol;
cga->cgacol = val;
if (old ^ val)
cga_recalctimings(cga);
return;
case 0x3DB:
case CGA_REGISTER_CLEAR_LIGHT_PEN_LATCH:
if (cga->lp_strobe == 1)
cga->lp_strobe = 0;
return;
case 0x3DC:
case CGA_REGISTER_SET_LIGHT_PEN_LATCH:
if (cga->lp_strobe == 0) {
cga->lp_strobe = 1;
cga_update_latch(cga);
@@ -146,21 +148,20 @@ cga_in(uint16_t addr, void *priv)
addr = (addr & 0xff9) | 0x004;
switch (addr) {
case 0x3D4:
case CGA_REGISTER_CRTC_INDEX:
ret = cga->crtcreg;
break;
case 0x3D5:
case CGA_REGISTER_CRTC_DATA:
ret = cga->crtc[cga->crtcreg];
break;
case 0x3DA:
case CGA_REGISTER_STATUS:
ret = cga->cgastat;
break;
case 0x3DB:
case CGA_REGISTER_CLEAR_LIGHT_PEN_LATCH:
if (cga->lp_strobe == 1)
cga->lp_strobe = 0;
break;
case 0x3DC:
case CGA_REGISTER_SET_LIGHT_PEN_LATCH:
if (cga->lp_strobe == 0) {
cga->lp_strobe = 1;
cga_update_latch(cga);
@@ -235,12 +236,12 @@ cga_recalctimings(cga_t *cga)
double _dispontime;
double _dispofftime;
if (cga->cgamode & 1) {
disptime = (double) (cga->crtc[0] + 1);
_dispontime = (double) cga->crtc[1];
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES) {
disptime = (double) (cga->crtc[CGA_CRTC_HTOTAL] + 1);
_dispontime = (double) cga->crtc[CGA_CRTC_HDISP];
} else {
disptime = (double) ((cga->crtc[0] + 1) << 1);
_dispontime = (double) (cga->crtc[1] << 1);
disptime = (double) ((cga->crtc[CGA_CRTC_HTOTAL] + 1) << 1);
_dispontime = (double) (cga->crtc[CGA_CRTC_HDISP] << 1);
}
_dispofftime = disptime - _dispontime;
_dispontime = _dispontime * CGACONST;
@@ -252,7 +253,7 @@ cga_recalctimings(cga_t *cga)
static void
cga_render(cga_t *cga, int line)
{
uint16_t ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff;
uint16_t ca = (cga->crtc[CGA_CRTC_CURSOR_ADDR_LOW] | (cga->crtc[CGA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x3fff;
int drawcursor;
int x;
int c;
@@ -262,33 +263,35 @@ cga_render(cga_t *cga, int line)
int cols[4];
int col;
if ((cga->cgamode & 0x12) == 0x12) {
int32_t highres_graphics_flag = (CGA_MODE_FLAG_HIGHRES_GRAPHICS | CGA_MODE_FLAG_GRAPHICS);
if (((cga->cgamode & highres_graphics_flag) == highres_graphics_flag)) {
for (c = 0; c < 8; ++c) {
buffer32->line[line][c] = 0;
if (cga->cgamode & 1)
buffer32->line[line][c + (cga->crtc[1] << 3) + 8] = 0;
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES)
buffer32->line[line][c + (cga->crtc[CGA_CRTC_HDISP] << 3) + 8] = 0;
else
buffer32->line[line][c + (cga->crtc[1] << 4) + 8] = 0;
buffer32->line[line][c + (cga->crtc[CGA_CRTC_HDISP] << 4) + 8] = 0;
}
} else {
for (c = 0; c < 8; ++c) {
buffer32->line[line][c] = (cga->cgacol & 15) + 16;
if (cga->cgamode & 1)
buffer32->line[line][c + (cga->crtc[1] << 3) + 8] = (cga->cgacol & 15) + 16;
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES)
buffer32->line[line][c + (cga->crtc[CGA_CRTC_HDISP] << 3) + 8] = (cga->cgacol & 15) + 16;
else
buffer32->line[line][c + (cga->crtc[1] << 4) + 8] = (cga->cgacol & 15) + 16;
buffer32->line[line][c + (cga->crtc[CGA_CRTC_HDISP] << 4) + 8] = (cga->cgacol & 15) + 16;
}
}
if (cga->cgamode & 1) {
for (x = 0; x < cga->crtc[1]; x++) {
if (cga->cgamode & 8) {
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES) {
for (x = 0; x < cga->crtc[CGA_CRTC_HDISP]; x++) {
if (cga->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) {
chr = cga->charbuffer[x << 1];
attr = cga->charbuffer[(x << 1) + 1];
} else
chr = attr = 0;
drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron);
cols[1] = (attr & 15) + 16;
if (cga->cgamode & 0x20) {
if (cga->cgamode & CGA_MODE_FLAG_BLINK) {
cols[0] = ((attr >> 4) & 7) + 16;
if ((cga->cgablink & 8) && (attr & 0x80) && !cga->drawcursor)
cols[1] = cols[0];
@@ -308,15 +311,15 @@ cga_render(cga_t *cga, int line)
cga->ma++;
}
} else if (!(cga->cgamode & 2)) {
for (x = 0; x < cga->crtc[1]; x++) {
if (cga->cgamode & 8) {
for (x = 0; x < cga->crtc[CGA_CRTC_HDISP]; x++) {
if (cga->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) {
chr = cga->vram[(cga->ma << 1) & 0x3fff];
attr = cga->vram[((cga->ma << 1) + 1) & 0x3fff];
} else
chr = attr = 0;
drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron);
cols[1] = (attr & 15) + 16;
if (cga->cgamode & 0x20) {
if (cga->cgamode & CGA_MODE_FLAG_BLINK) {
cols[0] = ((attr >> 4) & 7) + 16;
if ((cga->cgablink & 8) && (attr & 0x80))
cols[1] = cols[0];
@@ -337,10 +340,10 @@ cga_render(cga_t *cga, int line)
}
}
}
} else if (!(cga->cgamode & 16)) {
} else if (!(cga->cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)) {
cols[0] = (cga->cgacol & 15) | 16;
col = (cga->cgacol & 16) ? 24 : 16;
if (cga->cgamode & 4) {
if (cga->cgamode & CGA_MODE_FLAG_BW) {
cols[1] = col | 3; /* Cyan */
cols[2] = col | 4; /* Red */
cols[3] = col | 7; /* White */
@@ -353,8 +356,8 @@ cga_render(cga_t *cga, int line)
cols[2] = col | 4; /* Red */
cols[3] = col | 6; /* Yellow */
}
for (x = 0; x < cga->crtc[1]; x++) {
if (cga->cgamode & 8)
for (x = 0; x < cga->crtc[CGA_CRTC_HDISP]; x++) {
if (cga->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE)
dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) |
cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1];
else
@@ -370,8 +373,8 @@ cga_render(cga_t *cga, int line)
} else {
cols[0] = 0;
cols[1] = (cga->cgacol & 15) + 16;
for (x = 0; x < cga->crtc[1]; x++) {
if (cga->cgamode & 8)
for (x = 0; x < cga->crtc[CGA_CRTC_HDISP]; x++) {
if (cga->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE)
dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) |
cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1];
else
@@ -388,12 +391,14 @@ cga_render(cga_t *cga, int line)
static void
cga_render_blank(cga_t *cga, int line)
{
int col = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15) + 16;
int32_t highres_graphics_flag = (CGA_MODE_FLAG_HIGHRES_GRAPHICS | CGA_MODE_FLAG_GRAPHICS);
if (cga->cgamode & 1)
hline(buffer32, 0, line, (cga->crtc[1] << 3) + 16, col);
int col = ((cga->cgamode & highres_graphics_flag) == highres_graphics_flag) ? 0 : (cga->cgacol & 15) + 16;
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES)
hline(buffer32, 0, line, (cga->crtc[CGA_CRTC_HDISP] << 3) + 16, col);
else
hline(buffer32, 0, line, (cga->crtc[1] << 4) + 16, col);
hline(buffer32, 0, line, (cga->crtc[CGA_CRTC_HDISP] << 4) + 16, col);
}
static void
@@ -401,14 +406,15 @@ cga_render_process(cga_t *cga, int line)
{
int x;
uint8_t border;
int32_t highres_graphics_flag = (CGA_MODE_FLAG_HIGHRES_GRAPHICS | CGA_MODE_FLAG_GRAPHICS);
if (cga->cgamode & 1)
x = (cga->crtc[1] << 3) + 16;
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES)
x = (cga->crtc[CGA_CRTC_HDISP] << 3) + 16;
else
x = (cga->crtc[1] << 4) + 16;
x = (cga->crtc[CGA_CRTC_HDISP] << 4) + 16;
if (cga->composite) {
border = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15);
border = ((cga->cgamode & highres_graphics_flag) == highres_graphics_flag) ? 0 : (cga->cgacol & 15);
Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[line]);
} else
@@ -524,7 +530,7 @@ cga_poll(void *priv)
cga->cgastat |= 1;
cga->linepos = 1;
oldsc = cga->sc;
if ((cga->crtc[8] & 3) == 3)
if ((cga->crtc[CGA_CRTC_INTERLACE] & 3) == 3)
cga->sc = ((cga->sc << 1) + cga->oddeven) & 7;
if (cga->cgadispon) {
if (cga->displine < cga->firstline) {
@@ -573,7 +579,7 @@ cga_poll(void *priv)
}
cga->sc = oldsc;
if (cga->vc == cga->crtc[7] && !cga->sc)
if (cga->vc == cga->crtc[CGA_CRTC_VSYNC] && !cga->sc)
cga->cgastat |= 8;
cga->displine++;
if (cga->displine >= 360)
@@ -586,12 +592,11 @@ cga_poll(void *priv)
if (!cga->vsynctime)
cga->cgastat &= ~8;
}
if (cga->sc == (cga->crtc[11] & 31) || ((cga->crtc[8] & 3) == 3 &&
cga->sc == ((cga->crtc[11] & 31) >> 1))) {
if (cga->sc == (cga->crtc[CGA_CRTC_CURSOR_END] & 31) || ((cga->crtc[CGA_CRTC_INTERLACE] & 3) == 3 &&
cga->sc == ((cga->crtc[CGA_CRTC_CURSOR_END] & 31) >> 1))) {
cga->con = 0;
cga->coff = 1;
}
if ((cga->crtc[8] & 3) == 3 && cga->sc == (cga->crtc[9] >> 1))
if ((cga->crtc[CGA_CRTC_INTERLACE] & 3) == 3 && cga->sc == (cga->crtc[CGA_CRTC_MAX_SCANLINE_ADDR] >> 1))
cga->maback = cga->ma;
if (cga->vadj) {
cga->sc++;
@@ -600,27 +605,27 @@ cga_poll(void *priv)
cga->vadj--;
if (!cga->vadj) {
cga->cgadispon = 1;
cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff;
cga->ma = cga->maback = (cga->crtc[CGA_CRTC_START_ADDR_LOW] | (cga->crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff;
cga->sc = 0;
}
} else if (cga->sc == cga->crtc[9]) {
} else if (cga->sc == cga->crtc[CGA_CRTC_MAX_SCANLINE_ADDR]) {
cga->maback = cga->ma;
cga->sc = 0;
oldvc = cga->vc;
cga->vc++;
cga->vc &= 127;
if (cga->vc == cga->crtc[6])
if (cga->vc == cga->crtc[CGA_CRTC_VDISP])
cga->cgadispon = 0;
if (oldvc == cga->crtc[4]) {
if (oldvc == cga->crtc[CGA_CRTC_VTOTAL]) {
cga->vc = 0;
cga->vadj = cga->crtc[5];
cga->vadj = cga->crtc[CGA_CRTC_VTOTAL_ADJUST];
if (!cga->vadj) {
cga->cgadispon = 1;
cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff;
cga->ma = cga->maback = (cga->crtc[CGA_CRTC_START_ADDR_LOW] | (cga->crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff;
}
switch (cga->crtc[10] & 0x60) {
switch (cga->crtc[CGA_CRTC_CURSOR_START] & 0x60) {
case 0x20:
cga->cursoron = 0;
break;
@@ -633,15 +638,15 @@ cga_poll(void *priv)
}
}
if (cga->vc == cga->crtc[7]) {
if (cga->vc == cga->crtc[CGA_CRTC_VSYNC]) {
cga->cgadispon = 0;
cga->displine = 0;
cga->vsynctime = 16;
if (cga->crtc[7]) {
if (cga->cgamode & 1)
x = (cga->crtc[1] << 3) + 16;
if (cga->crtc[CGA_CRTC_VSYNC]) {
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES)
x = (cga->crtc[CGA_CRTC_HDISP] << 3) + 16;
else
x = (cga->crtc[1] << 4) + 16;
x = (cga->crtc[CGA_CRTC_HDISP] << 4) + 16;
cga->lastline++;
xs_temp = x;
@@ -657,7 +662,7 @@ cga_poll(void *priv)
if (!enable_overscan)
xs_temp -= 16;
if ((cga->cgamode & 8) && ((xs_temp != xsize) ||
if ((cga->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) && ((xs_temp != xsize) ||
(ys_temp != ysize) || video_force_resize_get())) {
xsize = xs_temp;
ysize = ys_temp;
@@ -691,15 +696,15 @@ cga_poll(void *priv)
video_res_x = xsize;
video_res_y = ysize;
if (cga->cgamode & 1) {
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES) {
video_res_x /= 8;
video_res_y /= cga->crtc[9] + 1;
video_res_y /= cga->crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1;
video_bpp = 0;
} else if (!(cga->cgamode & 2)) {
} else if (!(cga->cgamode & CGA_MODE_FLAG_GRAPHICS)) {
video_res_x /= 16;
video_res_y /= cga->crtc[9] + 1;
video_res_y /= cga->crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1;
video_bpp = 0;
} else if (!(cga->cgamode & 16)) {
} else if (!(cga->cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)) {
video_res_x /= 2;
video_bpp = 2;
} else
@@ -717,11 +722,11 @@ cga_poll(void *priv)
}
if (cga->cgadispon)
cga->cgastat &= ~1;
if (cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 &&
cga->sc == ((cga->crtc[10] & 31) >> 1)))
if (cga->sc == (cga->crtc[CGA_CRTC_CURSOR_START] & 31) || ((cga->crtc[CGA_CRTC_INTERLACE] & 3) == 3 &&
cga->sc == ((cga->crtc[CGA_CRTC_CURSOR_START] & 31) >> 1)))
cga->con = 1;
if (cga->cgadispon && (cga->cgamode & 1)) {
for (x = 0; x < (cga->crtc[1] << 1); x++)
if (cga->cgadispon && (cga->cgamode & CGA_MODE_FLAG_HIGHRES)) {
for (x = 0; x < (cga->crtc[CGA_CRTC_HDISP] << 1); x++)
cga->charbuffer[x] = cga->vram[((cga->ma << 1) + x) & 0x3fff];
}
}

View File

@@ -42,9 +42,6 @@
#define COLORPLUS_320x200_MODE 0x10 /* 320x200x16 mode active */
#define COLORPLUS_EITHER_MODE 0x30 /* Either mode active */
/* Bits in the CGA graphics mode register */
#define CGA_GRAPHICS_MODE 0x02 /* CGA graphics mode selected? */
#define CGA_RGB 0
#define CGA_COMPOSITE 1
@@ -80,7 +77,7 @@ colorplus_write(uint32_t addr, uint8_t val, void *priv)
{
colorplus_t *colorplus = (colorplus_t *) priv;
if ((colorplus->control & COLORPLUS_PLANE_SWAP) && (colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_GRAPHICS_MODE)) {
if ((colorplus->control & COLORPLUS_PLANE_SWAP) && (colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_MODE_FLAG_GRAPHICS)) {
addr ^= 0x4000;
} else if (!(colorplus->control & COLORPLUS_EITHER_MODE)) {
addr &= 0x3FFF;
@@ -99,7 +96,7 @@ colorplus_read(uint32_t addr, void *priv)
{
colorplus_t *colorplus = (colorplus_t *) priv;
if ((colorplus->control & COLORPLUS_PLANE_SWAP) && (colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_GRAPHICS_MODE)) {
if ((colorplus->control & COLORPLUS_PLANE_SWAP) && (colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_MODE_FLAG_GRAPHICS)) {
addr ^= 0x4000;
} else if (!(colorplus->control & COLORPLUS_EITHER_MODE)) {
addr &= 0x3FFF;
@@ -140,7 +137,7 @@ colorplus_poll(void *priv)
/* If one of the extra modes is not selected, drop down to the CGA
* drawing code. */
if (!((colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_GRAPHICS_MODE))) {
if (!((colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_MODE_FLAG_GRAPHICS))) {
cga_poll(&colorplus->cga);
return;
}
@@ -229,7 +226,6 @@ colorplus_poll(void *priv)
}
if (colorplus->cga.sc == (colorplus->cga.crtc[11] & 31) || ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == ((colorplus->cga.crtc[11] & 31) >> 1))) {
colorplus->cga.con = 0;
colorplus->cga.coff = 1;
}
if ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == (colorplus->cga.crtc[9] >> 1))
colorplus->cga.maback = colorplus->cga.ma;

View File

@@ -44,10 +44,6 @@
static uint32_t vflags;
static uint8_t mdaattr[256][2][2];
typedef struct compaq_cga_t {
cga_t cga;
} compaq_cga_t;
#ifdef ENABLE_COMPAQ_CGA_LOG
int compaq_cga_do_log = ENABLE_COMPAQ_CGA_LOG;
@@ -66,93 +62,93 @@ compaq_cga_log(const char *fmt, ...)
# define compaq_cga_log(fmt, ...)
#endif
void
compaq_cga_recalctimings(compaq_cga_t *self)
static void
compaq_cga_recalctimings(cga_t *dev)
{
double _dispontime;
double _dispofftime;
double disptime;
disptime = self->cga.crtc[0] + 1;
disptime = dev->crtc[0] + 1;
_dispontime = self->cga.crtc[1];
_dispontime = dev->crtc[1];
_dispofftime = disptime - _dispontime;
_dispontime *= MDACONST;
_dispofftime *= MDACONST;
self->cga.dispontime = (uint64_t) (_dispontime);
self->cga.dispofftime = (uint64_t) (_dispofftime);
dev->dispontime = (uint64_t) (_dispontime);
dev->dispofftime = (uint64_t) (_dispofftime);
}
void
static void
compaq_cga_poll(void *priv)
{
compaq_cga_t *self = (compaq_cga_t *) priv;
uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x3fff;
int drawcursor;
int x;
int c;
int xs_temp;
int ys_temp;
int oldvc;
uint8_t chr;
uint8_t attr;
uint8_t border;
uint8_t cols[4];
int oldsc;
int underline = 0;
int blink = 0;
cga_t *dev = (cga_t *) priv;
uint16_t ca = (dev->crtc[15] | (dev->crtc[14] << 8)) & 0x3fff;
int underline = 0;
int blink = 0;
int drawcursor;
int x;
int c;
int xs_temp;
int ys_temp;
int oldvc;
uint8_t chr;
uint8_t attr;
uint8_t border;
uint8_t cols[4];
int oldsc;
/* If in graphics mode or character height is not 13, behave as CGA */
if ((self->cga.cgamode & 0x12) || (self->cga.crtc[9] != 13)) {
if ((dev->cgamode & 0x12) || (dev->crtc[9] != 13)) {
overscan_x = overscan_y = 16;
cga_poll(&self->cga);
cga_poll(dev);
return;
} else
overscan_x = overscan_y = 0;
/* We are in Compaq 350-line CGA territory */
if (!self->cga.linepos) {
timer_advance_u64(&self->cga.timer, self->cga.dispofftime);
self->cga.cgastat |= 1;
self->cga.linepos = 1;
oldsc = self->cga.sc;
if ((self->cga.crtc[8] & 3) == 3)
self->cga.sc = ((self->cga.sc << 1) + self->cga.oddeven) & 7;
if (self->cga.cgadispon) {
if (self->cga.displine < self->cga.firstline) {
self->cga.firstline = self->cga.displine;
if (!dev->linepos) {
timer_advance_u64(&dev->timer, dev->dispofftime);
dev->cgastat |= 1;
dev->linepos = 1;
oldsc = dev->sc;
if ((dev->crtc[8] & 3) == 3)
dev->sc = ((dev->sc << 1) + dev->oddeven) & 7;
if (dev->cgadispon) {
if (dev->displine < dev->firstline) {
dev->firstline = dev->displine;
video_wait_for_buffer();
compaq_cga_log("Firstline %i\n", self->cga.firstline);
compaq_cga_log("Firstline %i\n", dev->firstline);
}
self->cga.lastline = self->cga.displine;
dev->lastline = dev->displine;
cols[0] = (self->cga.cgacol & 15) + 16;
cols[0] = (dev->cgacol & 15) + 16;
for (c = 0; c < 8; c++) {
buffer32->line[self->cga.displine][c] = cols[0];
if (self->cga.cgamode & 1)
buffer32->line[self->cga.displine][c + (self->cga.crtc[1] << 3) + 8] = cols[0];
buffer32->line[dev->displine][c] = cols[0];
if (dev->cgamode & 1)
buffer32->line[dev->displine][c + (dev->crtc[1] << 3) + 8] = cols[0];
else
buffer32->line[self->cga.displine][c + (self->cga.crtc[1] << 4) + 8] = cols[0];
buffer32->line[dev->displine][c + (dev->crtc[1] << 4) + 8] = cols[0];
}
if (self->cga.cgamode & 1) {
for (x = 0; x < self->cga.crtc[1]; x++) {
chr = self->cga.charbuffer[x << 1];
attr = self->cga.charbuffer[(x << 1) + 1];
drawcursor = ((self->cga.ma == ca) && self->cga.con && self->cga.cursoron);
if (dev->cgamode & 1) {
for (x = 0; x < dev->crtc[1]; x++) {
chr = dev->charbuffer[x << 1];
attr = dev->charbuffer[(x << 1) + 1];
drawcursor = ((dev->ma == ca) && dev->con && dev->cursoron);
if (vflags) {
underline = 0;
blink = ((self->cga.cgablink & 8) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor);
blink = ((dev->cgablink & 8) && (dev->cgamode & 0x20) && (attr & 0x80) && !drawcursor);
}
if (vflags && (self->cga.cgamode & 0x80)) {
if (vflags && (dev->cgamode & 0x80)) {
cols[0] = mdaattr[attr][blink][0];
cols[1] = mdaattr[attr][blink][1];
if ((self->cga.sc == 12) && ((attr & 7) == 1))
if ((dev->sc == 12) && ((attr & 7) == 1))
underline = 1;
} else if (self->cga.cgamode & 0x20) {
} else if (dev->cgamode & 0x20) {
cols[1] = (attr & 15) + 16;
cols[0] = ((attr >> 4) & 7) + 16;
@@ -160,7 +156,7 @@ compaq_cga_poll(void *priv)
if (blink)
cols[1] = cols[0];
} else {
if ((self->cga.cgablink & 8) && (attr & 0x80) && !self->cga.drawcursor)
if ((dev->cgablink & 8) && (attr & 0x80) && !dev->drawcursor)
cols[1] = cols[0];
}
} else {
@@ -170,33 +166,35 @@ compaq_cga_poll(void *priv)
if (vflags && underline) {
for (c = 0; c < 8; c++)
buffer32->line[self->cga.displine][(x << 3) + c + 8] = mdaattr[attr][blink][1];
buffer32->line[dev->displine][(x << 3) + c + 8] = mdaattr[attr][blink][1];
} else if (drawcursor) {
for (c = 0; c < 8; c++)
buffer32->line[self->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
buffer32->line[dev->displine][(x << 3) + c + 8] =
cols[(fontdatm[chr + dev->fontbase][dev->sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
} else {
for (c = 0; c < 8; c++)
buffer32->line[self->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0];
buffer32->line[dev->displine][(x << 3) + c + 8] =
cols[(fontdatm[chr + dev->fontbase][dev->sc & 15] & (1 << (c ^ 7))) ? 1 : 0];
}
self->cga.ma++;
dev->ma++;
}
} else {
for (x = 0; x < self->cga.crtc[1]; x++) {
chr = self->cga.vram[(self->cga.ma << 1) & 0x3fff];
attr = self->cga.vram[((self->cga.ma << 1) + 1) & 0x3fff];
drawcursor = ((self->cga.ma == ca) && self->cga.con && self->cga.cursoron);
for (x = 0; x < dev->crtc[1]; x++) {
chr = dev->vram[(dev->ma << 1) & 0x3fff];
attr = dev->vram[((dev->ma << 1) + 1) & 0x3fff];
drawcursor = ((dev->ma == ca) && dev->con && dev->cursoron);
if (vflags) {
underline = 0;
blink = ((self->cga.cgablink & 8) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor);
blink = ((dev->cgablink & 8) && (dev->cgamode & 0x20) && (attr & 0x80) && !drawcursor);
}
if (vflags && (self->cga.cgamode & 0x80)) {
if (vflags && (dev->cgamode & 0x80)) {
cols[0] = mdaattr[attr][blink][0];
cols[1] = mdaattr[attr][blink][1];
if (self->cga.sc == 12 && (attr & 7) == 1)
if (dev->sc == 12 && (attr & 7) == 1)
underline = 1;
} else if (self->cga.cgamode & 0x20) {
} else if (dev->cgamode & 0x20) {
cols[1] = (attr & 15) + 16;
cols[0] = ((attr >> 4) & 7) + 16;
@@ -204,129 +202,134 @@ compaq_cga_poll(void *priv)
if (blink)
cols[1] = cols[0];
} else {
if ((self->cga.cgablink & 8) && (attr & 0x80) && !self->cga.drawcursor)
if ((dev->cgablink & 8) && (attr & 0x80) && !dev->drawcursor)
cols[1] = cols[0];
}
} else {
cols[1] = (attr & 15) + 16;
cols[0] = (attr >> 4) + 16;
}
self->cga.ma++;
dev->ma++;
if (vflags && underline) {
for (c = 0; c < 8; c++)
buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 9] = mdaattr[attr][blink][1];
buffer32->line[dev->displine][(x << 4) + (c << 1) + 8] =
buffer32->line[dev->displine][(x << 4) + (c << 1) + 9] = mdaattr[attr][blink][1];
} else if (drawcursor) {
for (c = 0; c < 8; c++)
buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
buffer32->line[dev->displine][(x << 4) + (c << 1) + 8] =
buffer32->line[dev->displine][(x << 4) + (c << 1) + 1 + 8] =
cols[(fontdatm[chr + dev->fontbase][dev->sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
} else {
for (c = 0; c < 8; c++)
buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0];
buffer32->line[dev->displine][(x << 4) + (c << 1) + 8] =
buffer32->line[dev->displine][(x << 4) + (c << 1) + 1 + 8] =
cols[(fontdatm[chr + dev->fontbase][dev->sc & 15] & (1 << (c ^ 7))) ? 1 : 0];
}
}
}
} else {
cols[0] = (self->cga.cgacol & 15) + 16;
cols[0] = (dev->cgacol & 15) + 16;
if (self->cga.cgamode & 1)
hline(buffer32, 0, self->cga.displine, (self->cga.crtc[1] << 3) + 16, cols[0]);
if (dev->cgamode & 1)
hline(buffer32, 0, dev->displine, (dev->crtc[1] << 3) + 16, cols[0]);
else
hline(buffer32, 0, self->cga.displine, (self->cga.crtc[1] << 4) + 16, cols[0]);
hline(buffer32, 0, dev->displine, (dev->crtc[1] << 4) + 16, cols[0]);
}
if (self->cga.cgamode & 1)
x = (self->cga.crtc[1] << 3) + 16;
if (dev->cgamode & 1)
x = (dev->crtc[1] << 3) + 16;
else
x = (self->cga.crtc[1] << 4) + 16;
x = (dev->crtc[1] << 4) + 16;
if (self->cga.composite) {
if (self->cga.cgamode & 0x10)
if (dev->composite) {
if (dev->cgamode & 0x10)
border = 0x00;
else
border = self->cga.cgacol & 0x0f;
border = dev->cgacol & 0x0f;
if (vflags)
Composite_Process(self->cga.cgamode & 0x7f, border, x >> 2, buffer32->line[self->cga.displine]);
Composite_Process(dev->cgamode & 0x7f, border, x >> 2, buffer32->line[dev->displine]);
else
Composite_Process(self->cga.cgamode, border, x >> 2, buffer32->line[self->cga.displine]);
Composite_Process(dev->cgamode, border, x >> 2, buffer32->line[dev->displine]);
} else
video_process_8(x, self->cga.displine);
video_process_8(x, dev->displine);
self->cga.sc = oldsc;
if (self->cga.vc == self->cga.crtc[7] && !self->cga.sc)
self->cga.cgastat |= 8;
self->cga.displine++;
if (self->cga.displine >= 500)
self->cga.displine = 0;
dev->sc = oldsc;
if (dev->vc == dev->crtc[7] && !dev->sc)
dev->cgastat |= 8;
dev->displine++;
if (dev->displine >= 500)
dev->displine = 0;
} else {
timer_advance_u64(&self->cga.timer, self->cga.dispontime);
self->cga.linepos = 0;
if (self->cga.vsynctime) {
self->cga.vsynctime--;
if (!self->cga.vsynctime)
self->cga.cgastat &= ~8;
timer_advance_u64(&dev->timer, dev->dispontime);
dev->linepos = 0;
if (dev->vsynctime) {
dev->vsynctime--;
if (!dev->vsynctime)
dev->cgastat &= ~8;
}
if (self->cga.sc == (self->cga.crtc[11] & 31) || ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == ((self->cga.crtc[11] & 31) >> 1))) {
self->cga.con = 0;
self->cga.coff = 1;
if (dev->sc == (dev->crtc[11] & 31) || (((dev->crtc[8] & 3) == 3) &&
(dev->sc == ((dev->crtc[11] & 31) >> 1)))) {
dev->con = 0;
}
if ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == (self->cga.crtc[9] >> 1))
self->cga.maback = self->cga.ma;
if (self->cga.vadj) {
self->cga.sc++;
self->cga.sc &= 31;
self->cga.ma = self->cga.maback;
self->cga.vadj--;
if (!self->cga.vadj) {
self->cga.cgadispon = 1;
self->cga.ma = self->cga.maback = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x3fff;
self->cga.sc = 0;
if ((dev->crtc[8] & 3) == 3 && dev->sc == (dev->crtc[9] >> 1))
dev->maback = dev->ma;
if (dev->vadj) {
dev->sc++;
dev->sc &= 31;
dev->ma = dev->maback;
dev->vadj--;
if (!dev->vadj) {
dev->cgadispon = 1;
dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff;
dev->sc = 0;
}
} else if (self->cga.sc == self->cga.crtc[9]) {
self->cga.maback = self->cga.ma;
self->cga.sc = 0;
oldvc = self->cga.vc;
self->cga.vc++;
self->cga.vc &= 127;
} else if (dev->sc == dev->crtc[9]) {
dev->maback = dev->ma;
dev->sc = 0;
oldvc = dev->vc;
dev->vc++;
dev->vc &= 127;
if (self->cga.vc == self->cga.crtc[6])
self->cga.cgadispon = 0;
if (dev->vc == dev->crtc[6])
dev->cgadispon = 0;
if (oldvc == self->cga.crtc[4]) {
self->cga.vc = 0;
self->cga.vadj = self->cga.crtc[5];
if (oldvc == dev->crtc[4]) {
dev->vc = 0;
dev->vadj = dev->crtc[5];
if (!self->cga.vadj)
self->cga.cgadispon = 1;
if (!dev->vadj)
dev->cgadispon = 1;
if (!self->cga.vadj)
self->cga.ma = self->cga.maback = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x3fff;
if (!dev->vadj)
dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff;
if ((self->cga.crtc[10] & 0x60) == 0x20)
self->cga.cursoron = 0;
if ((dev->crtc[10] & 0x60) == 0x20)
dev->cursoron = 0;
else
self->cga.cursoron = self->cga.cgablink & 8;
dev->cursoron = dev->cgablink & 8;
}
if (self->cga.vc == self->cga.crtc[7]) {
self->cga.cgadispon = 0;
self->cga.displine = 0;
self->cga.vsynctime = 16;
if (dev->vc == dev->crtc[7]) {
dev->cgadispon = 0;
dev->displine = 0;
dev->vsynctime = 16;
if (self->cga.crtc[7]) {
compaq_cga_log("Lastline %i Firstline %i %i\n", self->cga.lastline,
self->cga.firstline, self->cga.lastline - self->cga.firstline);
if (dev->crtc[7]) {
compaq_cga_log("Lastline %i Firstline %i %i\n", dev->lastline,
dev->firstline, dev->lastline - dev->firstline);
if (self->cga.cgamode & 1)
x = (self->cga.crtc[1] << 3) + 16;
if (dev->cgamode & 1)
x = (dev->crtc[1] << 3) + 16;
else
x = (self->cga.crtc[1] << 4) + 16;
x = (dev->crtc[1] << 4) + 16;
self->cga.lastline++;
dev->lastline++;
xs_temp = x;
ys_temp = (self->cga.lastline - self->cga.firstline);
ys_temp = (dev->lastline - dev->firstline);
if ((xs_temp > 0) && (ys_temp > 0)) {
if (xs_temp < 64)
@@ -336,7 +339,8 @@ compaq_cga_poll(void *priv)
if (!enable_overscan)
xs_temp -= 16;
if ((self->cga.cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) {
if ((dev->cgamode & 8) && ((xs_temp != xsize) ||
(ys_temp != ysize) || video_force_resize_get())) {
xsize = xs_temp;
ysize = ys_temp;
set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0));
@@ -346,9 +350,9 @@ compaq_cga_poll(void *priv)
}
if (enable_overscan)
video_blit_memtoscreen(0, self->cga.firstline - 8, xsize, (self->cga.lastline - self->cga.firstline) + 16);
video_blit_memtoscreen(0, dev->firstline - 8, xsize, (dev->lastline - dev->firstline) + 16);
else
video_blit_memtoscreen(8, self->cga.firstline, xsize, self->cga.lastline - self->cga.firstline);
video_blit_memtoscreen(8, dev->firstline, xsize, dev->lastline - dev->firstline);
}
frames++;
@@ -357,63 +361,69 @@ compaq_cga_poll(void *priv)
if (enable_overscan)
xsize -= 16;
video_res_y = ysize;
if (self->cga.cgamode & 1) {
if (dev->cgamode & 1) {
video_res_x /= 8;
video_res_y /= self->cga.crtc[9] + 1;
video_res_y /= dev->crtc[9] + 1;
video_bpp = 0;
} else if (!(self->cga.cgamode & 2)) {
} else if (!(dev->cgamode & 2)) {
video_res_x /= 16;
video_res_y /= self->cga.crtc[9] + 1;
video_res_y /= dev->crtc[9] + 1;
video_bpp = 0;
} else if (!(self->cga.cgamode & 16)) {
} else if (!(dev->cgamode & 16)) {
video_res_x /= 2;
video_bpp = 2;
} else
video_bpp = 1;
}
self->cga.firstline = 1000;
self->cga.lastline = 0;
self->cga.cgablink++;
self->cga.oddeven ^= 1;
dev->firstline = 1000;
dev->lastline = 0;
dev->cgablink++;
dev->oddeven ^= 1;
}
} else {
self->cga.sc++;
self->cga.sc &= 31;
self->cga.ma = self->cga.maback;
dev->sc++;
dev->sc &= 31;
dev->ma = dev->maback;
}
if (self->cga.cgadispon)
self->cga.cgastat &= ~1;
if (dev->cgadispon)
dev->cgastat &= ~1;
if (self->cga.sc == (self->cga.crtc[10] & 31) || ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == ((self->cga.crtc[10] & 31) >> 1)))
self->cga.con = 1;
if (dev->sc == (dev->crtc[10] & 31) ||
(((dev->crtc[8] & 3) == 3) && (dev->sc == ((dev->crtc[10] & 31) >> 1))))
dev->con = 1;
if (self->cga.cgadispon && (self->cga.cgamode & 1)) {
for (x = 0; x < (self->cga.crtc[1] << 1); x++)
self->cga.charbuffer[x] = self->cga.vram[((self->cga.ma << 1) + x) & 0x3fff];
if (dev->cgadispon && (dev->cgamode & 1)) {
for (x = 0; x < (dev->crtc[1] << 1); x++)
dev->charbuffer[x] = dev->vram[((dev->ma << 1) + x) & 0x3fff];
}
}
}
void *
static void *
compaq_cga_init(const device_t *info)
{
int display_type;
compaq_cga_t *self = malloc(sizeof(compaq_cga_t));
memset(self, 0, sizeof(compaq_cga_t));
int display_type;
cga_t *dev = calloc(1, sizeof(cga_t));
display_type = device_get_config_int("display_type");
self->cga.composite = (display_type != CGA_RGB);
self->cga.revision = device_get_config_int("composite_type");
self->cga.snow_enabled = device_get_config_int("snow_enabled");
display_type = device_get_config_int("display_type");
dev->composite = (display_type != CGA_RGB);
dev->revision = device_get_config_int("composite_type");
dev->snow_enabled = device_get_config_int("snow_enabled");
self->cga.vram = malloc(0x4000);
dev->vram = malloc(0x4000);
cga_comp_init(self->cga.revision);
timer_add(&self->cga.timer, compaq_cga_poll, self, 1);
mem_mapping_add(&self->cga.mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL /*self->cga.vram*/, MEM_MAPPING_EXTERNAL, self);
io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, self);
cga_comp_init(dev->revision);
timer_add(&dev->timer, compaq_cga_poll, dev, 1);
mem_mapping_add(&dev->mapping, 0xb8000, 0x08000,
cga_read, NULL, NULL,
cga_write, NULL, NULL,
NULL, MEM_MAPPING_EXTERNAL, dev);
io_sethandler(0x03d0, 0x0010,
cga_in, NULL, NULL,
cga_out, NULL, NULL,
dev);
if (info->local) {
for (uint16_t c = 0; c < 256; c++) {
@@ -442,33 +452,34 @@ compaq_cga_init(const device_t *info)
overscan_x = overscan_y = 16;
self->cga.rgb_type = device_get_config_int("rgb_type");
cga_palette = (self->cga.rgb_type << 1);
dev->rgb_type = device_get_config_int("rgb_type");
cga_palette = (dev->rgb_type << 1);
cgapal_rebuild();
self->cga.crtc[9] = 13;
dev->crtc[9] = 13;
return self;
return dev;
}
void
static void
compaq_cga_close(void *priv)
{
compaq_cga_t *self = (compaq_cga_t *) priv;
cga_t *dev = (cga_t *) priv;
free(self->cga.vram);
free(self);
free(dev->vram);
free(dev);
}
void
static void
compaq_cga_speed_changed(void *priv)
{
compaq_cga_t *self = (compaq_cga_t *) priv;
cga_t *dev = (cga_t *) priv;
if (self->cga.crtc[9] == 13) /* Character height */
compaq_cga_recalctimings(self);
if (dev->crtc[9] == 13)
/* Character height */
compaq_cga_recalctimings(dev);
else
cga_recalctimings(&self->cga);
cga_recalctimings(dev);
}
extern const device_config_t cga_config[];

View File

@@ -399,7 +399,6 @@ hercules_poll(void *priv)
if (dev->sc == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[11] & 31) >> 1))) {
dev->con = 0;
dev->coff = 1;
}
if (dev->vadj) {

View File

@@ -77,7 +77,7 @@ typedef struct {
int linepos, displine;
int vc, sc;
uint16_t ma, maback;
int con, coff, cursoron;
int con, cursoron;
int dispon, blink;
int vsynctime;
int vadj;
@@ -536,7 +536,6 @@ herculesplus_poll(void *priv)
if (dev->sc == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[11] & 31) >> 1))) {
dev->con = 0;
dev->coff = 1;
}
if (dev->vadj) {
dev->sc++;

View File

@@ -167,7 +167,7 @@ typedef struct {
int linepos, displine;
int vc, sc;
uint16_t ma, maback;
int con, coff, cursoron;
int con, cursoron;
int dispon, blink;
int vsynctime;
int vadj;
@@ -899,7 +899,6 @@ incolor_poll(void *priv)
if (dev->sc == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[11] & 31) >> 1))) {
dev->con = 0;
dev->coff = 1;
}
if (dev->vadj) {

View File

@@ -200,7 +200,6 @@ mda_poll(void *priv)
}
if (mda->sc == (mda->crtc[11] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[11] & 31) >> 1))) {
mda->con = 0;
mda->coff = 1;
}
if (mda->vadj) {
mda->sc++;

View File

@@ -392,7 +392,6 @@ nga_poll(void *priv)
/* cursor stop scanline */
if (nga->cga.sc == (nga->cga.crtc[11] & 31) || ((nga->cga.crtc[8] & 3) == 3 && nga->cga.sc == ((nga->cga.crtc[11] & 31) >> 1))) {
nga->cga.con = 0;
nga->cga.coff = 1;
}
/* interlaced and max scanline per char reached */
if ((nga->cga.crtc[8] & 3) == 3 && nga->cga.sc == (nga->cga.crtc[9] >> 1))

View File

@@ -407,7 +407,6 @@ ogc_poll(void *priv)
}
if (ogc->cga.sc == (ogc->cga.crtc[11] & 31) || ((ogc->cga.crtc[8] & 3) == 3 && ogc->cga.sc == ((ogc->cga.crtc[11] & 31) >> 1))) {
ogc->cga.con = 0;
ogc->cga.coff = 1;
}
if ((ogc->cga.crtc[8] & 3) == 3 && ogc->cga.sc == (ogc->cga.crtc[9] >> 1))
ogc->cga.maback = ogc->cga.ma;

View File

@@ -158,7 +158,7 @@ typedef struct sigma_t {
int linepos, displine;
int sc, vc;
int cgadispon;
int con, coff, cursoron, cgablink;
int con, cursoron, cgablink;
int vsynctime, vadj;
int oddeven;
@@ -676,7 +676,6 @@ sigma_poll(void *priv)
}
if (sigma->sc == (sigma->crtc[11] & 31) || ((sigma->crtc[8] & 3) == 3 && sigma->sc == ((sigma->crtc[11] & 31) >> 1))) {
sigma->con = 0;
sigma->coff = 1;
}
if ((sigma->crtc[8] & 3) == 3 && sigma->sc == (sigma->crtc[9] >> 1))
sigma->maback = sigma->ma;