Merge branch '86Box:master' into machine_23

This commit is contained in:
BurnedPinguin
2024-01-27 09:34:42 +01:00
committed by GitHub
30 changed files with 815 additions and 597 deletions

View File

@@ -8,19 +8,14 @@
*
* Implementation of the Intel 450KX Mars Chipset.
*
* i450GX is way more popular of an option but needs more stuff.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Tiseno100,
*
* Authors: Tiseno100
*
* Copyright 2021-2024 Miran Grca.
* Copyright 2021 Tiseno100.
*/
/*
Note: i450KX PB manages PCI memory access with MC manages DRAM memory access.
Due to 86Box limitations we can't manage them seperately thus it is dev branch till then.
i450GX is way more popular of an option but needs more stuff.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
@@ -97,17 +92,18 @@ i450kx_smram_recalc(i450kx_t *dev, int bus)
const uint8_t *regs = bus ? dev->pb_pci_conf : dev->mc_pci_conf;
uint32_t addr;
uint32_t size;
int enable = bus ? !(regs[0x57] & 0x08) : (regs[0x57] & 0x08);
smram_disable(dev->smram[bus]);
addr = ((uint32_t) regs[0xb8] << 16) | ((uint32_t) regs[0xb9] << 24);
size = (((uint32_t) ((regs[0xbb] >> 4) & 0x0f)) << 16) + 0x00010000;
if ((addr != 0x00000000) && !!(regs[0x57] & 0x08)) {
if ((addr != 0x00000000) && enable) {
if (bus)
smram_enable_ex(dev->smram[bus], addr, addr, size, 0, !!(regs[0x57] & 8), 0, 1);
smram_enable_ex(dev->smram[bus], addr, addr, size, 0, 0, 0, enable);
else
smram_enable_ex(dev->smram[bus], addr, addr, size, !!(regs[0x57] & 8), 0, 1, 0);
smram_enable_ex(dev->smram[bus], addr, addr, size, 0, 0, enable, 0);
}
flushmmucache();
@@ -118,10 +114,8 @@ i450kx_vid_buf_recalc(i450kx_t *dev, int bus)
{
const uint8_t *regs = bus ? dev->pb_pci_conf : dev->mc_pci_conf;
#if 0
// int state = (regs[0x58] & 0x02) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_DISABLED | MEM_WRITE_DISABLED);
#endif
int state = (regs[0x58] & 0x02) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY);
int state = (regs[0x58] & 0x02) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) :
(MEM_READ_EXTANY | MEM_WRITE_EXTANY);
if (bus)
mem_set_mem_state_bus_both(0x000a0000, 0x00020000, state);
@@ -136,10 +130,10 @@ pb_write(int func, int addr, uint8_t val, void *priv)
{
i450kx_t *dev = (i450kx_t *) priv;
// pclog("i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80));
i450kx_log("i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80));
if (func == 0) {
i450kx_log("[%04X:%08X] i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X\n", CS, cpu_state.pc,
addr, val);
if (func == 0)
switch (addr) {
case 0x04:
dev->pb_pci_conf[addr] = (dev->pb_pci_conf[addr] & 0x04) | (val & 0x53);
@@ -373,6 +367,7 @@ pb_write(int func, int addr, uint8_t val, void *priv)
default:
break;
}
}
}
static uint8_t
@@ -381,10 +376,12 @@ pb_read(int func, int addr, void *priv)
const i450kx_t *dev = (i450kx_t *) priv;
uint8_t ret = 0xff;
if (func == 0)
if (func == 0) {
ret = dev->pb_pci_conf[addr];
// pclog("i450KX-PB: [R] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, ret, inb(0x80));
i450kx_log("[%04X:%08X] i450KX-PB: [R] dev->pb_pci_conf[%02X] = %02X\n", CS, cpu_state.pc,
addr, ret);
}
return ret;
}
@@ -407,10 +404,10 @@ mc_write(int func, int addr, uint8_t val, void *priv)
{
i450kx_t *dev = (i450kx_t *) priv;
// pclog("i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80));
i450kx_log("i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80));
if (func == 0) {
i450kx_log("[%04X:%08X] i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X\n", CS, cpu_state.pc,
addr, val);
if (func == 0)
switch (addr) {
case 0x4c:
dev->mc_pci_conf[addr] = val & 0xdf;
@@ -600,6 +597,7 @@ mc_write(int func, int addr, uint8_t val, void *priv)
default:
break;
}
}
}
static uint8_t
@@ -608,10 +606,12 @@ mc_read(int func, int addr, void *priv)
const i450kx_t *dev = (i450kx_t *) priv;
uint8_t ret = 0xff;
if (func == 0)
if (func == 0) {
ret = dev->mc_pci_conf[addr];
// pclog("i450KX-MC: [R] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, ret, inb(0x80));
i450kx_log("[%04X:%08X] i450KX-MC: [R] dev->mc_pci_conf[%02X] = %02X\n", CS, cpu_state.pc,
addr, ret);
}
return ret;
}
@@ -622,10 +622,6 @@ i450kx_reset(void *priv)
i450kx_t *dev = (i450kx_t *) priv;
uint32_t i;
#if 0
// pclog("i450KX: i450kx_reset()\n");
#endif
/* Defaults PB */
dev->pb_pci_conf[0x00] = 0x86;
dev->pb_pci_conf[0x01] = 0x80;

View File

@@ -48,6 +48,7 @@
#define CPU_BLOCK_END() cpu_block_end = 1
int cpu_override_dynarec = 0;
int inrecomp = 0;
int cpu_block_end = 0;
int cpu_end_block_after_ins = 0;
@@ -718,7 +719,7 @@ exec386_dynarec(int32_t cycs)
cycles_old = cycles;
oldtsc = tsc;
tsc_old = tsc;
if (!CACHE_ON()) /*Interpret block*/
if ((!CACHE_ON()) || cpu_override_dynarec) /*Interpret block*/
{
exec386_dynarec_int();
} else {

View File

@@ -2372,10 +2372,10 @@ cpu_CPUID(void)
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_CMOV;
} else if (EAX == 2) {
if (!strcmp(machine_get_internal_name(), "ap61")) {
/* if (!strcmp(machine_get_internal_name(), "ap61")) {
EAX = 0x00000001;
EDX = 0x00000000;
} else {
} else */ {
EAX = 0x03020101; /* Instruction TLB: 4 KB pages, 4-way set associative, 32 entries
Instruction TLB: 4 MB pages, fully associative, 2 entries
Data TLB: 4 KB pages, 4-way set associative, 64 entries */
@@ -2799,7 +2799,9 @@ amd_k_invalid_rdmsr:
case CPU_PENTIUM2:
case CPU_PENTIUM2D:
EAX = EDX = 0;
switch (ECX) {
/* Per RichardG's probing of a real Deschutes using my RDMSR tool,
we have discovered that the top 18 bits are filtered out. */
switch (ECX & 0x00003fff) {
case 0x00:
case 0x01:
break;
@@ -2821,6 +2823,11 @@ amd_k_invalid_rdmsr:
EDX = msr.apic_base >> 32;
cpu_log("APIC_BASE read : %08X%08X\n", EDX, EAX);
break;
/* Unknown (undocumented?) MSR used by the Hyper-V BIOS. */
case 0x20:
EAX = msr.ecx20 & 0xffffffff;
EDX = msr.ecx20 >> 32;
break;
case 0x2a:
EAX = 0xc4000000;
EDX = 0;
@@ -3022,26 +3029,6 @@ amd_k_invalid_rdmsr:
EAX = msr.ecx570 & 0xffffffff;
EDX = msr.ecx570 >> 32;
break;
case 0x1002ff:
EAX = msr.ecx1002ff & 0xffffffff;
EDX = msr.ecx1002ff >> 32;
break;
case 0x40000020:
EAX = msr.ecx40000020 & 0xffffffff;
EDX = msr.ecx40000020 >> 32;
break;
case 0xf0f00250:
EAX = msr.ecxf0f00250 & 0xffffffff;
EDX = msr.ecxf0f00250 >> 32;
break;
case 0xf0f00258:
EAX = msr.ecxf0f00258 & 0xffffffff;
EDX = msr.ecxf0f00258 >> 32;
break;
case 0xf0f00259:
EAX = msr.ecxf0f00259 & 0xffffffff;
EDX = msr.ecxf0f00259 >> 32;
break;
default:
i686_invalid_rdmsr:
cpu_log("RDMSR: Invalid MSR: %08X\n", ECX);
@@ -3303,7 +3290,9 @@ amd_k_invalid_wrmsr:
case CPU_PENTIUMPRO:
case CPU_PENTIUM2:
case CPU_PENTIUM2D:
switch (ECX) {
/* Per RichardG's probing of a real Deschutes using my RDMSR tool,
we have discovered that the top 18 bits are filtered out. */
switch (ECX & 0x00003fff) {
case 0x00:
case 0x01:
if (EAX || EDX)
@@ -3318,6 +3307,10 @@ amd_k_invalid_wrmsr:
msr.apic_base = EAX | ((uint64_t) EDX << 32);
#endif
break;
/* Unknown (undocumented?) MSR used by the Hyper-V BIOS. */
case 0x20:
msr.ecx20 = EAX | ((uint64_t) EDX << 32);
break;
case 0x2a:
break;
case 0x79:
@@ -3462,21 +3455,6 @@ amd_k_invalid_wrmsr:
case 0x570:
msr.ecx570 = EAX | ((uint64_t) EDX << 32);
break;
case 0x1002ff:
msr.ecx1002ff = EAX | ((uint64_t) EDX << 32);
break;
case 0x40000020:
msr.ecx40000020 = EAX | ((uint64_t) EDX << 32);
break;
case 0xf0f00250:
msr.ecxf0f00250 = EAX | ((uint64_t) EDX << 32);
break;
case 0xf0f00258:
msr.ecxf0f00258 = EAX | ((uint64_t) EDX << 32);
break;
case 0xf0f00259:
msr.ecxf0f00259 = EAX | ((uint64_t) EDX << 32);
break;
default:
i686_invalid_wrmsr:
cpu_log("WRMSR: Invalid MSR: %08X\n", ECX);

View File

@@ -253,6 +253,12 @@ typedef struct {
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
uint64_t apic_base; /* 0x0000001b - Should the Pentium not also have this? */
/* Weird long MSR's used by the Hyper-V BIOS. */
uint64_t ecx20; /* 0x00000020, really 0x40000020, but we filter out the top 18 bits
like a real Deschutes does. */
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
uint64_t ecx79; /* 0x00000079 */
/* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */
@@ -314,9 +320,6 @@ typedef struct {
/* IBM 486SLC and 486BL MSR's */
uint64_t ibm_por2; /* 0x00001002 - Processor Operation Register */
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
uint64_t ecx1002ff; /* 0x001002ff - MSR used by some Intel AMI boards */
/* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */
uint64_t amd_efer; /* 0xc0000080 */
@@ -338,14 +341,6 @@ typedef struct {
/* K6-3, K6-2P, and K6-3P MSR's */
uint64_t amd_l2aar; /* 0xc0000089 */
/* Weird long MSR's used by the Hyper-V BIOS. */
uint64_t ecx40000020; /* 0x40000020 */
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
uint64_t ecxf0f00250; /* 0xf0f00250 - Some weird long MSR's used by i686 AMI & some Phoenix BIOSes */
uint64_t ecxf0f00258; /* 0xf0f00258 */
uint64_t ecxf0f00259; /* 0xf0f00259 */
} msr_t;
typedef struct {
@@ -838,6 +833,9 @@ extern void nmi_raise(void);
extern MMX_REG *MMP[8];
extern uint16_t *MMEP[8];
extern int cpu_block_end;
extern int cpu_override_dynarec;
extern void mmx_init(void);
extern void prefetch_flush(void);

View File

@@ -73,8 +73,8 @@ ibm_5161_in(uint16_t port, void *priv)
02-03 = not used
04-07 = switch position
1 = Off
0 =On */
ret = dev->regs[3] & 0x01;
0 = On */
ret = (dev->regs[3] & 0x01) | (((~(0xf - ((mem_size + isa_mem_size) >> 6))) & 0xf) << 4);
break;
default:
@@ -95,8 +95,7 @@ ibm_5161_close(void *priv)
static void *
ibm_5161_init(UNUSED(const device_t *info))
{
ibm_5161_t *dev = (ibm_5161_t *) malloc(sizeof(ibm_5161_t));
memset(dev, 0, sizeof(ibm_5161_t));
ibm_5161_t *dev = (ibm_5161_t *) calloc(1, sizeof(ibm_5161_t));
/* Extender Card Registers */
io_sethandler(0x0210, 0x0004,

View File

@@ -1787,6 +1787,9 @@ kbc_at_process_cmd(void *priv)
if (dev->ib == 0xbb)
break;
if (strstr(machine_get_internal_name(), "pb") != NULL)
cpu_override_dynarec = 1;
if (dev->misc_flags & FLAG_PS2) {
set_enable_aux(dev, 1);
if ((dev->ports[1] != NULL) && (dev->ports[1]->priv != NULL)) {
@@ -1891,6 +1894,8 @@ kbc_at_read(uint16_t port, void *priv)
This also means that in AT mode, the IRQ is level-triggered. */
if (!(dev->misc_flags & FLAG_PS2))
picintclevel(1 << 1, &dev->irq_state);
if ((strstr(machine_get_internal_name(), "pb") != NULL) && (cpu_override_dynarec == 1))
cpu_override_dynarec = 0;
break;
case 0x64:

View File

@@ -21,6 +21,7 @@
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include "cpu.h"
#include <86box/device.h>
#include <86box/keyboard.h>
#include <86box/mouse.h>
@@ -276,6 +277,7 @@ ps2_write(void *priv)
break;
default:
mouse_ps2_log("%s: Bad command: %02X\n", dev->name, val);
kbc_at_dev_queue_add(dev, 0xfe, 0);
}
}

View File

@@ -107,7 +107,7 @@
#define ST11_BIOS_FILE_OLD "roms/hdd/st506/st11_bios_vers_1.7.bin"
#define ST11_BIOS_FILE_NEW "roms/hdd/st506/st11_bios_vers_2.0.bin"
#define WD1002A_WX1_BIOS_FILE "roms/hdd/st506/wd1002a_wx1-62-000094-032.bin"
#define WD1004A_WX1_BIOS_FILE "roms/hdd/st506/wd1002a_wx1-62-000094-032.bin"
#define WD1004A_WX1_BIOS_FILE "roms/hdd/st506/western_digital_WD1004A-27X.bin"
/* SuperBIOS was for both the WX1 and 27X, users jumpers readout to determine
if to use 26 sectors per track, 26 -> 17 sectors per track translation, or
17 sectors per track. */
@@ -1667,7 +1667,7 @@ st506_init(const device_t *info)
fn = WD1004A_WX1_BIOS_FILE;
/* The switches are read in reverse: 0 = closed, 1 = open.
Both open means MFM, 17 sectors per track. */
dev->switches = 0x10; /* autobios */
dev->switches = 0x30; /* autobios */
dev->base = device_get_config_hex16("base");
dev->irq = device_get_config_int("irq");
if (dev->irq == 2)

View File

@@ -661,7 +661,7 @@ extern int machine_at_8500tuc_init(const machine_t *);
extern int machine_at_p55t2s_init(const machine_t *);
extern int machine_at_p5vxb_init(const machine_t *);
extern int machine_at_dell_430vx_init(const machine_t *);
extern int machine_at_dellhannibalp_init(const machine_t *);
extern int machine_at_gw2kte_init(const machine_t *);
extern int machine_at_ap5s_init(const machine_t *);
@@ -713,7 +713,7 @@ extern int machine_at_ficpa2012_init(const machine_t *);
extern int machine_at_r534f_init(const machine_t *);
extern int machine_at_ms5146_init(const machine_t *);
extern int machine_at_cb52x_si_init(const machine_t *);
extern int machine_at_cb52xsi_init(const machine_t *);
extern int machine_at_m560_init(const machine_t *);
extern int machine_at_ms5164_init(const machine_t *);
@@ -731,12 +731,12 @@ extern int machine_at_ficva503a_init(const machine_t *);
extern int machine_at_5emapro_init(const machine_t *);
/* m_at_socket8.c */
extern int machine_at_ap61_init(const machine_t *);
extern int machine_at_p6rp4_init(const machine_t *);
extern int machine_at_aurora_init(const machine_t *);
extern int machine_at_686nx_init(const machine_t *);
extern int machine_at_acerv60n_init(const machine_t *);
extern int machine_at_lgibm440fx_init(const machine_t *);
extern int machine_at_lgibmx61_init(const machine_t *);
extern int machine_at_vs440fx_init(const machine_t *);
extern int machine_at_gw2kvenus_init(const machine_t *);
extern int machine_at_ap440fx_init(const machine_t *);
@@ -757,12 +757,12 @@ extern int machine_at_kn97_init(const machine_t *);
extern int machine_at_lx6_init(const machine_t *);
extern int machine_at_spitfire_init(const machine_t *);
extern int machine_at_mate_nx_ma30d_23d_init(const machine_t *);
extern int machine_at_ma30d_init(const machine_t *);
extern int machine_at_p6i440e2_init(const machine_t *);
extern int machine_at_p2bls_init(const machine_t *);
extern int machine_at_lgibm440bx_init(const machine_t *);
extern int machine_at_lgibmx7g_init(const machine_t *);
extern int machine_at_p3bf_init(const machine_t *);
extern int machine_at_bf6_init(const machine_t *);
extern int machine_at_ax6bc_init(const machine_t *);

View File

@@ -449,6 +449,8 @@ extern void mem_close(void);
extern void mem_reset(void);
extern void mem_remap_top(int kb);
extern void umc_smram_recalc(uint32_t start, int set);
extern mem_mapping_t *read_mapping[MEM_MAPPINGS_NO];
extern mem_mapping_t *write_mapping[MEM_MAPPINGS_NO];

View File

@@ -152,8 +152,10 @@ typedef struct ibm8514_t {
int hblank_ext;
int hblank_sub;
int v_total_reg;
int v_total;
int dispend;
int v_sync_start;
int v_syncstart;
int split;
int h_disp;

View File

@@ -56,6 +56,8 @@ typedef struct ega_t {
uint8_t *vram;
uint16_t light_pen;
int vidclock;
int fast;
int extvram;

View File

@@ -153,11 +153,11 @@ machine_at_spitfire_init(const machine_t *model)
}
int
machine_at_mate_nx_ma30d_23d_init(const machine_t *model)
machine_at_ma30d_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/mate_nx_ma30d_23d/BIOS.ROM",
ret = bios_load_linear("roms/machines/ma30d/BIOS.ROM",
0x000c0000, 262144, 0);
if (bios_only || !ret)
@@ -183,8 +183,7 @@ machine_at_mate_nx_ma30d_23d_init(const machine_t *model)
device_add(&keyboard_ps2_ami_pci_device);
device_add(&fdc37c67x_device);
device_add(&intel_flash_bxt_device);
spd_register(SPD_TYPE_SDRAM, 0xF, 256);
device_add(&lm78_device); /* no reporting in BIOS */
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
return ret;
}
@@ -261,11 +260,11 @@ machine_at_p2bls_init(const machine_t *model)
}
int
machine_at_lgibm440bx_init(const machine_t *model)
machine_at_lgibmx7g_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/lgibm440bx/ms6119.331",
ret = bios_load_linear("roms/machines/lgibmx7g/ms6119.331",
0x000c0000, 262144, 0);
if (bios_only || !ret)

View File

@@ -1240,11 +1240,11 @@ machine_at_ms5146_init(const machine_t *model)
}
int
machine_at_cb52x_si_init(const machine_t *model)
machine_at_cb52xsi_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/cb52x_si/CD5205S.ROM",
ret = bios_load_linear("roms/machines/cb52xsi/CD5205S.ROM",
0x000e0000, 131072, 0);
if (bios_only || !ret)

View File

@@ -672,15 +672,15 @@ machine_at_p5vxb_init(const machine_t *model)
}
int
machine_at_dell_430vx_init(const machine_t *model)
machine_at_dellhannibalp_init(const machine_t *model)
{
int ret;
ret = bios_load_linear_combined2("roms/machines/dell_430vx/1003DY0J.BIO",
"roms/machines/dell_430vx/1003DY0J.BI1",
"roms/machines/dell_430vx/1003DY0J.BI2",
"roms/machines/dell_430vx/1003DY0J.BI3",
"roms/machines/dell_430vx/1003DY0J.RCV",
ret = bios_load_linear_combined2("roms/machines/dellhannibalp/1003DY0J.BIO",
"roms/machines/dellhannibalp/1003DY0J.BI1",
"roms/machines/dellhannibalp/1003DY0J.BI2",
"roms/machines/dellhannibalp/1003DY0J.BI3",
"roms/machines/dellhannibalp/1003DY0J.RCV",
0x3a000, 128);
if (bios_only || !ret)

View File

@@ -39,6 +39,39 @@
#include "cpu.h"
#include <86box/machine.h>
int
machine_at_ap61_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/ap61/ap61r120.bin",
0x000e0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x19, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x14, PCI_CARD_NORTHBRIDGE_SEC, 0, 0, 0, 0);
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x07, PCI_CARD_IDE, 0xFE, 0xFF, 0, 0);
pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3);
device_add(&i450kx_device);
device_add(&sio_zb_device);
device_add(&ide_cmd646_device);
device_add(&keyboard_ps2_acer_pci_device);
device_add(&fdc37c665_device);
device_add(&sst_flash_29ee010_device);
// device_add(&intel_flash_bxt_device);
return ret;
}
int
machine_at_p6rp4_init(const machine_t *model)
{
@@ -162,11 +195,11 @@ machine_at_acerv60n_init(const machine_t *model)
}
int
machine_at_lgibm440fx_init(const machine_t *model)
machine_at_lgibmx61_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/lgibm440fx/bios.rom",
ret = bios_load_linear("roms/machines/lgibmx61/bios.rom",
0x000e0000, 131072, 0);
if (bios_only || !ret)
@@ -183,8 +216,10 @@ machine_at_lgibm440fx_init(const machine_t *model)
pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3);
device_add(&i440fx_device);
device_add(&piix3_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&w83787f_device);
// device_add(&keyboard_ps2_ami_pci_device);
device_add(&keyboard_ps2_ami_device);
// device_add(&w83787f_device);
device_add(&w83877f_president_device);
device_add(&sst_flash_29ee010_device);
return ret;

View File

@@ -646,7 +646,7 @@ machine_xt_glabios_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/glabios/GLABIOS_0.2.5_8E.ROM",
ret = bios_load_linear("roms/machines/glabios/GLABIOS_0.2.6_8X_012324.ROM",
0x000fe000, 8192, 0);
if (bios_only || !ret)
@@ -655,4 +655,4 @@ machine_xt_glabios_init(const machine_t *model)
machine_xt_init_ex(model);
return ret;
}
}

View File

@@ -709,6 +709,45 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
{
.name = "[8088] GLaBIOS",
.internal_name = "glabios",
.type = MACHINE_TYPE_8088,
.chipset = MACHINE_CHIPSET_DISCRETE,
.init = machine_xt_glabios_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_8088,
.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_PC,
.flags = MACHINE_FLAGS_NONE,
.ram = {
.min = 64,
.max = 640,
.step = 64
},
.nvrmask = 0,
.kbc_device = &keyboard_xt_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
},
{
.name = "[8088] Hyosung Topstar 88T",
.internal_name = "top88",
@@ -1804,45 +1843,6 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
{
.name = "[8088] GLaBIOS",
.internal_name = "glabios",
.type = MACHINE_TYPE_8088,
.chipset = MACHINE_CHIPSET_DISCRETE,
.init = machine_xt_glabios_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_8088,
.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_PC,
.flags = MACHINE_FLAGS_NONE,
.ram = {
.min = 64,
.max = 640,
.step = 64
},
.nvrmask = 0,
.kbc_device = &keyboard_xt_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
},
{
.name = "[GC100A] Philips P3120",
.internal_name = "p3120",
@@ -2769,8 +2769,8 @@ const machine_t machines[] = {
.cpu = {
.package = CPU_PKG_286,
.block = CPU_BLOCK_NONE,
.min_bus = 0,
.max_bus = 0,
.min_bus = 6000000,
.max_bus = 16000000,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
@@ -2809,8 +2809,8 @@ const machine_t machines[] = {
.cpu = {
.package = CPU_PKG_286,
.block = CPU_BLOCK_NONE,
.min_bus = 0,
.max_bus = 0,
.min_bus = 6000000,
.max_bus = 16000000,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
@@ -4876,9 +4876,9 @@ const machine_t machines[] = {
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_386DX,
.block = CPU_BLOCK_NONE,
.min_bus = 0,
.max_bus = 0,
.block = CPU_BLOCK(CPU_486DLC, CPU_RAPIDCAD),
.min_bus = 16000000,
.max_bus = 16000000,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
@@ -4915,9 +4915,9 @@ const machine_t machines[] = {
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_386DX,
.block = CPU_BLOCK_NONE,
.min_bus = 0,
.max_bus = 0,
.block = CPU_BLOCK(CPU_486DLC, CPU_RAPIDCAD),
.min_bus = 25000000,
.max_bus = 25000000,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
@@ -4955,8 +4955,8 @@ const machine_t machines[] = {
.cpu = {
.package = CPU_PKG_386DX,
.block = CPU_BLOCK_NONE,
.min_bus = 0,
.max_bus = 0,
.min_bus = 20000000,
.max_bus = 20000000,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
@@ -10408,10 +10408,10 @@ const machine_t machines[] = {
Command 0xA0 copyright string: (C)1994 AMI . */
{
.name = "[i430VX] Dell Hannibal+",
.internal_name = "dell_430vx",
.internal_name = "dellhannibalp",
.type = MACHINE_TYPE_SOCKET7_3V,
.chipset = MACHINE_CHIPSET_INTEL_430VX,
.init = machine_at_dell_430vx_init,
.init = machine_at_dellhannibalp_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
@@ -12040,10 +12040,10 @@ const machine_t machines[] = {
/* Has the SiS 5571 chipset with on-chip KBC. */
{
.name = "[SiS 5571] Daewoo CB52X-SI",
.internal_name = "cb52x_si",
.internal_name = "cb52xsi",
.type = MACHINE_TYPE_SOCKET7,
.chipset = MACHINE_CHIPSET_SIS_5571,
.init = machine_at_cb52x_si_init,
.init = machine_at_cb52xsi_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
@@ -12613,6 +12613,46 @@ const machine_t machines[] = {
/* Socket 8 machines */
/* 450KX */
/* This has an AMIKey-2, which is an updated version of type 'H'. */
{
.name = "[i450KX] AOpen AP61",
.internal_name = "ap61",
.type = MACHINE_TYPE_SOCKET8,
.chipset = MACHINE_CHIPSET_INTEL_450KX,
.init = machine_at_ap61_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_SOCKET8,
.block = CPU_BLOCK_NONE,
.min_bus = 60000000,
.max_bus = 66666667,
.min_voltage = 2100,
.max_voltage = 3500,
.min_multi = 1.5,
.max_multi = 8.0
},
.bus_flags = MACHINE_PS2_PCI,
.flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI,
.ram = {
.min = 8192,
.max = 524288,
.step = 8192
},
.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
},
/* This has an AMIKey-2, which is an updated version of type 'H'. */
{
.name = "[i450KX] ASUS P/I-P6RP4",
.internal_name = "p6rp4",
@@ -12942,10 +12982,10 @@ const machine_t machines[] = {
/* Has the AMIKey-2 (updated 'H') KBC firmware. */
{
.name = "[i440FX] LG IBM Multinet x61 (MSI MS-6106)",
.internal_name = "lgibm440fx",
.internal_name = "lgibmx61",
.type = MACHINE_TYPE_SOCKET8,
.chipset = MACHINE_CHIPSET_INTEL_440FX,
.init = machine_at_lgibm440fx_init,
.init = machine_at_lgibmx61_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
@@ -13275,10 +13315,10 @@ const machine_t machines[] = {
AMIKey-2 KBC firmware. */
{
.name = "[i440LX] NEC Mate NX MA30D/23D",
.internal_name = "mate_nx_ma30d_23d",
.internal_name = "ma30d",
.type = MACHINE_TYPE_SLOT1,
.chipset = MACHINE_CHIPSET_INTEL_440LX,
.init = machine_at_mate_nx_ma30d_23d_init,
.init = machine_at_ma30d_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
@@ -13297,7 +13337,7 @@ const machine_t machines[] = {
.flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI,
.ram = {
.min = 8192,
.max = 1048576,
.max = 786432,
.step = 8192
},
.nvrmask = 255,
@@ -13606,10 +13646,10 @@ const machine_t machines[] = {
/* Has the AMIKey-2 (updated 'H') KBC firmware. */
{
.name = "[i440BX] LG IBM Multinet i x7G (MSI MS-6119)",
.internal_name = "lgibm440bx",
.internal_name = "lgibmx7g",
.type = MACHINE_TYPE_SLOT1,
.chipset = MACHINE_CHIPSET_INTEL_440BX,
.init = machine_at_lgibm440bx_init,
.init = machine_at_lgibmx7g_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
@@ -13617,9 +13657,9 @@ const machine_t machines[] = {
.cpu = {
.package = CPU_PKG_SLOT1,
.block = CPU_BLOCK_NONE,
.min_bus = 50000000,
.max_bus = 112121212,
.min_voltage = 1300,
.min_bus = 66666667,
.max_bus = 100000000,
.min_voltage = 1800,
.max_voltage = 3500,
.min_multi = 1.5,
.max_multi = 8.0
@@ -13628,7 +13668,7 @@ const machine_t machines[] = {
.flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI,
.ram = {
.min = 8192,
.max = 1048576,
.max = 786432,
.step = 8192
},
.nvrmask = 255,

View File

@@ -1585,40 +1585,38 @@ do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write)
for (i = 0; i < num; i++)
a64[i] = (uint64_t) addr;
for (i = 0; i < num; i++) {
if (cr0 >> 31) {
if (write && ((i == 0) || !(addr & 0xfff)))
cond = (!page_lookup[addr >> 12] || !page_lookup[addr >> 12]->write_b);
if (cr0 >> 31) for (i = 0; i < num; i++) {
if (write && ((i == 0) || !(addr & 0xfff)))
cond = (!page_lookup[addr >> 12] || !page_lookup[addr >> 12]->write_b);
if (cond) {
/* If we have encountered at least one page fault, mark all subsequent addresses as
having page faulted, prevents false negatives in readmem*l_no_mmut. */
if ((i > 0) && cpu_state.abrt && !high_page)
a64[i] = a64[i - 1];
/* If we are on the same page, there is no need to translate again, as we can just
reuse the previous result. */
else if (i == 0) {
a = mmutranslatereal(addr, write);
a64[i] = (uint32_t) a;
if (cond) {
/* If we have encountered at least one page fault, mark all subsequent addresses as
having page faulted, prevents false negatives in readmem*l_no_mmut. */
if ((i > 0) && cpu_state.abrt && !high_page)
a64[i] = a64[i - 1];
/* If we are on the same page, there is no need to translate again, as we can just
reuse the previous result. */
else if (i == 0) {
a = mmutranslatereal(addr, write);
a64[i] = (uint32_t) a;
high_page = high_page || (!cpu_state.abrt && (a > 0xffffffffULL));
} else if (!(addr & 0xfff)) {
a = mmutranslatereal(last_addr, write);
a64[i] = (uint32_t) a;
high_page = high_page || (!cpu_state.abrt && (a > 0xffffffffULL));
} else if (!(addr & 0xfff)) {
a = mmutranslatereal(last_addr, write);
a64[i] = (uint32_t) a;
high_page = high_page || (!cpu_state.abrt && (a64[i] > 0xffffffffULL));
high_page = high_page || (!cpu_state.abrt && (a64[i] > 0xffffffffULL));
if (!cpu_state.abrt) {
a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff));
a64[i] = (uint32_t) a;
}
} else {
if (!cpu_state.abrt) {
a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff));
a64[i] = (uint32_t) a;
}
} else
mmu_perm = page_lookupp[addr >> 12];
}
} else {
a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff));
a64[i] = (uint32_t) a;
}
} else
mmu_perm = page_lookupp[addr >> 12];
addr++;
}
@@ -2871,6 +2869,35 @@ mem_init(void)
writelookupp = malloc((1 << 20) * sizeof(uint8_t));
}
static void
umc_page_recalc(uint32_t c, int set)
{
if (set) {
pages[c].mem = &ram[(c & 0xff) << 12];
pages[c].write_b = mem_write_ramb_page;
pages[c].write_w = mem_write_ramw_page;
pages[c].write_l = mem_write_raml_page;
} else {
pages[c].mem = page_ff;
pages[c].write_b = NULL;
pages[c].write_w = NULL;
pages[c].write_l = NULL;
}
#ifdef USE_NEW_DYNAREC
pages[c].evict_prev = EVICT_NOT_IN_LIST;
pages[c].byte_dirty_mask = &byte_dirty_mask[(c & 0xff) * 64];
pages[c].byte_code_present_mask = &byte_code_present_mask[(c & 0xff) * 64];
#endif
}
void
umc_smram_recalc(uint32_t start, int set)
{
for (uint32_t c = start; c < (start + 0x0020); c++)
umc_page_recalc(c, set);
}
void
mem_remap_top(int kb)
{

View File

@@ -308,6 +308,8 @@ enum CSCRBits {
#endif
enum CSCRBits {
CSCR_Testfun = 1 << 15, /* 1 = Auto-neg speeds up internal timer, WO, def 0 */
CSCR_Cable_Changed = 1 << 11, /* Undocumented: 1 = Cable status changed, 0 = No change */
CSCR_Cable = 1 << 10, /* Undocumented: 1 = Cable connected, 0 = Cable disconnected */
CSCR_LD = 1 << 9, /* Active low TPI link disable signal. When low, TPI still transmits link pulses and TPI stays in good link state. def 1*/
CSCR_HEART_BIT = 1 << 8, /* 1 = HEART BEAT enable, 0 = HEART BEAT disable. HEART BEAT function is only valid in 10Mbps mode. def 1*/
CSCR_JBEN = 1 << 7, /* 1 = enable jabber function. 0 = disable jabber function, def 1*/
@@ -2285,7 +2287,17 @@ rtl8139_TSAD_read(RTL8139State *s)
static uint16_t
rtl8139_CSCR_read(RTL8139State *s)
{
uint16_t ret = s->CSCR;
static uint16_t old_ret = 0xffff;
uint16_t ret = s->CSCR |
((net_cards_conf[s->nic->card_num].link_state & NET_LINK_DOWN) ? 0 : CSCR_Cable);
if (old_ret != 0xffff) {
ret &= ~CSCR_Cable_Changed;
if ((ret ^ old_ret) & CSCR_Cable)
ret |= CSCR_Cable_Changed;
}
old_ret = ret;
rtl8139_log("CSCR read val=0x%04x\n", ret);
@@ -2736,6 +2748,13 @@ rtl8139_io_readb(uint32_t addr, void *priv)
rtl8139_log("RTL8139C TxConfig at 0x43 read(b) val=0x%02x\n", ret);
break;
case CSCR:
ret = rtl8139_CSCR_read(s) & 0xff;
break;
case CSCR + 1:
ret = rtl8139_CSCR_read(s) >> 8;
break;
default:
rtl8139_log("not implemented read(b) addr=0x%x\n", addr);
ret = 0;
@@ -3105,6 +3124,12 @@ rtl8139_pci_read(UNUSED(int func), int addr, void *priv)
return 1;
case 0x14:
return 0;
case 0x15:
#ifdef USE_256_BYTE_BAR
return s->pci_conf[addr & 0xFF];
#else
return s->pci_conf[addr & 0xFF] & 0xf0;
#endif
case 0x2c:
return 0xEC;
case 0x2d:
@@ -3164,15 +3189,27 @@ rtl8139_pci_write(int func, int addr, uint8_t val, void *priv)
rtl8139_io_writeb_ioport, rtl8139_io_writew_ioport, rtl8139_io_writel_ioport,
priv);
break;
#ifndef USE_256_BYTE_BAR
case 0x14:
#endif
case 0x15:
case 0x16:
case 0x17:
s->pci_conf[addr & 0xFF] = val;
s->mem_base = (s->pci_conf[0x15] << 8) | (s->pci_conf[0x16] << 16) | (s->pci_conf[0x17] << 24);
s->mem_base = (s->pci_conf[0x15] << 8) | (s->pci_conf[0x16] << 16) |
(s->pci_conf[0x17] << 24);
#ifndef USE_256_BYTE_BAR
s->mem_base &= 0xfffff000;
#endif
rtl8139_log("New memory base: %08X\n", s->mem_base);
if (s->pci_conf[0x4] & PCI_COMMAND_MEM)
mem_mapping_set_addr(&s->bar_mem, (s->pci_conf[0x15] << 8) | (s->pci_conf[0x16] << 16) | (s->pci_conf[0x17] << 24), 256);
#ifdef USE_256_BYTE_BAR
mem_mapping_set_addr(&s->bar_mem, (s->pci_conf[0x15] << 8) | (s->pci_conf[0x16] << 16) |
(s->pci_conf[0x17] << 24), 256);
#else
mem_mapping_set_addr(&s->bar_mem, ((s->pci_conf[0x15] & 0xf0) << 8) |
(s->pci_conf[0x16] << 16) | (s->pci_conf[0x17] << 24), 4096);
#endif
break;
case 0x3c:
s->pci_conf[addr & 0xFF] = val;

View File

@@ -1038,37 +1038,55 @@ tulip_writel_io(uint16_t addr, uint32_t data, void *opaque)
static void
tulip_mem_writeb(uint32_t addr, uint8_t data, void *opaque)
{
return tulip_write(addr, data, opaque);
if ((addr & 0xfff) < 0x100)
tulip_write(addr, data, opaque);
}
static void
tulip_mem_writew(uint32_t addr, uint16_t data, void *opaque)
{
return tulip_write(addr, data, opaque);
if ((addr & 0xfff) < 0x100)
tulip_write(addr, data, opaque);
}
static void
tulip_mem_writel(uint32_t addr, uint32_t data, void *opaque)
{
return tulip_write(addr, data, opaque);
if ((addr & 0xfff) < 0x100)
tulip_write(addr, data, opaque);
}
static uint8_t
tulip_mem_readb(uint32_t addr, void *opaque)
{
return tulip_read(addr, opaque);
uint8_t ret = 0xff;
if ((addr & 0xfff) < 0x100)
ret = tulip_read(addr, opaque);
return ret;
}
static uint16_t
tulip_mem_readw(uint32_t addr, void *opaque)
{
return tulip_read(addr, opaque);
uint16_t ret = 0xffff;
if ((addr & 0xfff) < 0x100)
ret = tulip_read(addr, opaque);
return ret;
}
static uint32_t
tulip_mem_readl(uint32_t addr, void *opaque)
{
return tulip_read(addr, opaque);
uint32_t ret = 0xffffffff;
if ((addr & 0xfff) < 0x100)
ret = tulip_read(addr, opaque);
return ret;
}
static uint8_t
@@ -1208,11 +1226,17 @@ tulip_pci_read(UNUSED(int func), int addr, void *priv)
case 0x13:
ret = tulip_pci_bar[0].addr_regs[3];
break;
#ifdef USE_128_BYTE_BAR
case 0x14:
ret = (tulip_pci_bar[1].addr_regs[0] & 0x80);
break;
#endif
case 0x15:
#ifdef USE_128_BYTE_BAR
ret = tulip_pci_bar[1].addr_regs[1];
#else
ret = tulip_pci_bar[1].addr_regs[1] & 0xf0;
#endif
break;
case 0x16:
ret = tulip_pci_bar[1].addr_regs[2];
@@ -1283,7 +1307,7 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
//pclog("PCI write cmd: IOBase=%04x, MMIOBase=%08x, val=%02x.\n", s->PCIBase, s->MMIOBase, s->pci_conf[0x04]);
mem_mapping_disable(&s->memory);
if ((s->MMIOBase != 0) && (val & PCI_COMMAND_MEM))
mem_mapping_set_addr(&s->memory, s->MMIOBase, 128);
mem_mapping_enable(&s->memory);
break;
case 0x05:
s->pci_conf[0x05] = val & 1;
@@ -1308,18 +1332,28 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
priv);
}
break;
#ifndef USE_128_BYTE_BAR
case 0x14:
#endif
case 0x15:
case 0x16:
case 0x17:
mem_mapping_disable(&s->memory);
tulip_pci_bar[1].addr_regs[addr & 3] = val;
#ifdef USE_128_BYTE_BAR
tulip_pci_bar[1].addr &= 0xffffff80;
#else
tulip_pci_bar[1].addr &= 0xfffff000;
#endif
s->MMIOBase = tulip_pci_bar[1].addr;
if (s->pci_conf[0x4] & PCI_COMMAND_MEM) {
//pclog("PCI write=%02x, mmiobase=%08x, mmio?=%x.\n", addr, s->PCIBase, s->pci_conf[0x4] & PCI_COMMAND_MEM);
if (s->MMIOBase != 0)
#ifdef USE_128_BYTE_BAR
mem_mapping_set_addr(&s->memory, s->MMIOBase, 128);
#else
mem_mapping_set_addr(&s->memory, s->MMIOBase, 4096);
#endif
}
break;
case 0x30: /* PCI_ROMBAR */
@@ -1369,19 +1403,33 @@ nic_init(const device_t *info)
s->has_bios = 0;
}
#ifdef USE_128_BYTE_BAR
mem_mapping_add(&s->memory, 0x0fffff00, 128, tulip_mem_readb, tulip_mem_readw, tulip_mem_readl, tulip_mem_writeb, tulip_mem_writew, tulip_mem_writel, NULL, MEM_MAPPING_EXTERNAL, s);
#else
mem_mapping_add(&s->memory, 0x0ffff000, 4096, tulip_mem_readb, tulip_mem_readw, tulip_mem_readl, tulip_mem_writeb, tulip_mem_writew, tulip_mem_writel, NULL, MEM_MAPPING_EXTERNAL, s);
#endif
mem_mapping_disable(&s->memory);
s->device_info = info;
if (info->local != 3) {
/*Subsystem Vendor ID*/
s->eeprom_data[0] = info->local ? 0x25 : 0x11;
s->eeprom_data[1] = 0x10;
if (info->local == 2) {
/*Subsystem Vendor ID*/
s->eeprom_data[0] = 0x00;
s->eeprom_data[1] = 0x0a;
/*Subsystem ID*/
s->eeprom_data[2] = info->local ? 0x10 : 0x0a;
s->eeprom_data[3] = info->local ? 0x03 : 0x50;
/*Subsystem ID*/
s->eeprom_data[2] = 0x14;
s->eeprom_data[3] = 0x21;
} else {
/*Subsystem Vendor ID*/
s->eeprom_data[0] = info->local ? 0x25 : 0x11;
s->eeprom_data[1] = 0x10;
/*Subsystem ID*/
s->eeprom_data[2] = info->local ? 0x10 : 0x0a;
s->eeprom_data[3] = info->local ? 0x03 : 0x50;
}
/*Cardbus CIS Pointer low*/
s->eeprom_data[4] = 0x00;

View File

@@ -215,8 +215,9 @@ static void
w83787f_fdc_handler(w83787f_t *dev)
{
fdc_remove(dev->fdc);
if (!(dev->regs[0] & 0x20) && !(dev->regs[6] & 0x08))
if (!(dev->regs[0] & 0x20))
fdc_set_base(dev->fdc, (dev->regs[0] & 0x10) ? FDC_PRIMARY_ADDR : FDC_SECONDARY_ADDR);
fdc_set_power_down(dev->fdc, !!(dev->regs[6] & 0x08));
}
static void
@@ -258,10 +259,10 @@ w83787f_write(uint16_t port, uint8_t val, void *priv)
return;
} else {
if (dev->locked) {
if (dev->rw_locked)
if (dev->rw_locked && (dev->cur_reg <= 0x0b))
return;
if (dev->cur_reg == 6)
val &= 0xF3;
val &= 0xFB;
valxor = val ^ dev->regs[dev->cur_reg];
dev->regs[dev->cur_reg] = val;
} else
@@ -363,7 +364,7 @@ w83787f_read(uint16_t port, void *priv)
else if (port == 0x252) {
if (dev->cur_reg == 7)
ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2));
else if (!dev->rw_locked)
else if (!dev->rw_locked || (dev->cur_reg > 0x0b))
ret = dev->regs[dev->cur_reg];
}
}
@@ -406,6 +407,7 @@ w83787f_reset(w83787f_t *dev)
dev->regs[0x00] = 0xd0;
fdc_reset(dev->fdc);
w83787f_fdc_handler(dev);
dev->regs[0x01] = 0x2C;
dev->regs[0x03] = 0x70;

View File

@@ -78,12 +78,12 @@ w83877f_remap(w83877f_t *dev)
{
uint8_t hefras = HEFRAS;
io_removehandler(0x250, 0x0002,
io_removehandler(0x250, 0x0003,
w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, dev);
io_removehandler(FDC_PRIMARY_ADDR, 0x0002,
w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, dev);
dev->base_address = (hefras ? FDC_PRIMARY_ADDR : 0x250);
io_sethandler(dev->base_address, 0x0002,
io_sethandler(dev->base_address, hefras ? 0x0002 : 0x0003,
w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, dev);
dev->key_times = hefras + 1;
dev->key = (hefras ? 0x86 : 0x88) | HEFERE;
@@ -155,8 +155,9 @@ static void
w83877f_fdc_handler(w83877f_t *dev)
{
fdc_remove(dev->fdc);
if (!(dev->regs[6] & 0x08) && (dev->regs[0x20] & 0xc0))
fdc_set_base(dev->fdc, FDC_PRIMARY_ADDR);
if (dev->regs[0x20] & 0xc0)
fdc_set_base(dev->fdc, make_port(dev, 0x20));
fdc_set_power_down(dev->fdc, !!(dev->regs[6] & 0x08));
}
static void
@@ -252,7 +253,7 @@ w83877f_write(uint16_t port, uint8_t val, void *priv)
if (dev->cur_reg == 0x29)
return;
if (dev->cur_reg == 6)
val &= 0xF3;
val &= 0xFB;
valxor = val ^ dev->regs[dev->cur_reg];
dev->regs[dev->cur_reg] = val;
} else

View File

@@ -901,8 +901,10 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len)
case 0x6e8:
case 0x6e9:
if (!(port & 1)) {
dev->hdisped = val;
dev->hdisp = (dev->hdisped + 1) << 3;
if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) {
dev->hdisped = val;
dev->hdisp = (dev->hdisped + 1) << 3;
}
}
ibm8514_log("IBM 8514/A: H_DISP write 06E8 = %d, advfunc=%x.\n", dev->hdisp, dev->accel.advfunc_cntl & 4);
break;
@@ -910,8 +912,10 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len)
case 0xae8:
case 0xae9:
if (!(port & 1)) {
dev->hsync_start = val;
dev->hblankstart = (dev->hsync_start & 0x07) + 1;
if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) {
dev->hsync_start = val;
dev->hblankstart = (dev->hsync_start & 0x07) + 1;
}
}
ibm8514_log("IBM 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1);
break;
@@ -919,32 +923,44 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len)
case 0xee8:
case 0xee9:
if (!(port & 1)) {
dev->hsync_width = val;
dev->hblank_end_val = (dev->hblankstart + (dev->hsync_start & 0x1f) - 1) & 0x3f;
if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) {
dev->hsync_width = val;
dev->hblank_end_val = (dev->hblankstart + (dev->hsync_start & 0x1f) - 1) & 0x3f;
}
}
ibm8514_log("IBM 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1);
break;
case 0x12e8:
case 0x12e9:
WRITE8(port, dev->vtotal, val);
dev->vtotal &= 0x1fff;
if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) {
WRITE8(port, dev->v_total_reg, val);
dev->v_total_reg &= 0x1fff;
dev->vtotal = dev->v_total_reg;
dev->vtotal++;
}
break;
case 0x16e8:
case 0x16e9:
WRITE8(port, dev->v_disp, val);
dev->v_disp &= 0x1fff;
dev->vdisp = dev->v_disp;
dev->vdisp >>= 1;
dev->vdisp++;
if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) {
WRITE8(port, dev->v_disp, val);
dev->v_disp &= 0x1fff;
dev->vdisp = dev->v_disp;
dev->vdisp >>= 1;
dev->vdisp++;
}
ibm8514_log("IBM 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp);
break;
case 0x1ae8:
case 0x1ae9:
WRITE8(port, dev->vsyncstart, val);
dev->vsyncstart &= 0x1fff;
if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) {
WRITE8(port, dev->v_sync_start, val);
dev->v_sync_start &= 0x1fff;
dev->vsyncstart = dev->v_sync_start;
dev->vsyncstart++;
}
break;
case 0x1ee8:
@@ -988,14 +1004,6 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len)
dev->on[port & 1] = dev->accel.advfunc_cntl & 0x01;
vga_on = !dev->on[port & 1];
dev->vendor_mode[port & 1] = 0;
if (dev->on[0] || dev->on[1]) {
if (!(dev->accel.advfunc_cntl & 4)) {
if (dev->disp_cntl & 0x60) {
dev->hdisp = 640;
dev->vdisp = 480;
}
}
}
ibm8514_log("IBM 8514/A: (0x%04x): ON=%d, shadow crt=%x.\n", port, dev->on[port & 1], dev->accel.advfunc_cntl & 4);
svga_recalctimings(svga);
break;
@@ -4208,7 +4216,6 @@ ibm8514_poll(void *priv, svga_t *svga)
dev->firstline--;
wx = x;
wy = dev->lastline - dev->firstline;
svga_doblit(wx, wy, svga);
@@ -4262,17 +4269,14 @@ ibm8514_recalctimings(svga_t *svga)
dev->h_total = dev->htotal + 1;
dev->h_blankstart = dev->hblankstart;
dev->h_blank_end_val = dev->hblank_end_val;
dev->v_total = dev->vtotal + 1;
dev->v_syncstart = dev->vsyncstart + 1;
dev->rowcount = !!(dev->disp_cntl & 0x08);
dev->v_total = dev->vtotal;
dev->v_syncstart = dev->vsyncstart;
dev->dispend = dev->vdisp;
dev->rowcount = !!(dev->disp_cntl & 0x08);
if (dev->dispend == 766)
dev->dispend += 2;
if (dev->dispend == 598)
dev->dispend += 2;
if (dev->accel.advfunc_cntl & 4) {
dev->pitch = 1024;
if (!dev->h_disp) {
@@ -4289,25 +4293,18 @@ ibm8514_recalctimings(svga_t *svga)
svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
}
if (dev->interlace)
if (dev->interlace) {
dev->dispend >>= 1;
dev->v_syncstart >>= 2;
dev->v_total >>= 2;
} else {
dev->v_syncstart >>= 1;
dev->v_total >>= 1;
}
dev->rowoffset = 0x80;
svga->map8 = dev->pallook;
svga->render8514 = ibm8514_render_8bpp;
dev->hblankend = (dev->h_blankstart & ~0x3f) | dev->h_blank_end_val;
if (dev->hblankend <= dev->h_blankstart)
dev->hblankend += 0x40;
dev->hblankend += dev->hblank_ext;
dev->hblank_sub = 0;
if (dev->hblankend > dev->h_total) {
dev->hblankend &= 0x3f;
dev->hblank_sub = dev->hblankend + 1;
dev->h_disp -= dev->hblank_sub;
}
ibm8514_log("BPP=%d, Pitch = %d, rowoffset = %d, crtc13 = %02x, highres bit = %02x, has_vga? = %d.\n", dev->bpp, dev->pitch, dev->rowoffset, svga->crtc[0x13], dev->accel.advfunc_cntl & 4, !ibm8514_standalone_enabled);
}
}
@@ -4440,10 +4437,13 @@ ibm8514_close(void *priv)
{
svga_t *svga = (svga_t *) priv;
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
#ifdef ATI_8514_ULTRA
mach_t *mach = (mach_t *) svga->ext8514;
if (mach)
free(mach);
#endif
if (dev) {
free(dev->vram);

View File

@@ -59,7 +59,17 @@ static uint8_t mach_accel_inb(uint16_t port, void *priv);
static uint16_t mach_accel_inw(uint16_t port, void *priv);
static uint8_t mach_in(uint16_t addr, void *priv);
static void mach32_updatemapping(mach_t *mach, svga_t *svga);
#ifdef ATI_8514_ULTRA
static void ati8514_accel_outb(uint16_t port, uint8_t val, void *priv);
static void ati8514_accel_outw(uint16_t port, uint16_t val, void *priv);
static void ati8514_accel_outl(uint16_t port, uint32_t val, void *priv);
static uint8_t ati8514_accel_inb(uint16_t port, void *priv);
static uint16_t ati8514_accel_inw(uint16_t port, void *priv);
static uint32_t ati8514_accel_inl(uint16_t port, void *priv);
#endif
static void mach32_updatemapping(mach_t *mach, svga_t *svga);
#ifdef ENABLE_MACH_LOG
int mach_do_log = ENABLE_MACH_LOG;
@@ -113,9 +123,9 @@ mach_log(const char *fmt, ...)
#define READ_PIXTRANS_WORD(cx, n) \
if ((cmd == 0) || (cmd == 1) || (cmd == 5) || (mach->accel.cmd_type == -1)) { \
if (dev->bpp) { \
if (dev->bpp) \
temp = vram_w[((dev->accel.cy * dev->pitch) + (cx) + (n)) & (dev->vram_mask >> 1)]; \
} else { \
else { \
temp = dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n)) & dev->vram_mask]; \
temp |= (dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n + 1)) & dev->vram_mask] << 8); \
} \
@@ -2482,8 +2492,8 @@ ati8514_recalctimings(svga_t *svga)
dev->h_total = dev->htotal + 1;
dev->h_blankstart = dev->hblankstart;
dev->h_blank_end_val = dev->hblank_end_val;
dev->v_total = dev->vtotal + 1;
dev->v_syncstart = dev->vsyncstart + 1;
dev->v_total = dev->vtotal;
dev->v_syncstart = dev->vsyncstart;
dev->rowcount = !!(dev->disp_cntl & 0x08);
dev->dispend = dev->vdisp;
@@ -2604,8 +2614,8 @@ mach_recalctimings(svga_t *svga)
dev->h_total = dev->htotal + 1;
dev->h_blankstart = dev->hblankstart;
dev->h_blank_end_val = dev->hblank_end_val;
dev->v_total = dev->vtotal + 1;
dev->v_syncstart = dev->vsyncstart + 1;
dev->v_total = dev->vtotal;
dev->v_syncstart = dev->vsyncstart;
dev->dispend = dev->vdisp;
dev->rowcount = !!(dev->disp_cntl & 0x08);
@@ -2615,6 +2625,9 @@ mach_recalctimings(svga_t *svga)
if (dev->dispend == 598)
dev->dispend += 2;
if (dev->dispend == 478)
dev->dispend += 2;
if ((dev->local & 0xff) >= 0x02) {
if ((dev->accel.advfunc_cntl ^ dev->modechange) & 0x04) {
if ((mach->shadow_set ^ mach->compat_mode) & 0x03)
@@ -2710,8 +2723,11 @@ mach_recalctimings(svga_t *svga)
svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
if (((mach->shadow_set & 0x03) != 0x02) || !(dev->accel.advfunc_cntl & 0x04)) { /*Shadow set of 2 and bit 2 of port 0x4ae8 mean 1024x768+*/
dev->h_disp = 640;
dev->dispend = 480;
if (!(mach->accel.clock_sel & 0x01)) {
dev->h_disp = 640;
dev->dispend = 480;
}
dev->interlace = 0;
}
}
@@ -2726,26 +2742,12 @@ mach_recalctimings(svga_t *svga)
dev->pitch = dev->ext_pitch;
dev->rowoffset = dev->ext_crt_pitch;
mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, shadow=%x.\n", dev->accel.advfunc_cntl & 4, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0, mach->shadow_set & 3);
mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, shadow=%x interlace=%d.\n", dev->accel.advfunc_cntl & 4, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0, mach->shadow_set & 3, dev->interlace);
svga->map8 = dev->pallook;
svga->render8514 = ibm8514_render_8bpp;
if (mach->regs[0xb8] & 0x40)
svga->clock *= 2;
}
dev->hblankend = (dev->h_blankstart & ~0x3f) | dev->h_blank_end_val;
if (dev->hblankend <= dev->h_blankstart)
dev->hblankend += 0x40;
dev->hblankend += dev->hblank_ext;
dev->hblank_sub = 0;
if (dev->hblankend > dev->h_total) {
dev->hblankend &= 0x3f;
dev->hblank_sub = dev->hblankend + 1;
dev->h_disp -= dev->hblank_sub;
}
}
if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) {
@@ -3636,7 +3638,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8
case 0x6e8:
case 0x6e9:
if (!(port & 1)) {
if (((dev->disp_cntl & 0x60) == 0x20) || (mach->accel.clock_sel & 0x01)) {
if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) {
dev->hdisped = val;
dev->hdisp = (dev->hdisped + 1) << 3;
}
@@ -3647,8 +3649,10 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8
case 0xae8:
case 0xae9:
if (!(port & 1)) {
dev->hsync_start = val;
dev->hblankstart = (dev->hsync_start & 0x07) + 1;
if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) {
dev->hsync_start = val;
dev->hblankstart = (dev->hsync_start & 0x07) + 1;
}
}
mach_log("ATI 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1);
break;
@@ -3656,36 +3660,46 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8
case 0xee8:
case 0xee9:
if (!(port & 1)) {
dev->hsync_width = val;
dev->hblank_end_val = (dev->hblankstart + (dev->hsync_start & 0x1f) - 1) & 0x3f;
if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) {
dev->hsync_width = val;
dev->hblank_end_val = (dev->hblankstart + (dev->hsync_start & 0x1f) - 1) & 0x3f;
}
}
mach_log("ATI 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1);
break;
case 0x12e8:
case 0x12e9:
WRITE8(port, dev->vtotal, val);
dev->vtotal &= 0x1fff;
if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) {
WRITE8(port, dev->v_total_reg, val);
dev->v_total_reg &= 0x1fff;
dev->vtotal = dev->v_total_reg;
dev->vtotal++;
}
break;
case 0x16e8:
case 0x16e9:
if (((dev->disp_cntl & 0x60) == 0x20) || (mach->accel.clock_sel & 0x01)) {
if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) {
WRITE8(port, dev->v_disp, val);
dev->v_disp &= 0x1fff;
dev->vdisp = dev->v_disp;
dev->vdisp >>= 1;
dev->vdisp++;
}
dev->modechange = dev->accel.advfunc_cntl & 4;
mach->compat_mode = mach->shadow_set & 3;
dev->modechange = dev->accel.advfunc_cntl & 0x04;
mach->compat_mode = mach->shadow_set & 0x03;
mach_log("ATI 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp);
break;
case 0x1ae8:
case 0x1ae9:
WRITE8(port, dev->vsyncstart, val);
dev->vsyncstart &= 0x1fff;
if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) {
WRITE8(port, dev->v_sync_start, val);
dev->v_sync_start &= 0x1fff;
dev->vsyncstart = dev->v_sync_start;
dev->vsyncstart++;
}
break;
case 0x1ee8:
@@ -3694,7 +3708,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8
break;
case 0x22e8:
dev->disp_cntl = val & 0x7e;
dev->disp_cntl = val;
dev->interlace = !!(val & 0x10);
mach_log("ATI 8514/A: DISP_CNTL write 22E8 = %02x, interlace = %d\n", dev->disp_cntl, dev->interlace);
break;
@@ -4314,13 +4328,13 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in
case 0xcaee:
if (len == 1)
temp = dev->vsyncstart & 0xff;
temp = dev->v_sync_start & 0xff;
else
temp = dev->vsyncstart;
temp = dev->v_sync_start;
break;
case 0xcaef:
if (len == 1)
temp = dev->vsyncstart >> 8;
temp = dev->v_sync_start >> 8;
break;
case 0xceee:

View File

@@ -295,22 +295,22 @@ ega_in(uint16_t addr, void *priv)
break;
case 0x3c0:
if (ega_type)
if (ega_type == 1)
ret = ega->attraddr | ega->attr_palette_enable;
break;
case 0x3c1:
if (ega_type)
if (ega_type == 1)
ret = ega->attrregs[ega->attraddr];
break;
case 0x3c2:
ret = (egaswitches & (8 >> egaswitchread)) ? 0x10 : 0x00;
break;
case 0x3c4:
if (ega_type)
if (ega_type == 1)
ret = ega->seqaddr;
break;
case 0x3c5:
if (ega_type)
if (ega_type == 1)
ret = ega->seqregs[ega->seqaddr & 0xf];
break;
case 0x3c6:
@@ -318,24 +318,24 @@ ega_in(uint16_t addr, void *priv)
ret = ega->ctl_mode;
break;
case 0x3c8:
if (ega_type)
if (ega_type == 1)
ret = 2;
break;
case 0x3cc:
if (ega_type)
if (ega_type == 1)
ret = ega->miscout;
break;
case 0x3ce:
if (ega_type)
if (ega_type == 1)
ret = ega->gdcaddr;
break;
case 0x3cf:
if (ega_type)
if (ega_type == 1)
ret = ega->gdcreg[ega->gdcaddr & 0xf];
break;
case 0x3d0:
case 0x3d4:
if (ega_type)
if (ega_type == 1)
ret = ega->crtcreg;
break;
case 0x3d1:
@@ -349,14 +349,21 @@ ega_in(uint16_t addr, void *priv)
break;
case 0x10:
case 0x11:
/* TODO: Return light pen address once implemented. */
if (ega_type)
if (ega_type == 1)
ret = ega->crtc[ega->crtcreg];
else
ret = ega->light_pen >> 8;
break;
case 0x11:
if (ega_type == 1)
ret = ega->crtc[ega->crtcreg];
else
ret = ega->light_pen & 0xff;
break;
default:
if (ega_type)
if (ega_type == 1)
ret = ega->crtc[ega->crtcreg];
break;
}
@@ -557,7 +564,7 @@ ega_recalctimings(ega_t *ega)
overscan_x <<= 1;
ega->y_add = (overscan_y >> 1);
ega->x_add = (overscan_x >> 1);
ega->x_add = (overscan_x >> 1) - ega->scrollcache;
if (ega->vres)
ega->y_add >>= 1;
@@ -804,10 +811,6 @@ ega_poll(void *priv)
ega->cca = ega->ma;
ega->maback <<= 2;
ega->sc = 0;
if (ega->attrregs[0x10] & 0x20) {
ega->scrollcache = 0;
ega->x_add = (overscan_x >> 1);
}
}
if (ega->vc == ega->dispend) {
ega->dispon = 0;

View File

@@ -199,6 +199,7 @@ ega_render_graphics(ega_t *ega)
const bool attrblink = ((ega->attrregs[0x10] & 8) != 0);
const bool blinked = ega->blink & 0x10;
const bool crtcreset = ((ega->crtc[0x17] & 0x80) == 0);
const bool seq9dot = ((ega->seqregs[1] & 1) == 0);
const bool seqoddeven = ((ega->seqregs[1] & 4) != 0);
const uint8_t blinkmask = (attrblink && blinked ? 0x8 : 0x0);
uint32_t *p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
@@ -206,6 +207,15 @@ ega_render_graphics(ega_t *ega)
const int dotwidth = 1 << dwshift;
const int charwidth = dotwidth * 8;
int secondcclk = 0;
/* Compensate for 8dot scroll */
if (!seq9dot) {
for (int x = 0; x < dotwidth; x++) {
p[x] = ega->overscan_color;
}
p += dotwidth;
}
for (int x = 0; x <= (ega->hdisp + ega->scrollcache); x += charwidth) {
uint32_t addr = ega->remap_func(ega, ega->ma) & ega->vrammask;

View File

@@ -469,7 +469,7 @@ typedef struct mystique_t {
lfb_base, ctrl_base, iload_base,
ma_latch_old, maccess, mctlwtst, maccess_running,
softrap_pending_val;
atomic_uint status;
atomic_bool softrap_status_read;
@@ -502,7 +502,7 @@ typedef struct mystique_t {
int xoff, yoff, selline, ydst,
length_cur, iload_rem_count, idump_end_of_line, words,
ta_key, ta_mask, lastpix_r, lastpix_g,
lastpix_b, highv_line, beta, dither;
lastpix_b, highv_line, beta, dither, err, k1, k2;
int pattern[8][16];
@@ -764,13 +764,13 @@ mystique_out(uint16_t addr, uint8_t val, void *priv)
old = mystique->crtcext_regs[mystique->crtcext_idx];
if (mystique->crtcext_idx < 6)
mystique->crtcext_regs[mystique->crtcext_idx] = val;
if ((mystique->type >= MGA_1064SG) && (mystique->crtcext_idx == 0) &&
(mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE)) {
svga->rowoffset = svga->crtc[0x13] |
((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4);
if (!(mystique->type >= MGA_2164W))
if (!(mystique->type >= MGA_2164W))
svga->rowoffset <<= 1;
svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) |
@@ -2394,10 +2394,10 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv)
break;
case REG_SHIFT:
mystique->dwgreg.funcnt = val & 0xff;
mystique->dwgreg.funcnt = val & 0x7f;
mystique->dwgreg.xoff = val & 7;
mystique->dwgreg.yoff = (val >> 4) & 7;
mystique->dwgreg.stylelen = (val >> 16) & 0xff;
mystique->dwgreg.stylelen = (val >> 16) & 0x7f;
break;
case REG_PITCH:
@@ -2601,7 +2601,7 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv)
case REG_ALPHACTRL:
mystique->dwgreg.alphactrl = val;
break;
case REG_ALPHASTART:
mystique->dwgreg.alphastart = val;
break;
@@ -2617,7 +2617,7 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv)
case REG_FOGCOL:
mystique->dwgreg.fogcol = val;
break;
case REG_FOGSTART:
mystique->dwgreg.fogstart = val;
break;
@@ -2678,7 +2678,7 @@ mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *priv)
wake_fifo_thread(mystique);
}
/* HACK: For DirectX 9.0b Direct3D testing on Windows 98 SE.
The 4.12.013 drivers give an out-of-bounds busmastering range when dxdiag enumerates Direct3D, with exactly 16384 bytes of difference.
Don't attempt busmastering in such cases. This isn't ideal, but there are no more crashes faced in this case. */
if ((mystique->dma.primend & DMA_ADDR_MASK) < (mystique->dma.primaddress & DMA_ADDR_MASK) && ((mystique->dma.primaddress & DMA_ADDR_MASK) - (mystique->dma.primend & DMA_ADDR_MASK)) == 0x4000)
@@ -3229,7 +3229,7 @@ mystique_softrap_pending_timer(void *priv)
mystique_update_irqs(mystique);
mystique->softrap_pending--;
}
}
static void
@@ -4309,21 +4309,19 @@ z_check_32(uint32_t z, uint32_t old_z, uint32_t z_mode) // mystique->dwgreg.dwgc
}
static void
blit_line(mystique_t *mystique, int closed)
blit_line(mystique_t *mystique, int closed, int autoline)
{
svga_t *svga = &mystique->svga;
uint32_t src = 0;
uint32_t dst;
uint32_t old_dst;
int x;
int len = 0;
int x = mystique->dwgreg.xdst;
int z_write;
switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) {
case DWGCTRL_ATYPE_RSTR:
case DWGCTRL_ATYPE_RPL:
x = mystique->dwgreg.xdst;
while (len <= mystique->dwgreg.length) {
while (mystique->dwgreg.length >= 0) {
if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) {
switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) {
case MACCESS_PWIDTH_8:
@@ -4334,7 +4332,10 @@ blit_line(mystique_t *mystique, int closed)
if (closed) {
svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst;
svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount;
} else if (!closed && (len < mystique->dwgreg.length)) {
} else if (!closed && (mystique->dwgreg.length > 0) && ((mystique->dwgreg.err > 0) || (mystique->dwgreg.err < 0)) && !autoline) {
svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst;
svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount;
} else if (!closed && (mystique->dwgreg.length > 0) && autoline) {
svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst;
svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount;
}
@@ -4348,7 +4349,10 @@ blit_line(mystique_t *mystique, int closed)
if (closed) {
((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst;
svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount;
} else if (!closed && (len < mystique->dwgreg.length)) {
} else if (!closed && (mystique->dwgreg.length > 0) && ((mystique->dwgreg.err > 0) || (mystique->dwgreg.err < 0)) && !autoline) {
((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst;
svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount;
} else if (!closed && (mystique->dwgreg.length > 0) && autoline) {
((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst;
svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount;
}
@@ -4362,7 +4366,10 @@ blit_line(mystique_t *mystique, int closed)
if (closed) {
*(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000);
svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount;
} else if (!closed && (len < mystique->dwgreg.length)) {
} else if (!closed && (mystique->dwgreg.length > 0) && ((mystique->dwgreg.err > 0) || (mystique->dwgreg.err < 0)) && !autoline) {
*(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000);
svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount;
} else if (!closed && (mystique->dwgreg.length > 0) && autoline) {
*(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000);
svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount;
}
@@ -4376,7 +4383,10 @@ blit_line(mystique_t *mystique, int closed)
if (closed) {
((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst;
svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount;
} else if (!closed && (len < mystique->dwgreg.length)) {
} else if (!closed && (mystique->dwgreg.length > 0) && ((mystique->dwgreg.err > 0) || (mystique->dwgreg.err < 0)) && !autoline) {
((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst;
svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount;
} else if (!closed && (mystique->dwgreg.length > 0) && autoline) {
((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst;
svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount;
}
@@ -4387,28 +4397,34 @@ blit_line(mystique_t *mystique, int closed)
}
}
if (!mystique->dwgreg.length)
break;
if (mystique->dwgreg.sgn.sdydxl)
x += (mystique->dwgreg.sgn.sdxl ? -1 : 1);
else
else {
mystique->dwgreg.ydst += (mystique->dwgreg.sgn.sdy ? -1 : 1);
mystique->dwgreg.ydst &= 0x7fffff;
mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK));
if ((int32_t) mystique->dwgreg.ar[1] >= 0) {
mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2];
if (mystique->dwgreg.sgn.sdydxl)
}
if (mystique->dwgreg.err >= 0) {
mystique->dwgreg.err += mystique->dwgreg.k2;
if (mystique->dwgreg.sgn.sdydxl) {
mystique->dwgreg.ydst += (mystique->dwgreg.sgn.sdy ? -1 : 1);
mystique->dwgreg.ydst &= 0x7fffff;
mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK));
else
} else
x += (mystique->dwgreg.sgn.sdxl ? -1 : 1);
} else
mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0];
mystique->dwgreg.err += mystique->dwgreg.k1;
len++;
mystique->dwgreg.length--;
}
break;
case DWGCTRL_ATYPE_I:
case DWGCTRL_ATYPE_ZI:
z_write = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) == DWGCTRL_ATYPE_ZI);
x = mystique->dwgreg.xdst;
while (mystique->dwgreg.length > 0) {
if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) {
bool z_check_pass = false;
@@ -4471,8 +4487,8 @@ blit_line(mystique_t *mystique, int closed)
mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10];
mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14];
if ((int32_t) mystique->dwgreg.ar[1] >= 0) {
mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2];
if (mystique->dwgreg.err >= 0) {
mystique->dwgreg.err += mystique->dwgreg.k2;
if (mystique->dwgreg.sgn.sdydxl)
mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK));
@@ -4490,7 +4506,7 @@ blit_line(mystique_t *mystique, int closed)
mystique->dwgreg.dr[8] += mystique->dwgreg.dr[11];
mystique->dwgreg.dr[12] += mystique->dwgreg.dr[15];
} else
mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0];
mystique->dwgreg.err += mystique->dwgreg.k1;
mystique->dwgreg.length--;
}
@@ -4507,7 +4523,7 @@ blit_line(mystique_t *mystique, int closed)
}
static void
blit_autoline(mystique_t *mystique, int closed)
blit_line_start(mystique_t *mystique, int closed, int autoline)
{
int start_x = (int32_t) mystique->dwgreg.ar[5];
int start_y = (int32_t) mystique->dwgreg.ar[6];
@@ -4516,29 +4532,37 @@ blit_autoline(mystique_t *mystique, int closed)
int dx = end_x - start_x;
int dy = end_y - start_y;
if (ABS(dx) > ABS(dy)) {
mystique->dwgreg.sgn.sdydxl = 1;
mystique->dwgreg.ar[0] = 2 * ABS(dy);
mystique->dwgreg.ar[1] = 2 * ABS(dy) - ABS(dx) - ((start_y > end_y) ? 1 : 0);
mystique->dwgreg.ar[2] = 2 * ABS(dy) - 2 * ABS(dx);
mystique->dwgreg.length = ABS(end_x - start_x);
if (autoline) {
if (ABS(dx) > ABS(dy)) {
mystique->dwgreg.sgn.sdydxl = 1;
mystique->dwgreg.k1 = 2 * ABS(dy);
mystique->dwgreg.err = 2 * ABS(dy) - ABS(dx) - ((start_y > end_y) ? 1 : 0);
mystique->dwgreg.k2 = 2 * ABS(dy) - 2 * ABS(dx);
mystique->dwgreg.length = ABS(end_x - start_x);
} else {
mystique->dwgreg.sgn.sdydxl = 0;
mystique->dwgreg.k1 = 2 * ABS(dx);
mystique->dwgreg.err = 2 * ABS(dx) - ABS(dy) - ((start_y > end_y) ? 1 : 0);
mystique->dwgreg.k2 = 2 * ABS(dx) - 2 * ABS(dy);
mystique->dwgreg.length = ABS(end_y - start_y);
}
mystique->dwgreg.sgn.sdxl = (start_x > end_x) ? 1 : 0;
mystique->dwgreg.sgn.sdy = (start_y > end_y) ? 1 : 0;
} else {
mystique->dwgreg.sgn.sdydxl = 0;
mystique->dwgreg.ar[0] = 2 * ABS(dx);
mystique->dwgreg.ar[1] = 2 * ABS(dx) - ABS(dy) - ((start_y > end_y) ? 1 : 0);
mystique->dwgreg.ar[2] = 2 * ABS(dx) - 2 * ABS(dy);
mystique->dwgreg.length = ABS(end_y - start_y);
mystique->dwgreg.k1 = (int32_t) mystique->dwgreg.ar[0];
mystique->dwgreg.err = (int32_t) mystique->dwgreg.ar[1];
mystique->dwgreg.k2 = (int32_t) mystique->dwgreg.ar[2];
}
mystique->dwgreg.sgn.sdxl = (start_x > end_x) ? 1 : 0;
mystique->dwgreg.sgn.sdy = (start_y > end_y) ? 1 : 0;
blit_line(mystique, closed);
blit_line(mystique, closed, autoline);
mystique->dwgreg.ar[5] = end_x;
mystique->dwgreg.xdst = end_x;
mystique->dwgreg.ar[6] = end_y;
mystique->dwgreg.ydst = end_y;
mystique->dwgreg.ydst_lin = ((int32_t) (int16_t) mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg;
if (autoline) {
mystique->dwgreg.ar[5] = end_x;
mystique->dwgreg.xdst = end_x;
mystique->dwgreg.ar[6] = end_y;
mystique->dwgreg.ydst = end_y;
mystique->dwgreg.ydst_lin = ((int32_t) (int16_t) mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg;
}
}
static void
@@ -4552,6 +4576,8 @@ blit_trap(mystique_t *mystique)
uint32_t b_back;
int z_write;
int y;
int err_l = (int32_t)mystique->dwgreg.ar[1];
int err_r = (int32_t)mystique->dwgreg.ar[4];
const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT;
switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) {
@@ -4562,8 +4588,14 @@ blit_trap(mystique_t *mystique)
int16_t x_l = mystique->dwgreg.fxleft & 0xffff;
int16_t x_r = mystique->dwgreg.fxright & 0xffff;
int yoff = (mystique->dwgreg.yoff + mystique->dwgreg.ydst) & 7;
int len;
while (x_l != x_r) {
if (x_l > x_r)
len = x_l - x_r;
else
len = x_r - x_l;
while (len > 0) {
if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) {
int xoff = (mystique->dwgreg.xoff + (x_l & 7)) & 15;
int pattern = mystique->dwgreg.pattern[yoff][xoff];
@@ -4595,24 +4627,21 @@ blit_trap(mystique_t *mystique)
fatal("TRAP BLK/RPL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running);
}
}
if (x_l > x_r)
x_l--;
else
x_l++;
len--;
x_l++;
}
while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) {
mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0];
while ((err_l < 0) && mystique->dwgreg.ar[0]) {
err_l += mystique->dwgreg.ar[0];
mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1);
}
mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2];
err_l += mystique->dwgreg.ar[2];
while ((int32_t) mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) {
mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6];
while ((err_r < 0) && mystique->dwgreg.ar[6]) {
err_r += mystique->dwgreg.ar[6];
mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1);
}
mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5];
err_r += mystique->dwgreg.ar[5];
mystique->dwgreg.ydst++;
mystique->dwgreg.ydst &= 0x7fffff;
@@ -4628,8 +4657,14 @@ blit_trap(mystique_t *mystique)
int16_t x_l = mystique->dwgreg.fxleft & 0xffff;
int16_t x_r = mystique->dwgreg.fxright & 0xffff;
int yoff = (mystique->dwgreg.yoff + mystique->dwgreg.ydst) & 7;
int len;
while (x_l != x_r) {
if (x_l > x_r)
len = x_l - x_r;
else
len = x_r - x_l;
while (len > 0) {
if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) {
int xoff = (mystique->dwgreg.xoff + (x_l & 7)) & 15;
int pattern = mystique->dwgreg.pattern[yoff][xoff];
@@ -4674,23 +4709,21 @@ blit_trap(mystique_t *mystique)
fatal("TRAP RSTR PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running);
}
}
if (x_l > x_r)
x_l--;
else
x_l++;
x_l++;
len--;
}
while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) {
mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0];
while ((err_l < 0) && mystique->dwgreg.ar[0]) {
err_l += mystique->dwgreg.ar[0];
mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1);
}
mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2];
err_l += mystique->dwgreg.ar[2];
while ((int32_t) mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) {
mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6];
while ((err_r < 0) && mystique->dwgreg.ar[6]) {
err_r += mystique->dwgreg.ar[6];
mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1);
}
mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5];
err_r += mystique->dwgreg.ar[5];
mystique->dwgreg.ydst++;
mystique->dwgreg.ydst &= 0x7fffff;
@@ -5801,19 +5834,19 @@ mystique_start_blit(mystique_t *mystique)
switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) {
case DWGCTRL_OPCODE_LINE_OPEN:
blit_line(mystique, 0);
blit_line_start(mystique, 0, 0);
break;
case DWGCTRL_OPCODE_AUTOLINE_OPEN:
blit_autoline(mystique, 0);
blit_line_start(mystique, 0, 1);
break;
case DWGCTRL_OPCODE_LINE_CLOSE:
blit_line(mystique, 1);
blit_line_start(mystique, 1, 0);
break;
case DWGCTRL_OPCODE_AUTOLINE_CLOSE:
blit_autoline(mystique, 1);
blit_line_start(mystique, 1, 1);
break;
case DWGCTRL_OPCODE_TRAP:
@@ -6046,7 +6079,7 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv)
case 0x33:
ret = mystique->pci_regs[0x33];
break;
case 0x34:
ret = mystique->type == MGA_G100 ? 0xdc : 0x00;
break;
@@ -6089,7 +6122,7 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv)
case 0xdc:
ret = 0x01;
break;
case 0xdd:
ret = 0xf0;
break;
@@ -6097,7 +6130,7 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv)
case 0xde:
ret = 0x21;
break;
/* No support for turning off the video adapter yet. */
case 0xe0:
ret = 0x0;
@@ -6106,19 +6139,19 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv)
case 0xf0:
ret = 0x02;
break;
case 0xf1:
ret = 0x00;
break;
case 0xf2:
ret = 0x10;
break;
case 0xf4:
ret = 0x1;
break;
case 0xf5:
ret = 0x2;
break;
@@ -6126,15 +6159,15 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv)
case 0xf7:
ret = 0x1;
break;
case 0xf8:
ret = mystique->pci_regs[0xf8] & 0x7;
break;
case 0xf9:
ret = mystique->pci_regs[0xf9] & 0x3;
break;
case 0xfb:
ret = mystique->pci_regs[0xfb];
break;
@@ -6277,11 +6310,11 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
case 0xf8:
mystique->pci_regs[0xf8] = val & 0x7;
break;
case 0xf9:
mystique->pci_regs[0xf9] = val & 0x3;
break;
case 0xfb:
mystique->pci_regs[0xfb] = val;
break;
@@ -6455,7 +6488,7 @@ mystique_init(const device_t *info)
timer_add(&mystique->softrap_pending_timer, mystique_softrap_pending_timer, (void *) mystique, 1);
mystique->status = STATUS_ENDPRDMASTS;
mystique->softrap_status_read = 1;
mystique->svga.vsync_callback = mystique_vsync_callback;

View File

@@ -3921,6 +3921,7 @@ s3_recalctimings(svga_t *svga)
case S3_VISION968:
switch (s3->card_type) {
case S3_MIROVIDEO40SV_ERGO_968:
case S3_SPEA_MERCURY_P64V:
switch (s3->width) {
case 1280:
svga->hdisp = ((svga->hdisp << 1) / 3) << 1;

View File

@@ -178,8 +178,8 @@ xga_updatemapping(svga_t *svga)
}
}
xga_log("XGA opmode (extended) = %d, disp mode = %d, aperture = %d.\n", xga->op_mode & 7,
xga->disp_cntl_2 & 7, xga->aperture_cntl);
xga_log("XGA opmode (extended) = %d, disp mode = %d, aperture = %d, on = %d, linear endian reverse = %d.\n", xga->op_mode & 7,
xga->disp_cntl_2 & 7, xga->aperture_cntl, xga->on, xga->linear_endian_reverse);
}
xga_log("VGA on = %d, map = %02x.\n", vga_on, svga->gdcreg[6] & 0x0c);
}
@@ -198,7 +198,7 @@ xga_recalctimings(svga_t *svga)
xga->h_disp = (xga->hdisp + 1) << 3;
xga->rowoffset = (xga->hdisp + 1);
xga->rowoffset = xga->hdisp + 1;
xga->interlace = !!(xga->disp_cntl_1 & 0x08);
xga->rowcount = (xga->disp_cntl_2 & 0xc0) >> 6;
@@ -213,6 +213,11 @@ xga_recalctimings(svga_t *svga)
xga->ma_latch = xga->disp_start_addr;
if ((xga->disp_cntl_2 & 7) == 2)
xga->rowoffset >>= 1;
else if ((xga->disp_cntl_2 & 7) == 4)
xga->rowoffset <<= 1;
xga_log("XGA ClkSel1 = %d, ClkSel2 = %02x.\n", (xga->clk_sel_1 >> 2) & 3, xga->clk_sel_2 & 0x80);
switch ((xga->clk_sel_1 >> 2) & 3) {
case 0:
@@ -410,7 +415,7 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val)
xga->cursor_data_on = 1;
else if ((xga->sprite_pos >= 1) || (((xga->disp_cntl_2 & 7) == 2) || (xga->disp_cntl_2 & 7) == 4))
xga->cursor_data_on = 1;
else if (xga->aperture_cntl == 0) {
else if (!xga->aperture_cntl) {
if (xga->linear_endian_reverse && !(xga->access_mode & 8))
xga->cursor_data_on = 0;
}
@@ -422,10 +427,11 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val)
xga->cursor_data_on = 1;
else
xga->cursor_data_on = 0;
} else {
} else
xga->cursor_data_on = 0;
}
}
} else if (!xga->sprite_pos && xga->cursor_data_on && !xga->aperture_cntl && xga->linear_endian_reverse)
xga->cursor_data_on = 0;
xga_log("Sprite POS = %d, data on = %d, idx = %d, apcntl = %d\n", xga->sprite_pos,
xga->cursor_data_on, xga->sprite_pal_addr_idx, xga->aperture_cntl);
@@ -998,9 +1004,9 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int
addr += x;
if (!skip) {
READ(addr, byte);
} else {
} else
byte = mem_readb_phys(addr);
}
return byte;
case 4: /*16-bit*/
addr += (y * (width << 1));
@@ -1082,6 +1088,7 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui
} else {
byte = mem_readb_phys(addr);
}
if (xga->linear_endian_reverse)
mask = 0x0f << ((1 - (x & 1)) << 2);
else {
@@ -1259,31 +1266,17 @@ xga_line_draw_write(svga_t *svga)
uint32_t plane_mask = xga->accel.plane_mask;
uint32_t dstbase = xga->accel.px_map_base[xga->accel.dst_map];
uint32_t srcbase = xga->accel.px_map_base[xga->accel.src_map];
int dminor;
int destxtmp;
int dmajor;
int err;
int y = xga->accel.blt_width;
int x = 0;
int16_t dx;
int16_t dy;
int draw_pixel;
int16_t cx;
int16_t cy;
int err = xga->accel.bres_err_term;
int draw_pixel = 0;
dminor = xga->accel.bres_k1;
if (xga->accel.bres_k1 & 0x2000)
dminor |= ~0x1fff;
dminor >>= 1;
destxtmp = xga->accel.bres_k2;
if (xga->accel.bres_k2 & 0x2000)
destxtmp |= ~0x1fff;
dmajor = -(destxtmp - (dminor << 1)) >> 1;
err = xga->accel.bres_err_term;
if (xga->accel.bres_err_term & 0x2000)
err |= ~0x1fff;
cx = xga->accel.src_map_x & 0xfff;
cy = xga->accel.src_map_y & 0xfff;
dx = xga->accel.dst_map_x & 0x1fff;
if (xga->accel.dst_map_x >= 0x1800)
@@ -1300,75 +1293,46 @@ xga_line_draw_write(svga_t *svga)
if (xga->accel.pat_src == 8) {
if ((xga->accel.command & 0x30) == 0x30) {
while (y >= 0) {
draw_pixel = 1;
draw_pixel = 0;
if (xga->accel.octant & 0x01) {
if (xga->accel.octant & 0x02) { /*Bottom-to-Top*/
if (x)
draw_pixel = 1;
} else { /*Top-to-Bottom*/
if (y)
draw_pixel = 1;
}
} else if (!(xga->accel.octant & 0x04) && (err < (xga->accel.bres_k2 + xga->accel.bres_k1))) /*X+*/
draw_pixel = 1;
else if ((xga->accel.octant & 0x04) && (err >= 0)) /*X-*/
draw_pixel = 1;
if (xga->accel.command & 0xc0) {
if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color;
if (draw_pixel) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, cx, cy, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
ROP(1, dest_dat, src_dat);
xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1);
}
}
}
} else {
if (draw_pixel) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, cx, cy, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
ROP(1, dest_dat, src_dat);
dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask);
if (xga->accel.octant & 0x01) { /*Y Major*/
if (xga->accel.octant & 0x02) { /*Bottom-to-Top*/
if (!x)
draw_pixel = 0;
} else { /*Top-to-Bottom*/
if (!y)
draw_pixel = 0;
}
} else {
if (err >= 0) {
if (xga->accel.octant & 0x02) { /*Bottom-to-Top*/
if (!x)
draw_pixel = 0;
} else { /*Top-to-Bottom*/
if (!y)
draw_pixel = 0;
}
} else
draw_pixel = 0;
}
if (draw_pixel)
xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1);
}
}
} else {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
ROP(1, dest_dat, src_dat);
dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask);
if (xga->accel.octant & 0x01) { /*Y Major*/
if (xga->accel.octant & 0x02) { /*Bottom-to-Top*/
if (!x)
draw_pixel = 0;
} else { /*Top-to-Bottom*/
if (!y)
draw_pixel = 0;
}
} else {
if (err >= 0) {
if (xga->accel.octant & 0x02) { /*Bottom-to-Top*/
if (!x)
draw_pixel = 0;
} else { /*Top-to-Bottom*/
if (!y)
draw_pixel = 0;
}
} else
draw_pixel = 0;
}
if (draw_pixel)
xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1);
}
}
}
if (!y)
if (x == xga->accel.blt_width)
break;
if (xga->accel.octant & 0x01) {
@@ -1377,34 +1341,31 @@ xga_line_draw_write(svga_t *svga)
else
dy++;
while (err >= 0) {
err -= (dmajor << 1);
if (err >= 0) {
err += xga->accel.bres_k2;
if (xga->accel.octant & 0x04)
dx--;
else
dx++;
}
err += (dminor << 1);
} else
err += xga->accel.bres_k1;
} else {
if (xga->accel.octant & 0x04)
dx--;
else
dx++;
while (err >= 0) {
err -= (dmajor << 1);
if (err >= 0) {
err += xga->accel.bres_k2;
if (xga->accel.octant & 0x02)
dy--;
else
dy++;
}
err += (dminor << 1);
} else
err += xga->accel.bres_k1;
}
y--;
x++;
y--;
}
} else {
while (y >= 0) {
@@ -1451,47 +1412,40 @@ xga_line_draw_write(svga_t *svga)
else
dy++;
while (err >= 0) {
err -= (dmajor << 1);
if (err >= 0) {
err += xga->accel.bres_k2;
if (xga->accel.octant & 0x04)
dx--;
else
dx++;
}
err += (dminor << 1);
} else
err += xga->accel.bres_k1;
} else {
if (xga->accel.octant & 0x04)
dx--;
else
dx++;
while (err >= 0) {
err -= (dmajor << 1);
if (err >= 0) {
err += xga->accel.bres_k2;
if (xga->accel.octant & 0x02)
dy--;
else
dy++;
}
err += (dminor << 1);
} else
err += xga->accel.bres_k1;
}
y--;
x++;
}
}
}
xga->accel.dst_map_x = dx;
xga->accel.dst_map_y = dy;
}
static void
xga_bitblt(svga_t *svga)
{
xga_t *xga = (xga_t *) svga->xga;
uint8_t area_state = 0;
uint32_t src_dat;
uint32_t dest_dat;
uint32_t old_dest_dat;
@@ -1530,6 +1484,7 @@ xga_bitblt(svga_t *svga)
xga_log("D(%d,%d), SWH(%d,%d), BLT(%d,%d), dstwidth=%d.\n", dx, dy, xga->accel.x, xga->accel.y, srcwidth, srcheight, dstwidth);
xga->accel.pattern = 0;
xga->accel.filling = 0;
xga_log("XGA bitblt linear endian reverse=%d, access_mode=%x, octanty=%d, src command = %08x, "
"pxsrcmap=%x, pxpatmap=%x, pxdstmap=%x, srcmap=%d, patmap=%d, dstmap=%d, "
@@ -1660,70 +1615,66 @@ xga_bitblt(svga_t *svga)
xga->accel.px_map_width[0], xga->accel.px_map_width[1],
xga->accel.px_map_width[2], xga->accel.px_map_width[3], bkgdcol);
if (((xga->accel.command >> 24) & 0x0f) == 0x0a) {
if ((((xga->accel.command >> 24) & 0x0f) == 0x0a) && ((xga->accel.bkgd_mix & 0x1f) == 5)) {
while (xga->accel.y >= 0) {
mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, xga->accel.pat_src, patbase, patwidth + 1);
if (mix)
area_state = !area_state;
xga->accel.filling = !xga->accel.filling;
if (xga->accel.command & 0xc0) {
if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) {
if (area_state)
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol;
else
src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(area_state, dest_dat, src_dat);
dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask);
xga_log("1SRCDat=%02x, DSTDat=%02x, Old=%02x, MIX=%d.\n", src_dat, dest_dat, old_dest_dat, area_state);
xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1);
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol;
if (xga->accel.filling) {
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, 1024, 0);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(1, dest_dat, src_dat);
dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask);
xga_log("1SRCDat=%02x, DSTDat=%02x, Old=%02x, MIX=%d.\n", src_dat, dest_dat, old_dest_dat, area_state);
xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1);
}
}
}
} else {
if ((dx >= 0) && (dx <= dstwidth) && (dy >= 0) && (dy <= dstheight)) {
if (area_state)
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol;
else
src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(area_state, dest_dat, src_dat);
dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask);
xga_log("2Fill: NumXY(%d,%d): DXY(%d,%d): SRCDat=%02x, DSTDat=%02x, Old=%02x, frgdcol=%02x, bkgdcol=%02x, MIX=%d, frgdmix=%02x, bkgdmix=%02x, dstmapfmt=%02x, srcmapfmt=%02x, srcmapnum=%d.\n", x, y, dx, dy, src_dat, dest_dat, old_dest_dat, frgdcol, bkgdcol, area_state, xga->accel.frgd_mix & 0x1f, xga->accel.bkgd_mix & 0x1f, xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, xga->accel.px_map_format[xga->accel.src_map] & 0x0f, xga->accel.src_map);
xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1);
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol;
if (xga->accel.filling) {
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(1, dest_dat, src_dat);
dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask);
xga_log("2Fill: NumXY(%d,%d): DXY(%d,%d): SRCDat=%02x, DSTDat=%02x, Old=%02x, frgdcol=%02x, bkgdcol=%02x, MIX=%d, frgdmix=%02x, bkgdmix=%02x, dstmapfmt=%02x, srcmapfmt=%02x, srcmapnum=%d.\n", x, y, dx, dy, src_dat, dest_dat, old_dest_dat, frgdcol, bkgdcol, area_state, xga->accel.frgd_mix & 0x1f, xga->accel.bkgd_mix & 0x1f, xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, xga->accel.px_map_format[xga->accel.src_map] & 0x0f, xga->accel.src_map);
xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1);
}
}
}
}
xga->accel.sx = ((xga->accel.sx + 1) & srcwidth) | (xga->accel.sx & ~srcwidth);
xga->accel.px = ((xga->accel.px + 1) & patwidth) | (xga->accel.px & ~patwidth);
xga->accel.sx = ((xga->accel.sx + xdir) & srcwidth) | (xga->accel.sx & ~srcwidth);
xga->accel.px++;
dx++;
xga->accel.x--;
if (xga->accel.x < 0) {
area_state = 0;
xga->accel.y--;
xga->accel.x = xga->accel.blt_width & 0xfff;
dx = xga->accel.dst_map_x & 0x1fff;
if (xga->accel.dst_map_x >= 0x1800)
dx |= ~0x17ff;
xga->accel.sx = xga->accel.src_map_x & 0xfff;
xga->accel.px = xga->accel.pat_map_x & 0xfff;
xga->accel.sy = ((xga->accel.sy + ydir) & srcheight) | (xga->accel.sy & ~srcheight);
xga->accel.py += ydir;
dy += ydir;
xga->accel.py++;
if (xga->accel.y < 0) {
xga->accel.dst_map_x = dx;
xga->accel.dst_map_y = dy;
dy++;
xga->accel.filling = 0;
if (xga->accel.y < 0)
return;
}
}
}
} else {
@@ -1777,6 +1728,7 @@ xga_bitblt(svga_t *svga)
dx = xga->accel.dst_map_x & 0x1fff;
if (xga->accel.dst_map_x >= 0x1800)
dx |= ~0x17ff;
xga->accel.sx = xga->accel.src_map_x & 0xfff;
xga->accel.px = xga->accel.pat_map_x & 0xfff;
@@ -1870,7 +1822,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len)
if (len >= 2) {
xga->accel.bres_err_term = val & 0x3fff;
if (val & 0x2000)
xga->accel.bres_err_term |= ~0x3fff;
xga->accel.bres_err_term |= ~0x1fff;
} else
xga->accel.bres_err_term = (xga->accel.bres_err_term & 0x3f00) | val;
break;
@@ -1878,7 +1830,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len)
if (len == 1) {
xga->accel.bres_err_term = (xga->accel.bres_err_term & 0xff) | ((val & 0x3f) << 8);
if (val & 0x20)
xga->accel.bres_err_term |= ~0x3fff;
xga->accel.bres_err_term |= ~0x1fff;
}
break;
@@ -1886,7 +1838,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len)
if (len >= 2) {
xga->accel.bres_k1 = val & 0x3fff;
if (val & 0x2000)
xga->accel.bres_k1 |= ~0x3fff;
xga->accel.bres_k1 |= ~0x1fff;
} else
xga->accel.bres_k1 = (xga->accel.bres_k1 & 0x3f00) | val;
break;
@@ -1894,7 +1846,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len)
if (len == 1) {
xga->accel.bres_k1 = (xga->accel.bres_k1 & 0xff) | ((val & 0x3f) << 8);
if (val & 0x20)
xga->accel.bres_k1 |= ~0x3fff;
xga->accel.bres_k1 |= ~0x1fff;
}
break;
@@ -1902,7 +1854,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len)
if (len >= 2) {
xga->accel.bres_k2 = val & 0x3fff;
if (val & 0x2000)
xga->accel.bres_k2 |= ~0x3fff;
xga->accel.bres_k2 |= ~0x1fff;
} else
xga->accel.bres_k2 = (xga->accel.bres_k2 & 0x3f00) | val;
break;
@@ -1910,7 +1862,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len)
if (len == 1) {
xga->accel.bres_k2 = (xga->accel.bres_k2 & 0xff) | ((val & 0x3f) << 8);
if (val & 0x20)
xga->accel.bres_k2 |= ~0x3fff;
xga->accel.bres_k2 |= ~0x1fff;
}
break;
@@ -2015,6 +1967,30 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len)
xga->accel.plane_mask = (xga->accel.plane_mask & 0x00ffffff) | (val << 24);
break;
case 0x54:
if (len == 4)
xga->accel.carry_chain = val;
else if (len == 2)
xga->accel.carry_chain = (xga->accel.carry_chain & 0xffff0000) | val;
else
xga->accel.carry_chain = (xga->accel.carry_chain & 0xffffff00) | val;
break;
case 0x55:
if (len == 1)
xga->accel.carry_chain = (xga->accel.carry_chain & 0xffff00ff) | (val << 8);
break;
case 0x56:
if (len == 2)
xga->accel.carry_chain = (xga->accel.carry_chain & 0x0000ffff) | (val << 16);
else
xga->accel.carry_chain = (xga->accel.carry_chain & 0xff00ffff) | (val << 16);
break;
case 0x57:
if (len == 1)
xga->accel.carry_chain = (xga->accel.carry_chain & 0x00ffffff) | (val << 24);
break;
case 0x58:
if (len == 4)
xga->accel.frgd_color = val;
@@ -2454,7 +2430,7 @@ xga_hwcursor_draw(svga_t *svga, int displine)
int y_pos;
int comb = 0;
uint32_t *p;
int idx = (xga->cursor_data_on) ? 32 : 0;
int idx = xga->cursor_data_on ? 32 : 0;
if (xga->interlace && xga->hwcursor_oddeven)
xga->hwcursor_latch.addr += 16;
@@ -2549,20 +2525,24 @@ xga_render_4bpp(svga_t *svga)
for (int x = 0; x <= xga->h_disp; x += 16) {
dat = *(uint32_t *) (&xga->vram[xga->ma & xga->vram_mask]);
p[0] = xga->pallook[(dat >> 4) & 0x0f];
p[1] = xga->pallook[dat & 0x0f];
p[2] = xga->pallook[(dat >> 12) & 0x0f];
p[3] = xga->pallook[(dat >> 8) & 0x0f];
p[4] = xga->pallook[(dat >> 20) & 0x0f];
p[5] = xga->pallook[(dat >> 16) & 0x0f];
p[6] = xga->pallook[(dat >> 28) & 0x0f];
p[7] = xga->pallook[(dat >> 24) & 0x0f];
p[0] = xga->pallook[dat & 0x0f];
p[1] = xga->pallook[(dat >> 4) & 0x0f];
p[2] = xga->pallook[(dat >> 8) & 0x0f];
p[3] = xga->pallook[(dat >> 12) & 0x0f];
p[4] = xga->pallook[(dat >> 16) & 0x0f];
p[5] = xga->pallook[(dat >> 20) & 0x0f];
p[6] = xga->pallook[(dat >> 24) & 0x0f];
p[7] = xga->pallook[(dat >> 28) & 0x0f];
dat = *(uint32_t *) (&xga->vram[(xga->ma + 4) & xga->vram_mask]);
p[9] = xga->pallook[dat & 0x0f];
p[11] = xga->pallook[(dat >> 8) & 0x0f];
p[13] = xga->pallook[(dat >> 16) & 0x0f];
p[15] = xga->pallook[(dat >> 24) & 0x0f];
p[8] = xga->pallook[dat & 0x0f];
p[9] = xga->pallook[(dat >> 4) & 0x0f];
p[10] = xga->pallook[(dat >> 8) & 0x0f];
p[11] = xga->pallook[(dat >> 12) & 0x0f];
p[12] = xga->pallook[(dat >> 16) & 0x0f];
p[13] = xga->pallook[(dat >> 20) & 0x0f];
p[14] = xga->pallook[(dat >> 24) & 0x0f];
p[15] = xga->pallook[(dat >> 28) & 0x0f];
xga->ma += 8;
p += 16;
@@ -2626,7 +2606,7 @@ xga_render_16bpp(svga_t *svga)
xga->firstline_draw = xga->displine;
xga->lastline_draw = xga->displine;
for (x = 0; x <= (xga->h_disp); x += 8) {
for (x = 0; x <= xga->h_disp; x += 8) {
dat = *(uint32_t *) (&xga->vram[(xga->ma + (x << 1)) & xga->vram_mask]);
p[x] = video_16to32[dat & 0xffff];
p[x + 1] = video_16to32[dat >> 16];
@@ -2969,9 +2949,8 @@ xga_poll(void *priv, svga_t *svga)
video_wait_for_buffer_monitor(svga->monitor_index);
}
if (xga->hwcursor_on) {
if (xga->hwcursor_on)
xga->changedvram[xga->ma >> 12] = xga->changedvram[(xga->ma >> 12) + 1] = xga->interlace ? 3 : 2;
}
xga_do_render(svga);
@@ -2993,9 +2972,10 @@ xga_poll(void *priv, svga_t *svga)
if (xga->sc == xga->rowcount) {
xga->sc = 0;
xga->maback += (xga->rowoffset << (xga->disp_cntl_2 & 7));
xga->maback += (xga->rowoffset << 3);
if (xga->interlace)
xga->maback += (xga->rowoffset << (xga->disp_cntl_2 & 7));
xga->maback += (xga->rowoffset << 3);
xga->maback &= xga->vram_mask;
xga->ma = xga->maback;
} else {
@@ -3013,6 +2993,7 @@ xga_poll(void *priv, svga_t *svga)
xga->ma = xga->maback = (xga->rowoffset << 1);
else
xga->ma = xga->maback = 0;
xga->ma = (xga->ma << 2);
xga->maback = (xga->maback << 2);
@@ -3152,6 +3133,8 @@ xga_mca_reset(void *priv)
xga->on = 0;
vga_on = 1;
xga_mca_write(0x102, 0, svga);
xga->linear_endian_reverse = 0;
xga->a5_test = 0;
}
static void