Merge branch 'master' of https://github.com/86Box/86Box
31
src/86box.c
@@ -253,6 +253,8 @@ struct accelKey def_acc_keys[NUM_ACCELS] = {
|
||||
.seq="Ctrl+Alt+M" }
|
||||
};
|
||||
|
||||
char vmm_path[1024] = { '\0'}; /* TEMPORARY - VM manager path to scan for VMs */
|
||||
int vmm_enabled = 0;
|
||||
|
||||
/* Statistics. */
|
||||
extern int mmuflush;
|
||||
@@ -600,8 +602,8 @@ pc_show_usage(char *s)
|
||||
#ifdef _WIN32
|
||||
"-D or --debug\t\t\t- force debug output logging\n"
|
||||
#endif
|
||||
#if 0
|
||||
"-E or --nographic\t\t- forces the old behavior\n"
|
||||
#if 1
|
||||
"-E or --vmmpath\t\t- vm manager path\n"
|
||||
#endif
|
||||
"-F or --fullscreen\t\t- start in fullscreen mode\n"
|
||||
"-G or --lang langid\t\t- start with specified language\n"
|
||||
@@ -637,7 +639,7 @@ pc_show_usage(char *s)
|
||||
ui_msgbox(MBX_ANSI | ((s == NULL) ? MBX_INFO : MBX_WARNING), p);
|
||||
#else
|
||||
if (s == NULL)
|
||||
pclog(p);
|
||||
pclog("%s", p);
|
||||
else
|
||||
ui_msgbox(MBX_ANSI | MBX_WARNING, p);
|
||||
#endif
|
||||
@@ -734,13 +736,18 @@ usage:
|
||||
} else if (!strcasecmp(argv[c], "--debug") || !strcasecmp(argv[c], "-D")) {
|
||||
force_debug = 1;
|
||||
#endif
|
||||
#ifdef ENABLE_NG
|
||||
} else if (!strcasecmp(argv[c], "--nographic") || !strcasecmp(argv[c], "-E")) {
|
||||
/* Currently does nothing, but if/when we implement a built-in manager,
|
||||
it's going to force the manager not to run, allowing the old usage
|
||||
without parameter. */
|
||||
ng = 1;
|
||||
#endif
|
||||
//#ifdef ENABLE_NG
|
||||
} else if (!strcasecmp(argv[c], "--vmmpath") ||
|
||||
!strcasecmp(argv[c], "-E")) {
|
||||
/* Using this variable for vm manager path
|
||||
Temporary solution!*/
|
||||
if ((c+1) == argc) goto usage;
|
||||
char *vp = argv[++c];
|
||||
if ((strlen(vp) + 1) >= sizeof(vmm_path))
|
||||
memcpy(vmm_path, vp, sizeof(vmm_path));
|
||||
else
|
||||
memcpy(vmm_path, vp, strlen(vp) + 1);
|
||||
//#endif
|
||||
} else if (!strcasecmp(argv[c], "--fullscreen") || !strcasecmp(argv[c], "-F")) {
|
||||
start_in_fullscreen = 1;
|
||||
} else if (!strcasecmp(argv[c], "--logfile") || !strcasecmp(argv[c], "-L")) {
|
||||
@@ -1027,6 +1034,10 @@ usage:
|
||||
}
|
||||
|
||||
pclog("# Configuration file: %s\n#\n\n", cfg_path);
|
||||
if (strlen(vmm_path) != 0) {
|
||||
vmm_enabled = 1;
|
||||
pclog("# VM Manager enabled. Path: %s\n", vmm_path);
|
||||
}
|
||||
/*
|
||||
* We are about to read the configuration file, which MAY
|
||||
* put data into global variables (the hard- and floppy
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
add_library(chipset OBJECT
|
||||
82c100.c
|
||||
acc2036.c
|
||||
acc2168.c
|
||||
cs8220.c
|
||||
cs8230.c
|
||||
@@ -48,6 +49,7 @@ add_library(chipset OBJECT
|
||||
opti291.c
|
||||
opti391.c
|
||||
opti495.c
|
||||
opti498.c
|
||||
opti499.c
|
||||
opti602.c
|
||||
opti822.c
|
||||
|
||||
346
src/chipset/acc2036.c
Normal file
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
* 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 ACC 2036 chipset.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2025 Miran Grca.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.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/mem.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/plat_fallthrough.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
typedef struct {
|
||||
uint32_t virt;
|
||||
uint32_t phys;
|
||||
|
||||
mem_mapping_t mapping;
|
||||
} ram_page_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t reg;
|
||||
uint8_t regs[32];
|
||||
|
||||
ram_page_t ram_mid_pages[24];
|
||||
ram_page_t ems_pages[4];
|
||||
} acc2036_t;
|
||||
|
||||
static uint8_t
|
||||
acc2036_mem_read(uint32_t addr, void *priv)
|
||||
{
|
||||
ram_page_t *dev = (ram_page_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
addr = (addr - dev->virt) + dev->phys;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
ret = ram[addr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
acc2036_mem_readw(uint32_t addr, void *priv)
|
||||
{
|
||||
ram_page_t *dev = (ram_page_t *) priv;
|
||||
uint16_t ret = 0xffff;
|
||||
|
||||
addr = (addr - dev->virt) + dev->phys;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
ret = *(uint16_t *) &(ram[addr]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
acc2036_mem_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
ram_page_t *dev = (ram_page_t *) priv;
|
||||
|
||||
addr = (addr - dev->virt) + dev->phys;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
ram[addr] = val;
|
||||
}
|
||||
|
||||
static void
|
||||
acc2036_mem_writew(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
ram_page_t *dev = (ram_page_t *) priv;
|
||||
|
||||
addr = (addr - dev->virt) + dev->phys;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
*(uint16_t *) &(ram[addr]) = val;
|
||||
}
|
||||
|
||||
static void
|
||||
acc2036_recalc(acc2036_t *dev)
|
||||
{
|
||||
uint32_t ems_bases[4] = { 0x000c0000, 0x000c8000, 0x000d0000, 0x000e0000 };
|
||||
|
||||
int start_i = (ems_bases[dev->regs[0x0c] & 0x03] - 0x000a0000) >> 14;
|
||||
int end_i = start_i + 3;
|
||||
|
||||
for (int i = 0; i < 24; i++) {
|
||||
ram_page_t *rp = &dev->ram_mid_pages[i];
|
||||
mem_mapping_disable(&rp->mapping);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
ram_page_t *ep = &dev->ems_pages[i];
|
||||
mem_mapping_disable(&ep->mapping);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 24; i++) {
|
||||
ram_page_t *rp = &dev->ram_mid_pages[i];
|
||||
|
||||
if ((dev->regs[0x03] & 0x08) && (i >= start_i) && (i <= end_i)) {
|
||||
/* EMS */
|
||||
ram_page_t *ep = &dev->ems_pages[i - start_i];
|
||||
|
||||
mem_mapping_disable(&rp->mapping);
|
||||
mem_mapping_set_addr(&ep->mapping, ep->virt, 0x000040000);
|
||||
mem_mapping_set_exec(&ep->mapping, ram + ep->phys);
|
||||
mem_set_mem_state_both(ep->virt, 0x00004000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
} else {
|
||||
int master_write;
|
||||
int master_read;
|
||||
int bit;
|
||||
int ew_flag;
|
||||
int er_flag;
|
||||
int flags;
|
||||
uint8_t val;
|
||||
|
||||
mem_mapping_set_addr(&rp->mapping, rp->virt, 0x000040000);
|
||||
mem_mapping_set_exec(&rp->mapping, ram + rp->phys);
|
||||
|
||||
if ((i >= 8) && (i <= 15)) {
|
||||
/* 0C0000-0DFFFF */
|
||||
master_write = dev->regs[0x02] & 0x08;
|
||||
master_read = dev->regs[0x02] & 0x04;
|
||||
bit = ((i - 8) >> 1);
|
||||
val = dev->regs[0x0d] & (1 << bit);
|
||||
if (i >= 12) {
|
||||
ew_flag = (dev->regs[0x07] & 0x80) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL;
|
||||
er_flag = (dev->regs[0x07] & 0x80) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL;
|
||||
} else {
|
||||
ew_flag = (dev->regs[0x07] & 0x40) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL;
|
||||
er_flag = (dev->regs[0x07] & 0x40) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL;
|
||||
}
|
||||
flags = (val && master_write) ? MEM_WRITE_INTERNAL : ew_flag;
|
||||
flags |= (val && master_read) ? MEM_READ_INTERNAL : er_flag;
|
||||
mem_set_mem_state_both(rp->virt, 0x00004000, flags);
|
||||
} else if (i > 15) {
|
||||
/* 0E0000-0FFFFF */
|
||||
master_write = dev->regs[0x02] & 0x02;
|
||||
master_read = dev->regs[0x02] & 0x01;
|
||||
bit = (((i - 8) >> 2) + 2);
|
||||
val = dev->regs[0x0c] & (1 << bit);
|
||||
if (i >= 20) {
|
||||
ew_flag = MEM_WRITE_EXTANY;
|
||||
er_flag = MEM_READ_EXTANY;
|
||||
} else {
|
||||
ew_flag = (dev->regs[0x0c] & 0x10) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL;
|
||||
er_flag = (dev->regs[0x0c] & 0x10) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL;
|
||||
}
|
||||
flags = (val && master_write) ? MEM_WRITE_INTERNAL : ew_flag;
|
||||
flags |= (val && master_read) ? MEM_READ_INTERNAL : er_flag;
|
||||
mem_set_mem_state_both(rp->virt, 0x00004000, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->regs[0x00] & 0x40)
|
||||
mem_set_mem_state_both(0x00fe0000, 0x00010000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
else
|
||||
mem_set_mem_state_both(0x00fe0000, 0x00010000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
|
||||
for (int i = 0x01; i <= 0x06; i++) {
|
||||
uint32_t base = 0x00fe0000 - (i * 0x00010000);
|
||||
|
||||
if (dev->regs[i] & 0x40)
|
||||
mem_set_mem_state_both(base, 0x00008000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x00008000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
|
||||
if (dev->regs[i] & 0x80)
|
||||
mem_set_mem_state_both(base + 0x00008000, 0x00008000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
else
|
||||
mem_set_mem_state_both(base + 0x00008000, 0x00008000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
}
|
||||
|
||||
mem_remap_top(0);
|
||||
if (dev->regs[0x03] & 0x10) {
|
||||
if (dev->regs[0x02] & 0x0c)
|
||||
mem_remap_top(128);
|
||||
else if (dev->regs[0x02] & 0x03)
|
||||
mem_remap_top(256);
|
||||
else
|
||||
mem_remap_top(384);
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
acc2036_in(uint16_t port, void *priv) {
|
||||
acc2036_t *dev = (acc2036_t *) priv;
|
||||
uint8_t reg = dev->reg - 0x20;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (port & 0x0001) switch (dev->reg) {
|
||||
default:
|
||||
break;
|
||||
case 0x20 ... 0x2e:
|
||||
case 0x31 ... 0x3f:
|
||||
ret = dev->regs[reg];
|
||||
break;
|
||||
} else
|
||||
ret = dev->reg;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
acc2036_out(uint16_t port, uint8_t val, void *priv) {
|
||||
acc2036_t *dev = (acc2036_t *) priv;
|
||||
uint8_t reg = dev->reg - 0x20;
|
||||
|
||||
if (port & 0x0001) switch (dev->reg) {
|
||||
default:
|
||||
break;
|
||||
case 0x20 ... 0x23:
|
||||
dev->regs[reg] = val;
|
||||
acc2036_recalc(dev);
|
||||
break;
|
||||
case 0x24 ... 0x2b:
|
||||
dev->regs[reg] = val;
|
||||
dev->ems_pages[(reg - 0x04) >> 1].phys = ((dev->regs[reg & 0xfe] & 0x1f) << 19) |
|
||||
((dev->regs[reg | 0x01] & 0x1f) << 14);
|
||||
acc2036_recalc(dev);
|
||||
break;
|
||||
case 0x2c: case 0x2d:
|
||||
dev->regs[reg] = val;
|
||||
acc2036_recalc(dev);
|
||||
break;
|
||||
case 0x2e:
|
||||
dev->regs[reg] = val | 0x10;
|
||||
break;
|
||||
case 0x31:
|
||||
dev->regs[reg] = val;
|
||||
mem_a20_alt = (val & 0x01);
|
||||
mem_a20_recalc();
|
||||
flushmmucache();
|
||||
if (val & 0x02) {
|
||||
softresetx86(); /* Pulse reset! */
|
||||
cpu_set_edx();
|
||||
flushmmucache();
|
||||
}
|
||||
break;
|
||||
case 0x32 ... 0x3f:
|
||||
dev->regs[reg] = val;
|
||||
break;
|
||||
} else
|
||||
dev->reg = val;
|
||||
}
|
||||
|
||||
static void
|
||||
acc2036_close(void *priv)
|
||||
{
|
||||
acc2036_t *dev = (acc2036_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
acc2036_init(UNUSED(const device_t *info))
|
||||
{
|
||||
acc2036_t *dev = (acc2036_t *) calloc(1, sizeof(acc2036_t));
|
||||
|
||||
for (int i = 0; i < 24; i++) {
|
||||
ram_page_t *rp = &dev->ram_mid_pages[i];
|
||||
|
||||
rp->virt = 0x000a0000 + (i << 14);
|
||||
rp->phys = 0x000a0000 + (i << 14);
|
||||
mem_mapping_add(&rp->mapping, rp->virt, 0x00004000,
|
||||
acc2036_mem_read, acc2036_mem_readw, NULL,
|
||||
acc2036_mem_write, acc2036_mem_writew, NULL,
|
||||
ram + rp->phys, MEM_MAPPING_INTERNAL, rp);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
ram_page_t *ep = &dev->ems_pages[i];
|
||||
|
||||
ep->virt = 0x000d0000 + (i << 14);
|
||||
ep->phys = 0x00000000 + (i << 14);
|
||||
mem_mapping_add(&ep->mapping, ep->virt, 0x00004000,
|
||||
acc2036_mem_read, acc2036_mem_readw, NULL,
|
||||
acc2036_mem_write, acc2036_mem_writew, NULL,
|
||||
ram + ep->phys, MEM_MAPPING_INTERNAL, ep);
|
||||
mem_mapping_disable(&ep->mapping);
|
||||
}
|
||||
|
||||
mem_mapping_disable(&ram_mid_mapping);
|
||||
|
||||
dev->regs[0x00] = 0x02;
|
||||
dev->regs[0x0e] = 0x10;
|
||||
dev->regs[0x11] = 0x01;
|
||||
dev->regs[0x13] = 0x40;
|
||||
dev->regs[0x15] = 0x40;
|
||||
dev->regs[0x17] = 0x40;
|
||||
dev->regs[0x19] = 0x40;
|
||||
dev->regs[0x1b] = 0x40;
|
||||
dev->regs[0x1c] = 0x22;
|
||||
dev->regs[0x1d] = 0xc4;
|
||||
dev->regs[0x1f] = 0x30;
|
||||
acc2036_recalc(dev);
|
||||
|
||||
mem_a20_alt = 0x01;
|
||||
mem_a20_recalc();
|
||||
flushmmucache();
|
||||
|
||||
io_sethandler(0x00f2, 0x0002,
|
||||
acc2036_in, NULL, NULL, acc2036_out, NULL, NULL, dev);
|
||||
|
||||
device_add(&port_92_device);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t acc2036_device = {
|
||||
.name = "ACC 2036",
|
||||
.internal_name = "acc2036",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = acc2036_init,
|
||||
.close = acc2036_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
@@ -16,6 +16,7 @@
|
||||
* Copyright 2021 Tiseno100.
|
||||
* Copyright 2021 Miran Grca.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -158,7 +159,20 @@ opti283_shadow_recalc(opti283_t *dev)
|
||||
rom = dev->regs[0x11] & (1 << ((i >> 2) + 4));
|
||||
opti283_log("OPTI 283: %i/%08X: %i, %i, %i\n", i, base, (i >= 4) ? (1 << (i - 4)) : (1 << (i + 4)), (1 << (i >> 2)), (1 << ((i >> 2) + 4)));
|
||||
|
||||
if (sh_enable && rom) {
|
||||
if (sh_copy) {
|
||||
if (base >= 0x000e0000)
|
||||
shadowbios_write |= 1;
|
||||
if (base >= 0x000d0000)
|
||||
dev->shadow_high |= 1;
|
||||
|
||||
if (base >= 0xe0000) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_EXTANY, WRITE_INTERNAL\n", base, base + 0x3fff);
|
||||
} else {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_EXTERNAL, WRITE_INTERNAL\n", base, base + 0x3fff);
|
||||
}
|
||||
} else if (sh_enable && rom) {
|
||||
if (base >= 0x000e0000)
|
||||
shadowbios |= 1;
|
||||
if (base >= 0x000d0000)
|
||||
@@ -171,13 +185,8 @@ opti283_shadow_recalc(opti283_t *dev)
|
||||
if (base >= 0x000e0000)
|
||||
shadowbios_write |= 1;
|
||||
|
||||
if (sh_copy) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_INTERNAL, WRITE_INTERNAL\n", base, base + 0x3fff);
|
||||
} else {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_INTERNAL, WRITE_EXTERNAL\n", base, base + 0x3fff);
|
||||
}
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_INTERNAL, WRITE_INTERNAL\n", base, base + 0x3fff);
|
||||
}
|
||||
} else {
|
||||
if (base >= 0xe0000) {
|
||||
@@ -239,9 +248,21 @@ opti283_write(uint16_t addr, uint8_t val, void *priv)
|
||||
dev->regs[dev->index] = (dev->regs[dev->index] & 0x80) | (val & 0x7f);
|
||||
break;
|
||||
|
||||
case 0x14:
|
||||
case 0x14: {
|
||||
double bus_clk;
|
||||
switch (val & 0x01) {
|
||||
default:
|
||||
case 0x00:
|
||||
bus_clk = cpu_busspeed / 6.0;
|
||||
break;
|
||||
case 0x01:
|
||||
bus_clk = cpu_busspeed / 4.0;
|
||||
break;
|
||||
}
|
||||
cpu_set_isa_speed((int) round(bus_clk));
|
||||
reset_on_hlt = !!(val & 0x40);
|
||||
fallthrough;
|
||||
}
|
||||
case 0x11:
|
||||
case 0x12:
|
||||
case 0x13:
|
||||
@@ -310,6 +331,8 @@ opti283_init(UNUSED(const device_t *info))
|
||||
|
||||
opti283_shadow_recalc(dev);
|
||||
|
||||
cpu_set_isa_speed((int) round(cpu_busspeed / 6.0));
|
||||
|
||||
device_add(&port_92_device);
|
||||
|
||||
return dev;
|
||||
|
||||
@@ -8,14 +8,13 @@
|
||||
*
|
||||
* Implementation of the OPTi 82C493/82C495 chipset.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2020 Tiseno100.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -28,6 +27,7 @@
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/plat_fallthrough.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
@@ -166,6 +166,27 @@ opti495_write(uint16_t addr, uint8_t val, void *priv)
|
||||
case 0x26:
|
||||
opti495_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x25: {
|
||||
double bus_clk;
|
||||
switch (val & 0x03) {
|
||||
default:
|
||||
case 0x00:
|
||||
bus_clk = cpu_busspeed / 6.0;
|
||||
break;
|
||||
case 0x01:
|
||||
bus_clk = cpu_busspeed / 4.0;
|
||||
break;
|
||||
case 0x02:
|
||||
bus_clk = cpu_busspeed / 3.0;
|
||||
break;
|
||||
case 0x03:
|
||||
bus_clk = (cpu_busspeed * 2.0) / 5.0;
|
||||
break;
|
||||
}
|
||||
cpu_set_isa_speed((int) round(bus_clk));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,6 +280,8 @@ opti495_init(const device_t *info)
|
||||
|
||||
io_sethandler(0x00e1, 0x0002, opti495_read, NULL, NULL, opti495_write, NULL, NULL, dev);
|
||||
|
||||
cpu_set_isa_speed((int) round(cpu_busspeed / 6.0));
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
@@ -276,11 +299,25 @@ const device_t opti493_device = {
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t opti495_device = {
|
||||
const device_t opti495slc_device = {
|
||||
.name = "OPTi 82C495",
|
||||
.internal_name = "opti495",
|
||||
.internal_name = "opti495slc",
|
||||
.flags = 0,
|
||||
.local = OPTI495XLC,
|
||||
.local = OPTI495SLC,
|
||||
.init = opti495_init,
|
||||
.close = opti495_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t opti495sx_device = {
|
||||
.name = "OPTi 82C495SX",
|
||||
.internal_name = "opti495sx",
|
||||
.flags = 0,
|
||||
.local = OPTI495SX,
|
||||
.init = opti495_init,
|
||||
.close = opti495_close,
|
||||
.reset = NULL,
|
||||
|
||||
360
src/chipset/opti498.c
Normal file
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
* 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 OPTi 82C498 chipset.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2025 Miran Grca.
|
||||
*/
|
||||
#include <math.h>
|
||||
#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/mem.h>
|
||||
#include <86box/plat_fallthrough.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
#ifdef ENABLE_OPTI498_LOG
|
||||
int opti498_do_log = ENABLE_OPTI498_LOG;
|
||||
|
||||
static void
|
||||
opti498_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (opti498_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define opti498_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct mem_remapping_t {
|
||||
uint32_t phys;
|
||||
uint32_t virt;
|
||||
} mem_remapping_t;
|
||||
|
||||
typedef struct opti498_t {
|
||||
uint8_t index;
|
||||
/* 0x30 for 496/497, 0x70 for 498. */
|
||||
uint8_t reg_base;
|
||||
uint8_t shadow_high;
|
||||
uint8_t regs[256];
|
||||
mem_remapping_t mem_remappings[2];
|
||||
mem_mapping_t mem_mappings[2];
|
||||
} opti498_t;
|
||||
|
||||
static uint8_t
|
||||
opti498_read_remapped_ram(uint32_t addr, void *priv)
|
||||
{
|
||||
const mem_remapping_t *dev = (mem_remapping_t *) priv;
|
||||
|
||||
return mem_read_ram((addr - dev->virt) + dev->phys, priv);
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
opti498_read_remapped_ramw(uint32_t addr, void *priv)
|
||||
{
|
||||
const mem_remapping_t *dev = (mem_remapping_t *) priv;
|
||||
|
||||
return mem_read_ramw((addr - dev->virt) + dev->phys, priv);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
opti498_read_remapped_raml(uint32_t addr, void *priv)
|
||||
{
|
||||
const mem_remapping_t *dev = (mem_remapping_t *) priv;
|
||||
|
||||
return mem_read_raml((addr - dev->virt) + dev->phys, priv);
|
||||
}
|
||||
|
||||
static void
|
||||
opti498_write_remapped_ram(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
const mem_remapping_t *dev = (mem_remapping_t *) priv;
|
||||
|
||||
mem_write_ram((addr - dev->virt) + dev->phys, val, priv);
|
||||
}
|
||||
|
||||
static void
|
||||
opti498_write_remapped_ramw(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
const mem_remapping_t *dev = (mem_remapping_t *) priv;
|
||||
|
||||
mem_write_ramw((addr - dev->virt) + dev->phys, val, priv);
|
||||
}
|
||||
|
||||
static void
|
||||
opti498_write_remapped_raml(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
const mem_remapping_t *dev = (mem_remapping_t *) priv;
|
||||
|
||||
mem_write_raml((addr - dev->virt) + dev->phys, val, priv);
|
||||
}
|
||||
|
||||
static void
|
||||
opti498_shadow_recalc(opti498_t *dev)
|
||||
{
|
||||
uint32_t base;
|
||||
uint32_t rbase;
|
||||
uint8_t sh_enable;
|
||||
uint8_t sh_mode;
|
||||
uint8_t rom;
|
||||
uint8_t sh_copy;
|
||||
|
||||
shadowbios = shadowbios_write = 0;
|
||||
dev->shadow_high = 0;
|
||||
|
||||
opti498_log("OPTI 498: %02X %02X %02X %02X\n", dev->regs[0x02], dev->regs[0x03], dev->regs[0x04], dev->regs[0x05]);
|
||||
|
||||
if (dev->regs[0x02] & 0x80) {
|
||||
if (dev->regs[0x04] & 0x02) {
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
opti498_log("OPTI 498: F0000-FFFFF READ_EXTANY, WRITE_EXTANY\n");
|
||||
} else {
|
||||
shadowbios_write = 1;
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
opti498_log("OPTI 498: F0000-FFFFF READ_EXTANY, WRITE_INTERNAL\n");
|
||||
}
|
||||
} else {
|
||||
shadowbios = 1;
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
opti498_log("OPTI 498: F0000-FFFFF READ_INTERNAL, WRITE_DISABLED\n");
|
||||
}
|
||||
|
||||
sh_copy = dev->regs[0x02] & 0x08;
|
||||
for (uint8_t i = 0; i < 12; i++) {
|
||||
base = 0xc0000 + (i << 14);
|
||||
if (i >= 4)
|
||||
sh_enable = dev->regs[0x03] & (1 << (i - 4));
|
||||
else
|
||||
sh_enable = dev->regs[0x04] & (1 << (i + 4));
|
||||
sh_mode = dev->regs[0x02] & (1 << (i >> 2));
|
||||
rom = dev->regs[0x02] & (1 << ((i >> 2) + 4));
|
||||
opti498_log("OPTI 498: %i/%08X: %i, %i, %i\n", i, base, (i >= 4) ? (1 << (i - 4)) : (1 << (i + 4)), (1 << (i >> 2)), (1 << ((i >> 2) + 4)));
|
||||
|
||||
if (sh_copy) {
|
||||
if (base >= 0x000e0000)
|
||||
shadowbios_write |= 1;
|
||||
if (base >= 0x000d0000)
|
||||
dev->shadow_high |= 1;
|
||||
|
||||
if (base >= 0xe0000) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
opti498_log("OPTI 498: %08X-%08X READ_EXTANY, WRITE_INTERNAL\n", base, base + 0x3fff);
|
||||
} else {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
opti498_log("OPTI 498: %08X-%08X READ_EXTERNAL, WRITE_INTERNAL\n", base, base + 0x3fff);
|
||||
}
|
||||
} else if (sh_enable && rom) {
|
||||
if (base >= 0x000e0000)
|
||||
shadowbios |= 1;
|
||||
if (base >= 0x000d0000)
|
||||
dev->shadow_high |= 1;
|
||||
|
||||
if (sh_mode) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
opti498_log("OPTI 498: %08X-%08X READ_INTERNAL, WRITE_DISABLED\n", base, base + 0x3fff);
|
||||
} else {
|
||||
if (base >= 0x000e0000)
|
||||
shadowbios_write |= 1;
|
||||
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
opti498_log("OPTI 498: %08X-%08X READ_INTERNAL, WRITE_INTERNAL\n", base, base + 0x3fff);
|
||||
}
|
||||
} else {
|
||||
if (base >= 0xe0000) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_DISABLED);
|
||||
opti498_log("OPTI 498: %08X-%08X READ_EXTANY, WRITE_DISABLED\n", base, base + 0x3fff);
|
||||
} else {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_DISABLED);
|
||||
opti498_log("OPTI 498: %08X-%08X READ_EXTERNAL, WRITE_DISABLED\n", base, base + 0x3fff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rbase = ((uint32_t) (dev->regs[0x05] & 0x3f)) << 20;
|
||||
|
||||
if (rbase > 0) {
|
||||
dev->mem_remappings[0].virt = rbase;
|
||||
mem_mapping_set_addr(&dev->mem_mappings[0], rbase, 0x00020000);
|
||||
|
||||
if (!dev->shadow_high) {
|
||||
rbase += 0x00020000;
|
||||
dev->mem_remappings[1].virt = rbase;
|
||||
mem_mapping_set_addr(&dev->mem_mappings[1], rbase, 0x00020000);
|
||||
} else
|
||||
mem_mapping_disable(&dev->mem_mappings[1]);
|
||||
} else {
|
||||
mem_mapping_disable(&dev->mem_mappings[0]);
|
||||
mem_mapping_disable(&dev->mem_mappings[1]);
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
opti498_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
opti498_t *dev = (opti498_t *) priv;
|
||||
uint8_t reg = dev->index - dev->reg_base;
|
||||
|
||||
switch (addr) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
|
||||
case 0x24:
|
||||
opti498_log("OPTi 498: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
|
||||
if ((reg >= 0x00) && (reg <= 0x0b)) switch (reg) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x00:
|
||||
dev->regs[reg] = (dev->regs[reg] & 0xc0) | (val & 0x3f);
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
case 0x07 ... 0x0b:
|
||||
dev->regs[reg] = val;
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
dev->regs[reg] = val;
|
||||
opti498_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x06: {
|
||||
double bus_clk;
|
||||
dev->regs[reg] = val;
|
||||
switch (val & 0x03) {
|
||||
default:
|
||||
case 0x00:
|
||||
bus_clk = cpu_busspeed / 8.0;
|
||||
break;
|
||||
case 0x01:
|
||||
bus_clk = cpu_busspeed / 6.0;
|
||||
break;
|
||||
case 0x02:
|
||||
bus_clk = cpu_busspeed / 5.0;
|
||||
break;
|
||||
case 0x03:
|
||||
bus_clk = cpu_busspeed / 4.0;
|
||||
break;
|
||||
}
|
||||
cpu_set_isa_speed((int) round(bus_clk));
|
||||
reset_on_hlt = !!(val & 0x40);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dev->index = 0xff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
opti498_read(uint16_t addr, void *priv)
|
||||
{
|
||||
opti498_t *dev = (opti498_t *) priv;
|
||||
uint8_t reg = dev->index - dev->reg_base;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (addr == 0x24) {
|
||||
if ((reg >= 0x00) && (reg <= 0x0b))
|
||||
ret = dev->regs[reg];
|
||||
|
||||
dev->index = 0xff;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
opti498_close(void *priv)
|
||||
{
|
||||
opti498_t *dev = (opti498_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
opti498_init(UNUSED(const device_t *info))
|
||||
{
|
||||
opti498_t *dev = (opti498_t *) calloc(1, sizeof(opti498_t));
|
||||
|
||||
dev->reg_base = info->local & 0xff;
|
||||
|
||||
io_sethandler(0x0022, 0x0001, opti498_read, NULL, NULL, opti498_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0024, 0x0001, opti498_read, NULL, NULL, opti498_write, NULL, NULL, dev);
|
||||
|
||||
dev->regs[0x00] = 0x1f;
|
||||
dev->regs[0x01] = 0x8f;
|
||||
dev->regs[0x02] = 0xf0;
|
||||
dev->regs[0x07] = 0x70;
|
||||
dev->regs[0x09] = 0x70;
|
||||
|
||||
dev->mem_remappings[0].phys = 0x000a0000;
|
||||
dev->mem_remappings[1].phys = 0x000d0000;
|
||||
|
||||
mem_mapping_add(&dev->mem_mappings[0], 0, 0x00020000,
|
||||
opti498_read_remapped_ram, opti498_read_remapped_ramw, opti498_read_remapped_raml,
|
||||
opti498_write_remapped_ram, opti498_write_remapped_ramw, opti498_write_remapped_raml,
|
||||
&ram[dev->mem_remappings[0].phys], MEM_MAPPING_INTERNAL, &dev->mem_remappings[0]);
|
||||
mem_mapping_disable(&dev->mem_mappings[0]);
|
||||
|
||||
mem_mapping_add(&dev->mem_mappings[1], 0, 0x00020000,
|
||||
opti498_read_remapped_ram, opti498_read_remapped_ramw, opti498_read_remapped_raml,
|
||||
opti498_write_remapped_ram, opti498_write_remapped_ramw, opti498_write_remapped_raml,
|
||||
&ram[dev->mem_remappings[1].phys], MEM_MAPPING_INTERNAL, &dev->mem_remappings[1]);
|
||||
mem_mapping_disable(&dev->mem_mappings[1]);
|
||||
|
||||
opti498_shadow_recalc(dev);
|
||||
|
||||
cpu_set_isa_speed((int) round(cpu_busspeed / 8.0));
|
||||
|
||||
device_add(&port_92_device);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t opti498_device = {
|
||||
.name = "OPTi 82C498",
|
||||
.internal_name = "opti498",
|
||||
.flags = 0,
|
||||
.local = 0x70,
|
||||
.init = opti498_init,
|
||||
.close = opti498_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
@@ -16,6 +16,7 @@
|
||||
* Copyright 2008-2020 Tiseno100.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -148,9 +149,28 @@ opti499_write(uint16_t addr, uint8_t val, void *priv)
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x20:
|
||||
case 0x20: {
|
||||
double coeff = (val & 0x10) ? 1.0 : 2.0;
|
||||
double bus_clk;
|
||||
switch (dev->regs[0x25] & 0x03) {
|
||||
default:
|
||||
case 0x00:
|
||||
bus_clk = (cpu_busspeed * coeff) / 6.0;
|
||||
break;
|
||||
case 0x01:
|
||||
bus_clk = (cpu_busspeed * coeff) / 5.0;
|
||||
break;
|
||||
case 0x02:
|
||||
bus_clk = (cpu_busspeed * coeff) / 4.0;
|
||||
break;
|
||||
case 0x03:
|
||||
bus_clk = (cpu_busspeed * coeff) / 3.0;
|
||||
break;
|
||||
}
|
||||
cpu_set_isa_speed((int) round(bus_clk));
|
||||
reset_on_hlt = !(val & 0x02);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x21:
|
||||
cpu_cache_ext_enabled = !!(dev->regs[0x21] & 0x10);
|
||||
@@ -163,6 +183,28 @@ opti499_write(uint16_t addr, uint8_t val, void *priv)
|
||||
case 0x2d:
|
||||
opti499_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x25: {
|
||||
double coeff = (dev->regs[0x20] & 0x10) ? 1.0 : 2.0;
|
||||
double bus_clk;
|
||||
switch (val & 0x03) {
|
||||
default:
|
||||
case 0x00:
|
||||
bus_clk = (cpu_busspeed * coeff) / 8.0;
|
||||
break;
|
||||
case 0x01:
|
||||
bus_clk = (cpu_busspeed * coeff) / 6.0;
|
||||
break;
|
||||
case 0x02:
|
||||
bus_clk = (cpu_busspeed * coeff) / 5.0;
|
||||
break;
|
||||
case 0x03:
|
||||
bus_clk = (cpu_busspeed * coeff) / 4.0;
|
||||
break;
|
||||
}
|
||||
cpu_set_isa_speed((int) round(bus_clk));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,6 +271,8 @@ opti499_reset(void *priv)
|
||||
cpu_update_waitstates();
|
||||
|
||||
opti499_recalc(dev);
|
||||
|
||||
cpu_set_isa_speed((int) round((cpu_busspeed * 2.0) / 6.0));
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
* Copyright 2008-2020 Tiseno100.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -182,6 +183,27 @@ opti895_write(uint16_t addr, uint8_t val, void *priv)
|
||||
smram_state_change(dev->smram, 0, !!(val & 0x80));
|
||||
break;
|
||||
|
||||
case 0x25: {
|
||||
double bus_clk;
|
||||
switch (val & 0x03) {
|
||||
default:
|
||||
case 0x00:
|
||||
bus_clk = cpu_busspeed / 6.0;
|
||||
break;
|
||||
case 0x01:
|
||||
bus_clk = cpu_busspeed / 5.0;
|
||||
break;
|
||||
case 0x02:
|
||||
bus_clk = cpu_busspeed / 4.0;
|
||||
break;
|
||||
case 0x03:
|
||||
bus_clk = cpu_busspeed / 3.0;
|
||||
break;
|
||||
}
|
||||
cpu_set_isa_speed((int) round(bus_clk));
|
||||
break;
|
||||
}
|
||||
|
||||
case 0xe0:
|
||||
if (!(val & 0x01))
|
||||
dev->forced_green = 0;
|
||||
@@ -294,6 +316,8 @@ opti895_init(const device_t *info)
|
||||
|
||||
smram_enable(dev->smram, 0x00030000, 0x000b0000, 0x00010000, 0, 1);
|
||||
|
||||
cpu_set_isa_speed((int) round(cpu_busspeed / 6.0));
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
@@ -212,7 +212,7 @@ isarom_init(const device_t *info)
|
||||
static const device_config_t isarom_config[] = {
|
||||
{
|
||||
.name = "bios_fn",
|
||||
.description = "BIOS File",
|
||||
.description = "BIOS file",
|
||||
.type = CONFIG_FNAME,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
@@ -234,7 +234,7 @@ static const device_config_t isarom_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_size",
|
||||
.description = "BIOS Size:",
|
||||
.description = "BIOS size",
|
||||
.type = CONFIG_INT,
|
||||
.default_string = NULL,
|
||||
.default_int = 8192,
|
||||
@@ -260,7 +260,7 @@ static const device_config_t isarom_config[] = {
|
||||
static const device_config_t isarom_dual_config[] = {
|
||||
{
|
||||
.name = "bios_fn",
|
||||
.description = "BIOS File (ROM #1)",
|
||||
.description = "BIOS file (ROM #1)",
|
||||
.type = CONFIG_FNAME,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
@@ -271,7 +271,7 @@ static const device_config_t isarom_dual_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_addr",
|
||||
.description = "BIOS Address (ROM #1)",
|
||||
.description = "BIOS address (ROM #1)",
|
||||
.type = CONFIG_HEX20,
|
||||
.default_string = NULL,
|
||||
.default_int = 0x00000,
|
||||
@@ -282,7 +282,7 @@ static const device_config_t isarom_dual_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_size",
|
||||
.description = "BIOS Size (ROM #1):",
|
||||
.description = "BIOS size (ROM #1)",
|
||||
.type = CONFIG_INT,
|
||||
.default_string = NULL,
|
||||
.default_int = 8192,
|
||||
@@ -304,7 +304,7 @@ static const device_config_t isarom_dual_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_fn2",
|
||||
.description = "BIOS File (ROM #2)",
|
||||
.description = "BIOS file (ROM #2)",
|
||||
.type = CONFIG_FNAME,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
@@ -315,7 +315,7 @@ static const device_config_t isarom_dual_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_addr2",
|
||||
.description = "BIOS Address (ROM #2)",
|
||||
.description = "BIOS address (ROM #2)",
|
||||
.type = CONFIG_HEX20,
|
||||
.default_string = NULL,
|
||||
.default_int = 0x00000,
|
||||
@@ -326,7 +326,7 @@ static const device_config_t isarom_dual_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_size2",
|
||||
.description = "BIOS Size (ROM #2):",
|
||||
.description = "BIOS size (ROM #2)",
|
||||
.type = CONFIG_INT,
|
||||
.default_string = NULL,
|
||||
.default_int = 8192,
|
||||
@@ -352,7 +352,7 @@ static const device_config_t isarom_dual_config[] = {
|
||||
static const device_config_t isarom_quad_config[] = {
|
||||
{
|
||||
.name = "bios_fn",
|
||||
.description = "BIOS File (ROM #1)",
|
||||
.description = "BIOS file (ROM #1)",
|
||||
.type = CONFIG_FNAME,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
@@ -363,7 +363,7 @@ static const device_config_t isarom_quad_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_addr",
|
||||
.description = "BIOS Address (ROM #1)",
|
||||
.description = "BIOS address (ROM #1)",
|
||||
.type = CONFIG_HEX20,
|
||||
.default_string = NULL,
|
||||
.default_int = 0x00000,
|
||||
@@ -374,7 +374,7 @@ static const device_config_t isarom_quad_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_size",
|
||||
.description = "BIOS Size (ROM #1):",
|
||||
.description = "BIOS size (ROM #1)",
|
||||
.type = CONFIG_INT,
|
||||
.default_string = NULL,
|
||||
.default_int = 8192,
|
||||
@@ -396,7 +396,7 @@ static const device_config_t isarom_quad_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_fn2",
|
||||
.description = "BIOS File (ROM #2)",
|
||||
.description = "BIOS file (ROM #2)",
|
||||
.type = CONFIG_FNAME,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
@@ -407,7 +407,7 @@ static const device_config_t isarom_quad_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_addr2",
|
||||
.description = "BIOS Address (ROM #2)",
|
||||
.description = "BIOS address (ROM #2)",
|
||||
.type = CONFIG_HEX20,
|
||||
.default_string = NULL,
|
||||
.default_int = 0x00000,
|
||||
@@ -418,7 +418,7 @@ static const device_config_t isarom_quad_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_size2",
|
||||
.description = "BIOS Size (ROM #2):",
|
||||
.description = "BIOS size (ROM #2)",
|
||||
.type = CONFIG_INT,
|
||||
.default_string = NULL,
|
||||
.default_int = 8192,
|
||||
@@ -440,7 +440,7 @@ static const device_config_t isarom_quad_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_fn3",
|
||||
.description = "BIOS File (ROM #3)",
|
||||
.description = "BIOS file (ROM #3)",
|
||||
.type = CONFIG_FNAME,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
@@ -451,7 +451,7 @@ static const device_config_t isarom_quad_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_addr3",
|
||||
.description = "BIOS Address (ROM #3)",
|
||||
.description = "BIOS address (ROM #3)",
|
||||
.type = CONFIG_HEX20,
|
||||
.default_string = NULL,
|
||||
.default_int = 0x00000,
|
||||
@@ -462,7 +462,7 @@ static const device_config_t isarom_quad_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_size3",
|
||||
.description = "BIOS Size (ROM #3):",
|
||||
.description = "BIOS size (ROM #3)",
|
||||
.type = CONFIG_INT,
|
||||
.default_string = NULL,
|
||||
.default_int = 8192,
|
||||
@@ -484,7 +484,7 @@ static const device_config_t isarom_quad_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_fn4",
|
||||
.description = "BIOS File (ROM #4)",
|
||||
.description = "BIOS file (ROM #4)",
|
||||
.type = CONFIG_FNAME,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
@@ -495,7 +495,7 @@ static const device_config_t isarom_quad_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_addr4",
|
||||
.description = "BIOS Address (ROM #4)",
|
||||
.description = "BIOS address (ROM #4)",
|
||||
.type = CONFIG_HEX20,
|
||||
.default_string = NULL,
|
||||
.default_int = 0x00000,
|
||||
@@ -506,7 +506,7 @@ static const device_config_t isarom_quad_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "bios_size4",
|
||||
.description = "BIOS Size (ROM #4):",
|
||||
.description = "BIOS size (ROM #4)",
|
||||
.type = CONFIG_INT,
|
||||
.default_string = NULL,
|
||||
.default_int = 8192,
|
||||
|
||||
@@ -69,6 +69,7 @@ enum {
|
||||
KBD_TYPE_ZENITH,
|
||||
KBD_TYPE_PRAVETZ,
|
||||
KBD_TYPE_HYUNDAI,
|
||||
KBD_TYPE_FE2010,
|
||||
KBD_TYPE_XTCLONE
|
||||
};
|
||||
|
||||
@@ -80,6 +81,7 @@ typedef struct xtkbd_t {
|
||||
uint8_t pa;
|
||||
uint8_t pb;
|
||||
uint8_t pd;
|
||||
uint8_t cfg;
|
||||
uint8_t clock;
|
||||
uint8_t key_waiting;
|
||||
uint8_t type;
|
||||
@@ -832,12 +834,26 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
|
||||
kbd_log("XTkbd: Cassette motor is %s\n", !(val & 0x08) ? "ON" : "OFF");
|
||||
#endif
|
||||
break;
|
||||
#ifdef ENABLE_KEYBOARD_XT_LOG
|
||||
|
||||
case 0x62: /* Switch Register (aka Port C) */
|
||||
#ifdef ENABLE_KEYBOARD_XT_LOG
|
||||
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ))
|
||||
kbd_log("XTkbd: Cassette IN is %i\n", !!(val & 0x10));
|
||||
break;
|
||||
#endif
|
||||
if (kbd->type == KBD_TYPE_FE2010) {
|
||||
kbd_log("XTkbd: Switch register in is %02X\n", val);
|
||||
if (!(kbd->cfg & 0x08))
|
||||
kbd->pd = (kbd->pd & 0x30) | (val & 0xcf);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x63:
|
||||
if (kbd->type == KBD_TYPE_FE2010) {
|
||||
kbd_log("XTkbd: Configuration register in is %02X\n", val);
|
||||
if (!(kbd->cfg & 0x08))
|
||||
kbd->cfg = val;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xc0 ... 0xcf: /* Pravetz Flags */
|
||||
kbd_log("XTkbd: Port %02X out: %02X\n", port, val);
|
||||
@@ -912,7 +928,12 @@ kbd_read(uint16_t port, void *priv)
|
||||
break;
|
||||
|
||||
case 0x62: /* Switch Register (aka Port C) */
|
||||
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) ||
|
||||
if (kbd->type == KBD_TYPE_FE2010) {
|
||||
if (kbd->pb & 0x04) /* PB2 */
|
||||
ret = (kbd->pd & 0x0d) | (hasfpu ? 0x02 : 0x00);
|
||||
else
|
||||
ret = kbd->pd >> 4;
|
||||
} else if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) ||
|
||||
(kbd->type == KBD_TYPE_PRAVETZ)) {
|
||||
if (kbd->pb & 0x04) /* PB2 */
|
||||
switch (mem_size + isa_mem_size) {
|
||||
@@ -1037,7 +1058,7 @@ kbd_init(const device_t *info)
|
||||
(kbd->type <= KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_XTCLONE) ||
|
||||
(kbd->type == KBD_TYPE_COMPAQ) || (kbd->type == KBD_TYPE_TOSHIBA) ||
|
||||
(kbd->type == KBD_TYPE_OLIVETTI) || (kbd->type == KBD_TYPE_HYUNDAI) ||
|
||||
(kbd->type == KBD_TYPE_VTECH)) {
|
||||
(kbd->type == KBD_TYPE_VTECH) || (kbd->type == KBD_TYPE_FE2010)) {
|
||||
/* DIP switch readout: bit set = OFF, clear = ON. */
|
||||
if (kbd->type == KBD_TYPE_OLIVETTI)
|
||||
/* Olivetti M19
|
||||
@@ -1057,7 +1078,7 @@ kbd_init(const device_t *info)
|
||||
/* Switches 3, 4 - memory size. */
|
||||
if ((kbd->type == KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_XTCLONE) ||
|
||||
(kbd->type == KBD_TYPE_HYUNDAI) || (kbd->type == KBD_TYPE_COMPAQ) ||
|
||||
(kbd->type == KBD_TYPE_TOSHIBA)) {
|
||||
(kbd->type == KBD_TYPE_TOSHIBA) || (kbd->type == KBD_TYPE_FE2010)) {
|
||||
switch (mem_size) {
|
||||
case 256:
|
||||
kbd->pd |= 0x00;
|
||||
@@ -1356,7 +1377,7 @@ const device_t keyboard_xt_zenith_device = {
|
||||
|
||||
const device_t keyboard_xt_hyundai_device = {
|
||||
.name = "Hyundai XT Keyboard",
|
||||
.internal_name = "keyboard_x_hyundai",
|
||||
.internal_name = "keyboard_xt_hyundai",
|
||||
.flags = 0,
|
||||
.local = KBD_TYPE_HYUNDAI,
|
||||
.init = kbd_init,
|
||||
@@ -1368,6 +1389,20 @@ const device_t keyboard_xt_hyundai_device = {
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t keyboard_xt_fe2010_device = {
|
||||
.name = "Faraday FE2010 XT Keyboard",
|
||||
.internal_name = "keyboard_xt_fe2010",
|
||||
.flags = 0,
|
||||
.local = KBD_TYPE_FE2010,
|
||||
.init = kbd_init,
|
||||
.close = kbd_close,
|
||||
.reset = kbd_reset,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t keyboard_xtclone_device = {
|
||||
.name = "XT (Clone) Keyboard",
|
||||
.internal_name = "keyboard_xtclone",
|
||||
|
||||
@@ -109,7 +109,7 @@ static const device_config_t keycard_config[] = {
|
||||
};
|
||||
|
||||
const device_t novell_keycard_device = {
|
||||
.name = "Novell Netware 2.x Key Card",
|
||||
.name = "Novell NetWare 2.x Key Card",
|
||||
.internal_name = "mssystems",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
|
||||
@@ -183,7 +183,7 @@ static const device_config_t monster_fdc_config[] = {
|
||||
#if 0
|
||||
{
|
||||
.name = "bios_size",
|
||||
.description = "BIOS Size:",
|
||||
.description = "BIOS size",
|
||||
.type = CONFIG_HEX20,
|
||||
.default_string = NULL,
|
||||
.default_int = 32,
|
||||
|
||||
@@ -177,6 +177,8 @@ extern char usr_path[1024]; /* path (dir) of user data */
|
||||
extern char cfg_path[1024]; /* full path of config file */
|
||||
extern int open_dir_usr_path; /* default file open dialog directory of usr_path */
|
||||
extern char uuid[MAX_UUID_LEN]; /* UUID or machine identifier */
|
||||
extern char vmm_path[1024]; /* VM Manager path to scan (temporary) */
|
||||
extern int vmm_enabled;
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
extern FILE *stdlog; /* file to log output to */
|
||||
#endif
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#define EMU_CHIPSET_H
|
||||
|
||||
/* ACC */
|
||||
extern const device_t acc2036_device;
|
||||
extern const device_t acc2168_device;
|
||||
|
||||
/* ALi */
|
||||
@@ -123,7 +124,9 @@ extern const device_t opti381_device;
|
||||
extern const device_t opti391_device;
|
||||
extern const device_t opti481_device;
|
||||
extern const device_t opti493_device;
|
||||
extern const device_t opti495_device;
|
||||
extern const device_t opti495slc_device;
|
||||
extern const device_t opti495sx_device;
|
||||
extern const device_t opti498_device;
|
||||
extern const device_t opti499_device;
|
||||
extern const device_t opti601_device;
|
||||
extern const device_t opti602_device;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#ifndef EMU_FLASH_H
|
||||
#define EMU_FLASH_H
|
||||
|
||||
extern const device_t amd_am28f010_flash_device;
|
||||
extern const device_t catalyst_flash_device;
|
||||
|
||||
extern const device_t intel_flash_bxt_ami_device;
|
||||
|
||||
@@ -228,6 +228,7 @@ extern const device_t keyboard_xt_lxt3_device;
|
||||
extern const device_t keyboard_xt_olivetti_device;
|
||||
extern const device_t keyboard_xt_zenith_device;
|
||||
extern const device_t keyboard_xt_hyundai_device;
|
||||
extern const device_t keyboard_xt_fe2010_device;
|
||||
extern const device_t keyboard_xtclone_device;
|
||||
extern const device_t keyboard_at_device;
|
||||
extern const device_t keyboard_at_ami_device;
|
||||
|
||||
74
src/include/86box/m_pcjr.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Header files for the PCjr keyboard and video subsystems.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Connor Hyde, <mario64crashed@gmail.com>
|
||||
*
|
||||
* Copyright 2025 starfrost
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define PCJR_RGB 0
|
||||
#define PCJR_COMPOSITE 1
|
||||
#define PCJR_RGB_NO_BROWN 4
|
||||
#define PCJR_RGB_IBM_5153 5
|
||||
|
||||
typedef struct pcjr_s
|
||||
{
|
||||
/* Video Controller stuff. */
|
||||
mem_mapping_t mapping;
|
||||
uint8_t crtc[32];
|
||||
int crtcreg;
|
||||
int array_index;
|
||||
uint8_t array[32];
|
||||
int array_ff;
|
||||
int memctrl;
|
||||
uint8_t status;
|
||||
int addr_mode;
|
||||
uint8_t *vram;
|
||||
uint8_t *b8000;
|
||||
int linepos;
|
||||
int displine;
|
||||
int scanline;
|
||||
int vc;
|
||||
int dispon;
|
||||
int cursorvisible; // Is the cursor visible on the current scanline?
|
||||
int cursoron;
|
||||
int blink;
|
||||
int vsynctime;
|
||||
int fullchange;
|
||||
int vadj;
|
||||
uint16_t memaddr;
|
||||
uint16_t memaddr_backup;
|
||||
uint64_t dispontime;
|
||||
uint64_t dispofftime;
|
||||
pc_timer_t timer;
|
||||
int firstline;
|
||||
int lastline;
|
||||
int composite;
|
||||
int apply_hd;
|
||||
|
||||
/* Keyboard Controller stuff. */
|
||||
int latched;
|
||||
int data;
|
||||
int serial_data[44];
|
||||
int serial_pos;
|
||||
uint8_t pa;
|
||||
uint8_t pb;
|
||||
pc_timer_t send_delay_timer;
|
||||
|
||||
} pcjr_t;
|
||||
|
||||
void pcjr_recalc_timings(pcjr_t *pcjr);
|
||||
|
||||
// Note: This is a temporary solution until the pcjr video is made its own gfx card
|
||||
void pcjr_vid_init(pcjr_t *pcjr);
|
||||
95
src/include/86box/m_tandy.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Header files for the Tandy keyboard and video subsystems.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Connor Hyde, <mario64crashed@gmail.com>
|
||||
*
|
||||
* Copyright 2025 starfrost
|
||||
*/
|
||||
|
||||
typedef struct t1kvid_t {
|
||||
mem_mapping_t mapping;
|
||||
mem_mapping_t vram_mapping;
|
||||
|
||||
uint8_t crtc[32];
|
||||
int crtcreg;
|
||||
|
||||
int array_index;
|
||||
uint8_t array[256];
|
||||
int memctrl;
|
||||
uint8_t mode;
|
||||
uint8_t col;
|
||||
uint8_t status;
|
||||
|
||||
uint8_t *vram;
|
||||
uint8_t *b8000;
|
||||
uint32_t b8000_mask;
|
||||
uint32_t b8000_limit;
|
||||
uint8_t planar_ctrl;
|
||||
uint8_t lp_strobe;
|
||||
|
||||
int linepos;
|
||||
int displine;
|
||||
int scanline;
|
||||
int vc;
|
||||
int dispon;
|
||||
int cursorvisible;
|
||||
int cursoron;
|
||||
int blink;
|
||||
int fullchange;
|
||||
int vsynctime;
|
||||
int vadj;
|
||||
uint16_t memaddr;
|
||||
uint16_t memaddr_backup;
|
||||
|
||||
uint64_t dispontime;
|
||||
uint64_t dispofftime;
|
||||
pc_timer_t timer;
|
||||
int firstline;
|
||||
int lastline;
|
||||
|
||||
int composite;
|
||||
} t1kvid_t;
|
||||
|
||||
typedef struct t1keep_t {
|
||||
char *path;
|
||||
|
||||
int state;
|
||||
int count;
|
||||
int addr;
|
||||
int clk;
|
||||
uint16_t data;
|
||||
uint16_t store[64];
|
||||
} t1keep_t;
|
||||
|
||||
typedef struct tandy_t {
|
||||
mem_mapping_t ram_mapping;
|
||||
mem_mapping_t rom_mapping; /* SL2 */
|
||||
|
||||
uint8_t *rom; /* SL2 */
|
||||
uint8_t ram_bank;
|
||||
uint8_t rom_bank; /* SL2 */
|
||||
int rom_offset; /* SL2 */
|
||||
|
||||
uint32_t base;
|
||||
uint32_t mask;
|
||||
int is_hx;
|
||||
int is_sl2;
|
||||
|
||||
t1kvid_t *vid;
|
||||
} tandy_t;
|
||||
|
||||
void tandy_vid_init(tandy_t* dev);
|
||||
uint8_t tandy_vid_in(uint16_t addr, void* priv);
|
||||
void tandy_vid_out(uint16_t addr, uint8_t val, void *priv);
|
||||
|
||||
void tandy_vid_close(void* priv);
|
||||
void tandy_recalc_address_sl(tandy_t* dev); //this function is needed by both m_ and vid_tandy.c
|
||||
@@ -197,6 +197,7 @@ enum {
|
||||
MACHINE_CHIPSET_GC100A,
|
||||
MACHINE_CHIPSET_GC103,
|
||||
MACHINE_CHIPSET_HT18,
|
||||
MACHINE_CHIPSET_ACC_2036,
|
||||
MACHINE_CHIPSET_ACC_2168,
|
||||
MACHINE_CHIPSET_ALI_M1217,
|
||||
MACHINE_CHIPSET_ALI_M6117,
|
||||
@@ -240,7 +241,9 @@ enum {
|
||||
MACHINE_CHIPSET_OPTI_391,
|
||||
MACHINE_CHIPSET_OPTI_481,
|
||||
MACHINE_CHIPSET_OPTI_493,
|
||||
MACHINE_CHIPSET_OPTI_495,
|
||||
MACHINE_CHIPSET_OPTI_495SLC,
|
||||
MACHINE_CHIPSET_OPTI_495SX,
|
||||
MACHINE_CHIPSET_OPTI_498,
|
||||
MACHINE_CHIPSET_OPTI_499,
|
||||
MACHINE_CHIPSET_OPTI_895_802G,
|
||||
MACHINE_CHIPSET_OPTI_547_597,
|
||||
@@ -456,6 +459,7 @@ extern int machine_at_px286_init(const machine_t *);
|
||||
extern int machine_at_quadt286_init(const machine_t *);
|
||||
extern int machine_at_mr286_init(const machine_t *);
|
||||
|
||||
extern int machine_at_pbl300sx_init(const machine_t *);
|
||||
extern int machine_at_neat_init(const machine_t *);
|
||||
extern int machine_at_neat_ami_init(const machine_t *);
|
||||
extern int machine_at_ataripc4_init(const machine_t *);
|
||||
@@ -475,6 +479,7 @@ 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_at122_init(const machine_t *);
|
||||
extern int machine_at_tuliptc7_init(const machine_t *);
|
||||
|
||||
extern int machine_at_pc8_init(const machine_t *);
|
||||
@@ -544,6 +549,7 @@ extern int machine_at_winbios1429_init(const machine_t *);
|
||||
extern int machine_at_opti495_init(const machine_t *);
|
||||
extern int machine_at_opti495_ami_init(const machine_t *);
|
||||
extern int machine_at_opti495_mr_init(const machine_t *);
|
||||
extern int machine_at_c747_init(const machine_t *);
|
||||
extern int machine_at_exp4349_init(const machine_t *);
|
||||
|
||||
extern int machine_at_vect486vl_init(const machine_t *);
|
||||
@@ -564,6 +570,7 @@ extern int machine_at_dtk461_init(const machine_t *);
|
||||
extern int machine_at_sis401_init(const machine_t *);
|
||||
extern int machine_at_isa486_init(const machine_t *);
|
||||
extern int machine_at_av4_init(const machine_t *);
|
||||
extern int machine_at_advantage40xxd_init(const machine_t *);
|
||||
extern int machine_at_valuepoint433_init(const machine_t *);
|
||||
|
||||
extern int machine_at_vli486sv2g_init(const machine_t *);
|
||||
@@ -973,6 +980,7 @@ extern int machine_xt_kaypropc_init(const machine_t *);
|
||||
extern int machine_xt_sansx16_init(const machine_t *);
|
||||
extern int machine_xt_bw230_init(const machine_t *);
|
||||
extern int machine_xt_pb8810_init(const machine_t *);
|
||||
extern int machine_xt_tuliptc8_init(const machine_t *);
|
||||
|
||||
extern int machine_xt_v20xt_init(const machine_t *);
|
||||
|
||||
|
||||
@@ -125,6 +125,10 @@ extern const device_t sio_detect_device;
|
||||
#endif /* USE_SIO_DETECT */
|
||||
|
||||
/* UMC */
|
||||
extern const device_t um82c862f_device;
|
||||
extern const device_t um82c862f_ide_device;
|
||||
extern const device_t um82c863f_device;
|
||||
extern const device_t um82c863f_ide_device;
|
||||
extern const device_t um8663af_device;
|
||||
extern const device_t um8663af_ide_device;
|
||||
extern const device_t um8663af_sec_device;
|
||||
|
||||
@@ -80,7 +80,7 @@ typedef struct ibm8514_t {
|
||||
uint32_t vram_mask;
|
||||
uint32_t pallook[512];
|
||||
uint32_t bios_addr;
|
||||
uint32_t ma_latch;
|
||||
uint32_t memaddr_latch;
|
||||
|
||||
PALETTE vgapal;
|
||||
uint8_t hwcursor_oddeven;
|
||||
@@ -220,8 +220,8 @@ typedef struct ibm8514_t {
|
||||
int lastline_draw;
|
||||
int displine;
|
||||
int fullchange;
|
||||
uint32_t ma;
|
||||
uint32_t maback;
|
||||
uint32_t memaddr;
|
||||
uint32_t memaddr_backup;
|
||||
|
||||
uint8_t *vram;
|
||||
uint8_t *changedvram;
|
||||
@@ -236,7 +236,7 @@ typedef struct ibm8514_t {
|
||||
int hdisp;
|
||||
int hdisp2;
|
||||
int hdisped;
|
||||
int sc;
|
||||
int scanline;
|
||||
int vsyncstart;
|
||||
int vsyncwidth;
|
||||
int vtotal;
|
||||
|
||||
@@ -137,6 +137,7 @@ typedef struct mach_t {
|
||||
int16_t dx_end;
|
||||
int16_t dy;
|
||||
int16_t dy_end;
|
||||
int16_t dx_first_row_start;
|
||||
int16_t dx_start;
|
||||
int16_t dy_start;
|
||||
int16_t cy;
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>,
|
||||
* Connor Hyde / starfrost, <mario64crashed@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
@@ -56,6 +57,7 @@ typedef enum cga_crtc_registers_e
|
||||
CGA_CRTC_LIGHT_PEN_ADDR_LOW = 0x11, // Light pen address low 8 bits (not currently supported)
|
||||
} cga_crtc_registers;
|
||||
|
||||
// Registers for the CGA
|
||||
typedef enum cga_registers_e
|
||||
{
|
||||
CGA_REGISTER_CRTC_INDEX = 0x3D4,
|
||||
@@ -85,16 +87,16 @@ typedef struct cga_t {
|
||||
int fontbase;
|
||||
int linepos;
|
||||
int displine;
|
||||
int sc;
|
||||
int scanline;
|
||||
int vc;
|
||||
int cgadispon;
|
||||
int con;
|
||||
int cursorvisible; // Determines if the cursor is visible FOR THE CURRENT SCANLINE.
|
||||
int cursoron;
|
||||
int cgablink;
|
||||
int vsynctime;
|
||||
int vadj;
|
||||
uint16_t ma;
|
||||
uint16_t maback;
|
||||
uint16_t memaddr;
|
||||
uint16_t memaddr_backup;
|
||||
int oddeven;
|
||||
|
||||
uint64_t dispontime;
|
||||
|
||||
@@ -39,7 +39,7 @@ typedef struct ega_t {
|
||||
uint8_t lb;
|
||||
uint8_t lc;
|
||||
uint8_t ld;
|
||||
uint8_t stat;
|
||||
uint8_t status;
|
||||
uint8_t colourcompare;
|
||||
uint8_t colournocare;
|
||||
uint8_t scrblank;
|
||||
@@ -68,12 +68,12 @@ typedef struct ega_t {
|
||||
int chain4;
|
||||
int chain2_read;
|
||||
int chain2_write;
|
||||
int con;
|
||||
int cursorvisible;
|
||||
int oddeven_page;
|
||||
int oddeven_chain;
|
||||
int vc;
|
||||
int real_vc;
|
||||
int sc;
|
||||
int scanline;
|
||||
int dispon;
|
||||
int hdisp_on;
|
||||
int cursoron;
|
||||
@@ -115,14 +115,14 @@ typedef struct ega_t {
|
||||
int chipset;
|
||||
int mono_display;
|
||||
|
||||
int mdacols[256][2][2];
|
||||
int mda_attr_to_color_table[256][2][2];
|
||||
|
||||
uint32_t charseta;
|
||||
uint32_t charsetb;
|
||||
uint32_t ma_latch;
|
||||
uint32_t ma;
|
||||
uint32_t maback;
|
||||
uint32_t ca;
|
||||
uint32_t memaddr_latch;
|
||||
uint32_t memaddr;
|
||||
uint32_t memaddr_backup;
|
||||
uint32_t cursoraddr;
|
||||
uint32_t vram_limit;
|
||||
uint32_t overscan_color;
|
||||
uint32_t cca;
|
||||
@@ -189,11 +189,11 @@ extern void ega_set_type(void *priv, uint32_t local);
|
||||
extern int firstline_draw;
|
||||
extern int lastline_draw;
|
||||
extern int displine;
|
||||
extern int sc;
|
||||
extern int scanline;
|
||||
|
||||
extern uint32_t ma;
|
||||
extern uint32_t ca;
|
||||
extern int con;
|
||||
extern uint32_t memaddr;
|
||||
extern uint32_t cursoraddr;
|
||||
extern int cursorvisible;
|
||||
extern int cursoron;
|
||||
extern int cgablink;
|
||||
|
||||
|
||||
@@ -33,9 +33,9 @@
|
||||
} \
|
||||
\
|
||||
if (nr & VAR_ROW0_MA13) \
|
||||
out_addr = (out_addr & ~0x8000) | ((ega->sc & 1) ? 0x8000 : 0); \
|
||||
out_addr = (out_addr & ~0x8000) | ((ega->scanline & 1) ? 0x8000 : 0); \
|
||||
if (nr & VAR_ROW1_MA14) \
|
||||
out_addr = (out_addr & ~0x10000) | ((ega->sc & 2) ? 0x10000 : 0); \
|
||||
out_addr = (out_addr & ~0x10000) | ((ega->scanline & 2) ? 0x10000 : 0); \
|
||||
\
|
||||
return out_addr; \
|
||||
}
|
||||
|
||||
@@ -13,10 +13,12 @@
|
||||
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Jasmine Iwanek, <jriwanek@gmail.com>
|
||||
*
|
||||
* Connor Hyde / starfrost, <mario64crashed@gmail.com
|
||||
*
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
* Copyright 2021 Jasmine Iwanek.
|
||||
* Copyright 2025 starfrost
|
||||
*/
|
||||
|
||||
#ifndef VIDEO_HERCULES_H
|
||||
@@ -31,7 +33,7 @@ typedef struct {
|
||||
|
||||
uint8_t ctrl;
|
||||
uint8_t ctrl2;
|
||||
uint8_t stat;
|
||||
uint8_t status;
|
||||
|
||||
uint64_t dispontime;
|
||||
uint64_t dispofftime;
|
||||
@@ -43,20 +45,20 @@ typedef struct {
|
||||
int linepos;
|
||||
int displine;
|
||||
int vc;
|
||||
int sc;
|
||||
uint16_t ma;
|
||||
uint16_t maback;
|
||||
int con;
|
||||
int scanline;
|
||||
uint16_t memaddr;
|
||||
uint16_t memaddr_backup;
|
||||
int cursorvisible;
|
||||
int cursoron;
|
||||
int dispon;
|
||||
int blink;
|
||||
int vsynctime;
|
||||
int vadj;
|
||||
|
||||
int lp_ff;
|
||||
int fullchange;
|
||||
int lp_ff;
|
||||
int fullchange;
|
||||
|
||||
int cols[256][2][2];
|
||||
int cols[256][2][2];
|
||||
|
||||
uint8_t *vram;
|
||||
int monitor_index;
|
||||
|
||||
@@ -1,41 +1,123 @@
|
||||
/* 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 Monochrome Display and Printer card.
|
||||
*
|
||||
* Authors: Sarah Walker, starfrost
|
||||
*
|
||||
* Copyright 2007-2024 Sarah Walker
|
||||
* Copyright 2025 Connor Hyde / starfrost, <mario64crashed@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef VIDEO_MDA_H
|
||||
#define VIDEO_MDA_H
|
||||
|
||||
// Defines
|
||||
#define MDA_CRTC_NUM_REGISTERS 32
|
||||
|
||||
// Enums & structures
|
||||
|
||||
typedef enum mda_registers_e
|
||||
{
|
||||
MDA_REGISTER_START = 0x3B0,
|
||||
|
||||
MDA_REGISTER_CRTC_INDEX = 0x3B4,
|
||||
MDA_REGISTER_CRTC_DATA = 0x3B5,
|
||||
MDA_REGISTER_MODE_CONTROL = 0x3B8,
|
||||
MDA_REGISTER_CRT_STATUS = 0x3BA,
|
||||
MDA_REGISTER_PARALLEL_DATA = 0x3BC,
|
||||
MDA_REGISTER_PRINTER_STATUS = 0x3BD,
|
||||
MDA_REGISTER_PRINTER_CONTROL = 0x3BE,
|
||||
|
||||
MDA_REGISTER_END = 0x3BF,
|
||||
} mda_registers;
|
||||
|
||||
// Motorola MC6845 CRTC registers (without light pen for some reason)
|
||||
typedef enum mda_crtc_registers_e
|
||||
{
|
||||
MDA_CRTC_HTOTAL = 0x0, // Horizontal total (total number of characters incl. hsync)
|
||||
MDA_CRTC_HDISP = 0x1, // Horizontal display
|
||||
MDA_CRTC_HSYNC_POS = 0x2, // Horizontal position of horizontal ysnc
|
||||
MDA_CRTC_HSYNC_WIDTH = 0x3, // Width of horizontal sync
|
||||
MDA_CRTC_VTOTAL = 0x4, // Vertical total (total number of scanlines incl. vsync)
|
||||
MDA_CRTC_VTOTAL_ADJUST = 0x5, // Vertical total adjust value
|
||||
MDA_CRTC_VDISP = 0x6, // Vertical display (total number of displayed scanline)
|
||||
MDA_CRTC_VSYNC = 0x7, // Vertical sync scanline number
|
||||
MDA_CRTC_INTERLACE = 0x8, // Interlacing mode
|
||||
MDA_CRTC_MAX_SCANLINE_ADDR = 0x9, // Maximum scanline address
|
||||
MDA_CRTC_CURSOR_START = 0xA, // Cursor start scanline
|
||||
MDA_CRTC_CURSOR_END = 0xB, // Cursor end scanline
|
||||
MDA_CRTC_START_ADDR_HIGH = 0xC, // Screen start address high 8 bits
|
||||
MDA_CRTC_START_ADDR_LOW = 0xD, // Screen start address low 8 bits
|
||||
MDA_CRTC_CURSOR_ADDR_HIGH = 0xE, // Cursor address high 8 bits
|
||||
MDA_CRTC_CURSOR_ADDR_LOW = 0xF, // Cursor address low 8 bits
|
||||
} mda_crtc_registers;
|
||||
|
||||
typedef enum mda_mode_flags_e
|
||||
{
|
||||
MDA_MODE_HIGHRES = 1 << 0, // MUST be enabled for sane operation
|
||||
MDA_MODE_BW = 1 << 1, // UNUSED in most cases. Not present on Hercules
|
||||
MDA_MODE_VIDEO_ENABLE = 1 << 3,
|
||||
MDA_MODE_BLINK = 1 << 5,
|
||||
} mda_mode_flags;
|
||||
|
||||
typedef enum mda_colors_e
|
||||
{
|
||||
MDA_COLOR_BLACK = 0,
|
||||
MDA_COLOR_BLUE = 1,
|
||||
MDA_COLOR_GREEN = 2,
|
||||
MDA_COLOR_CYAN = 3,
|
||||
MDA_COLOR_RED = 4,
|
||||
MDA_COLOR_MAGENTA = 5,
|
||||
MDA_COLOR_BROWN = 6,
|
||||
MDA_COLOR_WHITE = 7,
|
||||
MDA_COLOR_GREY = 8,
|
||||
MDA_COLOR_BRIGHT_BLUE = 9,
|
||||
MDA_COLOR_BRIGHT_GREEN = 10,
|
||||
MDA_COLOR_BRIGHT_CYAN = 11,
|
||||
MDA_COLOR_BRIGHT_RED = 12,
|
||||
MDA_COLOR_BRIGHT_MAGENTA = 13,
|
||||
MDA_COLOR_BRIGHT_YELLOW = 14,
|
||||
MDA_COLOR_BRIGHT_WHITE = 15,
|
||||
} mda_colors;
|
||||
|
||||
typedef struct mda_t {
|
||||
mem_mapping_t mapping;
|
||||
|
||||
uint8_t crtc[32];
|
||||
int crtcreg;
|
||||
uint8_t crtc[MDA_CRTC_NUM_REGISTERS];
|
||||
int32_t crtcreg;
|
||||
|
||||
uint8_t ctrl;
|
||||
uint8_t stat;
|
||||
uint8_t mode;
|
||||
uint8_t status;
|
||||
|
||||
uint64_t dispontime;
|
||||
uint64_t dispofftime;
|
||||
pc_timer_t timer;
|
||||
uint64_t dispontime;
|
||||
uint64_t dispofftime;
|
||||
pc_timer_t timer;
|
||||
|
||||
int firstline;
|
||||
int lastline;
|
||||
int32_t firstline;
|
||||
int32_t lastline;
|
||||
|
||||
int fontbase;
|
||||
int linepos;
|
||||
int displine;
|
||||
int vc;
|
||||
int sc;
|
||||
uint16_t ma;
|
||||
uint16_t maback;
|
||||
int con;
|
||||
int cursoron;
|
||||
int dispon;
|
||||
int blink;
|
||||
int vsynctime;
|
||||
int vadj;
|
||||
int monitor_index;
|
||||
int prev_monitor_index;
|
||||
int32_t fontbase;
|
||||
int32_t linepos;
|
||||
int32_t displine;
|
||||
int32_t vc;
|
||||
int32_t scanline;
|
||||
uint16_t memaddr;
|
||||
uint16_t memaddr_backup;
|
||||
int32_t cursorvisible;
|
||||
int32_t cursoron;
|
||||
int32_t dispon;
|
||||
int32_t blink;
|
||||
int32_t vsynctime;
|
||||
int32_t vadj;
|
||||
int32_t monitor_index;
|
||||
int32_t prev_monitor_index;
|
||||
int32_t monitor_type; // Used for MDA Colour support (REV0 u64)
|
||||
|
||||
uint8_t *vram;
|
||||
} mda_t;
|
||||
|
||||
@@ -115,13 +115,13 @@ typedef struct pgc {
|
||||
int displine;
|
||||
int vc;
|
||||
int cgadispon;
|
||||
int con;
|
||||
int cursorvisible;
|
||||
int cursoron;
|
||||
int cgablink;
|
||||
int vsynctime;
|
||||
int vadj;
|
||||
uint16_t ma;
|
||||
uint16_t maback;
|
||||
uint16_t memaddr;
|
||||
uint16_t memaddr_backup;
|
||||
int oddeven;
|
||||
|
||||
uint64_t dispontime;
|
||||
|
||||
@@ -100,12 +100,12 @@ typedef struct svga_t {
|
||||
int dispon;
|
||||
int hdisp_on;
|
||||
int vc;
|
||||
int sc;
|
||||
int scanline;
|
||||
int linepos;
|
||||
int vslines;
|
||||
int linecountff;
|
||||
int oddeven;
|
||||
int con;
|
||||
int cursorvisible;
|
||||
int cursoron;
|
||||
int blink;
|
||||
int scrollcache;
|
||||
@@ -152,15 +152,15 @@ typedef struct svga_t {
|
||||
uint32_t charseta;
|
||||
uint32_t charsetb;
|
||||
uint32_t adv_flags;
|
||||
uint32_t ma_latch;
|
||||
uint32_t memaddr_latch;
|
||||
uint32_t ca_adj;
|
||||
uint32_t ma;
|
||||
uint32_t maback;
|
||||
uint32_t memaddr;
|
||||
uint32_t memaddr_backup;
|
||||
uint32_t write_bank;
|
||||
uint32_t read_bank;
|
||||
uint32_t extra_banks[2];
|
||||
uint32_t banked_mask;
|
||||
uint32_t ca;
|
||||
uint32_t cursoraddr;
|
||||
uint32_t overscan_color;
|
||||
uint32_t *map8;
|
||||
uint32_t pallook[512];
|
||||
|
||||
@@ -23,11 +23,11 @@
|
||||
extern int firstline_draw;
|
||||
extern int lastline_draw;
|
||||
extern int displine;
|
||||
extern int sc;
|
||||
extern int scanline;
|
||||
|
||||
extern uint32_t ma;
|
||||
extern uint32_t ca;
|
||||
extern int con;
|
||||
extern uint32_t memaddr;
|
||||
extern uint32_t cursoraddr;
|
||||
extern int cursorvisible;
|
||||
extern int cursoron;
|
||||
extern int cgablink;
|
||||
|
||||
|
||||
@@ -47,9 +47,9 @@
|
||||
} \
|
||||
\
|
||||
if (nr & VAR_ROW0_MA13) \
|
||||
out_addr = (out_addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); \
|
||||
out_addr = (out_addr & ~0x8000) | ((svga->scanline & 1) ? 0x8000 : 0); \
|
||||
if (nr & VAR_ROW1_MA14) \
|
||||
out_addr = (out_addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); \
|
||||
out_addr = (out_addr & ~0x10000) | ((svga->scanline & 2) ? 0x10000 : 0); \
|
||||
\
|
||||
return out_addr; \
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ typedef struct xga_t {
|
||||
int dispon;
|
||||
int h_disp_on;
|
||||
int vc;
|
||||
int sc;
|
||||
int scanline;
|
||||
int linepos;
|
||||
int oddeven;
|
||||
int firstline;
|
||||
@@ -160,12 +160,12 @@ typedef struct xga_t {
|
||||
uint32_t hwc_color0;
|
||||
uint32_t hwc_color1;
|
||||
uint32_t disp_start_addr;
|
||||
uint32_t ma_latch;
|
||||
uint32_t memaddr_latch;
|
||||
uint32_t vram_size;
|
||||
uint32_t vram_mask;
|
||||
uint32_t rom_addr;
|
||||
uint32_t ma;
|
||||
uint32_t maback;
|
||||
uint32_t memaddr;
|
||||
uint32_t memaddr_backup;
|
||||
uint32_t read_bank;
|
||||
uint32_t write_bank;
|
||||
uint32_t px_map_base;
|
||||
|
||||
@@ -75,6 +75,7 @@ enum {
|
||||
#define FONT_IBM_MDA_437_NORDIC_PATH "roms/video/mda/4733197.bin"
|
||||
#define FONT_KAM_PATH "roms/video/mda/kam.bin"
|
||||
#define FONT_KAMCL16_PATH "roms/video/mda/kamcl16.bin"
|
||||
#define FONT_TULIP_DGA_PATH "roms/video/mda/tulip-dga-bios.bin"
|
||||
|
||||
typedef struct video_timings_t {
|
||||
int type;
|
||||
@@ -187,6 +188,10 @@ extern bitmap_t *buffer32;
|
||||
#define efscrnsz_y (monitors[monitor_index_global].mon_efscrnsz_y)
|
||||
#define unscaled_size_x (monitors[monitor_index_global].mon_unscaled_size_x)
|
||||
#define unscaled_size_y (monitors[monitor_index_global].mon_unscaled_size_y)
|
||||
|
||||
#define CGAPAL_CGA_START 16 // Where the 16-color cga text/composite starts
|
||||
|
||||
|
||||
extern PALETTE cgapal;
|
||||
extern PALETTE cgapal_mono[6];
|
||||
#if 0
|
||||
@@ -359,6 +364,7 @@ extern const device_t gd5420_isa_device;
|
||||
extern const device_t gd5420_onboard_device;
|
||||
extern const device_t gd5422_isa_device;
|
||||
extern const device_t gd5424_vlb_device;
|
||||
extern const device_t gd5424_onboard_device;
|
||||
extern const device_t gd5426_isa_device;
|
||||
extern const device_t gd5426_diamond_speedstar_pro_a1_isa_device;
|
||||
extern const device_t gd5426_vlb_device;
|
||||
@@ -395,6 +401,7 @@ extern const device_t gd5480_pci_device;
|
||||
/* Compaq CGA */
|
||||
extern const device_t compaq_cga_device;
|
||||
extern const device_t compaq_cga_2_device;
|
||||
extern const device_t compaq_plasma_device;
|
||||
|
||||
/* Olivetti OGC */
|
||||
extern const device_t ogc_device;
|
||||
@@ -467,6 +474,7 @@ extern const device_t if386jega_device;
|
||||
|
||||
/* Oak OTI-0x7 */
|
||||
extern const device_t oti037c_device;
|
||||
extern const device_t oti037_pbl300sx_device;
|
||||
extern const device_t oti067_device;
|
||||
extern const device_t oti067_acer386_device;
|
||||
extern const device_t oti067_ama932j_device;
|
||||
@@ -613,6 +621,11 @@ extern const device_t nv3t_device_agp;
|
||||
/* Wyse 700 */
|
||||
extern const device_t wy700_device;
|
||||
|
||||
/* Tandy */
|
||||
extern const device_t tandy_1000_video_device;
|
||||
extern const device_t tandy_1000hx_video_device;
|
||||
extern const device_t tandy_1000sl_video_device;
|
||||
|
||||
#endif
|
||||
|
||||
#endif /*EMU_VIDEO_H*/
|
||||
|
||||
@@ -23,7 +23,6 @@ add_library(mch OBJECT
|
||||
m_xt_laserxt.c
|
||||
m_xt_philips.c
|
||||
m_xt_t1000.c
|
||||
m_xt_t1000_vid.c
|
||||
m_xt_xi8088.c
|
||||
m_xt_zenith.c
|
||||
m_pcjr.c
|
||||
@@ -37,7 +36,6 @@ add_library(mch OBJECT
|
||||
m_at_commodore.c
|
||||
m_at_grid.c
|
||||
m_at_t3100e.c
|
||||
m_at_t3100e_vid.c
|
||||
m_ps1.c
|
||||
m_ps1_hdc.c
|
||||
m_ps2_isa.c
|
||||
|
||||
@@ -105,7 +105,7 @@ typedef struct amsvid_t {
|
||||
int cga_enabled; /* 1640 */
|
||||
uint8_t cgacol;
|
||||
uint8_t cgamode;
|
||||
uint8_t stat;
|
||||
uint8_t status;
|
||||
uint8_t plane_write; /* 1512/200 */
|
||||
uint8_t plane_read; /* 1512/200 */
|
||||
uint8_t border; /* 1512/200 */
|
||||
@@ -113,17 +113,17 @@ typedef struct amsvid_t {
|
||||
int fontbase; /* 1512/200 */
|
||||
int linepos;
|
||||
int displine;
|
||||
int sc;
|
||||
int scanline;
|
||||
int vc;
|
||||
int cgadispon;
|
||||
int con;
|
||||
int cursorvisible;
|
||||
int cursoron;
|
||||
int cgablink;
|
||||
int vsynctime;
|
||||
int fullchange;
|
||||
int vadj;
|
||||
uint16_t ma;
|
||||
uint16_t maback;
|
||||
uint16_t memaddr;
|
||||
uint16_t memaddr_backup;
|
||||
int dispon;
|
||||
int blink;
|
||||
uint64_t dispontime; /* 1512/1640 */
|
||||
@@ -290,7 +290,7 @@ vid_in_1512(uint16_t addr, void *priv)
|
||||
break;
|
||||
|
||||
case 0x03da:
|
||||
ret = vid->stat;
|
||||
ret = vid->status;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -339,7 +339,7 @@ static void
|
||||
vid_poll_1512(void *priv)
|
||||
{
|
||||
amsvid_t *vid = (amsvid_t *) priv;
|
||||
uint16_t ca = (vid->crtc[15] | (vid->crtc[14] << 8)) & 0x3fff;
|
||||
uint16_t cursoraddr = (vid->crtc[15] | (vid->crtc[14] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x;
|
||||
int c;
|
||||
@@ -353,13 +353,13 @@ vid_poll_1512(void *priv)
|
||||
uint16_t dat4;
|
||||
int cols[4];
|
||||
int col;
|
||||
int oldsc;
|
||||
int scanline_old;
|
||||
|
||||
if (!vid->linepos) {
|
||||
timer_advance_u64(&vid->timer, vid->dispofftime);
|
||||
vid->stat |= 1;
|
||||
vid->status |= 1;
|
||||
vid->linepos = 1;
|
||||
oldsc = vid->sc;
|
||||
scanline_old = vid->scanline;
|
||||
if (vid->dispon) {
|
||||
if (vid->displine < vid->firstline) {
|
||||
vid->firstline = vid->displine;
|
||||
@@ -369,26 +369,26 @@ vid_poll_1512(void *priv)
|
||||
for (c = 0; c < 8; c++) {
|
||||
if ((vid->cgamode & 0x12) == 0x12) {
|
||||
buffer32->line[vid->displine << 1][c] = buffer32->line[(vid->displine << 1) + 1][c] = (vid->border & 15) + 16;
|
||||
if (vid->cgamode & 1) {
|
||||
if (vid->cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 3) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 3) + 8] = 0;
|
||||
} else {
|
||||
buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 4) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 4) + 8] = 0;
|
||||
}
|
||||
} else {
|
||||
buffer32->line[vid->displine << 1][c] = buffer32->line[(vid->displine << 1) + 1][c] = (vid->cgacol & 15) + 16;
|
||||
if (vid->cgamode & 1) {
|
||||
if (vid->cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 3) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 3) + 8] = (vid->cgacol & 15) + 16;
|
||||
} else {
|
||||
buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 4) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 4) + 8] = (vid->cgacol & 15) + 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (vid->cgamode & 1) {
|
||||
if (vid->cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
for (x = 0; x < 80; x++) {
|
||||
chr = vid->vram[(vid->ma << 1) & 0x3fff];
|
||||
attr = vid->vram[((vid->ma << 1) + 1) & 0x3fff];
|
||||
drawcursor = ((vid->ma == ca) && vid->con && vid->cursoron);
|
||||
if (vid->cgamode & 0x20) {
|
||||
chr = vid->vram[(vid->memaddr<< 1) & 0x3fff];
|
||||
attr = vid->vram[((vid->memaddr<< 1) + 1) & 0x3fff];
|
||||
drawcursor = ((vid->memaddr== cursoraddr) && vid->cursorvisible && vid->cursoron);
|
||||
if (vid->cgamode & CGA_MODE_FLAG_BLINK) {
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
if ((vid->blink & 16) && (attr & 0x80) && !drawcursor)
|
||||
@@ -399,21 +399,23 @@ vid_poll_1512(void *priv)
|
||||
}
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[vid->displine << 1][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[vid->fontbase + chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
buffer32->line[vid->displine << 1][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[vid->fontbase + chr][vid->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
}
|
||||
} else {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[vid->displine << 1][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[vid->fontbase + chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
buffer32->line[vid->displine << 1][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[vid->fontbase + chr][vid->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
vid->ma++;
|
||||
vid->memaddr++;
|
||||
}
|
||||
} else if (!(vid->cgamode & 2)) {
|
||||
} else if (!(vid->cgamode & CGA_MODE_FLAG_GRAPHICS)) {
|
||||
for (x = 0; x < 40; x++) {
|
||||
chr = vid->vram[(vid->ma << 1) & 0x3fff];
|
||||
attr = vid->vram[((vid->ma << 1) + 1) & 0x3fff];
|
||||
drawcursor = ((vid->ma == ca) && vid->con && vid->cursoron);
|
||||
if (vid->cgamode & 0x20) {
|
||||
chr = vid->vram[(vid->memaddr<< 1) & 0x3fff];
|
||||
attr = vid->vram[((vid->memaddr<< 1) + 1) & 0x3fff];
|
||||
drawcursor = ((vid->memaddr == cursoraddr)
|
||||
&& vid->cursorvisible && vid->cursoron);
|
||||
|
||||
if (vid->cgamode & CGA_MODE_FLAG_BLINK) {
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
if ((vid->blink & 16) && (attr & 0x80))
|
||||
@@ -422,21 +424,21 @@ vid_poll_1512(void *priv)
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = (attr >> 4) + 16;
|
||||
}
|
||||
vid->ma++;
|
||||
vid->memaddr++;
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[vid->fontbase + chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[vid->fontbase + chr][vid->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
}
|
||||
} else {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[vid->fontbase + chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[vid->fontbase + chr][vid->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!(vid->cgamode & 16)) {
|
||||
} else if (!(vid->cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)) {
|
||||
cols[0] = (vid->cgacol & 15) | 16;
|
||||
col = (vid->cgacol & 16) ? 24 : 16;
|
||||
if (vid->cgamode & 4) {
|
||||
if (vid->cgamode & CGA_MODE_FLAG_BW) {
|
||||
cols[1] = col | 3;
|
||||
cols[2] = col | 4;
|
||||
cols[3] = col | 7;
|
||||
@@ -450,8 +452,8 @@ vid_poll_1512(void *priv)
|
||||
cols[3] = col | 6;
|
||||
}
|
||||
for (x = 0; x < 40; x++) {
|
||||
dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000)] << 8) | vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000) + 1];
|
||||
vid->ma++;
|
||||
dat = (vid->vram[((vid->memaddr<< 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000)] << 8) | vid->vram[((vid->memaddr<< 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000) + 1];
|
||||
vid->memaddr++;
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14];
|
||||
dat <<= 2;
|
||||
@@ -459,13 +461,13 @@ vid_poll_1512(void *priv)
|
||||
}
|
||||
} else {
|
||||
for (x = 0; x < 40; x++) {
|
||||
ca = ((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000);
|
||||
dat = (vid->vram[ca] << 8) | vid->vram[ca + 1];
|
||||
dat2 = (vid->vram[ca + 0x4000] << 8) | vid->vram[ca + 0x4001];
|
||||
dat3 = (vid->vram[ca + 0x8000] << 8) | vid->vram[ca + 0x8001];
|
||||
dat4 = (vid->vram[ca + 0xc000] << 8) | vid->vram[ca + 0xc001];
|
||||
cursoraddr = ((vid->memaddr<< 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000);
|
||||
dat = (vid->vram[cursoraddr] << 8) | vid->vram[cursoraddr + 1];
|
||||
dat2 = (vid->vram[cursoraddr + 0x4000] << 8) | vid->vram[cursoraddr + 0x4001];
|
||||
dat3 = (vid->vram[cursoraddr + 0x8000] << 8) | vid->vram[cursoraddr + 0x8001];
|
||||
dat4 = (vid->vram[cursoraddr + 0xc000] << 8) | vid->vram[cursoraddr + 0xc001];
|
||||
|
||||
vid->ma++;
|
||||
vid->memaddr++;
|
||||
for (c = 0; c < 16; c++) {
|
||||
buffer32->line[vid->displine << 1][(x << 4) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + c + 8] = (((dat >> 15) | ((dat2 >> 15) << 1) | ((dat3 >> 15) << 2) | ((dat4 >> 15) << 3)) & (vid->cgacol & 15)) + 16;
|
||||
dat <<= 1;
|
||||
@@ -477,7 +479,7 @@ vid_poll_1512(void *priv)
|
||||
}
|
||||
} else {
|
||||
cols[0] = ((vid->cgamode & 0x12) == 0x12) ? 0 : (vid->cgacol & 15) + 16;
|
||||
if (vid->cgamode & 1) {
|
||||
if (vid->cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
hline(buffer32, 0, (vid->displine << 1), (vid->crtc[1] << 3) + 16, cols[0]);
|
||||
hline(buffer32, 0, (vid->displine << 1) + 1, (vid->crtc[1] << 3) + 16, cols[0]);
|
||||
} else {
|
||||
@@ -486,7 +488,7 @@ vid_poll_1512(void *priv)
|
||||
}
|
||||
}
|
||||
|
||||
if (vid->cgamode & 1)
|
||||
if (vid->cgamode & CGA_MODE_FLAG_HIGHRES)
|
||||
x = (vid->crtc[1] << 3) + 16;
|
||||
else
|
||||
x = (vid->crtc[1] << 4) + 16;
|
||||
@@ -494,9 +496,9 @@ vid_poll_1512(void *priv)
|
||||
video_process_8(x, vid->displine << 1);
|
||||
video_process_8(x, (vid->displine << 1) + 1);
|
||||
|
||||
vid->sc = oldsc;
|
||||
vid->scanline = scanline_old;
|
||||
if (vid->vsynctime)
|
||||
vid->stat |= 8;
|
||||
vid->status |= 8;
|
||||
vid->displine++;
|
||||
if (vid->displine >= 360)
|
||||
vid->displine = 0;
|
||||
@@ -505,29 +507,29 @@ vid_poll_1512(void *priv)
|
||||
if ((vid->lastline - vid->firstline) == 199)
|
||||
vid->dispon = 0; /*Amstrad PC1512 always displays 200 lines, regardless of CRTC settings*/
|
||||
if (vid->dispon)
|
||||
vid->stat &= ~1;
|
||||
vid->status &= ~1;
|
||||
vid->linepos = 0;
|
||||
if (vid->vsynctime) {
|
||||
vid->vsynctime--;
|
||||
if (!vid->vsynctime)
|
||||
vid->stat &= ~8;
|
||||
vid->status &= ~8;
|
||||
}
|
||||
if (vid->sc == (vid->crtc[11] & 31)) {
|
||||
vid->con = 0;
|
||||
if (vid->scanline == (vid->crtc[11] & 31)) {
|
||||
vid->cursorvisible = 0;
|
||||
}
|
||||
if (vid->vadj) {
|
||||
vid->sc++;
|
||||
vid->sc &= 31;
|
||||
vid->ma = vid->maback;
|
||||
vid->scanline++;
|
||||
vid->scanline &= 31;
|
||||
vid->memaddr= vid->memaddr_backup;
|
||||
vid->vadj--;
|
||||
if (!vid->vadj) {
|
||||
vid->dispon = 1;
|
||||
vid->ma = vid->maback = (vid->crtc[13] | (vid->crtc[12] << 8)) & 0x3fff;
|
||||
vid->sc = 0;
|
||||
vid->memaddr= vid->memaddr_backup = (vid->crtc[13] | (vid->crtc[12] << 8)) & 0x3fff;
|
||||
vid->scanline = 0;
|
||||
}
|
||||
} else if (vid->sc == vid->crtc[9]) {
|
||||
vid->maback = vid->ma;
|
||||
vid->sc = 0;
|
||||
} else if (vid->scanline == vid->crtc[9]) {
|
||||
vid->memaddr_backup = vid->memaddr;
|
||||
vid->scanline = 0;
|
||||
vid->vc++;
|
||||
vid->vc &= 127;
|
||||
|
||||
@@ -545,7 +547,7 @@ vid_poll_1512(void *priv)
|
||||
vid->displine = 0;
|
||||
vid->vsynctime = 46;
|
||||
|
||||
if (vid->cgamode & 1)
|
||||
if (vid->cgamode & CGA_MODE_FLAG_HIGHRES)
|
||||
x = (vid->crtc[1] << 3) + 16;
|
||||
else
|
||||
x = (vid->crtc[1] << 4) + 16;
|
||||
@@ -582,15 +584,15 @@ vid_poll_1512(void *priv)
|
||||
|
||||
video_res_x = xsize;
|
||||
video_res_y = ysize;
|
||||
if (vid->cgamode & 1) {
|
||||
if (vid->cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
video_res_x /= 8;
|
||||
video_res_y /= vid->crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(vid->cgamode & 2)) {
|
||||
} else if (!(vid->cgamode & CGA_MODE_FLAG_GRAPHICS)) {
|
||||
video_res_x /= 16;
|
||||
video_res_y /= vid->crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(vid->cgamode & 16)) {
|
||||
} else if (!(vid->cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)) {
|
||||
video_res_x /= 2;
|
||||
video_bpp = 2;
|
||||
} else {
|
||||
@@ -602,12 +604,12 @@ vid_poll_1512(void *priv)
|
||||
vid->blink++;
|
||||
}
|
||||
} else {
|
||||
vid->sc++;
|
||||
vid->sc &= 31;
|
||||
vid->ma = vid->maback;
|
||||
vid->scanline++;
|
||||
vid->scanline &= 31;
|
||||
vid->memaddr= vid->memaddr_backup;
|
||||
}
|
||||
if (vid->sc == (vid->crtc[10] & 31))
|
||||
vid->con = 1;
|
||||
if (vid->scanline == (vid->crtc[10] & 31))
|
||||
vid->cursorvisible = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1044,7 +1046,7 @@ vid_in_200(uint16_t addr, void *priv)
|
||||
|
||||
switch (addr) {
|
||||
case 0x03b8:
|
||||
return (mda->ctrl);
|
||||
return (mda->mode);
|
||||
|
||||
case 0x03d8:
|
||||
return (cga->cgamode);
|
||||
@@ -1106,9 +1108,9 @@ vid_out_200(uint16_t addr, uint8_t val, void *priv)
|
||||
}
|
||||
return;
|
||||
case 0x3b8:
|
||||
old = mda->ctrl;
|
||||
mda->ctrl = val;
|
||||
if ((mda->ctrl ^ old) & 3)
|
||||
old = mda->mode;
|
||||
mda->mode = val;
|
||||
if ((mda->mode ^ old) & 3)
|
||||
mda_recalctimings(mda);
|
||||
vid->crtc_index &= 0x1F;
|
||||
vid->crtc_index |= 0x80;
|
||||
@@ -1210,11 +1212,11 @@ vid_out_200(uint16_t addr, uint8_t val, void *priv)
|
||||
|
||||
static void
|
||||
lcd_draw_char_80(amsvid_t *vid, uint32_t *buffer, uint8_t chr,
|
||||
uint8_t attr, int drawcursor, int blink, int sc,
|
||||
uint8_t attr, int drawcursor, int blink, int scanline,
|
||||
int mode160, uint8_t control)
|
||||
{
|
||||
int c;
|
||||
uint8_t bits = fontdat[chr + vid->cga.fontbase][sc];
|
||||
uint8_t bits = fontdat[chr + vid->cga.fontbase][scanline];
|
||||
uint8_t bright = 0;
|
||||
uint16_t mask;
|
||||
|
||||
@@ -1245,10 +1247,10 @@ lcd_draw_char_80(amsvid_t *vid, uint32_t *buffer, uint8_t chr,
|
||||
|
||||
static void
|
||||
lcd_draw_char_40(amsvid_t *vid, uint32_t *buffer, uint8_t chr,
|
||||
uint8_t attr, int drawcursor, int blink, int sc,
|
||||
uint8_t attr, int drawcursor, int blink, int scanline,
|
||||
uint8_t control)
|
||||
{
|
||||
uint8_t bits = fontdat[chr + vid->cga.fontbase][sc];
|
||||
uint8_t bits = fontdat[chr + vid->cga.fontbase][scanline];
|
||||
uint8_t mask = 0x80;
|
||||
|
||||
if (attr & 8) /* bright */
|
||||
@@ -1269,91 +1271,91 @@ static void
|
||||
lcdm_poll(amsvid_t *vid)
|
||||
{
|
||||
mda_t *mda = &vid->mda;
|
||||
uint16_t ca = (mda->crtc[15] | (mda->crtc[14] << 8)) & 0x3fff;
|
||||
uint16_t cursoraddr = (mda->crtc[MDA_CRTC_CURSOR_ADDR_LOW] | (mda->crtc[MDA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x;
|
||||
int oldvc;
|
||||
uint8_t chr;
|
||||
uint8_t attr;
|
||||
int oldsc;
|
||||
int scanline_old;
|
||||
int blink;
|
||||
|
||||
if (!mda->linepos) {
|
||||
timer_advance_u64(&vid->timer, mda->dispofftime);
|
||||
mda->stat |= 1;
|
||||
mda->status |= 1;
|
||||
mda->linepos = 1;
|
||||
oldsc = mda->sc;
|
||||
if ((mda->crtc[8] & 3) == 3)
|
||||
mda->sc = (mda->sc << 1) & 7;
|
||||
scanline_old = mda->scanline;
|
||||
if ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3)
|
||||
mda->scanline = (mda->scanline << 1) & 7;
|
||||
if (mda->dispon) {
|
||||
if (mda->displine < mda->firstline)
|
||||
mda->firstline = mda->displine;
|
||||
mda->lastline = mda->displine;
|
||||
for (x = 0; x < mda->crtc[1]; x++) {
|
||||
chr = mda->vram[(mda->ma << 1) & 0xfff];
|
||||
attr = mda->vram[((mda->ma << 1) + 1) & 0xfff];
|
||||
drawcursor = ((mda->ma == ca) && mda->con && mda->cursoron);
|
||||
blink = ((mda->blink & 16) && (mda->ctrl & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
for (x = 0; x < mda->crtc[MDA_CRTC_HDISP]; x++) {
|
||||
chr = mda->vram[(mda->memaddr<< 1) & 0xfff];
|
||||
attr = mda->vram[((mda->memaddr<< 1) + 1) & 0xfff];
|
||||
drawcursor = ((mda->memaddr== cursoraddr) && mda->cursorvisible && mda->cursoron);
|
||||
blink = ((mda->blink & 16) && (mda->mode & MDA_MODE_BLINK) && (attr & 0x80) && !drawcursor);
|
||||
|
||||
lcd_draw_char_80(vid, &(buffer32->line[mda->displine])[x * 8], chr, attr, drawcursor, blink, mda->sc, 0, mda->ctrl);
|
||||
mda->ma++;
|
||||
lcd_draw_char_80(vid, &(buffer32->line[mda->displine])[x * 8], chr, attr, drawcursor, blink, mda->scanline, 0, mda->mode);
|
||||
mda->memaddr++;
|
||||
}
|
||||
}
|
||||
mda->sc = oldsc;
|
||||
if (mda->vc == mda->crtc[7] && !mda->sc)
|
||||
mda->stat |= 8;
|
||||
mda->scanline = scanline_old;
|
||||
if (mda->vc == mda->crtc[MDA_CRTC_VSYNC] && !mda->scanline)
|
||||
mda->status |= 8;
|
||||
mda->displine++;
|
||||
if (mda->displine >= 500)
|
||||
mda->displine = 0;
|
||||
} else {
|
||||
timer_advance_u64(&vid->timer, mda->dispontime);
|
||||
if (mda->dispon)
|
||||
mda->stat &= ~1;
|
||||
mda->status &= ~1;
|
||||
mda->linepos = 0;
|
||||
if (mda->vsynctime) {
|
||||
mda->vsynctime--;
|
||||
if (!mda->vsynctime)
|
||||
mda->stat &= ~8;
|
||||
mda->status &= ~8;
|
||||
}
|
||||
if (mda->sc == (mda->crtc[11] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[11] & 31) >> 1))) {
|
||||
mda->con = 0;
|
||||
if (mda->scanline == (mda->crtc[MDA_CRTC_CURSOR_END] & 31) || ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3 && mda->scanline == ((mda->crtc[MDA_CRTC_CURSOR_END] & 31) >> 1))) {
|
||||
mda->cursorvisible = 0;
|
||||
}
|
||||
if (mda->vadj) {
|
||||
mda->sc++;
|
||||
mda->sc &= 31;
|
||||
mda->ma = mda->maback;
|
||||
mda->scanline++;
|
||||
mda->scanline &= 31;
|
||||
mda->memaddr= mda->memaddr_backup;
|
||||
mda->vadj--;
|
||||
if (!mda->vadj) {
|
||||
mda->dispon = 1;
|
||||
mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff;
|
||||
mda->sc = 0;
|
||||
mda->memaddr= mda->memaddr_backup = (mda->crtc[MDA_CRTC_START_ADDR_LOW] | (mda->crtc[MDA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
mda->scanline = 0;
|
||||
}
|
||||
} else if (mda->sc == mda->crtc[9] || ((mda->crtc[8] & 3) == 3 && mda->sc == (mda->crtc[9] >> 1))) {
|
||||
mda->maback = mda->ma;
|
||||
mda->sc = 0;
|
||||
} else if (mda->scanline == mda->crtc[MDA_CRTC_MAX_SCANLINE_ADDR] || ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3 && mda->scanline == (mda->crtc[MDA_CRTC_MAX_SCANLINE_ADDR] >> 1))) {
|
||||
mda->memaddr_backup = mda->memaddr;
|
||||
mda->scanline = 0;
|
||||
oldvc = mda->vc;
|
||||
mda->vc++;
|
||||
mda->vc &= 127;
|
||||
if (mda->vc == mda->crtc[6])
|
||||
if (mda->vc == mda->crtc[MDA_CRTC_VDISP])
|
||||
mda->dispon = 0;
|
||||
if (oldvc == mda->crtc[4]) {
|
||||
if (oldvc == mda->crtc[MDA_CRTC_VTOTAL]) {
|
||||
mda->vc = 0;
|
||||
mda->vadj = mda->crtc[5];
|
||||
mda->vadj = mda->crtc[MDA_CRTC_VTOTAL_ADJUST];
|
||||
if (!mda->vadj)
|
||||
mda->dispon = 1;
|
||||
if (!mda->vadj)
|
||||
mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff;
|
||||
if ((mda->crtc[10] & 0x60) == 0x20)
|
||||
mda->memaddr= mda->memaddr_backup = (mda->crtc[MDA_CRTC_START_ADDR_LOW] | (mda->crtc[MDA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
if ((mda->crtc[MDA_CRTC_CURSOR_START] & 0x60) == 0x20)
|
||||
mda->cursoron = 0;
|
||||
else
|
||||
mda->cursoron = mda->blink & 16;
|
||||
}
|
||||
if (mda->vc == mda->crtc[7]) {
|
||||
if (mda->vc == mda->crtc[MDA_CRTC_VSYNC]) {
|
||||
mda->dispon = 0;
|
||||
mda->displine = 0;
|
||||
mda->vsynctime = 16;
|
||||
if (mda->crtc[7]) {
|
||||
x = mda->crtc[1] * 8;
|
||||
if (mda->crtc[MDA_CRTC_VSYNC]) {
|
||||
x = mda->crtc[MDA_CRTC_HDISP] * 8;
|
||||
mda->lastline++;
|
||||
if ((x != xsize) || ((mda->lastline - mda->firstline) != ysize) || video_force_resize_get()) {
|
||||
xsize = x;
|
||||
@@ -1369,8 +1371,8 @@ lcdm_poll(amsvid_t *vid)
|
||||
}
|
||||
video_blit_memtoscreen(0, mda->firstline, xsize, ysize);
|
||||
frames++;
|
||||
video_res_x = mda->crtc[1];
|
||||
video_res_y = mda->crtc[6];
|
||||
video_res_x = mda->crtc[MDA_CRTC_HDISP];
|
||||
video_res_y = mda->crtc[MDA_CRTC_VDISP];
|
||||
video_bpp = 0;
|
||||
}
|
||||
mda->firstline = 1000;
|
||||
@@ -1378,12 +1380,12 @@ lcdm_poll(amsvid_t *vid)
|
||||
mda->blink++;
|
||||
}
|
||||
} else {
|
||||
mda->sc++;
|
||||
mda->sc &= 31;
|
||||
mda->ma = mda->maback;
|
||||
mda->scanline++;
|
||||
mda->scanline &= 31;
|
||||
mda->memaddr= mda->memaddr_backup;
|
||||
}
|
||||
if (mda->sc == (mda->crtc[10] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[10] & 31) >> 1)))
|
||||
mda->con = 1;
|
||||
if (mda->scanline == (mda->crtc[MDA_CRTC_CURSOR_START] & 31) || ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3 && mda->scanline == ((mda->crtc[MDA_CRTC_CURSOR_START] & 31) >> 1)))
|
||||
mda->cursorvisible = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1399,19 +1401,19 @@ lcdc_poll(amsvid_t *vid)
|
||||
uint8_t chr;
|
||||
uint8_t attr;
|
||||
uint16_t dat;
|
||||
int oldsc;
|
||||
uint16_t ca;
|
||||
int scanline_old;
|
||||
uint16_t cursoraddr;
|
||||
int blink;
|
||||
|
||||
ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff;
|
||||
cursoraddr = (cga->crtc[CGA_CRTC_CURSOR_ADDR_LOW] | (cga->crtc[CGA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
|
||||
if (!cga->linepos) {
|
||||
timer_advance_u64(&vid->timer, cga->dispofftime);
|
||||
cga->cgastat |= 1;
|
||||
cga->linepos = 1;
|
||||
oldsc = cga->sc;
|
||||
if ((cga->crtc[8] & 3) == 3)
|
||||
cga->sc = ((cga->sc << 1) + cga->oddeven) & 7;
|
||||
scanline_old = cga->scanline;
|
||||
if ((cga->crtc[CGA_CRTC_INTERLACE] & 3) == 3)
|
||||
cga->scanline = ((cga->scanline << 1) + cga->oddeven) & 7;
|
||||
if (cga->cgadispon) {
|
||||
if (cga->displine < cga->firstline) {
|
||||
cga->firstline = cga->displine;
|
||||
@@ -1419,30 +1421,30 @@ lcdc_poll(amsvid_t *vid)
|
||||
}
|
||||
cga->lastline = cga->displine;
|
||||
|
||||
if (cga->cgamode & 1) {
|
||||
for (x = 0; x < cga->crtc[1]; x++) {
|
||||
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
for (x = 0; x < cga->crtc[CGA_CRTC_HDISP]; x++) {
|
||||
chr = cga->charbuffer[x << 1];
|
||||
attr = cga->charbuffer[(x << 1) + 1];
|
||||
drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron);
|
||||
blink = ((cga->cgablink & 16) && (cga->cgamode & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
lcd_draw_char_80(vid, &(buffer32->line[cga->displine << 1])[x * 8], chr, attr, drawcursor, blink, cga->sc, cga->cgamode & 0x40, cga->cgamode);
|
||||
lcd_draw_char_80(vid, &(buffer32->line[(cga->displine << 1) + 1])[x * 8], chr, attr, drawcursor, blink, cga->sc, cga->cgamode & 0x40, cga->cgamode);
|
||||
cga->ma++;
|
||||
drawcursor = ((cga->memaddr == cursoraddr) && cga->cursorvisible && cga->cursoron);
|
||||
blink = ((cga->cgablink & 16) && (cga->cgamode & CGA_MODE_FLAG_BLINK) && (attr & 0x80) && !drawcursor);
|
||||
lcd_draw_char_80(vid, &(buffer32->line[cga->displine << 1])[x * 8], chr, attr, drawcursor, blink, cga->scanline, cga->cgamode & 0x40, cga->cgamode);
|
||||
lcd_draw_char_80(vid, &(buffer32->line[(cga->displine << 1) + 1])[x * 8], chr, attr, drawcursor, blink, cga->scanline, cga->cgamode & 0x40, cga->cgamode);
|
||||
cga->memaddr++;
|
||||
}
|
||||
} else if (!(cga->cgamode & 2)) {
|
||||
for (x = 0; x < cga->crtc[1]; x++) {
|
||||
chr = cga->vram[(cga->ma << 1) & 0x3fff];
|
||||
attr = cga->vram[((cga->ma << 1) + 1) & 0x3fff];
|
||||
drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron);
|
||||
blink = ((cga->cgablink & 16) && (cga->cgamode & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
lcd_draw_char_40(vid, &(buffer32->line[cga->displine << 1])[x * 16], chr, attr, drawcursor, blink, cga->sc, cga->cgamode);
|
||||
lcd_draw_char_40(vid, &(buffer32->line[(cga->displine << 1) + 1])[x * 16], chr, attr, drawcursor, blink, cga->sc, cga->cgamode);
|
||||
cga->ma++;
|
||||
} else if (!(cga->cgamode & CGA_MODE_FLAG_GRAPHICS)) {
|
||||
for (x = 0; x < cga->crtc[CGA_CRTC_HDISP]; x++) {
|
||||
chr = cga->vram[(cga->memaddr << 1) & 0x3fff];
|
||||
attr = cga->vram[((cga->memaddr << 1) + 1) & 0x3fff];
|
||||
drawcursor = ((cga->memaddr == cursoraddr) && cga->cursorvisible && cga->cursoron);
|
||||
blink = ((cga->cgablink & 16) && (cga->cgamode & CGA_MODE_FLAG_BLINK) && (attr & 0x80) && !drawcursor);
|
||||
lcd_draw_char_40(vid, &(buffer32->line[cga->displine << 1])[x * 16], chr, attr, drawcursor, blink, cga->scanline, cga->cgamode);
|
||||
lcd_draw_char_40(vid, &(buffer32->line[(cga->displine << 1) + 1])[x * 16], chr, attr, drawcursor, blink, cga->scanline, cga->cgamode);
|
||||
cga->memaddr++;
|
||||
}
|
||||
} else { /* Graphics mode */
|
||||
for (x = 0; x < cga->crtc[1]; x++) {
|
||||
dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1];
|
||||
cga->ma++;
|
||||
for (x = 0; x < cga->crtc[CGA_CRTC_HDISP]; x++) {
|
||||
dat = (cga->vram[((cga->memaddr << 1) & 0x1fff) + ((cga->scanline & 1) * 0x2000)] << 8) | cga->vram[((cga->memaddr << 1) & 0x1fff) + ((cga->scanline & 1) * 0x2000) + 1];
|
||||
cga->memaddr++;
|
||||
for (uint8_t c = 0; c < 16; c++) {
|
||||
buffer32->line[cga->displine << 1][(x << 4) + c] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + c] = (dat & 0x8000) ? blue : green;
|
||||
dat <<= 1;
|
||||
@@ -1450,22 +1452,22 @@ lcdc_poll(amsvid_t *vid)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (cga->cgamode & 1) {
|
||||
hline(buffer32, 0, (cga->displine << 1), (cga->crtc[1] << 3), green);
|
||||
hline(buffer32, 0, (cga->displine << 1) + 1, (cga->crtc[1] << 3), green);
|
||||
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES) {
|
||||
hline(buffer32, 0, (cga->displine << 1), (cga->crtc[CGA_CRTC_HDISP] << 3), green);
|
||||
hline(buffer32, 0, (cga->displine << 1) + 1, (cga->crtc[CGA_CRTC_HDISP] << 3), green);
|
||||
} else {
|
||||
hline(buffer32, 0, (cga->displine << 1), (cga->crtc[1] << 4), green);
|
||||
hline(buffer32, 0, (cga->displine << 1) + 1, (cga->crtc[1] << 4), green);
|
||||
hline(buffer32, 0, (cga->displine << 1), (cga->crtc[CGA_CRTC_HDISP] << 4), green);
|
||||
hline(buffer32, 0, (cga->displine << 1) + 1, (cga->crtc[CGA_CRTC_HDISP] << 4), green);
|
||||
}
|
||||
}
|
||||
|
||||
if (cga->cgamode & 1)
|
||||
x = (cga->crtc[1] << 3);
|
||||
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES)
|
||||
x = (cga->crtc[CGA_CRTC_HDISP] << 3);
|
||||
else
|
||||
x = (cga->crtc[1] << 4);
|
||||
x = (cga->crtc[CGA_CRTC_HDISP] << 4);
|
||||
|
||||
cga->sc = oldsc;
|
||||
if (cga->vc == cga->crtc[7] && !cga->sc)
|
||||
cga->scanline = scanline_old;
|
||||
if (cga->vc == cga->crtc[CGA_CRTC_VSYNC] && !cga->scanline)
|
||||
cga->cgastat |= 8;
|
||||
cga->displine++;
|
||||
if (cga->displine >= 360)
|
||||
@@ -1478,53 +1480,53 @@ lcdc_poll(amsvid_t *vid)
|
||||
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))) {
|
||||
cga->con = 0;
|
||||
if (cga->scanline == (cga->crtc[CGA_CRTC_CURSOR_END] & 31) || ((cga->crtc[CGA_CRTC_INTERLACE] & 3) == 3 && cga->scanline == ((cga->crtc[CGA_CRTC_CURSOR_END] & 31) >> 1))) {
|
||||
cga->cursorvisible = 0;
|
||||
}
|
||||
if ((cga->crtc[8] & 3) == 3 && cga->sc == (cga->crtc[9] >> 1))
|
||||
cga->maback = cga->ma;
|
||||
if ((cga->crtc[CGA_CRTC_INTERLACE] & 3) == 3 && cga->scanline == (cga->crtc[CGA_CRTC_MAX_SCANLINE_ADDR] >> 1))
|
||||
cga->memaddr_backup = cga->memaddr;
|
||||
if (cga->vadj) {
|
||||
cga->sc++;
|
||||
cga->sc &= 31;
|
||||
cga->ma = cga->maback;
|
||||
cga->scanline++;
|
||||
cga->scanline &= 31;
|
||||
cga->memaddr = cga->memaddr_backup;
|
||||
cga->vadj--;
|
||||
if (!cga->vadj) {
|
||||
cga->cgadispon = 1;
|
||||
cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff;
|
||||
cga->sc = 0;
|
||||
cga->memaddr = cga->memaddr_backup = (cga->crtc[CGA_CRTC_START_ADDR_LOW] | (cga->crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
cga->scanline = 0;
|
||||
}
|
||||
} else if (cga->sc == cga->crtc[9]) {
|
||||
cga->maback = cga->ma;
|
||||
cga->sc = 0;
|
||||
} else if (cga->scanline == cga->crtc[CGA_CRTC_MAX_SCANLINE_ADDR]) {
|
||||
cga->memaddr_backup = cga->memaddr;
|
||||
cga->scanline = 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;
|
||||
if (!cga->vadj)
|
||||
cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff;
|
||||
if ((cga->crtc[10] & 0x60) == 0x20)
|
||||
cga->memaddr = cga->memaddr_backup = (cga->crtc[CGA_CRTC_START_ADDR_LOW] | (cga->crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff;
|
||||
if ((cga->crtc[CGA_CRTC_CURSOR_START] & 0x60) == 0x20)
|
||||
cga->cursoron = 0;
|
||||
else
|
||||
cga->cursoron = cga->cgablink & 8;
|
||||
}
|
||||
|
||||
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);
|
||||
if (cga->crtc[CGA_CRTC_VSYNC]) {
|
||||
if (cga->cgamode & CGA_MODE_FLAG_HIGHRES)
|
||||
x = (cga->crtc[CGA_CRTC_HDISP] << 3);
|
||||
else
|
||||
x = (cga->crtc[1] << 4);
|
||||
x = (cga->crtc[CGA_CRTC_HDISP] << 4);
|
||||
cga->lastline++;
|
||||
|
||||
xs_temp = x;
|
||||
@@ -1536,7 +1538,7 @@ lcdc_poll(amsvid_t *vid)
|
||||
if (ys_temp < 32)
|
||||
ys_temp = 400;
|
||||
|
||||
if ((cga->cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) {
|
||||
if ((cga->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) {
|
||||
xsize = xs_temp;
|
||||
ysize = ys_temp;
|
||||
set_screen_size(xsize, ysize);
|
||||
@@ -1553,15 +1555,15 @@ lcdc_poll(amsvid_t *vid)
|
||||
|
||||
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
|
||||
@@ -1573,17 +1575,17 @@ lcdc_poll(amsvid_t *vid)
|
||||
cga->oddeven ^= 1;
|
||||
}
|
||||
} else {
|
||||
cga->sc++;
|
||||
cga->sc &= 31;
|
||||
cga->ma = cga->maback;
|
||||
cga->scanline++;
|
||||
cga->scanline &= 31;
|
||||
cga->memaddr = cga->memaddr_backup;
|
||||
}
|
||||
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)))
|
||||
cga->con = 1;
|
||||
if (cga->cgadispon && (cga->cgamode & 1)) {
|
||||
for (x = 0; x < (cga->crtc[1] << 1); x++)
|
||||
cga->charbuffer[x] = cga->vram[((cga->ma << 1) + x) & 0x3fff];
|
||||
if (cga->scanline == (cga->crtc[CGA_CRTC_CURSOR_START] & 31) || ((cga->crtc[CGA_CRTC_INTERLACE] & 3) == 3 && cga->scanline == ((cga->crtc[CGA_CRTC_CURSOR_START] & 31) >> 1)))
|
||||
cga->cursorvisible = 1;
|
||||
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->memaddr << 1) + x) & 0x3fff];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,6 +169,72 @@ machine_at_quadt386sx_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const device_config_t pbl300sx_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "bios",
|
||||
.description = "BIOS Version",
|
||||
.type = CONFIG_BIOS,
|
||||
.default_string = "pbl300sx",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "1991", .internal_name = "pbl300sx_1991", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pbl300sx/V1.10_1113_910723.bin", "" } },
|
||||
{ .name = "1992", .internal_name = "pbl300sx", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pbl300sx/pb_l300sx_1992.bin", "" } },
|
||||
{ .files_no = 0 }
|
||||
},
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t pbl300sx_device = {
|
||||
.name = "Packard Bell Legend 300SX",
|
||||
.internal_name = "pbl300sx_device",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = pbl300sx_config
|
||||
};
|
||||
|
||||
int
|
||||
machine_at_pbl300sx_init(const machine_t *model)
|
||||
{
|
||||
int ret = 0;
|
||||
const char* fn;
|
||||
|
||||
/* No ROMs available */
|
||||
if (!device_available(model->device))
|
||||
return ret;
|
||||
|
||||
device_context(model->device);
|
||||
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);
|
||||
device_add(&acc2036_device);
|
||||
|
||||
device_add(&keyboard_ps2_phoenix_device);
|
||||
device_add(&um82c862f_ide_device);
|
||||
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(machine_get_vid_device(machine));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_neat_init(const machine_t *model)
|
||||
{
|
||||
@@ -292,6 +358,22 @@ machine_at_dells200_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_at122_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/at122/FINAL.BIN",
|
||||
0x000f0000, 65536, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_ctat_common_init(model);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_tuliptc7_init(const machine_t *model)
|
||||
{
|
||||
@@ -1128,7 +1210,7 @@ machine_at_3302_init(const machine_t *model)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(¶dise_pvga1a_ncr3302_device);
|
||||
device_add(machine_get_vid_device(machine));
|
||||
|
||||
device_add(&keyboard_at_ncr_device);
|
||||
|
||||
|
||||
@@ -682,7 +682,7 @@ machine_at_opti495_init(const machine_t *model)
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&opti495_device);
|
||||
device_add(&opti495slc_device);
|
||||
|
||||
device_add(&keyboard_at_device);
|
||||
|
||||
@@ -697,7 +697,7 @@ machine_at_opti495_ami_common_init(const machine_t *model)
|
||||
{
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&opti495_device);
|
||||
device_add(&opti495sx_device);
|
||||
|
||||
device_add(&keyboard_at_ami_device);
|
||||
|
||||
@@ -737,6 +737,32 @@ machine_at_opti495_mr_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_c747_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/c747/486-C747 Tandon.BIN",
|
||||
0x000f0000, 65536, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
/* The EFAR chipset is a rebrand of the OPTi 495SX. */
|
||||
device_add(&opti495sx_device);
|
||||
|
||||
/*
|
||||
No idea what KBC it actually has but this produces the
|
||||
desired behavior: command A9 does absolutely nothing.
|
||||
*/
|
||||
device_add(&keyboard_at_siemens_device);
|
||||
device_add(&um82c862f_ide_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_exp4349_init(const machine_t *model)
|
||||
{
|
||||
@@ -822,6 +848,7 @@ machine_at_403tg_d_mr_init(const machine_t *model)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const device_config_t pb450_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
@@ -974,7 +1001,8 @@ machine_at_mvi486_init(const machine_t *model)
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&opti495_device);
|
||||
device_add(&opti498_device);
|
||||
|
||||
device_add(&keyboard_at_device);
|
||||
device_add(&pc87311_ide_device);
|
||||
|
||||
@@ -1009,6 +1037,31 @@ machine_at_ami471_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_advantage40xxd_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/advantage40xxd/AST101.09A",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
device_add(&sis_85c471_device);
|
||||
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(machine_get_vid_device(machine));
|
||||
|
||||
device_add(&keyboard_ps2_phoenix_device);
|
||||
device_add(&um82c863f_ide_device);
|
||||
|
||||
device_add(&intel_flash_bxt_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_vli486sv2g_init(const machine_t *model)
|
||||
{
|
||||
@@ -2447,7 +2500,7 @@ machine_at_actionpc2600_init(const machine_t *model)
|
||||
device_add(&keyboard_ps2_tg_ami_device);
|
||||
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(&tgui9440_onboard_pci_device);
|
||||
device_add(machine_get_vid_device(machine));
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -2479,7 +2532,7 @@ machine_at_actiontower8400_init(const machine_t *model)
|
||||
device_add(&intel_flash_bxt_device); // The ActionPC 2600 has this so I'm gonna assume this does too.
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(&gd5430_onboard_pci_device);
|
||||
device_add(machine_get_vid_device(machine));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -44,9 +44,6 @@
|
||||
#include <86box/vid_cga_comp.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
|
||||
static video_timings_t timing_compaq_plasma = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 };
|
||||
|
||||
enum {
|
||||
COMPAQ_PORTABLEII = 0,
|
||||
COMPAQ_PORTABLEIII,
|
||||
@@ -55,752 +52,11 @@ enum {
|
||||
COMPAQ_DESKPRO386_05_1988
|
||||
};
|
||||
|
||||
#define CGA_RGB 0
|
||||
#define CGA_COMPOSITE 1
|
||||
|
||||
/*Very rough estimate*/
|
||||
#define VID_CLOCK (double) (651 * 416 * 60)
|
||||
|
||||
/* Mapping of attributes to colours */
|
||||
static uint32_t amber;
|
||||
static uint32_t black;
|
||||
static uint32_t blinkcols[256][2];
|
||||
static uint32_t normcols[256][2];
|
||||
|
||||
/* Video options set by the motherboard; they will be picked up by the card
|
||||
* on the next poll.
|
||||
*
|
||||
* Bit 3: Disable built-in video (for add-on card)
|
||||
* Bit 2: Thin font
|
||||
* Bits 0,1: Font set (not currently implemented)
|
||||
*/
|
||||
static int8_t cpq_st_display_internal = -1;
|
||||
|
||||
static uint8_t mdaattr[256][2][2];
|
||||
|
||||
static void
|
||||
compaq_plasma_display_set(uint8_t internal)
|
||||
{
|
||||
cpq_st_display_internal = internal;
|
||||
}
|
||||
|
||||
typedef struct compaq_plasma_t {
|
||||
cga_t cga;
|
||||
mem_mapping_t font_ram_mapping;
|
||||
uint8_t *font_ram;
|
||||
uint8_t port_13c6;
|
||||
uint8_t port_23c6;
|
||||
uint8_t port_27c6;
|
||||
uint8_t internal_monitor;
|
||||
} compaq_plasma_t;
|
||||
|
||||
static int compaq_machine_type = 0;
|
||||
|
||||
/* Compaq Deskpro 386 remaps RAM from 0xA0000-0xFFFFF to 0xFA0000-0xFFFFFF */
|
||||
static mem_mapping_t ram_mapping;
|
||||
|
||||
static void compaq_plasma_recalcattrs(compaq_plasma_t *self);
|
||||
|
||||
static void
|
||||
compaq_plasma_recalctimings(compaq_plasma_t *self)
|
||||
{
|
||||
double _dispontime;
|
||||
double _dispofftime;
|
||||
double disptime;
|
||||
|
||||
if (!self->internal_monitor && !(self->port_23c6 & 0x01)) {
|
||||
cga_recalctimings(&self->cga);
|
||||
return;
|
||||
}
|
||||
|
||||
disptime = 651;
|
||||
_dispontime = 640;
|
||||
_dispofftime = disptime - _dispontime;
|
||||
self->cga.dispontime = (uint64_t) (_dispontime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32));
|
||||
self->cga.dispofftime = (uint64_t) (_dispofftime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32));
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_plasma_waitstates(UNUSED(void *priv))
|
||||
{
|
||||
int ws_array[16] = { 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8 };
|
||||
int ws;
|
||||
|
||||
ws = ws_array[cycles & 0xf];
|
||||
sub_cycles(ws);
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_plasma_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
|
||||
if (self->port_23c6 & 0x08)
|
||||
self->font_ram[addr & 0x1fff] = val;
|
||||
else
|
||||
self->cga.vram[addr & 0x7fff] = val;
|
||||
|
||||
compaq_plasma_waitstates(&self->cga);
|
||||
}
|
||||
static uint8_t
|
||||
compaq_plasma_read(uint32_t addr, void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
uint8_t ret;
|
||||
|
||||
compaq_plasma_waitstates(&self->cga);
|
||||
|
||||
if (self->port_23c6 & 0x08)
|
||||
ret = (self->font_ram[addr & 0x1fff]);
|
||||
else
|
||||
ret = (self->cga.vram[addr & 0x7fff]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_plasma_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
/* Emulated CRTC, register select */
|
||||
case 0x3d0:
|
||||
case 0x3d2:
|
||||
case 0x3d4:
|
||||
case 0x3d6:
|
||||
cga_out(addr, val, &self->cga);
|
||||
break;
|
||||
|
||||
/* Emulated CRTC, value */
|
||||
case 0x3d1:
|
||||
case 0x3d3:
|
||||
case 0x3d5:
|
||||
case 0x3d7:
|
||||
cga_out(addr, val, &self->cga);
|
||||
compaq_plasma_recalctimings(self);
|
||||
break;
|
||||
case 0x3d8:
|
||||
case 0x3d9:
|
||||
cga_out(addr, val, &self->cga);
|
||||
break;
|
||||
|
||||
case 0x13c6:
|
||||
self->port_13c6 = val;
|
||||
compaq_plasma_display_set((self->port_13c6 & 0x08) ? 1 : 0);
|
||||
/*
|
||||
For bits 2-0, John gives 0 = CGA, 1 = EGA, 3 = MDA;
|
||||
Another source (Ralf Brown?) gives 4 = CGA, 5 = EGA, 7 = MDA;
|
||||
This leads me to believe bit 2 is not relevant to the mode.
|
||||
*/
|
||||
if ((val & 0x03) == 0x03)
|
||||
mem_mapping_set_addr(&self->cga.mapping, 0xb0000, 0x08000);
|
||||
else
|
||||
mem_mapping_set_addr(&self->cga.mapping, 0xb8000, 0x08000);
|
||||
break;
|
||||
|
||||
case 0x23c6:
|
||||
self->port_23c6 = val;
|
||||
compaq_plasma_recalcattrs(self);
|
||||
break;
|
||||
|
||||
case 0x27c6:
|
||||
self->port_27c6 = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
compaq_plasma_in(uint16_t addr, void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3d4:
|
||||
case 0x3da:
|
||||
case 0x3db:
|
||||
case 0x3dc:
|
||||
ret = cga_in(addr, &self->cga);
|
||||
break;
|
||||
|
||||
case 0x3d1:
|
||||
case 0x3d3:
|
||||
case 0x3d5:
|
||||
case 0x3d7:
|
||||
ret = cga_in(addr, &self->cga);
|
||||
break;
|
||||
|
||||
case 0x3d8:
|
||||
ret = self->cga.cgamode;
|
||||
break;
|
||||
|
||||
case 0x13c6:
|
||||
ret = self->port_13c6;
|
||||
#if 0
|
||||
if ((self->cga.cgamode & 0x28) == 0x00)
|
||||
ret |= 0x04;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x17c6:
|
||||
ret = 0xe6;
|
||||
break;
|
||||
|
||||
case 0x1bc6:
|
||||
ret = 0x40;
|
||||
break;
|
||||
|
||||
case 0x23c6:
|
||||
ret = self->port_23c6;
|
||||
break;
|
||||
|
||||
case 0x27c6:
|
||||
ret = self->port_27c6 & 0x3f;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_plasma_poll(void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
uint8_t chr;
|
||||
uint8_t attr;
|
||||
uint8_t sc;
|
||||
uint16_t ma = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x7fff;
|
||||
uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x7fff;
|
||||
uint16_t addr;
|
||||
int drawcursor;
|
||||
int cursorline;
|
||||
int blink = 0;
|
||||
int underline = 0;
|
||||
int c;
|
||||
int x;
|
||||
uint32_t ink = 0;
|
||||
uint32_t fg = (self->cga.cgacol & 0x0f) ? amber : black;
|
||||
uint32_t bg = black;
|
||||
uint32_t cols[2];
|
||||
uint8_t dat;
|
||||
uint8_t pattern;
|
||||
uint32_t ink0 = 0;
|
||||
uint32_t ink1 = 0;
|
||||
|
||||
/* Switch between internal plasma and external CRT display. */
|
||||
if ((cpq_st_display_internal != -1) && (cpq_st_display_internal != self->internal_monitor)) {
|
||||
self->internal_monitor = cpq_st_display_internal;
|
||||
compaq_plasma_recalctimings(self);
|
||||
}
|
||||
|
||||
/* graphic mode and not mode 40h */
|
||||
if (!self->internal_monitor && !(self->port_23c6 & 0x01)) {
|
||||
/* standard cga mode */
|
||||
cga_poll(&self->cga);
|
||||
return;
|
||||
} else {
|
||||
/* mode 40h or text mode */
|
||||
if (!self->cga.linepos) {
|
||||
timer_advance_u64(&self->cga.timer, self->cga.dispofftime);
|
||||
self->cga.cgastat |= 1;
|
||||
self->cga.linepos = 1;
|
||||
if (self->cga.cgadispon) {
|
||||
if (self->cga.displine == 0)
|
||||
video_wait_for_buffer();
|
||||
|
||||
/* 80-col */
|
||||
if (self->cga.cgamode & 0x01) {
|
||||
sc = self->cga.displine & 0x0f;
|
||||
addr = ((ma & ~1) + (self->cga.displine >> 4) * 80) << 1;
|
||||
ma += (self->cga.displine >> 4) * 80;
|
||||
|
||||
if ((self->cga.crtc[0x0a] & 0x60) == 0x20)
|
||||
cursorline = 0;
|
||||
else
|
||||
cursorline = (((self->cga.crtc[0x0a] & 0x0f) << 1) <= sc) && (((self->cga.crtc[0x0b] & 0x0f) << 1) >= sc);
|
||||
|
||||
/* for each text column */
|
||||
for (x = 0; x < 80; x++) {
|
||||
/* video output enabled */
|
||||
if (self->cga.cgamode & 0x08) {
|
||||
/* character */
|
||||
chr = self->cga.vram[(addr + (x << 1)) & 0x7fff];
|
||||
/* text attributes */
|
||||
attr = self->cga.vram[(addr + ((x << 1) + 1)) & 0x7fff];
|
||||
} else {
|
||||
chr = 0x00;
|
||||
attr = 0x00;
|
||||
}
|
||||
uint8_t hi_bit = attr & 0x08;
|
||||
/* check if cursor has to be drawn */
|
||||
drawcursor = ((ma == ca) && cursorline && (self->cga.cgamode & 0x08) && (self->cga.cgablink & 0x10));
|
||||
/* check if character underline mode should be set */
|
||||
underline = ((attr & 0x07) == 0x01);
|
||||
underline = underline || (((self->port_23c6 >> 5) == 2) && hi_bit);
|
||||
if (underline) {
|
||||
/* set forecolor to white */
|
||||
attr = attr | 0x7;
|
||||
}
|
||||
blink = 0;
|
||||
/* set foreground */
|
||||
cols[1] = blinkcols[attr][1];
|
||||
/* blink active */
|
||||
if (self->cga.cgamode & 0x20) {
|
||||
cols[0] = blinkcols[attr][0];
|
||||
/* attribute 7 active and not cursor */
|
||||
if ((self->cga.cgablink & 0x08) && (attr & 0x80) && !drawcursor) {
|
||||
/* set blinking */
|
||||
cols[1] = cols[0];
|
||||
blink = 1;
|
||||
}
|
||||
} else {
|
||||
/* Set intensity bit */
|
||||
cols[1] = normcols[attr][1];
|
||||
cols[0] = normcols[attr][0];
|
||||
}
|
||||
|
||||
/* character address */
|
||||
uint16_t chr_addr = ((chr * 16) + sc) & 0x0fff;
|
||||
if (((self->port_23c6 >> 5) == 3) && hi_bit)
|
||||
chr_addr |= 0x1000;
|
||||
|
||||
/* character underline active and 7th row of pixels in character height being drawn */
|
||||
if (underline && (sc == 7)) {
|
||||
/* for each pixel in character width */
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = mdaattr[attr][blink][1];
|
||||
} else if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
|
||||
if (hi_bit) {
|
||||
if ((self->port_23c6 >> 5) == 1) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] ^= (amber ^ black);
|
||||
} else if ((self->port_23c6 >> 5) == 4) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
uint32_t b = ((buffer32->line[self->cga.displine][(x << 3) + c]) >> 1) & 0x7f;
|
||||
uint32_t g = ((buffer32->line[self->cga.displine][(x << 3) + c]) >> 9) & 0x7f;
|
||||
uint32_t r = ((buffer32->line[self->cga.displine][(x << 3) + c]) >> 17) & 0x7f;
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = b | (g << 8) || (r << 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
ma++;
|
||||
}
|
||||
}
|
||||
/* 40-col */
|
||||
else if (!(self->cga.cgamode & 0x02)) {
|
||||
sc = self->cga.displine & 0x0f;
|
||||
addr = ((ma & ~1) + (self->cga.displine >> 4) * 40) << 1;
|
||||
ma += (self->cga.displine >> 4) * 40;
|
||||
|
||||
if ((self->cga.crtc[0x0a] & 0x60) == 0x20)
|
||||
cursorline = 0;
|
||||
else
|
||||
cursorline = (((self->cga.crtc[0x0a] & 0x0f) << 1) <= sc) && (((self->cga.crtc[0x0b] & 0x0f) << 1) >= sc);
|
||||
|
||||
for (x = 0; x < 40; x++) {
|
||||
/* video output enabled */
|
||||
if (self->cga.cgamode & 0x08) {
|
||||
/* character */
|
||||
chr = self->cga.vram[(addr + (x << 1)) & 0x7fff];
|
||||
/* text attributes */
|
||||
attr = self->cga.vram[(addr + ((x << 1) + 1)) & 0x7fff];
|
||||
} else {
|
||||
chr = 0x00;
|
||||
attr = 0x00;
|
||||
}
|
||||
uint8_t hi_bit = attr & 0x08;
|
||||
/* check if cursor has to be drawn */
|
||||
drawcursor = ((ma == ca) && cursorline && (self->cga.cgamode & 0x08) && (self->cga.cgablink & 0x10));
|
||||
/* check if character underline mode should be set */
|
||||
underline = ((attr & 0x07) == 0x01);
|
||||
underline = underline || (((self->port_23c6 >> 5) == 2) && hi_bit);
|
||||
if (underline) {
|
||||
/* set forecolor to white */
|
||||
attr = attr | 0x7;
|
||||
}
|
||||
blink = 0;
|
||||
/* set foreground */
|
||||
cols[1] = blinkcols[attr][1];
|
||||
/* blink active */
|
||||
if (self->cga.cgamode & 0x20) {
|
||||
cols[0] = blinkcols[attr][0];
|
||||
/* attribute 7 active and not cursor */
|
||||
if ((self->cga.cgablink & 0x08) && (attr & 0x80) && !drawcursor) {
|
||||
/* set blinking */
|
||||
cols[1] = cols[0];
|
||||
blink = 1;
|
||||
}
|
||||
} else {
|
||||
/* Set intensity bit */
|
||||
cols[1] = normcols[attr][1];
|
||||
cols[0] = normcols[attr][0];
|
||||
}
|
||||
|
||||
/* character address */
|
||||
uint16_t chr_addr = ((chr * 16) + sc) & 0x0fff;
|
||||
if (((self->port_23c6 >> 5) == 3) && hi_bit)
|
||||
chr_addr |= 0x1000;
|
||||
|
||||
/* character underline active and 7th row of pixels in character height being drawn */
|
||||
if (underline && (sc == 7)) {
|
||||
/* for each pixel in character width */
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = mdaattr[attr][blink][1];
|
||||
} else if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
|
||||
if (hi_bit) {
|
||||
if ((self->port_23c6 >> 5) == 1)
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] ^= (amber ^ black);
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] ^= (amber ^ black);
|
||||
}
|
||||
else if ((self->port_23c6 >> 5) == 4)
|
||||
for (c = 0; c < 8; c++) {
|
||||
uint32_t b = ((buffer32->line[self->cga.displine][(x << 4) + (c << 1)]) >> 1) & 0x7f;
|
||||
uint32_t g = ((buffer32->line[self->cga.displine][(x << 4) + (c << 1)]) >> 9) & 0x7f;
|
||||
uint32_t r = ((buffer32->line[self->cga.displine][(x << 4) + (c << 1)]) >> 17) & 0x7f;
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = b | (g << 8) || (r << 16);
|
||||
}
|
||||
}
|
||||
ma++;
|
||||
}
|
||||
} else {
|
||||
if (self->cga.cgamode & 0x10) {
|
||||
/* 640x400 mode */
|
||||
if (self->port_23c6 & 0x01) /* 640*400 */ {
|
||||
addr = ((self->cga.displine) & 1) * 0x2000 + ((self->cga.displine >> 1) & 1) * 0x4000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1);
|
||||
} else {
|
||||
addr = ((self->cga.displine >> 1) & 1) * 0x2000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1);
|
||||
}
|
||||
for (uint8_t x = 0; x < 80; x++) {
|
||||
dat = self->cga.vram[addr & 0x7fff];
|
||||
addr++;
|
||||
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
ink = (dat & 0x80) ? fg : bg;
|
||||
if (!(self->cga.cgamode & 0x08))
|
||||
ink = black;
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = ink;
|
||||
dat <<= 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
addr = ((self->cga.displine >> 1) & 1) * 0x2000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1);
|
||||
for (uint8_t x = 0; x < 80; x++) {
|
||||
dat = self->cga.vram[addr & 0x7fff];
|
||||
addr++;
|
||||
|
||||
for (uint8_t c = 0; c < 4; c++) {
|
||||
pattern = (dat & 0xC0) >> 6;
|
||||
if (!(self->cga.cgamode & 0x08))
|
||||
pattern = 0;
|
||||
|
||||
switch (pattern & 3) {
|
||||
case 0:
|
||||
ink0 = ink1 = black;
|
||||
break;
|
||||
case 1:
|
||||
if (self->cga.displine & 0x01) {
|
||||
ink0 = black;
|
||||
ink1 = black;
|
||||
} else {
|
||||
ink0 = amber;
|
||||
ink1 = black;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (self->cga.displine & 0x01) {
|
||||
ink0 = black;
|
||||
ink1 = amber;
|
||||
} else {
|
||||
ink0 = amber;
|
||||
ink1 = black;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
ink0 = ink1 = amber;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
buffer32->line[self->cga.displine][(x << 3) + (c << 1)] = ink0;
|
||||
buffer32->line[self->cga.displine][(x << 3) + (c << 1) + 1] = ink1;
|
||||
dat <<= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self->cga.displine++;
|
||||
/* Hardcode a fixed refresh rate and VSYNC timing */
|
||||
if (self->cga.displine == 400) { /* Start of VSYNC */
|
||||
self->cga.cgastat |= 8;
|
||||
self->cga.cgadispon = 0;
|
||||
}
|
||||
if (self->cga.displine == 416) { /* End of VSYNC */
|
||||
self->cga.displine = 0;
|
||||
self->cga.cgastat &= ~8;
|
||||
self->cga.cgadispon = 1;
|
||||
}
|
||||
} else {
|
||||
timer_advance_u64(&self->cga.timer, self->cga.dispontime);
|
||||
if (self->cga.cgadispon)
|
||||
self->cga.cgastat &= ~1;
|
||||
|
||||
self->cga.linepos = 0;
|
||||
|
||||
if (self->cga.displine == 400) {
|
||||
xsize = 640;
|
||||
ysize = 400;
|
||||
|
||||
if ((self->cga.cgamode & 0x08) || video_force_resize_get()) {
|
||||
set_screen_size(xsize, ysize);
|
||||
|
||||
if (video_force_resize_get())
|
||||
video_force_resize_set(0);
|
||||
}
|
||||
/* Plasma specific */
|
||||
video_blit_memtoscreen(0, 0, xsize, ysize);
|
||||
frames++;
|
||||
|
||||
/* Fixed 640x400 resolution */
|
||||
video_res_x = 640;
|
||||
video_res_y = 400;
|
||||
|
||||
if (self->cga.cgamode & 0x02) {
|
||||
if (self->cga.cgamode & 0x10)
|
||||
video_bpp = 1;
|
||||
else
|
||||
video_bpp = 2;
|
||||
} else
|
||||
video_bpp = 0;
|
||||
|
||||
self->cga.cgablink++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_plasma_mdaattr_rebuild(void)
|
||||
{
|
||||
for (uint16_t c = 0; c < 256; c++) {
|
||||
mdaattr[c][0][0] = mdaattr[c][1][0] = mdaattr[c][1][1] = 16;
|
||||
if (c & 8)
|
||||
mdaattr[c][0][1] = 15 + 16;
|
||||
else
|
||||
mdaattr[c][0][1] = 7 + 16;
|
||||
}
|
||||
|
||||
mdaattr[0x70][0][1] = 16;
|
||||
mdaattr[0x70][0][0] = mdaattr[0x70][1][0] = mdaattr[0x70][1][1] = 16 + 15;
|
||||
mdaattr[0xF0][0][1] = 16;
|
||||
mdaattr[0xF0][0][0] = mdaattr[0xF0][1][0] = mdaattr[0xF0][1][1] = 16 + 15;
|
||||
mdaattr[0x78][0][1] = 16 + 7;
|
||||
mdaattr[0x78][0][0] = mdaattr[0x78][1][0] = mdaattr[0x78][1][1] = 16 + 15;
|
||||
mdaattr[0xF8][0][1] = 16 + 7;
|
||||
mdaattr[0xF8][0][0] = mdaattr[0xF8][1][0] = mdaattr[0xF8][1][1] = 16 + 15;
|
||||
mdaattr[0x00][0][1] = mdaattr[0x00][1][1] = 16;
|
||||
mdaattr[0x08][0][1] = mdaattr[0x08][1][1] = 16;
|
||||
mdaattr[0x80][0][1] = mdaattr[0x80][1][1] = 16;
|
||||
mdaattr[0x88][0][1] = mdaattr[0x88][1][1] = 16;
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_plasma_recalcattrs(compaq_plasma_t *self)
|
||||
{
|
||||
int n;
|
||||
|
||||
/* val behaves as follows:
|
||||
* Bit 0: Attributes 01-06, 08-0E are inverse video
|
||||
* Bit 1: Attributes 01-06, 08-0E are bold
|
||||
* Bit 2: Attributes 11-16, 18-1F, 21-26, 28-2F ... F1-F6, F8-FF
|
||||
* are inverse video
|
||||
* Bit 3: Attributes 11-16, 18-1F, 21-26, 28-2F ... F1-F6, F8-FF
|
||||
* are bold */
|
||||
|
||||
/* Set up colours */
|
||||
amber = makecol(0xff, 0x7d, 0x00);
|
||||
black = makecol(0x64, 0x19, 0x00);
|
||||
|
||||
/* Initialize the attribute mapping. Start by defaulting everything
|
||||
* to black on amber, and with bold set by bit 3 */
|
||||
for (n = 0; n < 256; n++) {
|
||||
blinkcols[n][0] = normcols[n][0] = amber;
|
||||
blinkcols[n][1] = normcols[n][1] = black;
|
||||
}
|
||||
|
||||
/* Colours 0x11-0xFF are controlled by bits 2 and 3 of the
|
||||
* passed value. Exclude x0 and x8, which are always black on
|
||||
* amber. */
|
||||
for (n = 0x11; n <= 0xFF; n++) {
|
||||
if ((n & 7) == 0)
|
||||
continue;
|
||||
if ((self->port_23c6 >> 5) == 1) { /* Inverse */
|
||||
blinkcols[n][0] = normcols[n][0] = amber;
|
||||
blinkcols[n][1] = normcols[n][1] = black;
|
||||
} else { /* Normal */
|
||||
blinkcols[n][0] = normcols[n][0] = black;
|
||||
blinkcols[n][1] = normcols[n][1] = amber;
|
||||
}
|
||||
}
|
||||
/* Set up the 01-0E range, controlled by bits 0 and 1 of the
|
||||
* passed value. When blinking is enabled this also affects 81-8E. */
|
||||
for (n = 0x01; n <= 0x0E; n++) {
|
||||
if (n == 7)
|
||||
continue;
|
||||
if ((self->port_23c6 >> 5) == 1) {
|
||||
blinkcols[n][0] = normcols[n][0] = amber;
|
||||
blinkcols[n][1] = normcols[n][1] = black;
|
||||
blinkcols[n + 128][0] = amber;
|
||||
blinkcols[n + 128][1] = black;
|
||||
} else {
|
||||
blinkcols[n][0] = normcols[n][0] = black;
|
||||
blinkcols[n][1] = normcols[n][1] = amber;
|
||||
blinkcols[n + 128][0] = black;
|
||||
blinkcols[n + 128][1] = amber;
|
||||
}
|
||||
}
|
||||
/* Colours 07 and 0F are always amber on black. If blinking is
|
||||
* enabled so are 87 and 8F. */
|
||||
for (n = 0x07; n <= 0x0F; n += 8) {
|
||||
blinkcols[n][0] = normcols[n][0] = black;
|
||||
blinkcols[n][1] = normcols[n][1] = amber;
|
||||
blinkcols[n + 128][0] = black;
|
||||
blinkcols[n + 128][1] = amber;
|
||||
}
|
||||
/* When not blinking, colours 81-8F are always amber on black. */
|
||||
for (n = 0x81; n <= 0x8F; n++) {
|
||||
normcols[n][0] = black;
|
||||
normcols[n][1] = amber;
|
||||
}
|
||||
|
||||
/* Finally do the ones which are solid black. These differ between
|
||||
* the normal and blinking mappings */
|
||||
for (n = 0; n <= 0xFF; n += 0x11)
|
||||
normcols[n][0] = normcols[n][1] = black;
|
||||
|
||||
/* In the blinking range, 00 11 22 .. 77 and 80 91 A2 .. F7 are black */
|
||||
for (n = 0; n <= 0x77; n += 0x11) {
|
||||
blinkcols[n][0] = blinkcols[n][1] = black;
|
||||
blinkcols[n + 128][0] = blinkcols[n + 128][1] = black;
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
compaq_plasma_init(UNUSED(const device_t *info))
|
||||
{
|
||||
compaq_plasma_t *self = calloc(1, sizeof(compaq_plasma_t));
|
||||
|
||||
cga_init(&self->cga);
|
||||
video_inform(VIDEO_FLAG_TYPE_CGA, &timing_compaq_plasma);
|
||||
|
||||
self->cga.composite = 0;
|
||||
self->cga.revision = 0;
|
||||
|
||||
self->cga.vram = malloc(0x8000);
|
||||
self->internal_monitor = 1;
|
||||
self->font_ram = malloc(0x2000);
|
||||
|
||||
cga_comp_init(self->cga.revision);
|
||||
timer_set_callback(&self->cga.timer, compaq_plasma_poll);
|
||||
timer_set_p(&self->cga.timer, self);
|
||||
|
||||
mem_mapping_add(&self->cga.mapping, 0xb8000, 0x08000,
|
||||
compaq_plasma_read, NULL, NULL,
|
||||
compaq_plasma_write, NULL, NULL,
|
||||
NULL, MEM_MAPPING_EXTERNAL, self);
|
||||
for (int i = 1; i <= 2; i++) {
|
||||
io_sethandler(0x03c6 + (i << 12), 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
|
||||
io_sethandler(0x07c6 + (i << 12), 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
|
||||
io_sethandler(0x0bc6 + (i << 12), 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
|
||||
}
|
||||
io_sethandler(0x03d0, 0x0010, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
|
||||
|
||||
overscan_x = overscan_y = 16;
|
||||
|
||||
self->cga.rgb_type = device_get_config_int("rgb_type");
|
||||
cga_palette = (self->cga.rgb_type << 1);
|
||||
cgapal_rebuild();
|
||||
compaq_plasma_mdaattr_rebuild();
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_plasma_close(void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
|
||||
free(self->cga.vram);
|
||||
free(self->font_ram);
|
||||
free(self);
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_plasma_speed_changed(void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
|
||||
compaq_plasma_recalctimings(self);
|
||||
}
|
||||
|
||||
const device_config_t compaq_plasma_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "rgb_type",
|
||||
.description = "RGB type",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = "",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "Color", .value = 0 },
|
||||
{ .description = "Green Monochrome", .value = 1 },
|
||||
{ .description = "Amber Monochrome", .value = 2 },
|
||||
{ .description = "Gray Monochrome", .value = 3 },
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t compaq_plasma_device = {
|
||||
.name = "Compaq Plasma",
|
||||
.internal_name = "compaq_plasma",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = compaq_plasma_init,
|
||||
.close = compaq_plasma_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = compaq_plasma_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = compaq_plasma_config
|
||||
};
|
||||
|
||||
static uint8_t
|
||||
read_ram(uint32_t addr, UNUSED(void *priv))
|
||||
|
||||
@@ -96,21 +96,21 @@ machine_at_d842_init(const machine_t *model)
|
||||
ret = bios_load_linear(fn, 0x000e0000, 131072, 0);
|
||||
device_context_restore();
|
||||
|
||||
machine_at_common_init(model);
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&ide_pci_2ch_device);
|
||||
pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); /* Onboard */
|
||||
pci_register_slot(0x03, PCI_CARD_VIDEO, 4, 0, 0, 0); /* Onboard */
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); /* Slot 01 */
|
||||
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); /* Slot 02 */
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); /* Onboard */
|
||||
pci_register_slot(0x03, PCI_CARD_VIDEO, 4, 0, 0, 0); /* Onboard */
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); /* Slot 01 */
|
||||
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); /* Slot 02 */
|
||||
|
||||
device_add(&keyboard_ps2_pci_device);
|
||||
device_add(&i430nx_device);
|
||||
device_add(&sio_zb_device);
|
||||
device_add(&fdc37c665_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -127,18 +127,17 @@ static const device_config_t d842_config[] = {
|
||||
.spinner = { 0 }, /*W1*/
|
||||
.bios = {
|
||||
{ .name = "Version 1.03 Revision 1.03.842 (11/24/1994)", .internal_name = "d842", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842.bin", "" } },
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842.BIN", "" } },
|
||||
{ .name = "Version 4.04 Revision 1.05.842 (03/15/1996)", .internal_name = "d842_mar96", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_mar96.bin", "" } },
|
||||
{ .name = "Version 4.04 Revision 1.06.842 (04/03/1998)", .internal_name = "d842_apr98", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_apr98.bin", "" } },
|
||||
{ .name = "Version 4.04 Revision 1.07.842 (06/02/1998)", .internal_name = "d842_jun98", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_jun98.bin", "" } },
|
||||
{ .name = "Version 1.03 Revision 1.09.842 (07/08/1996)", .internal_name = "d842_jul96", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "Version 4.04 Revision 1.07.842 (06/02/1998)", .internal_name = "d842_jun98", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_jun98.BIN", "" } },
|
||||
{ .name = "Version 1.03 Revision 1.09.842 (07/08/1996)", .internal_name = "d842_jul96", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_jul96.bin", "" } },
|
||||
{ .name = "Version 1.03 Revision 1.10.842 (06/04/1998)", .internal_name = "d842_jun98_1", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_jun98_1.bin", "" } },
|
||||
|
||||
{ .name = "Version 1.03 Revision 1.10.842 (06/04/1998)", .internal_name = "d842_jun98_1", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_jun98_1.bin", "" } },
|
||||
},
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
@@ -155,7 +154,7 @@ const device_t d842_device = {
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = &d842_config[0]
|
||||
|
||||
@@ -628,25 +628,24 @@ machine_at_d943_init(const machine_t *model)
|
||||
ret = bios_load_linear(fn, 0x000e0000, 131072, 0);
|
||||
device_context_restore();
|
||||
|
||||
machine_at_common_init_ex(model, 2);
|
||||
device_add(&amstrad_megapc_nvr_device);
|
||||
machine_at_common_init_ex(model, 2);
|
||||
device_add(&amstrad_megapc_nvr_device);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0);
|
||||
pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 2, 4, 1);
|
||||
pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 1, 3, 4);
|
||||
pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 3, 2, 4);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0);
|
||||
pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 2, 4, 1);
|
||||
pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 1, 3, 4);
|
||||
pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 3, 2, 4);
|
||||
device_add(&i430hx_device);
|
||||
device_add(&piix3_device);
|
||||
device_add(&keyboard_ps2_pci_device);
|
||||
device_add(&fdc37c665_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
spd_register(SPD_TYPE_EDO, 0x7, 256);
|
||||
|
||||
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
spd_register(SPD_TYPE_EDO, 0x7, 256);
|
||||
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(machine_get_vid_device(machine));
|
||||
|
||||
if (sound_card_current[0] == SOUND_INTERNAL)
|
||||
@@ -670,11 +669,10 @@ static const device_config_t d943_config[] = {
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d943/d943_oct96.bin", "" } },
|
||||
{ .name = "Version 4.05 Revision 1.03.943 (12/12/1996)", .internal_name = "d943_dec96", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d943/d943_dec96.bin", "" } },
|
||||
{ .name = "Version 4.05 Revision 1.05.943 (09/04/1997)", .internal_name = "d943_sept97", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "Version 4.05 Revision 1.05.943 (09/04/1997)", .internal_name = "d943_sept97", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d943/d943_sept97.bin", "" } },
|
||||
{ .name = "Version 4.05 Revision 1.06.943 (10/29/1997)", .internal_name = "d943_oct97", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d943/d943_oct97.bin", "" } },
|
||||
|
||||
},
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
@@ -691,7 +689,7 @@ const device_t d943_device = {
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = &d943_config[0]
|
||||
|
||||
@@ -58,13 +58,13 @@ static void
|
||||
elt_vid_off_poll(void *priv)
|
||||
{
|
||||
cga_t *cga = priv;
|
||||
uint8_t hdisp = cga->crtc[1];
|
||||
uint8_t hdisp = cga->crtc[CGA_CRTC_HDISP];
|
||||
|
||||
/* Don't display anything.
|
||||
* TODO: Do something less stupid to emulate backlight off. */
|
||||
cga->crtc[1] = 0;
|
||||
cga->crtc[CGA_CRTC_HDISP] = 0;
|
||||
cga_poll(cga);
|
||||
cga->crtc[1] = hdisp;
|
||||
cga->crtc[CGA_CRTC_HDISP] = hdisp;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -48,11 +48,10 @@
|
||||
#include <86box/snd_sn76489.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_cga_comp.h>
|
||||
#include <86box/m_pcjr.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
#define PCJR_RGB 0
|
||||
#define PCJR_COMPOSITE 1
|
||||
|
||||
#define STAT_PARITY 0x80
|
||||
#define STAT_RTIMEOUT 0x40
|
||||
@@ -63,49 +62,10 @@
|
||||
#define STAT_IFULL 0x02
|
||||
#define STAT_OFULL 0x01
|
||||
|
||||
typedef struct pcjr_t {
|
||||
/* Video Controller stuff. */
|
||||
mem_mapping_t mapping;
|
||||
uint8_t crtc[32];
|
||||
int crtcreg;
|
||||
int array_index;
|
||||
uint8_t array[32];
|
||||
int array_ff;
|
||||
int memctrl;
|
||||
uint8_t stat;
|
||||
int addr_mode;
|
||||
uint8_t *vram;
|
||||
uint8_t *b8000;
|
||||
int linepos;
|
||||
int displine;
|
||||
int sc;
|
||||
int vc;
|
||||
int dispon;
|
||||
int con;
|
||||
int cursoron;
|
||||
int blink;
|
||||
int vsynctime;
|
||||
int fullchange;
|
||||
int vadj;
|
||||
uint16_t ma;
|
||||
uint16_t maback;
|
||||
uint64_t dispontime;
|
||||
uint64_t dispofftime;
|
||||
pc_timer_t timer;
|
||||
int firstline;
|
||||
int lastline;
|
||||
int composite;
|
||||
int apply_hd;
|
||||
|
||||
/* Keyboard Controller stuff. */
|
||||
int latched;
|
||||
int data;
|
||||
int serial_data[44];
|
||||
int serial_pos;
|
||||
uint8_t pa;
|
||||
uint8_t pb;
|
||||
pc_timer_t send_delay_timer;
|
||||
} pcjr_t;
|
||||
static uint8_t key_queue[16];
|
||||
static int key_queue_start = 0;
|
||||
static int key_queue_end = 0;
|
||||
|
||||
/*PCjr keyboard has no escape scancodes, and no scancodes beyond 54
|
||||
Map right alt to 54h (FN) */
|
||||
@@ -626,643 +586,6 @@ const scancode scancode_pcjr[512] = {
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static video_timings_t timing_dram = { VIDEO_BUS, 0, 0, 0, 0, 0, 0 }; /*No additional waitstates*/
|
||||
|
||||
static uint8_t crtcmask[32] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f,
|
||||
0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static uint8_t key_queue[16];
|
||||
static int key_queue_start = 0;
|
||||
static int key_queue_end = 0;
|
||||
|
||||
static void
|
||||
recalc_address(pcjr_t *pcjr)
|
||||
{
|
||||
uint8_t masked_memctrl = pcjr->memctrl;
|
||||
|
||||
/* According to the Technical Reference, bits 2 and 5 are
|
||||
ignored if there is only 64k of RAM and there are only
|
||||
4 pages. */
|
||||
if (mem_size < 128)
|
||||
masked_memctrl &= ~0x24;
|
||||
|
||||
if ((pcjr->memctrl & 0xc0) == 0xc0) {
|
||||
pcjr->vram = &ram[(masked_memctrl & 0x06) << 14];
|
||||
pcjr->b8000 = &ram[(masked_memctrl & 0x30) << 11];
|
||||
} else {
|
||||
pcjr->vram = &ram[(masked_memctrl & 0x07) << 14];
|
||||
pcjr->b8000 = &ram[(masked_memctrl & 0x38) << 11];
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
recalc_timings(pcjr_t *pcjr)
|
||||
{
|
||||
double _dispontime;
|
||||
double _dispofftime;
|
||||
double disptime;
|
||||
|
||||
if (pcjr->array[0] & 1) {
|
||||
disptime = pcjr->crtc[0] + 1;
|
||||
_dispontime = pcjr->crtc[1];
|
||||
} else {
|
||||
disptime = (pcjr->crtc[0] + 1) << 1;
|
||||
_dispontime = pcjr->crtc[1] << 1;
|
||||
}
|
||||
|
||||
_dispofftime = disptime - _dispontime;
|
||||
_dispontime *= CGACONST;
|
||||
_dispofftime *= CGACONST;
|
||||
pcjr->dispontime = (uint64_t) (_dispontime);
|
||||
pcjr->dispofftime = (uint64_t) (_dispofftime);
|
||||
}
|
||||
|
||||
static int
|
||||
vid_get_h_overscan_size(pcjr_t *pcjr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (pcjr->array[0] & 1)
|
||||
ret = 128;
|
||||
else
|
||||
ret = 256;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
vid_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
pcjr_t *pcjr = (pcjr_t *) priv;
|
||||
uint8_t old;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3d0:
|
||||
case 0x3d2:
|
||||
case 0x3d4:
|
||||
case 0x3d6:
|
||||
pcjr->crtcreg = val & 0x1f;
|
||||
return;
|
||||
|
||||
case 0x3d1:
|
||||
case 0x3d3:
|
||||
case 0x3d5:
|
||||
case 0x3d7:
|
||||
old = pcjr->crtc[pcjr->crtcreg];
|
||||
pcjr->crtc[pcjr->crtcreg] = val & crtcmask[pcjr->crtcreg];
|
||||
if (pcjr->crtcreg == 2)
|
||||
overscan_x = vid_get_h_overscan_size(pcjr);
|
||||
if (old != val) {
|
||||
if (pcjr->crtcreg < 0xe || pcjr->crtcreg > 0x10) {
|
||||
pcjr->fullchange = changeframecount;
|
||||
recalc_timings(pcjr);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
case 0x3da:
|
||||
if (!pcjr->array_ff)
|
||||
pcjr->array_index = val & 0x1f;
|
||||
else {
|
||||
if (pcjr->array_index & 0x10)
|
||||
val &= 0x0f;
|
||||
pcjr->array[pcjr->array_index & 0x1f] = val;
|
||||
if (!(pcjr->array_index & 0x1f))
|
||||
update_cga16_color(val);
|
||||
}
|
||||
pcjr->array_ff = !pcjr->array_ff;
|
||||
break;
|
||||
|
||||
case 0x3df:
|
||||
pcjr->memctrl = val;
|
||||
pcjr->pa = val; /* The PCjr BIOS expects the value written to 3DF to
|
||||
then be readable from port 60, others it errors out
|
||||
with only 64k RAM set (but somehow, still works with
|
||||
128k or more RAM). */
|
||||
pcjr->addr_mode = val >> 6;
|
||||
recalc_address(pcjr);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
vid_in(uint16_t addr, void *priv)
|
||||
{
|
||||
pcjr_t *pcjr = (pcjr_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3d0:
|
||||
case 0x3d2:
|
||||
case 0x3d4:
|
||||
case 0x3d6:
|
||||
ret = pcjr->crtcreg;
|
||||
break;
|
||||
|
||||
case 0x3d1:
|
||||
case 0x3d3:
|
||||
case 0x3d5:
|
||||
case 0x3d7:
|
||||
ret = pcjr->crtc[pcjr->crtcreg];
|
||||
break;
|
||||
|
||||
case 0x3da:
|
||||
pcjr->array_ff = 0;
|
||||
pcjr->stat ^= 0x10;
|
||||
ret = pcjr->stat;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
vid_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
pcjr_t *pcjr = (pcjr_t *) priv;
|
||||
|
||||
if (pcjr->memctrl == -1)
|
||||
return;
|
||||
|
||||
pcjr->b8000[addr & 0x3fff] = val;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
vid_read(uint32_t addr, void *priv)
|
||||
{
|
||||
const pcjr_t *pcjr = (pcjr_t *) priv;
|
||||
|
||||
if (pcjr->memctrl == -1)
|
||||
return 0xff;
|
||||
|
||||
return (pcjr->b8000[addr & 0x3fff]);
|
||||
}
|
||||
|
||||
static int
|
||||
vid_get_h_overscan_delta(pcjr_t *pcjr)
|
||||
{
|
||||
int def;
|
||||
int coef;
|
||||
int ret;
|
||||
|
||||
switch ((pcjr->array[0] & 0x13) | ((pcjr->array[3] & 0x08) << 5)) {
|
||||
case 0x13: /*320x200x16*/
|
||||
def = 0x56;
|
||||
coef = 8;
|
||||
break;
|
||||
case 0x12: /*160x200x16*/
|
||||
def = 0x2c; /* I'm going to assume a datasheet erratum here. */
|
||||
coef = 16;
|
||||
break;
|
||||
case 0x03: /*640x200x4*/
|
||||
def = 0x56;
|
||||
coef = 8;
|
||||
break;
|
||||
case 0x01: /*80 column text*/
|
||||
def = 0x5a;
|
||||
coef = 8;
|
||||
break;
|
||||
case 0x00: /*40 column text*/
|
||||
default:
|
||||
def = 0x2c;
|
||||
coef = 16;
|
||||
break;
|
||||
case 0x02: /*320x200x4*/
|
||||
def = 0x2b;
|
||||
coef = 16;
|
||||
break;
|
||||
case 0x102: /*640x200x2*/
|
||||
def = 0x2b;
|
||||
coef = 16;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = pcjr->crtc[0x02] - def;
|
||||
|
||||
if (ret < -8)
|
||||
ret = -8;
|
||||
|
||||
if (ret > 8)
|
||||
ret = 8;
|
||||
|
||||
return ret * coef;
|
||||
}
|
||||
|
||||
static void
|
||||
vid_blit_h_overscan(pcjr_t *pcjr)
|
||||
{
|
||||
int cols = (pcjr->array[2] & 0xf) + 16;;
|
||||
int y0 = pcjr->firstline << 1;
|
||||
int y = (pcjr->lastline << 1) + 16;
|
||||
int ho_s = vid_get_h_overscan_size(pcjr);
|
||||
int i;
|
||||
int x;
|
||||
|
||||
if (pcjr->array[0] & 1)
|
||||
x = (pcjr->crtc[1] << 3) + ho_s;
|
||||
else
|
||||
x = (pcjr->crtc[1] << 4) + ho_s;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
hline(buffer32, 0, y0 + i, x, cols);
|
||||
hline(buffer32, 0, y + i, x, cols);
|
||||
|
||||
if (pcjr->composite) {
|
||||
Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[y0 + i]);
|
||||
Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[y + i]);
|
||||
} else {
|
||||
video_process_8(x, y0 + i);
|
||||
video_process_8(x, y + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vid_poll(void *priv)
|
||||
{
|
||||
pcjr_t *pcjr = (pcjr_t *) priv;
|
||||
uint16_t ca = (pcjr->crtc[15] | (pcjr->crtc[14] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x;
|
||||
int xs_temp;
|
||||
int ys_temp;
|
||||
int oldvc;
|
||||
uint8_t chr;
|
||||
uint8_t attr;
|
||||
uint16_t dat;
|
||||
int cols[4];
|
||||
int oldsc;
|
||||
int l = (pcjr->displine << 1) + 16;
|
||||
int ho_s = vid_get_h_overscan_size(pcjr);
|
||||
int ho_d = vid_get_h_overscan_delta(pcjr) + (ho_s / 2);
|
||||
|
||||
if (!pcjr->linepos) {
|
||||
timer_advance_u64(&pcjr->timer, pcjr->dispofftime);
|
||||
pcjr->stat &= ~1;
|
||||
pcjr->linepos = 1;
|
||||
oldsc = pcjr->sc;
|
||||
if ((pcjr->crtc[8] & 3) == 3)
|
||||
pcjr->sc = (pcjr->sc << 1) & 7;
|
||||
if (pcjr->dispon) {
|
||||
uint16_t offset = 0;
|
||||
uint16_t mask = 0x1fff;
|
||||
|
||||
if (pcjr->displine < pcjr->firstline) {
|
||||
pcjr->firstline = pcjr->displine;
|
||||
video_wait_for_buffer();
|
||||
}
|
||||
pcjr->lastline = pcjr->displine;
|
||||
cols[0] = (pcjr->array[2] & 0xf) + 16;
|
||||
|
||||
if (pcjr->array[0] & 1) {
|
||||
hline(buffer32, 0, l, (pcjr->crtc[1] << 3) + ho_s, cols[0]);
|
||||
hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 3) + ho_s, cols[0]);
|
||||
} else {
|
||||
hline(buffer32, 0, l, (pcjr->crtc[1] << 4) + ho_s, cols[0]);
|
||||
hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 4) + ho_s, cols[0]);
|
||||
}
|
||||
|
||||
switch (pcjr->addr_mode) {
|
||||
case 0: /*Alpha*/
|
||||
offset = 0;
|
||||
mask = 0x3fff;
|
||||
break;
|
||||
case 1: /*Low resolution graphics*/
|
||||
offset = (pcjr->sc & 1) * 0x2000;
|
||||
break;
|
||||
case 3: /*High resolution graphics*/
|
||||
offset = (pcjr->sc & 3) * 0x2000;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch ((pcjr->array[0] & 0x13) | ((pcjr->array[3] & 0x08) << 5)) {
|
||||
case 0x13: /*320x200x16*/
|
||||
for (x = 0; x < pcjr->crtc[1]; x++) {
|
||||
int ef_x = (x << 3) + ho_d;
|
||||
dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset] << 8) |
|
||||
pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1];
|
||||
pcjr->ma++;
|
||||
buffer32->line[l][ef_x] = buffer32->line[l][ef_x + 1] =
|
||||
buffer32->line[l + 1][ef_x] = buffer32->line[l + 1][ef_x + 1] =
|
||||
pcjr->array[((dat >> 12) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[l][ef_x + 2] = buffer32->line[l][ef_x + 3] =
|
||||
buffer32->line[l + 1][ef_x + 2] = buffer32->line[l + 1][ef_x + 3] =
|
||||
pcjr->array[((dat >> 8) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[l][ef_x + 4] = buffer32->line[l][ef_x + 5] =
|
||||
buffer32->line[l + 1][ef_x + 4] = buffer32->line[l + 1][ef_x + 5] =
|
||||
pcjr->array[((dat >> 4) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[l][ef_x + 6] = buffer32->line[l][ef_x + 7] =
|
||||
buffer32->line[l + 1][ef_x + 6] = buffer32->line[l + 1][ef_x + 7] =
|
||||
pcjr->array[(dat & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
}
|
||||
break;
|
||||
case 0x12: /*160x200x16*/
|
||||
for (x = 0; x < pcjr->crtc[1]; x++) {
|
||||
int ef_x = (x << 4) + ho_d;
|
||||
dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset] << 8) |
|
||||
pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1];
|
||||
pcjr->ma++;
|
||||
buffer32->line[l][ef_x] = buffer32->line[l][ef_x + 1] =
|
||||
buffer32->line[l][ef_x + 2] = buffer32->line[l][ef_x + 3] =
|
||||
buffer32->line[l + 1][ef_x] = buffer32->line[l + 1][ef_x + 1] =
|
||||
buffer32->line[l + 1][ef_x + 2] = buffer32->line[l + 1][ef_x + 3] =
|
||||
pcjr->array[((dat >> 12) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[l][ef_x + 4] = buffer32->line[l][ef_x + 5] =
|
||||
buffer32->line[l][ef_x + 6] = buffer32->line[l][ef_x + 7] =
|
||||
buffer32->line[l + 1][ef_x + 4] = buffer32->line[l + 1][ef_x + 5] =
|
||||
buffer32->line[l + 1][ef_x + 6] = buffer32->line[l + 1][ef_x + 7] =
|
||||
pcjr->array[((dat >> 8) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[l][ef_x + 8] = buffer32->line[l][ef_x + 9] =
|
||||
buffer32->line[l][ef_x + 10] = buffer32->line[l][ef_x + 11] =
|
||||
buffer32->line[l + 1][ef_x + 8] = buffer32->line[l + 1][ef_x + 9] =
|
||||
buffer32->line[l + 1][ef_x + 10] = buffer32->line[l + 1][ef_x + 11] =
|
||||
pcjr->array[((dat >> 4) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[l][ef_x + 12] = buffer32->line[l][ef_x + 13] =
|
||||
buffer32->line[l][ef_x + 14] = buffer32->line[l][ef_x + 15] =
|
||||
buffer32->line[l + 1][ef_x + 12] = buffer32->line[l + 1][ef_x + 13] =
|
||||
buffer32->line[l + 1][ef_x + 14] = buffer32->line[l + 1][ef_x + 15] =
|
||||
pcjr->array[(dat & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
}
|
||||
break;
|
||||
case 0x03: /*640x200x4*/
|
||||
for (x = 0; x < pcjr->crtc[1]; x++) {
|
||||
int ef_x = (x << 3) + ho_d;
|
||||
dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1] << 8) |
|
||||
pcjr->vram[((pcjr->ma << 1) & mask) + offset];
|
||||
pcjr->ma++;
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
chr = (dat >> 7) & 1;
|
||||
chr |= ((dat >> 14) & 2);
|
||||
buffer32->line[l][ef_x + c] = buffer32->line[l + 1][ef_x + c] =
|
||||
pcjr->array[(chr & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
dat <<= 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x01: /*80 column text*/
|
||||
for (x = 0; x < pcjr->crtc[1]; x++) {
|
||||
int ef_x = (x << 3) + ho_d;
|
||||
chr = pcjr->vram[((pcjr->ma << 1) & mask) + offset];
|
||||
attr = pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1];
|
||||
drawcursor = ((pcjr->ma == ca) && pcjr->con && pcjr->cursoron);
|
||||
if (pcjr->array[3] & 4) {
|
||||
cols[1] = pcjr->array[((attr & 15) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
if ((pcjr->blink & 16) && (attr & 0x80) && !drawcursor)
|
||||
cols[1] = cols[0];
|
||||
} else {
|
||||
cols[1] = pcjr->array[((attr & 15) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
}
|
||||
if (pcjr->sc & 8)
|
||||
for (uint8_t c = 0; c < 8; c++)
|
||||
buffer32->line[l][ef_x + c] =
|
||||
buffer32->line[l + 1][ef_x + c] = cols[0];
|
||||
else
|
||||
for (uint8_t c = 0; c < 8; c++)
|
||||
buffer32->line[l][ef_x + c] =
|
||||
buffer32->line[l + 1][ef_x + c] =
|
||||
cols[(fontdat[chr][pcjr->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
if (drawcursor)
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
buffer32->line[l][ef_x + c] ^= 15;
|
||||
buffer32->line[l + 1][ef_x + c] ^= 15;
|
||||
}
|
||||
pcjr->ma++;
|
||||
}
|
||||
break;
|
||||
case 0x00: /*40 column text*/
|
||||
for (x = 0; x < pcjr->crtc[1]; x++) {
|
||||
int ef_x = (x << 4) + ho_d;
|
||||
chr = pcjr->vram[((pcjr->ma << 1) & mask) + offset];
|
||||
attr = pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1];
|
||||
drawcursor = ((pcjr->ma == ca) && pcjr->con && pcjr->cursoron);
|
||||
if (pcjr->array[3] & 4) {
|
||||
cols[1] = pcjr->array[((attr & 15) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
if ((pcjr->blink & 16) && (attr & 0x80) && !drawcursor)
|
||||
cols[1] = cols[0];
|
||||
} else {
|
||||
cols[1] = pcjr->array[((attr & 15) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1] & 0x0f) + 16] + 16;
|
||||
}
|
||||
pcjr->ma++;
|
||||
if (pcjr->sc & 8)
|
||||
for (uint8_t c = 0; c < 8; c++)
|
||||
buffer32->line[l][ef_x + (c << 1)] =
|
||||
buffer32->line[l][ef_x + (c << 1) + 1] =
|
||||
buffer32->line[l + 1][ef_x + (c << 1)] =
|
||||
buffer32->line[l + 1][ef_x + (c << 1) + 1] = cols[0];
|
||||
else
|
||||
for (uint8_t c = 0; c < 8; c++)
|
||||
buffer32->line[l][ef_x + (c << 1)] =
|
||||
buffer32->line[l][ef_x + (c << 1) + 1] =
|
||||
buffer32->line[l + 1][ef_x + (c << 1)] =
|
||||
buffer32->line[l + 1][ef_x + (c << 1) + 1] =
|
||||
cols[(fontdat[chr][pcjr->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
if (drawcursor)
|
||||
for (uint8_t c = 0; c < 16; c++) {
|
||||
buffer32->line[l][ef_x + c] ^= 15;
|
||||
buffer32->line[l + 1][ef_x + c] ^= 15;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x02: /*320x200x4*/
|
||||
cols[0] = pcjr->array[0 + 16] + 16;
|
||||
cols[1] = pcjr->array[1 + 16] + 16;
|
||||
cols[2] = pcjr->array[2 + 16] + 16;
|
||||
cols[3] = pcjr->array[3 + 16] + 16;
|
||||
for (x = 0; x < pcjr->crtc[1]; x++) {
|
||||
int ef_x = (x << 4) + ho_d;
|
||||
dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset] << 8) |
|
||||
pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1];
|
||||
pcjr->ma++;
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
buffer32->line[l][ef_x + (c << 1)] =
|
||||
buffer32->line[l][ef_x + (c << 1) + 1] =
|
||||
buffer32->line[l + 1][ef_x + (c << 1)] =
|
||||
buffer32->line[l + 1][ef_x + (c << 1) + 1] = cols[dat >> 14];
|
||||
dat <<= 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x102: /*640x200x2*/
|
||||
cols[0] = pcjr->array[0 + 16] + 16;
|
||||
cols[1] = pcjr->array[1 + 16] + 16;
|
||||
for (x = 0; x < pcjr->crtc[1]; x++) {
|
||||
int ef_x = (x << 4) + ho_d;
|
||||
dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset] << 8) |
|
||||
pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1];
|
||||
pcjr->ma++;
|
||||
for (uint8_t c = 0; c < 16; c++) {
|
||||
buffer32->line[l][ef_x + c] = buffer32->line[l + 1][ef_x + c] =
|
||||
cols[dat >> 15];
|
||||
dat <<= 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (pcjr->array[3] & 4) {
|
||||
if (pcjr->array[0] & 1) {
|
||||
hline(buffer32, 0, l, (pcjr->crtc[1] << 3) + ho_s, (pcjr->array[2] & 0xf) + 16);
|
||||
hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 3) + ho_s, (pcjr->array[2] & 0xf) + 16);
|
||||
} else {
|
||||
hline(buffer32, 0, l, (pcjr->crtc[1] << 4) + ho_s, (pcjr->array[2] & 0xf) + 16);
|
||||
hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 4) + ho_s, (pcjr->array[2] & 0xf) + 16);
|
||||
}
|
||||
} else {
|
||||
cols[0] = pcjr->array[0 + 16] + 16;
|
||||
if (pcjr->array[0] & 1) {
|
||||
hline(buffer32, 0, l, (pcjr->crtc[1] << 3) + ho_s, cols[0]);
|
||||
hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 3) + ho_s, cols[0]);
|
||||
} else {
|
||||
hline(buffer32, 0, l, (pcjr->crtc[1] << 4) + ho_s, cols[0]);
|
||||
hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 4) + ho_s, cols[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pcjr->array[0] & 1)
|
||||
x = (pcjr->crtc[1] << 3) + ho_s;
|
||||
else
|
||||
x = (pcjr->crtc[1] << 4) + ho_s;
|
||||
if (pcjr->composite) {
|
||||
Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[l]);
|
||||
Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[l + 1]);
|
||||
} else {
|
||||
video_process_8(x, l);
|
||||
video_process_8(x, l + 1);
|
||||
}
|
||||
pcjr->sc = oldsc;
|
||||
if (pcjr->vc == pcjr->crtc[7] && !pcjr->sc) {
|
||||
pcjr->stat |= 8;
|
||||
}
|
||||
pcjr->displine++;
|
||||
if (pcjr->displine >= 360)
|
||||
pcjr->displine = 0;
|
||||
} else {
|
||||
timer_advance_u64(&pcjr->timer, pcjr->dispontime);
|
||||
if (pcjr->dispon)
|
||||
pcjr->stat |= 1;
|
||||
pcjr->linepos = 0;
|
||||
if (pcjr->vsynctime) {
|
||||
pcjr->vsynctime--;
|
||||
if (!pcjr->vsynctime) {
|
||||
pcjr->stat &= ~8;
|
||||
}
|
||||
}
|
||||
if (pcjr->sc == (pcjr->crtc[11] & 31) || ((pcjr->crtc[8] & 3) == 3 && pcjr->sc == ((pcjr->crtc[11] & 31) >> 1))) {
|
||||
pcjr->con = 0;
|
||||
}
|
||||
if (pcjr->vadj) {
|
||||
pcjr->sc++;
|
||||
pcjr->sc &= 31;
|
||||
pcjr->ma = pcjr->maback;
|
||||
pcjr->vadj--;
|
||||
if (!pcjr->vadj) {
|
||||
pcjr->dispon = 1;
|
||||
pcjr->ma = pcjr->maback = (pcjr->crtc[13] | (pcjr->crtc[12] << 8)) & 0x3fff;
|
||||
pcjr->sc = 0;
|
||||
}
|
||||
} else if (pcjr->sc == pcjr->crtc[9] || ((pcjr->crtc[8] & 3) == 3 && pcjr->sc == (pcjr->crtc[9] >> 1))) {
|
||||
pcjr->maback = pcjr->ma;
|
||||
pcjr->sc = 0;
|
||||
oldvc = pcjr->vc;
|
||||
pcjr->vc++;
|
||||
pcjr->vc &= 127;
|
||||
if (pcjr->vc == pcjr->crtc[6])
|
||||
pcjr->dispon = 0;
|
||||
if (oldvc == pcjr->crtc[4]) {
|
||||
pcjr->vc = 0;
|
||||
pcjr->vadj = pcjr->crtc[5];
|
||||
if (!pcjr->vadj)
|
||||
pcjr->dispon = 1;
|
||||
if (!pcjr->vadj)
|
||||
pcjr->ma = pcjr->maback = (pcjr->crtc[13] | (pcjr->crtc[12] << 8)) & 0x3fff;
|
||||
if ((pcjr->crtc[10] & 0x60) == 0x20)
|
||||
pcjr->cursoron = 0;
|
||||
else
|
||||
pcjr->cursoron = pcjr->blink & 16;
|
||||
}
|
||||
if (pcjr->vc == pcjr->crtc[7]) {
|
||||
pcjr->dispon = 0;
|
||||
pcjr->displine = 0;
|
||||
pcjr->vsynctime = 16;
|
||||
picint(1 << 5);
|
||||
if (pcjr->crtc[7]) {
|
||||
if (pcjr->array[0] & 1)
|
||||
x = (pcjr->crtc[1] << 3) + ho_s;
|
||||
else
|
||||
x = (pcjr->crtc[1] << 4) + ho_s;
|
||||
pcjr->lastline++;
|
||||
|
||||
xs_temp = x;
|
||||
ys_temp = (pcjr->lastline - pcjr->firstline) << 1;
|
||||
|
||||
if ((xs_temp > 0) && (ys_temp > 0)) {
|
||||
int actual_ys = ys_temp;
|
||||
|
||||
if (xs_temp < 64)
|
||||
xs_temp = 656;
|
||||
if (ys_temp < 32)
|
||||
ys_temp = 400;
|
||||
if (!enable_overscan)
|
||||
xs_temp -= ho_s;
|
||||
|
||||
if ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get()) {
|
||||
xsize = xs_temp;
|
||||
ysize = ys_temp;
|
||||
|
||||
set_screen_size(xsize, ysize + (enable_overscan ? 32 : 0));
|
||||
|
||||
if (video_force_resize_get())
|
||||
video_force_resize_set(0);
|
||||
}
|
||||
|
||||
vid_blit_h_overscan(pcjr);
|
||||
|
||||
if (enable_overscan) {
|
||||
video_blit_memtoscreen(0, pcjr->firstline << 1,
|
||||
xsize, actual_ys + 32);
|
||||
} else if (pcjr->apply_hd) {
|
||||
video_blit_memtoscreen(ho_s / 2, (pcjr->firstline << 1) + 16,
|
||||
xsize, actual_ys);
|
||||
} else {
|
||||
video_blit_memtoscreen(ho_d, (pcjr->firstline << 1) + 16,
|
||||
xsize, actual_ys);
|
||||
}
|
||||
}
|
||||
|
||||
frames++;
|
||||
video_res_x = xsize;
|
||||
video_res_y = ysize;
|
||||
}
|
||||
pcjr->firstline = 1000;
|
||||
pcjr->lastline = 0;
|
||||
pcjr->blink++;
|
||||
}
|
||||
} else {
|
||||
pcjr->sc++;
|
||||
pcjr->sc &= 31;
|
||||
pcjr->ma = pcjr->maback;
|
||||
}
|
||||
if (pcjr->sc == (pcjr->crtc[10] & 31) || ((pcjr->crtc[8] & 3) == 3 && pcjr->sc == ((pcjr->crtc[10] & 31) >> 1)))
|
||||
pcjr->con = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
kbd_write(uint16_t port, uint8_t val, void *priv)
|
||||
@@ -1433,35 +756,7 @@ speed_changed(void *priv)
|
||||
{
|
||||
pcjr_t *pcjr = (pcjr_t *) priv;
|
||||
|
||||
recalc_timings(pcjr);
|
||||
}
|
||||
|
||||
static void
|
||||
pcjr_vid_init(pcjr_t *pcjr)
|
||||
{
|
||||
int display_type;
|
||||
|
||||
video_inform(VIDEO_FLAG_TYPE_CGA, &timing_dram);
|
||||
|
||||
pcjr->memctrl = -1;
|
||||
if (mem_size < 128)
|
||||
pcjr->memctrl &= ~0x24;
|
||||
|
||||
display_type = device_get_config_int("display_type");
|
||||
pcjr->composite = (display_type != PCJR_RGB);
|
||||
pcjr->apply_hd = device_get_config_int("apply_hd");
|
||||
overscan_x = 256;
|
||||
overscan_y = 32;
|
||||
|
||||
mem_mapping_add(&pcjr->mapping, 0xb8000, 0x08000,
|
||||
vid_read, NULL, NULL,
|
||||
vid_write, NULL, NULL, NULL, 0, pcjr);
|
||||
io_sethandler(0x03d0, 16,
|
||||
vid_in, NULL, NULL, vid_out, NULL, NULL, pcjr);
|
||||
timer_add(&pcjr->timer, vid_poll, pcjr, 1);
|
||||
|
||||
cga_palette = 0;
|
||||
cgapal_rebuild();
|
||||
pcjr_recalc_timings(pcjr);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1487,9 +782,11 @@ static const device_config_t pcjr_config[] = {
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "RGB", .value = PCJR_RGB },
|
||||
{ .description = "Composite", .value = PCJR_COMPOSITE },
|
||||
{ .description = "" }
|
||||
{ .description = "RGB", .value = PCJR_RGB },
|
||||
{ .description = "Composite", .value = PCJR_COMPOSITE },
|
||||
{ .description = "RGB (no brown)", .value = PCJR_RGB_NO_BROWN },
|
||||
{ .description = "RGB (IBM 5153)", .value = PCJR_RGB_IBM_5153 },
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -44,12 +44,9 @@
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_cga_comp.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/m_tandy.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
enum {
|
||||
TANDY_RGB = 0,
|
||||
TANDY_COMPOSITE
|
||||
};
|
||||
|
||||
enum {
|
||||
TYPE_TANDY = 0,
|
||||
@@ -65,79 +62,6 @@ enum {
|
||||
EEPROM_WRITE
|
||||
};
|
||||
|
||||
typedef struct t1kvid_t {
|
||||
mem_mapping_t mapping;
|
||||
mem_mapping_t vram_mapping;
|
||||
|
||||
uint8_t crtc[32];
|
||||
int crtcreg;
|
||||
|
||||
int array_index;
|
||||
uint8_t array[256];
|
||||
int memctrl;
|
||||
uint8_t mode;
|
||||
uint8_t col;
|
||||
uint8_t stat;
|
||||
|
||||
uint8_t *vram;
|
||||
uint8_t *b8000;
|
||||
uint32_t b8000_mask;
|
||||
uint32_t b8000_limit;
|
||||
uint8_t planar_ctrl;
|
||||
uint8_t lp_strobe;
|
||||
|
||||
int linepos;
|
||||
int displine;
|
||||
int sc;
|
||||
int vc;
|
||||
int dispon;
|
||||
int con;
|
||||
int cursoron;
|
||||
int blink;
|
||||
int fullchange;
|
||||
int vsynctime;
|
||||
int vadj;
|
||||
uint16_t ma;
|
||||
uint16_t maback;
|
||||
|
||||
uint64_t dispontime;
|
||||
uint64_t dispofftime;
|
||||
pc_timer_t timer;
|
||||
int firstline;
|
||||
int lastline;
|
||||
|
||||
int composite;
|
||||
} t1kvid_t;
|
||||
|
||||
typedef struct t1keep_t {
|
||||
char *path;
|
||||
|
||||
int state;
|
||||
int count;
|
||||
int addr;
|
||||
int clk;
|
||||
uint16_t data;
|
||||
uint16_t store[64];
|
||||
} t1keep_t;
|
||||
|
||||
typedef struct tandy_t {
|
||||
mem_mapping_t ram_mapping;
|
||||
mem_mapping_t rom_mapping; /* SL2 */
|
||||
|
||||
uint8_t *rom; /* SL2 */
|
||||
uint8_t ram_bank;
|
||||
uint8_t rom_bank; /* SL2 */
|
||||
int rom_offset; /* SL2 */
|
||||
|
||||
uint32_t base;
|
||||
uint32_t mask;
|
||||
int is_hx;
|
||||
int is_sl2;
|
||||
|
||||
t1kvid_t *vid;
|
||||
} tandy_t;
|
||||
|
||||
static video_timings_t timing_dram = { VIDEO_BUS, 0, 0, 0, 0, 0, 0 }; /*No additional waitstates*/
|
||||
|
||||
static const scancode scancode_tandy[512] = {
|
||||
// clang-format off
|
||||
@@ -655,22 +579,8 @@ static const scancode scancode_tandy[512] = {
|
||||
{ .mk = { 0 }, .brk = { 0 } } /* 1ff */
|
||||
// clang-format on
|
||||
};
|
||||
static uint8_t crtcmask[32] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f,
|
||||
0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static uint8_t crtcmask_sl[32] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff,
|
||||
0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static int eep_data_out;
|
||||
|
||||
static uint8_t vid_in(uint16_t addr, void *priv);
|
||||
static void vid_out(uint16_t addr, uint8_t val, void *priv);
|
||||
static int eep_data_out;
|
||||
|
||||
#ifdef ENABLE_TANDY_LOG
|
||||
int tandy_do_log = ENABLE_TANDY_LOG;
|
||||
@@ -690,762 +600,7 @@ tandy_log(const char *fmt, ...)
|
||||
# define tandy_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static void
|
||||
recalc_mapping(tandy_t *dev)
|
||||
{
|
||||
t1kvid_t *vid = dev->vid;
|
||||
|
||||
mem_mapping_disable(&vid->mapping);
|
||||
io_removehandler(0x03d0, 16,
|
||||
vid_in, NULL, NULL, vid_out, NULL, NULL, dev);
|
||||
|
||||
if (vid->planar_ctrl & 4) {
|
||||
mem_mapping_enable(&vid->mapping);
|
||||
if (vid->array[5] & 1)
|
||||
mem_mapping_set_addr(&vid->mapping, 0xa0000, 0x10000);
|
||||
else
|
||||
mem_mapping_set_addr(&vid->mapping, 0xb8000, 0x8000);
|
||||
io_sethandler(0x03d0, 16, vid_in, NULL, NULL, vid_out, NULL, NULL, dev);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
recalc_timings(tandy_t *dev)
|
||||
{
|
||||
t1kvid_t *vid = dev->vid;
|
||||
|
||||
double _dispontime;
|
||||
double _dispofftime;
|
||||
double disptime;
|
||||
|
||||
if (vid->mode & 1) {
|
||||
disptime = vid->crtc[0] + 1;
|
||||
_dispontime = vid->crtc[1];
|
||||
} else {
|
||||
disptime = (vid->crtc[0] + 1) << 1;
|
||||
_dispontime = vid->crtc[1] << 1;
|
||||
}
|
||||
|
||||
_dispofftime = disptime - _dispontime;
|
||||
_dispontime *= CGACONST;
|
||||
_dispofftime *= CGACONST;
|
||||
vid->dispontime = (uint64_t) (_dispontime);
|
||||
vid->dispofftime = (uint64_t) (_dispofftime);
|
||||
}
|
||||
|
||||
static void
|
||||
recalc_address(tandy_t *dev)
|
||||
{
|
||||
t1kvid_t *vid = dev->vid;
|
||||
|
||||
if ((vid->memctrl & 0xc0) == 0xc0) {
|
||||
vid->vram = &ram[((vid->memctrl & 0x06) << 14) + dev->base];
|
||||
vid->b8000 = &ram[((vid->memctrl & 0x30) << 11) + dev->base];
|
||||
vid->b8000_mask = 0x7fff;
|
||||
} else {
|
||||
vid->vram = &ram[((vid->memctrl & 0x07) << 14) + dev->base];
|
||||
vid->b8000 = &ram[((vid->memctrl & 0x38) << 11) + dev->base];
|
||||
vid->b8000_mask = 0x3fff;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
recalc_address_sl(tandy_t *dev)
|
||||
{
|
||||
t1kvid_t *vid = dev->vid;
|
||||
|
||||
vid->b8000_limit = 0x8000;
|
||||
|
||||
if (vid->array[5] & 1) {
|
||||
vid->vram = &ram[((vid->memctrl & 0x04) << 14) + dev->base];
|
||||
vid->b8000 = &ram[((vid->memctrl & 0x20) << 11) + dev->base];
|
||||
} else if ((vid->memctrl & 0xc0) == 0xc0) {
|
||||
vid->vram = &ram[((vid->memctrl & 0x06) << 14) + dev->base];
|
||||
vid->b8000 = &ram[((vid->memctrl & 0x30) << 11) + dev->base];
|
||||
} else {
|
||||
vid->vram = &ram[((vid->memctrl & 0x07) << 14) + dev->base];
|
||||
vid->b8000 = &ram[((vid->memctrl & 0x38) << 11) + dev->base];
|
||||
if ((vid->memctrl & 0x38) == 0x38)
|
||||
vid->b8000_limit = 0x4000;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vid_update_latch(t1kvid_t *vid)
|
||||
{
|
||||
uint32_t lp_latch = vid->displine * vid->crtc[1];
|
||||
|
||||
vid->crtc[0x10] = (lp_latch >> 8) & 0x3f;
|
||||
vid->crtc[0x11] = lp_latch & 0xff;
|
||||
}
|
||||
|
||||
static void
|
||||
vid_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
tandy_t *dev = (tandy_t *) priv;
|
||||
t1kvid_t *vid = dev->vid;
|
||||
uint8_t old;
|
||||
|
||||
if ((addr >= 0x3d0) && (addr <= 0x3d7))
|
||||
addr = (addr & 0xff9) | 0x004;
|
||||
|
||||
switch (addr) {
|
||||
case 0x03d4:
|
||||
vid->crtcreg = val & 0x1f;
|
||||
break;
|
||||
|
||||
case 0x03d5:
|
||||
old = vid->crtc[vid->crtcreg];
|
||||
if (dev->is_sl2)
|
||||
vid->crtc[vid->crtcreg] = val & crtcmask_sl[vid->crtcreg];
|
||||
else
|
||||
vid->crtc[vid->crtcreg] = val & crtcmask[vid->crtcreg];
|
||||
if (old != val) {
|
||||
if (vid->crtcreg < 0xe || vid->crtcreg > 0x10) {
|
||||
vid->fullchange = changeframecount;
|
||||
recalc_timings(dev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x03d8:
|
||||
old = vid->mode;
|
||||
vid->mode = val;
|
||||
if ((old ^ val) & 0x01)
|
||||
recalc_timings(dev);
|
||||
if (!dev->is_sl2)
|
||||
update_cga16_color(vid->mode);
|
||||
break;
|
||||
|
||||
case 0x03d9:
|
||||
vid->col = val;
|
||||
break;
|
||||
|
||||
case 0x03da:
|
||||
vid->array_index = val & 0x1f;
|
||||
break;
|
||||
|
||||
case 0x3db:
|
||||
if (!dev->is_sl2 && (vid->lp_strobe == 1))
|
||||
vid->lp_strobe = 0;
|
||||
break;
|
||||
|
||||
case 0x3dc:
|
||||
if (!dev->is_sl2 && (vid->lp_strobe == 0)) {
|
||||
vid->lp_strobe = 1;
|
||||
vid_update_latch(vid);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x03de:
|
||||
if (vid->array_index & 16)
|
||||
val &= 0xf;
|
||||
vid->array[vid->array_index & 0x1f] = val;
|
||||
if (dev->is_sl2) {
|
||||
if ((vid->array_index & 0x1f) == 5) {
|
||||
recalc_mapping(dev);
|
||||
recalc_address_sl(dev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x03df:
|
||||
vid->memctrl = val;
|
||||
if (dev->is_sl2)
|
||||
recalc_address_sl(dev);
|
||||
else
|
||||
recalc_address(dev);
|
||||
break;
|
||||
|
||||
case 0x0065:
|
||||
if (val == 8)
|
||||
return; /*Hack*/
|
||||
vid->planar_ctrl = val;
|
||||
recalc_mapping(dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
vid_in(uint16_t addr, void *priv)
|
||||
{
|
||||
const tandy_t *dev = (tandy_t *) priv;
|
||||
t1kvid_t *vid = dev->vid;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if ((addr >= 0x3d0) && (addr <= 0x3d7))
|
||||
addr = (addr & 0xff9) | 0x004;
|
||||
|
||||
switch (addr) {
|
||||
case 0x03d4:
|
||||
ret = vid->crtcreg;
|
||||
break;
|
||||
|
||||
case 0x03d5:
|
||||
ret = vid->crtc[vid->crtcreg];
|
||||
break;
|
||||
|
||||
case 0x03da:
|
||||
ret = vid->stat;
|
||||
break;
|
||||
|
||||
case 0x3db:
|
||||
if (!dev->is_sl2 && (vid->lp_strobe == 1))
|
||||
vid->lp_strobe = 0;
|
||||
break;
|
||||
|
||||
case 0x3dc:
|
||||
if (!dev->is_sl2 && (vid->lp_strobe == 0)) {
|
||||
vid->lp_strobe = 1;
|
||||
vid_update_latch(vid);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
vid_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
tandy_t *dev = (tandy_t *) priv;
|
||||
t1kvid_t *vid = dev->vid;
|
||||
|
||||
if (vid->memctrl == -1)
|
||||
return;
|
||||
|
||||
if (dev->is_sl2) {
|
||||
if (vid->array[5] & 1)
|
||||
vid->b8000[addr & 0xffff] = val;
|
||||
else {
|
||||
if ((addr & 0x7fff) < vid->b8000_limit)
|
||||
vid->b8000[addr & 0x7fff] = val;
|
||||
}
|
||||
} else {
|
||||
vid->b8000[addr & vid->b8000_mask] = val;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
vid_read(uint32_t addr, void *priv)
|
||||
{
|
||||
const tandy_t *dev = (tandy_t *) priv;
|
||||
const t1kvid_t *vid = dev->vid;
|
||||
|
||||
if (vid->memctrl == -1)
|
||||
return 0xff;
|
||||
|
||||
if (dev->is_sl2) {
|
||||
if (vid->array[5] & 1)
|
||||
return (vid->b8000[addr & 0xffff]);
|
||||
if ((addr & 0x7fff) < vid->b8000_limit)
|
||||
return (vid->b8000[addr & 0x7fff]);
|
||||
else
|
||||
return 0xff;
|
||||
} else {
|
||||
return (vid->b8000[addr & vid->b8000_mask]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vid_poll(void *priv)
|
||||
{
|
||||
tandy_t *dev = (tandy_t *) priv;
|
||||
t1kvid_t *vid = dev->vid;
|
||||
uint16_t ca = (vid->crtc[15] | (vid->crtc[14] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x;
|
||||
int c;
|
||||
int xs_temp;
|
||||
int ys_temp;
|
||||
int oldvc;
|
||||
uint8_t chr;
|
||||
uint8_t attr;
|
||||
uint16_t dat;
|
||||
int cols[4];
|
||||
int col;
|
||||
int oldsc;
|
||||
|
||||
if (!vid->linepos) {
|
||||
timer_advance_u64(&vid->timer, vid->dispofftime);
|
||||
vid->stat |= 1;
|
||||
vid->linepos = 1;
|
||||
oldsc = vid->sc;
|
||||
if ((vid->crtc[8] & 3) == 3)
|
||||
vid->sc = (vid->sc << 1) & 7;
|
||||
if (vid->dispon) {
|
||||
if (vid->displine < vid->firstline) {
|
||||
vid->firstline = vid->displine;
|
||||
video_wait_for_buffer();
|
||||
}
|
||||
vid->lastline = vid->displine;
|
||||
cols[0] = (vid->array[2] & 0xf) + 16;
|
||||
for (c = 0; c < 8; c++) {
|
||||
if (vid->array[3] & 4) {
|
||||
buffer32->line[vid->displine << 1][c] = buffer32->line[(vid->displine << 1) + 1][c] = cols[0];
|
||||
if (vid->mode & 1) {
|
||||
buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 3) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 3) + 8] = cols[0];
|
||||
} else {
|
||||
buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 4) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 4) + 8] = cols[0];
|
||||
}
|
||||
} else if ((vid->mode & 0x12) == 0x12) {
|
||||
buffer32->line[vid->displine << 1][c] = buffer32->line[(vid->displine << 1) + 1][c] = 0;
|
||||
if (vid->mode & 1) {
|
||||
buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 3) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 3) + 8] = 0;
|
||||
} else {
|
||||
buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 4) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 4) + 8] = 0;
|
||||
}
|
||||
} else {
|
||||
buffer32->line[vid->displine << 1][c] = buffer32->line[(vid->displine << 1) + 1][c] = (vid->col & 15) + 16;
|
||||
if (vid->mode & 1) {
|
||||
buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 3) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 3) + 8] = (vid->col & 15) + 16;
|
||||
} else {
|
||||
buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 4) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 4) + 8] = (vid->col & 15) + 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dev->is_sl2 && (vid->array[5] & 1)) { /*640x200x16*/
|
||||
for (x = 0; x < vid->crtc[1] * 2; x++) {
|
||||
dat = (vid->vram[(vid->ma << 1) & 0xffff] << 8) | vid->vram[((vid->ma << 1) + 1) & 0xffff];
|
||||
vid->ma++;
|
||||
buffer32->line[vid->displine << 1][(x << 2) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 2) + 8] = vid->array[((dat >> 12) & 0xf) + 16] + 16;
|
||||
buffer32->line[vid->displine << 1][(x << 2) + 9] = buffer32->line[(vid->displine << 1) + 1][(x << 2) + 9] = vid->array[((dat >> 8) & 0xf) + 16] + 16;
|
||||
buffer32->line[vid->displine << 1][(x << 2) + 10] = buffer32->line[(vid->displine << 1) + 1][(x << 2) + 10] = vid->array[((dat >> 4) & 0xf) + 16] + 16;
|
||||
buffer32->line[vid->displine << 1][(x << 2) + 11] = buffer32->line[(vid->displine << 1) + 1][(x << 2) + 11] = vid->array[(dat & 0xf) + 16] + 16;
|
||||
}
|
||||
} else if ((vid->array[3] & 0x10) && (vid->mode & 1)) { /*320x200x16*/
|
||||
for (x = 0; x < vid->crtc[1]; x++) {
|
||||
dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000)] << 8) | vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000) + 1];
|
||||
vid->ma++;
|
||||
buffer32->line[vid->displine << 1][(x << 3) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 8] = buffer32->line[vid->displine << 1][(x << 3) + 9] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 9] = vid->array[((dat >> 12) & vid->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[vid->displine << 1][(x << 3) + 10] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 10] = buffer32->line[vid->displine << 1][(x << 3) + 11] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 11] = vid->array[((dat >> 8) & vid->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[vid->displine << 1][(x << 3) + 12] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 12] = buffer32->line[vid->displine << 1][(x << 3) + 13] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 13] = vid->array[((dat >> 4) & vid->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[vid->displine << 1][(x << 3) + 14] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 14] = buffer32->line[vid->displine << 1][(x << 3) + 15] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 15] = vid->array[(dat & vid->array[1] & 0x0f) + 16] + 16;
|
||||
}
|
||||
} else if (vid->array[3] & 0x10) { /*160x200x16*/
|
||||
for (x = 0; x < vid->crtc[1]; x++) {
|
||||
if (dev->is_sl2) {
|
||||
dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000)] << 8) | vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000) + 1];
|
||||
} else {
|
||||
dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000)] << 8) | vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000) + 1];
|
||||
}
|
||||
vid->ma++;
|
||||
buffer32->line[vid->displine << 1][(x << 4) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 8] = buffer32->line[vid->displine << 1][(x << 4) + 9] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 9] = buffer32->line[vid->displine << 1][(x << 4) + 10] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 10] = buffer32->line[vid->displine << 1][(x << 4) + 11] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 11] = vid->array[((dat >> 12) & vid->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[vid->displine << 1][(x << 4) + 12] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 12] = buffer32->line[vid->displine << 1][(x << 4) + 13] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 13] = buffer32->line[vid->displine << 1][(x << 4) + 14] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 14] = buffer32->line[vid->displine << 1][(x << 4) + 15] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 15] = vid->array[((dat >> 8) & vid->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[vid->displine << 1][(x << 4) + 16] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 16] = buffer32->line[vid->displine << 1][(x << 4) + 17] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 17] = buffer32->line[vid->displine << 1][(x << 4) + 18] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 18] = buffer32->line[vid->displine << 1][(x << 4) + 19] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 19] = vid->array[((dat >> 4) & vid->array[1] & 0x0f) + 16] + 16;
|
||||
buffer32->line[vid->displine << 1][(x << 4) + 20] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 20] = buffer32->line[vid->displine << 1][(x << 4) + 21] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 21] = buffer32->line[vid->displine << 1][(x << 4) + 22] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 22] = buffer32->line[vid->displine << 1][(x << 4) + 23] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 23] = vid->array[(dat & vid->array[1] & 0x0f) + 16] + 16;
|
||||
}
|
||||
} else if (vid->array[3] & 0x08) { /*640x200x4 - this implementation is a complete guess!*/
|
||||
for (x = 0; x < vid->crtc[1]; x++) {
|
||||
dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000)] << 8) | vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000) + 1];
|
||||
vid->ma++;
|
||||
for (c = 0; c < 8; c++) {
|
||||
chr = (dat >> 6) & 2;
|
||||
chr |= ((dat >> 15) & 1);
|
||||
buffer32->line[vid->displine << 1][(x << 3) + 8 + c] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 8 + c] = vid->array[(chr & vid->array[1]) + 16] + 16;
|
||||
dat <<= 1;
|
||||
}
|
||||
}
|
||||
} else if (vid->mode & 1) {
|
||||
for (x = 0; x < vid->crtc[1]; x++) {
|
||||
chr = vid->vram[(vid->ma << 1) & 0x3fff];
|
||||
attr = vid->vram[((vid->ma << 1) + 1) & 0x3fff];
|
||||
drawcursor = ((vid->ma == ca) && vid->con && vid->cursoron);
|
||||
if (vid->mode & 0x20) {
|
||||
cols[1] = vid->array[((attr & 15) & vid->array[1]) + 16] + 16;
|
||||
cols[0] = vid->array[(((attr >> 4) & 7) & vid->array[1]) + 16] + 16;
|
||||
if ((vid->blink & 16) && (attr & 0x80) && !drawcursor)
|
||||
cols[1] = cols[0];
|
||||
} else {
|
||||
cols[1] = vid->array[((attr & 15) & vid->array[1]) + 16] + 16;
|
||||
cols[0] = vid->array[((attr >> 4) & vid->array[1]) + 16] + 16;
|
||||
}
|
||||
if (vid->sc & 8) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[vid->displine << 1][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] = cols[0];
|
||||
}
|
||||
} else {
|
||||
for (c = 0; c < 8; c++) {
|
||||
if (vid->sc == 8) {
|
||||
buffer32->line[vid->displine << 1][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
} else {
|
||||
buffer32->line[vid->displine << 1][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[vid->displine << 1][(x << 3) + c + 8] ^= 15;
|
||||
buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] ^= 15;
|
||||
}
|
||||
}
|
||||
vid->ma++;
|
||||
}
|
||||
} else if (!(vid->mode & 2)) {
|
||||
for (x = 0; x < vid->crtc[1]; x++) {
|
||||
chr = vid->vram[(vid->ma << 1) & 0x3fff];
|
||||
attr = vid->vram[((vid->ma << 1) + 1) & 0x3fff];
|
||||
drawcursor = ((vid->ma == ca) && vid->con && vid->cursoron);
|
||||
if (vid->mode & 0x20) {
|
||||
cols[1] = vid->array[((attr & 15) & vid->array[1]) + 16] + 16;
|
||||
cols[0] = vid->array[(((attr >> 4) & 7) & vid->array[1]) + 16] + 16;
|
||||
if ((vid->blink & 16) && (attr & 0x80) && !drawcursor)
|
||||
cols[1] = cols[0];
|
||||
} else {
|
||||
cols[1] = vid->array[((attr & 15) & vid->array[1]) + 16] + 16;
|
||||
cols[0] = vid->array[((attr >> 4) & vid->array[1]) + 16] + 16;
|
||||
}
|
||||
vid->ma++;
|
||||
if (vid->sc & 8) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = cols[0];
|
||||
} else {
|
||||
for (c = 0; c < 8; c++) {
|
||||
if (vid->sc == 8) {
|
||||
buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
} else {
|
||||
buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 16; c++) {
|
||||
buffer32->line[vid->displine << 1][(x << 4) + c + 8] ^= 15;
|
||||
buffer32->line[(vid->displine << 1) + 1][(x << 4) + c + 8] ^= 15;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!(vid->mode & 16)) {
|
||||
cols[0] = (vid->col & 15);
|
||||
col = (vid->col & 16) ? 8 : 0;
|
||||
if (vid->mode & 4) {
|
||||
cols[1] = col | 3;
|
||||
cols[2] = col | 4;
|
||||
cols[3] = col | 7;
|
||||
} else if (vid->col & 32) {
|
||||
cols[1] = col | 3;
|
||||
cols[2] = col | 5;
|
||||
cols[3] = col | 7;
|
||||
} else {
|
||||
cols[1] = col | 2;
|
||||
cols[2] = col | 4;
|
||||
cols[3] = col | 6;
|
||||
}
|
||||
cols[0] = vid->array[(cols[0] & vid->array[1]) + 16] + 16;
|
||||
cols[1] = vid->array[(cols[1] & vid->array[1]) + 16] + 16;
|
||||
cols[2] = vid->array[(cols[2] & vid->array[1]) + 16] + 16;
|
||||
cols[3] = vid->array[(cols[3] & vid->array[1]) + 16] + 16;
|
||||
for (x = 0; x < vid->crtc[1]; x++) {
|
||||
dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000)] << 8) | vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000) + 1];
|
||||
vid->ma++;
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14];
|
||||
dat <<= 2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cols[0] = 0;
|
||||
cols[1] = vid->array[(vid->col & vid->array[1]) + 16] + 16;
|
||||
for (x = 0; x < vid->crtc[1]; x++) {
|
||||
dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000)] << 8) | vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000) + 1];
|
||||
vid->ma++;
|
||||
for (c = 0; c < 16; c++) {
|
||||
buffer32->line[vid->displine << 1][(x << 4) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + c + 8] = cols[dat >> 15];
|
||||
dat <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (vid->array[3] & 4) {
|
||||
if (vid->mode & 1) {
|
||||
hline(buffer32, 0, (vid->displine << 1), (vid->crtc[1] << 3) + 16, (vid->array[2] & 0xf) + 16);
|
||||
hline(buffer32, 0, (vid->displine << 1) + 1, (vid->crtc[1] << 3) + 16, (vid->array[2] & 0xf) + 16);
|
||||
} else {
|
||||
hline(buffer32, 0, (vid->displine << 1), (vid->crtc[1] << 4) + 16, (vid->array[2] & 0xf) + 16);
|
||||
hline(buffer32, 0, (vid->displine << 1) + 1, (vid->crtc[1] << 4) + 16, (vid->array[2] & 0xf) + 16);
|
||||
}
|
||||
} else {
|
||||
cols[0] = ((vid->mode & 0x12) == 0x12) ? 0 : (vid->col & 0xf) + 16;
|
||||
if (vid->mode & 1) {
|
||||
hline(buffer32, 0, (vid->displine << 1), (vid->crtc[1] << 3) + 16, cols[0]);
|
||||
hline(buffer32, 0, (vid->displine << 1) + 1, (vid->crtc[1] << 3) + 16, cols[0]);
|
||||
} else {
|
||||
hline(buffer32, 0, (vid->displine << 1), (vid->crtc[1] << 4) + 16, cols[0]);
|
||||
hline(buffer32, 0, (vid->displine << 1) + 1, (vid->crtc[1] << 4) + 16, cols[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vid->mode & 1)
|
||||
x = (vid->crtc[1] << 3) + 16;
|
||||
else
|
||||
x = (vid->crtc[1] << 4) + 16;
|
||||
if (!dev->is_sl2 && vid->composite) {
|
||||
Composite_Process(vid->mode, 0, x >> 2, buffer32->line[vid->displine << 1]);
|
||||
Composite_Process(vid->mode, 0, x >> 2, buffer32->line[(vid->displine << 1) + 1]);
|
||||
} else {
|
||||
video_process_8(x, vid->displine << 1);
|
||||
video_process_8(x, (vid->displine << 1) + 1);
|
||||
}
|
||||
vid->sc = oldsc;
|
||||
if (vid->vc == vid->crtc[7] && !vid->sc)
|
||||
vid->stat |= 8;
|
||||
vid->displine++;
|
||||
if (vid->displine >= 360)
|
||||
vid->displine = 0;
|
||||
} else {
|
||||
timer_advance_u64(&vid->timer, vid->dispontime);
|
||||
if (vid->dispon)
|
||||
vid->stat &= ~1;
|
||||
vid->linepos = 0;
|
||||
if (vid->vsynctime) {
|
||||
vid->vsynctime--;
|
||||
if (!vid->vsynctime)
|
||||
vid->stat &= ~8;
|
||||
}
|
||||
if (vid->sc == (vid->crtc[11] & 31) || ((vid->crtc[8] & 3) == 3 && vid->sc == ((vid->crtc[11] & 31) >> 1))) {
|
||||
vid->con = 0;
|
||||
}
|
||||
if (vid->vadj) {
|
||||
vid->sc++;
|
||||
vid->sc &= 31;
|
||||
vid->ma = vid->maback;
|
||||
vid->vadj--;
|
||||
if (!vid->vadj) {
|
||||
vid->dispon = 1;
|
||||
if (dev->is_sl2 && (vid->array[5] & 1))
|
||||
vid->ma = vid->maback = vid->crtc[13] | (vid->crtc[12] << 8);
|
||||
else
|
||||
vid->ma = vid->maback = (vid->crtc[13] | (vid->crtc[12] << 8)) & 0x3fff;
|
||||
vid->sc = 0;
|
||||
}
|
||||
} else if (vid->sc == vid->crtc[9] || ((vid->crtc[8] & 3) == 3 && vid->sc == (vid->crtc[9] >> 1))) {
|
||||
vid->maback = vid->ma;
|
||||
vid->sc = 0;
|
||||
oldvc = vid->vc;
|
||||
vid->vc++;
|
||||
if (dev->is_sl2)
|
||||
vid->vc &= 255;
|
||||
else
|
||||
vid->vc &= 127;
|
||||
if (vid->vc == vid->crtc[6])
|
||||
vid->dispon = 0;
|
||||
if (oldvc == vid->crtc[4]) {
|
||||
vid->vc = 0;
|
||||
vid->vadj = vid->crtc[5];
|
||||
if (!vid->vadj)
|
||||
vid->dispon = 1;
|
||||
if (!vid->vadj) {
|
||||
if (dev->is_sl2 && (vid->array[5] & 1))
|
||||
vid->ma = vid->maback = vid->crtc[13] | (vid->crtc[12] << 8);
|
||||
else
|
||||
vid->ma = vid->maback = (vid->crtc[13] | (vid->crtc[12] << 8)) & 0x3fff;
|
||||
}
|
||||
if ((vid->crtc[10] & 0x60) == 0x20)
|
||||
vid->cursoron = 0;
|
||||
else
|
||||
vid->cursoron = vid->blink & 16;
|
||||
}
|
||||
if (vid->vc == vid->crtc[7]) {
|
||||
vid->dispon = 0;
|
||||
vid->displine = 0;
|
||||
vid->vsynctime = 16;
|
||||
picint(1 << 5);
|
||||
if (vid->crtc[7]) {
|
||||
if (vid->mode & 1)
|
||||
x = (vid->crtc[1] << 3) + 16;
|
||||
else
|
||||
x = (vid->crtc[1] << 4) + 16;
|
||||
vid->lastline++;
|
||||
|
||||
xs_temp = x;
|
||||
ys_temp = (vid->lastline - vid->firstline) << 1;
|
||||
|
||||
if ((xs_temp > 0) && (ys_temp > 0)) {
|
||||
if (xs_temp < 64)
|
||||
xs_temp = 656;
|
||||
if (ys_temp < 32)
|
||||
ys_temp = 400;
|
||||
if (!enable_overscan)
|
||||
xs_temp -= 16;
|
||||
|
||||
if ((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));
|
||||
|
||||
if (video_force_resize_get())
|
||||
video_force_resize_set(0);
|
||||
}
|
||||
|
||||
if (enable_overscan) {
|
||||
video_blit_memtoscreen(0, (vid->firstline - 4) << 1,
|
||||
xsize, ((vid->lastline - vid->firstline) + 8) << 1);
|
||||
} else {
|
||||
video_blit_memtoscreen(8, vid->firstline << 1,
|
||||
xsize, (vid->lastline - vid->firstline) << 1);
|
||||
}
|
||||
}
|
||||
|
||||
frames++;
|
||||
|
||||
video_res_x = xsize;
|
||||
video_res_y = ysize;
|
||||
if ((vid->array[3] & 0x10) && (vid->mode & 1)) { /*320x200x16*/
|
||||
video_res_x /= 2;
|
||||
video_bpp = 4;
|
||||
} else if (vid->array[3] & 0x10) { /*160x200x16*/
|
||||
video_res_x /= 4;
|
||||
video_bpp = 4;
|
||||
} else if (vid->array[3] & 0x08) { /*640x200x4 - this implementation is a complete guess!*/
|
||||
video_bpp = 2;
|
||||
} else if (vid->mode & 1) {
|
||||
video_res_x /= 8;
|
||||
video_res_y /= vid->crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(vid->mode & 2)) {
|
||||
video_res_x /= 16;
|
||||
video_res_y /= vid->crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(vid->mode & 16)) {
|
||||
video_res_x /= 2;
|
||||
video_bpp = 2;
|
||||
} else {
|
||||
video_bpp = 1;
|
||||
}
|
||||
}
|
||||
vid->firstline = 1000;
|
||||
vid->lastline = 0;
|
||||
vid->blink++;
|
||||
}
|
||||
} else {
|
||||
vid->sc++;
|
||||
vid->sc &= 31;
|
||||
vid->ma = vid->maback;
|
||||
}
|
||||
if (vid->sc == (vid->crtc[10] & 31) || ((vid->crtc[8] & 3) == 3 && vid->sc == ((vid->crtc[10] & 31) >> 1)))
|
||||
vid->con = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vid_speed_changed(void *priv)
|
||||
{
|
||||
tandy_t *dev = (tandy_t *) priv;
|
||||
|
||||
recalc_timings(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
vid_close(void *priv)
|
||||
{
|
||||
tandy_t *dev = (tandy_t *) priv;
|
||||
|
||||
free(dev->vid);
|
||||
dev->vid = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
vid_init(tandy_t *dev)
|
||||
{
|
||||
int display_type;
|
||||
t1kvid_t *vid;
|
||||
|
||||
vid = calloc(1, sizeof(t1kvid_t));
|
||||
vid->memctrl = -1;
|
||||
|
||||
video_inform(VIDEO_FLAG_TYPE_CGA, &timing_dram);
|
||||
|
||||
display_type = device_get_config_int("display_type");
|
||||
vid->composite = (display_type != TANDY_RGB);
|
||||
|
||||
cga_comp_init(1);
|
||||
|
||||
if (dev->is_sl2) {
|
||||
vid->b8000_limit = 0x8000;
|
||||
vid->planar_ctrl = 4;
|
||||
overscan_x = overscan_y = 16;
|
||||
|
||||
io_sethandler(0x0065, 1, vid_in, NULL, NULL, vid_out, NULL, NULL, dev);
|
||||
} else
|
||||
vid->b8000_mask = 0x3fff;
|
||||
|
||||
timer_add(&vid->timer, vid_poll, dev, 1);
|
||||
mem_mapping_add(&vid->mapping, 0xb8000, 0x08000,
|
||||
vid_read, NULL, NULL, vid_write, NULL, NULL, NULL, 0, dev);
|
||||
io_sethandler(0x03d0, 16,
|
||||
vid_in, NULL, NULL, vid_out, NULL, NULL, dev);
|
||||
|
||||
dev->vid = vid;
|
||||
}
|
||||
|
||||
const device_config_t vid_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "display_type",
|
||||
.description = "Display type",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = "",
|
||||
.default_int = TANDY_RGB,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "RGB", .value = TANDY_RGB },
|
||||
{ .description = "Composite", .value = TANDY_COMPOSITE },
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t vid_device = {
|
||||
.name = "Tandy 1000",
|
||||
.internal_name = "tandy1000_video",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
.close = vid_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = vid_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = vid_config
|
||||
};
|
||||
|
||||
const device_t vid_device_hx = {
|
||||
.name = "Tandy 1000 HX",
|
||||
.internal_name = "tandy1000_hx_video",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
.close = vid_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = vid_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = vid_config
|
||||
};
|
||||
|
||||
const device_t vid_device_sl = {
|
||||
.name = "Tandy 1000SL2",
|
||||
.internal_name = "tandy1000_sl_video",
|
||||
.flags = 0,
|
||||
.local = 1,
|
||||
.init = NULL,
|
||||
.close = vid_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = vid_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
static void
|
||||
eep_write(UNUSED(uint16_t addr), uint8_t val, void *priv)
|
||||
@@ -1630,12 +785,12 @@ tandy_write(uint16_t addr, uint8_t val, void *priv)
|
||||
}
|
||||
if (dev->is_hx) {
|
||||
io_removehandler(0x03d0, 16,
|
||||
vid_in, NULL, NULL, vid_out, NULL, NULL, dev);
|
||||
tandy_vid_in, NULL, NULL, tandy_vid_out, NULL, NULL, dev);
|
||||
if (val & 0x01)
|
||||
mem_mapping_disable(&dev->vid->mapping);
|
||||
else {
|
||||
io_sethandler(0x03d0, 16,
|
||||
vid_in, NULL, NULL, vid_out, NULL, NULL, dev);
|
||||
tandy_vid_in, NULL, NULL, tandy_vid_out, NULL, NULL, dev);
|
||||
mem_mapping_set_addr(&dev->vid->mapping, 0xb8000, 0x8000);
|
||||
}
|
||||
} else {
|
||||
@@ -1654,7 +809,7 @@ tandy_write(uint16_t addr, uint8_t val, void *priv)
|
||||
mem_mapping_set_addr(&dev->ram_mapping,
|
||||
((val >> 1) & 7) * 128 * 1024,
|
||||
0x20000);
|
||||
recalc_address_sl(dev);
|
||||
tandy_recalc_address_sl(dev);
|
||||
dev->ram_bank = val;
|
||||
break;
|
||||
|
||||
@@ -1803,10 +958,10 @@ machine_tandy1k_init(const machine_t *model, int type)
|
||||
keyboard_set_table(scancode_tandy);
|
||||
io_sethandler(0x00a0, 1,
|
||||
tandy_read, NULL, NULL, tandy_write, NULL, NULL, dev);
|
||||
device_context(&vid_device);
|
||||
vid_init(dev);
|
||||
device_context(&tandy_1000_video_device);
|
||||
tandy_vid_init(dev);
|
||||
device_context_restore();
|
||||
device_add_ex(&vid_device, dev);
|
||||
device_add_ex(&tandy_1000_video_device, dev);
|
||||
device_add((type == TYPE_TANDY1000SX) ? &ncr8496_device : &sn76489_device);
|
||||
break;
|
||||
|
||||
@@ -1815,10 +970,10 @@ machine_tandy1k_init(const machine_t *model, int type)
|
||||
keyboard_set_table(scancode_tandy);
|
||||
io_sethandler(0x00a0, 1,
|
||||
tandy_read, NULL, NULL, tandy_write, NULL, NULL, dev);
|
||||
device_context(&vid_device_hx);
|
||||
vid_init(dev);
|
||||
device_context(&tandy_1000hx_video_device);
|
||||
tandy_vid_init(dev);
|
||||
device_context_restore();
|
||||
device_add_ex(&vid_device_hx, dev);
|
||||
device_add_ex(&tandy_1000hx_video_device, dev);
|
||||
device_add(&ncr8496_device);
|
||||
device_add(&eep_1000hx_device);
|
||||
break;
|
||||
@@ -1828,10 +983,10 @@ machine_tandy1k_init(const machine_t *model, int type)
|
||||
init_rom(dev);
|
||||
io_sethandler(0xffe8, 8,
|
||||
tandy_read, NULL, NULL, tandy_write, NULL, NULL, dev);
|
||||
device_context(&vid_device_sl);
|
||||
vid_init(dev);
|
||||
device_context(&tandy_1000sl_video_device);
|
||||
tandy_vid_init(dev);
|
||||
device_context_restore();
|
||||
device_add_ex(&vid_device_sl, dev);
|
||||
device_add_ex(&tandy_1000sl_video_device, dev);
|
||||
device_add(&pssj_device);
|
||||
device_add(&eep_1000sl2_device);
|
||||
break;
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/port_6x.h>
|
||||
#include <86box/video.h>
|
||||
@@ -668,6 +669,34 @@ machine_xt_amixt_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_xt_tuliptc8_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/tuliptc8/tulip-bios_xt_compact_2.bin",
|
||||
0x000fc000, 16384, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
device_add(&keyboard_xt_fe2010_device);
|
||||
|
||||
if (fdc_current[0] == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
machine_common_init(model);
|
||||
|
||||
pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt);
|
||||
|
||||
nmi_init();
|
||||
standalone_gameport_type = &gameport_device;
|
||||
|
||||
device_add(&amstrad_megapc_nvr_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// TODO
|
||||
// Onboard EGA Graphics (NSI Logic EVC315-S on early boards STMicroelectronics EGA on later revisions)
|
||||
// RTC
|
||||
|
||||
@@ -1918,7 +1918,7 @@ m19_vid_out(uint16_t addr, uint8_t val, void *priv)
|
||||
/* activating plantronics mode */
|
||||
if (addr == 0x3dd) {
|
||||
/* already in graphics mode */
|
||||
if ((val & 0x30) && (vid->ogc.cga.cgamode & 0x2))
|
||||
if ((val & 0x30) && (vid->ogc.cga.cgamode & CGA_MODE_FLAG_GRAPHICS))
|
||||
vid->mode = PLANTRONICS_MODE;
|
||||
else
|
||||
vid->mode = OLIVETTI_OGC_MODE;
|
||||
|
||||
@@ -39,8 +39,10 @@
|
||||
// Temporarily here till we move everything out into the right files
|
||||
extern const device_t pcjr_device;
|
||||
extern const device_t m19_vid_device;
|
||||
extern const device_t vid_device;
|
||||
extern const device_t vid_device_hx;
|
||||
extern const device_t tandy_1000_video_device;
|
||||
extern const device_t tandy_1000hx_video_device;
|
||||
extern const device_t tandy_1000sl_video_device;
|
||||
|
||||
extern const device_t t1000_video_device;
|
||||
extern const device_t xi8088_device;
|
||||
extern const device_t cga_device;
|
||||
@@ -50,7 +52,6 @@ extern const device_t vid_pc2086_device;
|
||||
extern const device_t vid_pc3086_device;
|
||||
extern const device_t vid_200_device;
|
||||
extern const device_t vid_ppc512_device;
|
||||
extern const device_t vid_device_sl;
|
||||
extern const device_t t1200_video_device;
|
||||
extern const device_t compaq_plasma_device;
|
||||
extern const device_t ps1_2011_device;
|
||||
@@ -70,6 +71,7 @@ extern const device_t d842_device;
|
||||
extern const device_t d943_device;
|
||||
extern const device_t dells333sl_device;
|
||||
extern const device_t hot433a_device;
|
||||
extern const device_t pbl300sx_device;
|
||||
|
||||
const machine_filter_t machine_types[] = {
|
||||
{ "None", MACHINE_TYPE_NONE },
|
||||
@@ -106,6 +108,7 @@ const machine_filter_t machine_chipsets[] = {
|
||||
{ "Headland GC100A", MACHINE_CHIPSET_GC100A },
|
||||
{ "Headland GC103", MACHINE_CHIPSET_GC103 },
|
||||
{ "Headland HT18", MACHINE_CHIPSET_HT18 },
|
||||
{ "ACC 2036", MACHINE_CHIPSET_ACC_2036 },
|
||||
{ "ACC 2168", MACHINE_CHIPSET_ACC_2168 },
|
||||
{ "ALi M1217", MACHINE_CHIPSET_ALI_M1217 },
|
||||
{ "ALi M6117", MACHINE_CHIPSET_ALI_M6117 },
|
||||
@@ -149,7 +152,9 @@ const machine_filter_t machine_chipsets[] = {
|
||||
{ "OPTi 391", MACHINE_CHIPSET_OPTI_391 },
|
||||
{ "OPTi 481", MACHINE_CHIPSET_OPTI_481 },
|
||||
{ "OPTi 493", MACHINE_CHIPSET_OPTI_493 },
|
||||
{ "OPTi 495", MACHINE_CHIPSET_OPTI_495 },
|
||||
{ "OPTi 495SLC", MACHINE_CHIPSET_OPTI_495SLC },
|
||||
{ "OPTi 495SX", MACHINE_CHIPSET_OPTI_495SX },
|
||||
{ "OPTi 498", MACHINE_CHIPSET_OPTI_498 },
|
||||
{ "OPTi 499", MACHINE_CHIPSET_OPTI_499 },
|
||||
{ "OPTi 895/802G", MACHINE_CHIPSET_OPTI_895_802G },
|
||||
{ "OPTi 547/597", MACHINE_CHIPSET_OPTI_547_597 },
|
||||
@@ -1591,7 +1596,7 @@ const machine_t machines[] = {
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = &vid_device,
|
||||
.vid_device = &tandy_1000_video_device,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
@@ -1630,7 +1635,7 @@ const machine_t machines[] = {
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = &vid_device_hx,
|
||||
.vid_device = &tandy_1000hx_video_device,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
@@ -2025,6 +2030,45 @@ const machine_t machines[] = {
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
{
|
||||
.name = "[V20] Tulip PC Compact 2",
|
||||
.internal_name = "tuliptc8",
|
||||
.type = MACHINE_TYPE_8088,
|
||||
.chipset = MACHINE_CHIPSET_DISCRETE,
|
||||
.init = machine_xt_tuliptc8_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
.gpio_acpi_handler = NULL,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_8088,
|
||||
.block = CPU_BLOCK(CPU_8088),
|
||||
.min_bus = 0,
|
||||
.max_bus = 0,
|
||||
.min_voltage = 0,
|
||||
.max_voltage = 0,
|
||||
.min_multi = 0,
|
||||
.max_multi = 0
|
||||
},
|
||||
.bus_flags = MACHINE_PC,
|
||||
.flags = MACHINE_FLAGS_NONE,
|
||||
.ram = {
|
||||
.min = 64,
|
||||
.max = 640,
|
||||
.step = 64
|
||||
},
|
||||
.nvrmask = 63,
|
||||
.kbc_device = &keyboard_xtclone_device,
|
||||
.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
|
||||
},
|
||||
|
||||
/* 8086 Machines */
|
||||
{
|
||||
@@ -2531,7 +2575,7 @@ const machine_t machines[] = {
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = &vid_device_sl,
|
||||
.vid_device = &tandy_1000sl_video_device,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
@@ -3416,6 +3460,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] PC's Limited (Dell) 28608L/AT122",
|
||||
.internal_name = "at122",
|
||||
.type = MACHINE_TYPE_286,
|
||||
.chipset = MACHINE_CHIPSET_CT_AT,
|
||||
.init = machine_at_at122_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
|
||||
},
|
||||
/* No proper pictures of the KBC exist, though it seems to have the IBM AT KBC
|
||||
firmware. */
|
||||
{
|
||||
@@ -3692,7 +3777,7 @@ const machine_t machines[] = {
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = NULL,
|
||||
.vid_device = ¶dise_pvga1a_ncr3302_device,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
@@ -4300,6 +4385,46 @@ const machine_t machines[] = {
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* Most likely has Phonenix KBC firmware. */
|
||||
{
|
||||
.name = "[ACC 2036] Packard Bell Legend 300SX",
|
||||
.internal_name = "pbl300sx",
|
||||
.type = MACHINE_TYPE_386SX,
|
||||
.chipset = MACHINE_CHIPSET_ACC_2036,
|
||||
.init = machine_at_pbl300sx_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
.gpio_acpi_handler = NULL,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_386SX,
|
||||
.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,
|
||||
.flags = MACHINE_IDE | MACHINE_VIDEO,
|
||||
.ram = {
|
||||
.min = 1024,
|
||||
.max = 16384,
|
||||
.step = 1024
|
||||
},
|
||||
.nvrmask = 127,
|
||||
.kbc_device = NULL,
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = &pbl300sx_device,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = &oti037_pbl300sx_device,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* This has an AMIKey-2, which is an updated version of type 'H'. */
|
||||
{
|
||||
.name = "[ALi M1217] Acrosser AR-B1374",
|
||||
@@ -5716,10 +5841,10 @@ const machine_t machines[] = {
|
||||
but the BIOS sends commands C9 without a parameter and D5, both of which are
|
||||
Phoenix MultiKey commands. */
|
||||
{
|
||||
.name = "[OPTi 495] U-Board OPTi 495SLC",
|
||||
.name = "[OPTi 495SLC] U-Board OPTi 495SLC",
|
||||
.internal_name = "award495",
|
||||
.type = MACHINE_TYPE_386DX,
|
||||
.chipset = MACHINE_CHIPSET_OPTI_495,
|
||||
.chipset = MACHINE_CHIPSET_OPTI_495SLC,
|
||||
.init = machine_at_opti495_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
@@ -5958,12 +6083,52 @@ const machine_t machines[] = {
|
||||
},
|
||||
|
||||
/* 386DX/486 machines */
|
||||
/* Has AMIKey F KBC firmware. The EFAR chipst is a rebrand of OPTi 495SX. */
|
||||
{
|
||||
.name = "[OPTi 495SX] CAF Technology C747",
|
||||
.internal_name = "c747",
|
||||
.type = MACHINE_TYPE_386DX_486,
|
||||
.chipset = MACHINE_CHIPSET_OPTI_495SX,
|
||||
.init = machine_at_c747_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
.gpio_acpi_handler = NULL,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_386DX | 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_APM | MACHINE_IDE,
|
||||
.ram = {
|
||||
.min = 1024,
|
||||
.max = 32768,
|
||||
.step = 1024
|
||||
},
|
||||
.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 AMIKey F KBC firmware. */
|
||||
{
|
||||
.name = "[OPTi 495] DataExpert SX495",
|
||||
.name = "[OPTi 495SX] DataExpert SX495",
|
||||
.internal_name = "ami495",
|
||||
.type = MACHINE_TYPE_386DX_486,
|
||||
.chipset = MACHINE_CHIPSET_OPTI_495,
|
||||
.chipset = MACHINE_CHIPSET_OPTI_495SX,
|
||||
.init = machine_at_opti495_ami_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
@@ -6000,10 +6165,10 @@ const machine_t machines[] = {
|
||||
},
|
||||
/* Has AMIKey F KBC firmware (it's just the MR BIOS for the above machine). */
|
||||
{
|
||||
.name = "[OPTi 495] DataExpert SX495 (MR BIOS)",
|
||||
.name = "[OPTi 495SX] DataExpert SX495 (MR BIOS)",
|
||||
.internal_name = "mr495",
|
||||
.type = MACHINE_TYPE_386DX_486,
|
||||
.chipset = MACHINE_CHIPSET_OPTI_495,
|
||||
.chipset = MACHINE_CHIPSET_OPTI_495SX,
|
||||
.init = machine_at_opti495_mr_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
@@ -6325,10 +6490,10 @@ const machine_t machines[] = {
|
||||
/* Uses some variant of Phoenix MultiKey/42 as the Intel 8242 chip has a Phoenix
|
||||
copyright. */
|
||||
{
|
||||
.name = "[OPTi 495] Mylex MVI486",
|
||||
.name = "[OPTi 498] Mylex MVI486",
|
||||
.internal_name = "mvi486",
|
||||
.type = MACHINE_TYPE_486,
|
||||
.chipset = MACHINE_CHIPSET_OPTI_495,
|
||||
.chipset = MACHINE_CHIPSET_OPTI_498,
|
||||
.init = machine_at_mvi486_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
@@ -6484,6 +6649,46 @@ const machine_t machines[] = {
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* Has Phoenix KBC firmware. */
|
||||
{
|
||||
.name = "[SiS 471] AST Advantage! 40xxd",
|
||||
.internal_name = "advantage40xxd",
|
||||
.type = MACHINE_TYPE_486,
|
||||
.chipset = MACHINE_CHIPSET_SIS_471,
|
||||
.init = machine_at_advantage40xxd_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 = 2
|
||||
},
|
||||
.bus_flags = MACHINE_PS2_VLB,
|
||||
.flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM,
|
||||
.ram = {
|
||||
.min = 4096,
|
||||
.max = 36864,
|
||||
.step = 4096
|
||||
},
|
||||
.nvrmask = 127,
|
||||
.kbc_device = NULL,
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = &gd5424_onboard_device,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* Has AMIKey F KBC firmware. */
|
||||
{
|
||||
.name = "[Symphony SL42C460] DTK PKM-0031Y",
|
||||
@@ -9235,7 +9440,7 @@ const machine_t machines[] = {
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = NULL,
|
||||
.vid_device = &tgui9440_onboard_pci_device,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
@@ -9276,7 +9481,7 @@ const machine_t machines[] = {
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = NULL,
|
||||
.vid_device = &gd5430_onboard_pci_device,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <86box/timer.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_fallthrough.h>
|
||||
|
||||
#define FLAG_WORD 4
|
||||
#define FLAG_BXB 2
|
||||
@@ -44,21 +45,22 @@ enum {
|
||||
};
|
||||
|
||||
enum {
|
||||
CMD_SET_READ = 0x00,
|
||||
CMD_READ_SIGNATURE = 0x90,
|
||||
CMD_ERASE = 0x20,
|
||||
CMD_ERASE_CONFIRM = 0x20,
|
||||
CMD_ERASE_VERIFY = 0xA0,
|
||||
CMD_PROGRAM = 0x40,
|
||||
CMD_PROGRAM_VERIFY = 0xC0,
|
||||
CMD_RESET = 0xFF
|
||||
CMD_SET_READ = 0x00,
|
||||
CMD_READ_AUTO_SELECT = 0x80,
|
||||
CMD_READ_SIGNATURE = 0x90,
|
||||
CMD_ERASE = 0x20,
|
||||
CMD_ERASE_CONFIRM = 0x20,
|
||||
CMD_ERASE_VERIFY = 0xA0,
|
||||
CMD_PROGRAM = 0x40,
|
||||
CMD_PROGRAM_VERIFY = 0xC0,
|
||||
CMD_RESET = 0xFF
|
||||
};
|
||||
|
||||
typedef struct flash_t {
|
||||
uint8_t command;
|
||||
uint8_t is_amd;
|
||||
uint8_t pad;
|
||||
uint8_t pad0;
|
||||
uint8_t pad1;
|
||||
uint8_t *array;
|
||||
|
||||
mem_mapping_t mapping;
|
||||
@@ -83,11 +85,22 @@ flash_read(uint32_t addr, void *priv)
|
||||
ret = dev->array[addr];
|
||||
break;
|
||||
|
||||
case CMD_READ_AUTO_SELECT:
|
||||
if (!dev->is_amd)
|
||||
break;
|
||||
fallthrough;
|
||||
case CMD_READ_SIGNATURE:
|
||||
if (addr == 0x00000)
|
||||
ret = 0x31; /* CATALYST */
|
||||
else if (addr == 0x00001)
|
||||
ret = 0xB4; /* 28F010 */
|
||||
if (dev->is_amd) {
|
||||
if (addr == 0x00000)
|
||||
ret = 0x01; /* AMD */
|
||||
else if (addr == 0x00001)
|
||||
ret = 0xa7; /* Am28F010 */
|
||||
} else {
|
||||
if (addr == 0x00000)
|
||||
ret = 0x31; /* CATALYST */
|
||||
else if (addr == 0x00001)
|
||||
ret = 0xb4; /* 28F010 */
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -205,6 +218,7 @@ catalyst_flash_init(UNUSED(const device_t *info))
|
||||
catalyst_flash_add_mappings(dev);
|
||||
|
||||
dev->command = CMD_RESET;
|
||||
dev->is_amd = info->local;
|
||||
|
||||
fp = nvr_fopen(flash_path, "rb");
|
||||
if (fp) {
|
||||
@@ -244,3 +258,17 @@ const device_t catalyst_flash_device = {
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t amd_am28f010_flash_device = {
|
||||
.name = "AMD Am28F010-D Flash BIOS",
|
||||
.internal_name = "amd_am28f010_flash",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 1,
|
||||
.init = catalyst_flash_init,
|
||||
.close = catalyst_flash_close,
|
||||
.reset = catalyst_flash_reset,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -197,6 +197,49 @@ add_library(ui STATIC
|
||||
qt_mediahistorymanager.cpp
|
||||
qt_mediahistorymanager.hpp
|
||||
|
||||
qt_updatecheck.cpp
|
||||
qt_updatecheck.hpp
|
||||
qt_updatecheckdialog.cpp
|
||||
qt_updatecheckdialog.hpp
|
||||
qt_updatecheckdialog.ui
|
||||
qt_updatedetails.cpp
|
||||
qt_updatedetails.hpp
|
||||
qt_updatedetails.ui
|
||||
qt_downloader.cpp
|
||||
qt_downloader.hpp
|
||||
|
||||
qt_vmmanager_clientsocket.cpp
|
||||
qt_vmmanager_clientsocket.hpp
|
||||
qt_vmmanager_serversocket.cpp
|
||||
qt_vmmanager_serversocket.hpp
|
||||
qt_vmmanager_protocol.cpp
|
||||
qt_vmmanager_protocol.hpp
|
||||
qt_vmmanager_details.hpp
|
||||
qt_vmmanager_details.cpp
|
||||
qt_vmmanager_details.ui
|
||||
qt_vmmanager_addmachine.cpp
|
||||
qt_vmmanager_addmachine.hpp
|
||||
qt_vmmanager_detailsection.cpp
|
||||
qt_vmmanager_detailsection.hpp
|
||||
qt_vmmanager_detailsection.ui
|
||||
qt_vmmanager_listviewdelegate.hpp
|
||||
qt_vmmanager_listviewdelegate.cpp
|
||||
qt_vmmanager_preferences.cpp
|
||||
qt_vmmanager_preferences.hpp
|
||||
qt_vmmanager_preferences.ui
|
||||
qt_vmmanager_main.hpp
|
||||
qt_vmmanager_main.cpp
|
||||
qt_vmmanager_main.ui
|
||||
qt_vmmanager_model.cpp
|
||||
qt_vmmanager_model.hpp
|
||||
qt_vmmanager_system.cpp
|
||||
qt_vmmanager_system.hpp
|
||||
qt_vmmanager_config.cpp
|
||||
qt_vmmanager_config.hpp
|
||||
qt_vmmanager_mainwindow.cpp
|
||||
qt_vmmanager_mainwindow.hpp
|
||||
qt_vmmanager_mainwindow.ui
|
||||
|
||||
../qt_resources.qrc
|
||||
./qdarkstyle/dark/darkstyle.qrc
|
||||
|
||||
|
||||
BIN
src/qt/assets/86box-wizard.png
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
BIN
src/qt/assets/systemicons/cpq_deskpro.png
Normal file
|
After Width: | Height: | Size: 239 KiB |
BIN
src/qt/assets/systemicons/cpq_port_386.png
Normal file
|
After Width: | Height: | Size: 245 KiB |
BIN
src/qt/assets/systemicons/cpq_port_II.png
Normal file
|
After Width: | Height: | Size: 158 KiB |
BIN
src/qt/assets/systemicons/cpq_port_III.png
Normal file
|
After Width: | Height: | Size: 198 KiB |
BIN
src/qt/assets/systemicons/cpq_portable.png
Normal file
|
After Width: | Height: | Size: 137 KiB |
BIN
src/qt/assets/systemicons/cpq_pres_2240.png
Normal file
|
After Width: | Height: | Size: 162 KiB |
BIN
src/qt/assets/systemicons/cpq_pres_4500.png
Normal file
|
After Width: | Height: | Size: 129 KiB |
BIN
src/qt/assets/systemicons/ibm330.png
Normal file
|
After Width: | Height: | Size: 182 KiB |
BIN
src/qt/assets/systemicons/ibm_at.png
Normal file
|
After Width: | Height: | Size: 276 KiB |
BIN
src/qt/assets/systemicons/ibm_pc_81.png
Normal file
|
After Width: | Height: | Size: 289 KiB |
BIN
src/qt/assets/systemicons/ibm_pc_82.png
Normal file
|
After Width: | Height: | Size: 289 KiB |
BIN
src/qt/assets/systemicons/ibm_pcjr.png
Normal file
|
After Width: | Height: | Size: 289 KiB |
BIN
src/qt/assets/systemicons/ibm_ps2_m70.png
Normal file
|
After Width: | Height: | Size: 214 KiB |
BIN
src/qt/assets/systemicons/ibm_ps2_m80.png
Normal file
|
After Width: | Height: | Size: 259 KiB |
BIN
src/qt/assets/systemicons/ibm_psvp_486.png
Normal file
|
After Width: | Height: | Size: 212 KiB |
BIN
src/qt/assets/systemicons/ibm_psvp_p60.png
Normal file
|
After Width: | Height: | Size: 212 KiB |
BIN
src/qt/assets/systemicons/ibm_xt_82.png
Normal file
|
After Width: | Height: | Size: 289 KiB |
BIN
src/qt/assets/systemicons/ibm_xt_86.png
Normal file
|
After Width: | Height: | Size: 289 KiB |
BIN
src/qt/assets/systemicons/olivetti_m19.png
Normal file
|
After Width: | Height: | Size: 257 KiB |
BIN
src/qt/assets/systemicons/olivetti_m21.png
Normal file
|
After Width: | Height: | Size: 317 KiB |
BIN
src/qt/assets/systemicons/olivetti_m24.png
Normal file
|
After Width: | Height: | Size: 204 KiB |
BIN
src/qt/assets/systemicons/olivetti_m24sp.png
Normal file
|
After Width: | Height: | Size: 204 KiB |
BIN
src/qt/assets/systemicons/os_archlinux_x2.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
src/qt/assets/systemicons/os_cloud_x2.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
src/qt/assets/systemicons/os_debian_x2.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
src/qt/assets/systemicons/os_dos_x2.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
src/qt/assets/systemicons/os_fedora_x2.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
src/qt/assets/systemicons/os_freebsd_x2.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
src/qt/assets/systemicons/os_gentoo_x2.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
src/qt/assets/systemicons/os_jrockitve_x2.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
src/qt/assets/systemicons/os_l4_x2.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
src/qt/assets/systemicons/os_linux22_x2.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
src/qt/assets/systemicons/os_linux24_x2.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
src/qt/assets/systemicons/os_linux26_x2.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
src/qt/assets/systemicons/os_linux_x2.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
src/qt/assets/systemicons/os_macosx_x2.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
src/qt/assets/systemicons/os_mandriva_x2.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
src/qt/assets/systemicons/os_netbsd_x2.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
src/qt/assets/systemicons/os_netware_x2.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
src/qt/assets/systemicons/os_openbsd_x2.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
BIN
src/qt/assets/systemicons/os_opensuse_x2.png
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
src/qt/assets/systemicons/os_oracle_x2.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
src/qt/assets/systemicons/os_oraclesolaris_x2.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
src/qt/assets/systemicons/os_os2_other_x2.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
src/qt/assets/systemicons/os_os2ecs_x2.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
src/qt/assets/systemicons/os_os2warp3_x2.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
src/qt/assets/systemicons/os_os2warp45_x2.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
src/qt/assets/systemicons/os_os2warp4_x2.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
src/qt/assets/systemicons/os_other_x2.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
src/qt/assets/systemicons/os_qnx_x2.png
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
src/qt/assets/systemicons/os_redhat_x2.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |