Merge branch 'master' into master

This commit is contained in:
David Hrdlička
2020-11-20 01:21:54 +01:00
committed by GitHub
72 changed files with 15905 additions and 8596 deletions

View File

@@ -35,6 +35,7 @@
#include <86box/pit.h>
#include <86box/apm.h>
#include <86box/acpi.h>
#include <86box/machine.h>
#ifdef ENABLE_ACPI_LOG
@@ -81,35 +82,24 @@ acpi_update_irq(void *priv)
}
static void
acpi_raise_smi_common(void *priv)
{
acpi_t *dev = (acpi_t *) priv;
if ((dev->vendor == VEN_VIA) || (dev->vendor == VEN_VIA_596B)) {
if ((!dev->regs.smi_lock || !dev->regs.smi_active)) {
smi_line = 1;
dev->regs.smi_active = 1;
}
} else if (dev->vendor == VEN_INTEL) {
smi_line = 1;
/* Clear bit 16 of GLBCTL. */
dev->regs.glbctl &= ~0x00010000;
} else if (dev->vendor == VEN_SMC)
smi_line = 1;
}
static void
acpi_raise_smi(void *priv)
{
acpi_t *dev = (acpi_t *) priv;
if ((dev->vendor == VEN_INTEL) && !(dev->regs.glbctl & 0x00010000))
return;
if (dev->regs.glbctl & 0x01)
acpi_raise_smi_common(dev);
if (dev->regs.glbctl & 0x01) {
if ((dev->vendor == VEN_VIA) || (dev->vendor == VEN_VIA_596B)) {
if ((!dev->regs.smi_lock || !dev->regs.smi_active)) {
smi_line = 1;
dev->regs.smi_active = 1;
}
} else if (dev->vendor == VEN_INTEL) {
smi_line = 1;
/* Clear bit 16 of GLBCTL. */
dev->regs.glbctl &= ~0x00010000;
} else if (dev->vendor == VEN_SMC)
smi_line = 1;
}
}
@@ -1119,7 +1109,7 @@ acpi_apm_out(uint16_t port, uint8_t val, void *p)
if (dev->apm->do_smi) {
if (dev->vendor == VEN_INTEL)
dev->regs.glbsts |= 0x20;
acpi_raise_smi_common(dev);
acpi_raise_smi(dev);
}
} else
dev->apm->stat = val;
@@ -1167,8 +1157,14 @@ acpi_reset(void *priv)
- Bit 11: ATX power (active high)
- Bit 4: 80-conductor cable on primary IDE channel (active low)
- Bit 3: 80-conductor cable on secondary IDE channel (active low)
- Bit 2: password cleared (active low) */
dev->regs.gpi_val = 0xffffffe7;
- Bit 2: password cleared (active low)
AEWIN WCF-681:
- Bit 3: 80-conductor cable on primary IDE channel (active low)
- Bit 2: 80-conductor cable on secondary IDE channel (active low)
Acorp 6VIA85X:
- Bit 3: 80-conductor cable on secondary IDE channel (active low)
- Bit 1: 80-conductor cable on primary IDE channel (active low) */
dev->regs.gpi_val = !strcmp(machines[machine].internal_name, "wcf681") ? 0xffffffe3 : 0xffffffe5;
}
}

View File

@@ -143,7 +143,7 @@ i4x0_smram_handler_phase1(i4x0_t *dev)
size[0] = 0x00020000;
}
if (((regs[0x72] & 0x78) == 0x48) || ((regs[0x72] & 0x28) == 0x08))
if (regs[0x72] & 0x08)
smram_enable(dev->smram_low, base[0], base[0] & 0x000f0000, size[0],
((regs[0x72] & 0x78) == 0x48), (regs[0x72] & 0x08));

View File

@@ -260,7 +260,7 @@ sis_85c4xx_init(const device_t *info)
mem_size_mb = mem_size >> 10;
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed < 25000000)
if (cpu_s->rspeed < 25000000)
dev->regs[0x08] = 0x80;
if (dev->is_471) {

View File

@@ -363,20 +363,16 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv)
apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */
apollo_smram_map(dev, 0, 0x000a0000, 0x00020000, 3); /* Non-SMM: Code Invalid, Data Invalid */
break;
} else if(dev->id >= VIA_597) switch (val & 0x03) {
} else if (dev->id >= VIA_597) switch (val & 0x03) {
case 0x00:
default:
/* Disable SMI Address Redirection (default) */
apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 0);
if (dev->id == VIA_597)
apollo_smram_map(dev, 1, 0x00030000, 0x00020000, 1);
apollo_smram_map(dev, 0, 0x000a0000, 0x00020000, 0);
break;
case 0x01:
/* Allow access to DRAM Axxxx-Bxxxx for both normal and SMI cycles */
apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1);
if (dev->id == VIA_597)
apollo_smram_map(dev, 1, 0x00030000, 0x00020000, 1);
apollo_smram_map(dev, 0, 0x000a0000, 0x00020000, 1);
break;
case 0x02:
@@ -391,8 +387,6 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv)
case 0x03:
/* Allow SMI Axxxx-Bxxxx DRAM access */
apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1);
if (dev->id == VIA_597)
apollo_smram_map(dev, 1, 0x00030000, 0x00020000, 1);
apollo_smram_map(dev, 0, 0x000a0000, 0x00020000, 0);
break;
} else switch(val & 0x03) {
@@ -711,7 +705,7 @@ const device_t via_vpx_device =
{
"VIA Apollo VPX",
DEVICE_PCI,
VIA_597, /*VT82C585*/
VIA_585, /*VT82C585*/
via_apollo_init,
via_apollo_close,
via_apollo_reset,
@@ -725,7 +719,7 @@ const device_t amd640_device =
{
"AMD 640 System Controller",
DEVICE_PCI,
VIA_597, /*VT82C595*/
VIA_595, /*VT82C595*/
via_apollo_init,
via_apollo_close,
via_apollo_reset,

View File

@@ -509,11 +509,20 @@ load_machine(void)
{
char *cat = "Machine";
char *p;
int c, i, speed, legacy_mfg, legacy_cpu;
double multi;
p = config_get_string(cat, "machine", NULL);
if (p != NULL)
machine = machine_get_machine_from_internal_name(p);
else
if (p != NULL) {
if (! strcmp(p, "8500ttc")) /* fix typo */
machine = machine_get_machine_from_internal_name("8600ttc");
else if (! strcmp(p, "president")) /* migrate removed machine */
machine = machine_get_machine_from_internal_name("mb500n");
else if (! strcmp(p, "j656vxd")) /* migrate removed machine */
machine = machine_get_machine_from_internal_name("p55va");
else
machine = machine_get_machine_from_internal_name(p);
} else
machine = 0;
if (machine >= machine_count())
machine = machine_count() - 1;
@@ -521,36 +530,106 @@ load_machine(void)
/* This is for backwards compatibility. */
p = config_get_string(cat, "model", NULL);
if (p != NULL) {
/* Detect the old model typos and fix them. */
if (! strcmp(p, "p55r2p4")) {
if (! strcmp(p, "p55r2p4")) /* fix typo */
machine = machine_get_machine_from_internal_name("p55t2p4");
} else if (! strcmp(p, "8500ttc")) {
machine = machine_get_machine_from_internal_name("8600ttc");
} else {
else
machine = machine_get_machine_from_internal_name(p);
}
config_delete_var(cat, "model");
}
if (machine >= machine_count())
machine = machine_count() - 1;
cpu_manufacturer = config_get_int(cat, "cpu_manufacturer", 0);
if ((cpu_manufacturer >= (sizeof(machines[machine].cpu) / sizeof(machines[machine].cpu[0]))) ||
(machines[machine].cpu[cpu_manufacturer].cpus == NULL))
cpu_manufacturer = 0;
cpu_f = NULL;
p = config_get_string(cat, "cpu_family", NULL);
if (p) {
cpu_f = cpu_get_family(p);
cpu = config_get_int(cat, "cpu", 0);
for (int i = 0; i != cpu; i++) {
if (machines[machine].cpu[cpu_manufacturer].cpus[i].cpu_type == -1) {
cpu = 0;
break;
if (cpu_f && !cpu_family_is_eligible(cpu_f, machine)) /* only honor eligible families */
cpu_f = NULL;
} else {
/* Backwards compatibility with the previous CPU model system. */
legacy_mfg = config_get_int(cat, "cpu_manufacturer", 0);
legacy_cpu = config_get_int(cat, "cpu", 0);
/* Check if either legacy ID is present, and if they are within bounds. */
if (((legacy_mfg > 0) || (legacy_cpu > 0)) && (legacy_mfg >= 0) && (legacy_mfg < 4) && (legacy_cpu >= 0)) {
/* Look for a machine entry on the legacy table. */
p = machine_get_internal_name();
c = 0;
while (cpu_legacy_table[c].machine) {
if (!strcmp(p, cpu_legacy_table[c].machine))
break;
c++;
}
if (cpu_legacy_table[c].machine) {
/* Determine the amount of CPU entries on the table. */
i = -1;
while (cpu_legacy_table[c].tables[legacy_mfg][++i].family);
/* If the CPU ID is out of bounds, reset to the last known ID. */
if (legacy_cpu >= i)
legacy_cpu = i - 1;
const cpu_legacy_table_t *legacy_table_entry = &cpu_legacy_table[c].tables[legacy_mfg][legacy_cpu];
/* Check if the referenced family exists. */
cpu_f = cpu_get_family(legacy_table_entry->family);
if (cpu_f) {
/* Save the new values. */
config_set_string(cat, "cpu_family", (char *) legacy_table_entry->family);
config_set_int(cat, "cpu_speed", legacy_table_entry->rspeed);
config_set_double(cat, "cpu_multi", legacy_table_entry->multi);
}
}
}
}
if (cpu_f) {
speed = config_get_int(cat, "cpu_speed", 0);
multi = config_get_double(cat, "cpu_multi", 0);
/* Find the configured CPU. */
cpu = 0;
c = 0;
i = 256;
while (cpu_f->cpus[cpu].cpu_type) {
if (cpu_is_eligible(cpu_f, cpu, machine)) { /* skip ineligible CPUs */
if ((cpu_f->cpus[cpu].rspeed == speed) && (cpu_f->cpus[cpu].multi == multi)) /* exact speed/multiplier match */
break;
else if ((cpu_f->cpus[cpu].rspeed >= speed) && (i == 256)) /* closest speed match */
i = cpu;
c = cpu; /* store fastest eligible CPU */
}
cpu++;
}
if (!cpu_f->cpus[cpu].cpu_type) /* if no exact match was found, use closest matching faster CPU, or fastest eligible CPU */
cpu = MIN(i, c);
} else { /* default */
/* Find first eligible family. */
c = 0;
while (!cpu_family_is_eligible(&cpu_families[c], machine)) {
if (cpu_families[c++].package == 0) { /* end of list */
fatal("No eligible CPU families for the selected machine\n");
return;
}
}
cpu_f = (cpu_family_t *) &cpu_families[c];
/* Find first eligible CPU in that family. */
cpu = 0;
while (!cpu_is_eligible(cpu_f, cpu, machine)) {
if (cpu_f->cpus[cpu++].cpu_type == 0) { /* end of list */
cpu = 0;
break;
}
}
}
cpu_s = (CPU *) &cpu_f->cpus[cpu];
cpu_waitstates = config_get_int(cat, "cpu_waitstates", 0);
p = (char *)config_get_string(cat, "fpu_type", "none");
fpu_type = fpu_get_type(machine, cpu_manufacturer, cpu, p);
fpu_type = fpu_get_type(cpu_f, cpu, p);
mem_size = config_get_int(cat, "mem_size", 4096);
@@ -1045,7 +1124,7 @@ load_floppy_drives(void)
for (c=0; c<FDD_NUM; c++) {
sprintf(temp, "fdd_%02i_type", c+1);
p = config_get_string(cat, temp, (c < 2) ? "525_2dd" : "none");
fdd_set_type(c, fdd_get_from_internal_name(p));
fdd_set_type(c, fdd_get_from_internal_name(p));
if (fdd_get_type(c) > 13)
fdd_set_type(c, 13);
config_delete_var(cat, temp);
@@ -1108,7 +1187,7 @@ load_floppy_and_cdrom_drives(void)
for (c=0; c<FDD_NUM; c++) {
sprintf(temp, "fdd_%02i_type", c+1);
p = config_get_string(cat, temp, (c < 2) ? "525_2dd" : "none");
fdd_set_type(c, fdd_get_from_internal_name(p));
fdd_set_type(c, fdd_get_from_internal_name(p));
if (fdd_get_type(c) > 13)
fdd_set_type(c, 13);
@@ -1519,13 +1598,14 @@ config_load(void)
memset(zip_drives, 0, sizeof(zip_drive_t));
if (! config_read(cfg_path)) {
cpu_f = (cpu_family_t *) &cpu_families[0];
cpu = 0;
#ifdef USE_LANGUAGE
plat_langid = 0x0409;
#endif
scale = 1;
machine = machine_get_machine_from_internal_name("ibmpc");
fpu_type = fpu_get_type(machine, cpu_manufacturer, cpu, "none");
fpu_type = fpu_get_type(cpu_f, cpu, "none");
gfxcard = video_get_video_from_internal_name("cga");
vid_api = plat_vidapi("default");
time_sync = TIME_SYNC_ENABLED;
@@ -1671,14 +1751,14 @@ save_general(void)
config_delete_var(cat, "sound_gain");
if (confirm_reset != 1)
config_set_int(cat, "confirm_reset", confirm_reset);
config_set_int(cat, "confirm_reset", confirm_reset);
else
config_delete_var(cat, "confirm_reset");
config_delete_var(cat, "confirm_reset");
if (confirm_exit != 1)
config_set_int(cat, "confirm_exit", confirm_exit);
config_set_int(cat, "confirm_exit", confirm_exit);
else
config_delete_var(cat, "confirm_exit");
config_delete_var(cat, "confirm_exit");
#ifdef USE_LANGUAGE
if (plat_langid == 0x0409)
@@ -1703,18 +1783,67 @@ static void
save_machine(void)
{
char *cat = "Machine";
char *p;
int c, i = 0, legacy_mfg, legacy_cpu = -1, closest_legacy_cpu = -1;
config_set_string(cat, "machine", machine_get_internal_name());
p = machine_get_internal_name();
config_set_string(cat, "machine", p);
if (cpu_manufacturer == 0)
config_delete_var(cat, "cpu_manufacturer");
else
config_set_int(cat, "cpu_manufacturer", cpu_manufacturer);
config_set_string(cat, "cpu_family", (char *) cpu_f->internal_name);
config_set_int(cat, "cpu_speed", cpu_f->cpus[cpu].rspeed);
config_set_double(cat, "cpu_multi", cpu_f->cpus[cpu].multi);
if (cpu == 0)
config_delete_var(cat, "cpu");
else
config_set_int(cat, "cpu", cpu);
/* Forwards compatibility with the previous CPU model system. */
config_delete_var(cat, "cpu_manufacturer");
config_delete_var(cat, "cpu");
/* Look for a machine entry on the legacy table. */
c = 0;
while (cpu_legacy_table[c].machine) {
if (!strcmp(p, cpu_legacy_table[c].machine))
break;
c++;
}
if (cpu_legacy_table[c].machine) {
/* Look for a corresponding CPU entry. */
cpu_legacy_table_t *legacy_table_entry;
for (legacy_mfg = 0; legacy_mfg < 4; legacy_mfg++) {
if (!cpu_legacy_table[c].tables[legacy_mfg])
continue;
i = 0;
do {
legacy_table_entry = (cpu_legacy_table_t *) &cpu_legacy_table[c].tables[legacy_mfg][i];
/* Match the family name, speed and multiplier. */
if (!strcmp(cpu_f->internal_name, legacy_table_entry->family)) {
if ((legacy_table_entry->rspeed == cpu_f->cpus[cpu].rspeed) &&
(legacy_table_entry->multi == cpu_f->cpus[cpu].multi)) { /* exact speed/multiplier match */
legacy_cpu = i;
break;
} else if ((legacy_table_entry->rspeed >= cpu_f->cpus[cpu].rspeed) &&
(closest_legacy_cpu == -1)) { /* closest speed match */
closest_legacy_cpu = i;
}
}
} while (cpu_legacy_table[c].tables[legacy_mfg][++i].family);
/* Use the closest speed match if no exact match was found. */
if ((legacy_cpu == -1) && (closest_legacy_cpu > -1)) {
legacy_cpu = closest_legacy_cpu;
break;
} else if (legacy_cpu > -1) /* exact match found */
break;
}
/* Set legacy values if a match was found. */
if (legacy_cpu > -1) {
if (legacy_mfg)
config_set_int(cat, "cpu_manufacturer", legacy_mfg);
if (legacy_cpu)
config_set_int(cat, "cpu", legacy_cpu);
}
}
if (cpu_waitstates == 0)
config_delete_var(cat, "cpu_waitstates");
@@ -1724,7 +1853,7 @@ save_machine(void)
if (fpu_type == 0)
config_delete_var(cat, "fpu_type");
else
config_set_string(cat, "fpu_type", (char *) fpu_get_internal_name(machine, cpu_manufacturer, cpu, fpu_type));
config_set_string(cat, "fpu_type", (char *) fpu_get_internal_name(cpu_f, cpu, fpu_type));
if (mem_size == 4096)
config_delete_var(cat, "mem_size");
@@ -2332,6 +2461,27 @@ config_get_int(char *head, char *name, int def)
}
double
config_get_double(char *head, char *name, double def)
{
section_t *section;
entry_t *entry;
double value;
section = find_section(head);
if (section == NULL)
return(def);
entry = find_entry(section, name);
if (entry == NULL)
return(def);
sscanf(entry->data, "%lg", &value);
return(value);
}
int
config_get_hex16(char *head, char *name, int def)
{
@@ -2450,6 +2600,25 @@ config_set_int(char *head, char *name, int val)
}
void
config_set_double(char *head, char *name, double val)
{
section_t *section;
entry_t *ent;
section = find_section(head);
if (section == NULL)
section = create_section(head);
ent = find_entry(section, name);
if (ent == NULL)
ent = create_entry(section, name);
sprintf(ent->data, "%lg", val);
mbstowcs(ent->wdata, ent->data, 512);
}
void
config_set_hex16(char *head, char *name, int val)
{

View File

@@ -257,6 +257,30 @@ exec386(int cycs)
if (!use32) cpu_state.pc &= 0xffff;
#endif
if (cpu_state.abrt) {
flags_rebuild();
tempi = cpu_state.abrt & ABRT_MASK;
cpu_state.abrt = 0;
x86_doabrt(tempi);
if (cpu_state.abrt) {
cpu_state.abrt = 0;
#ifndef USE_NEW_DYNAREC
CS = oldcs;
#endif
cpu_state.pc = cpu_state.oldpc;
x386_log("Double fault %i\n", ins);
pmodeint(8, 0);
if (cpu_state.abrt) {
cpu_state.abrt = 0;
softresetx86();
cpu_set_edx();
#ifdef ENABLE_386_LOG
x386_log("Triple fault - reset\n");
#endif
}
}
}
ins_cycles -= cycles;
tsc += ins_cycles;
@@ -308,28 +332,6 @@ exec386(int cycs)
loadcs(readmemw(0, addr + 2));
}
}
} else if (cpu_state.abrt) {
flags_rebuild();
tempi = cpu_state.abrt & ABRT_MASK;
cpu_state.abrt = 0;
x86_doabrt(tempi);
if (cpu_state.abrt) {
cpu_state.abrt = 0;
#ifndef USE_NEW_DYNAREC
CS = oldcs;
#endif
cpu_state.pc = cpu_state.oldpc;
x386_log("Double fault %i\n", ins);
pmodeint(8, 0);
if (cpu_state.abrt) {
cpu_state.abrt = 0;
softresetx86();
cpu_set_edx();
#ifdef ENABLE_386_LOG
x386_log("Triple fault - reset\n");
#endif
}
}
}
cpu_end_block_after_ins = 0;

View File

@@ -2138,7 +2138,7 @@ void codegen_timing_k6_block_start()
void codegen_timing_k6_start()
{
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_K6)
if (cpu_s->cpu_type == CPU_K6)
{
units = k6_units;
nr_units = NR_K6_UNITS;

View File

@@ -1945,7 +1945,7 @@ void codegen_timing_p6_block_start()
void codegen_timing_p6_start()
{
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_PENTIUMPRO)
if (cpu_s->cpu_type == CPU_PENTIUMPRO)
{
units = ppro_units;
nr_units = NR_PPRO_UNITS;

View File

@@ -150,6 +150,7 @@ int in_smm = 0, smi_line = 0, smi_latched = 0, smm_in_hlt = 0;
int smi_block = 0;
uint32_t smbase = 0x30000;
cpu_family_t *cpu_f;
CPU *cpu_s;
int cpu_effective;
int cpu_multi;
@@ -177,7 +178,7 @@ int is286,
is386,
is486 = 1,
is486sx, is486dx, is486sx2, is486dx2, isdx4,
cpu_iscyrix,
cpu_isintel, cpu_iscyrix,
hascache,
isibm486,
israpidcad,
@@ -310,12 +311,115 @@ cpu_dynamic_switch(int new_cpu)
void
cpu_set_edx(void)
{
EDX = machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].edx_reset;
EDX = cpu_s->edx_reset;
}
int fpu_get_type(int machine, int cpu_manufacturer, int cpu, const char *internal_name)
cpu_family_t *
cpu_get_family(const char *internal_name)
{
CPU *cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu];
int c = 0;
while (cpu_families[c].package) {
if (!strcmp(internal_name, cpu_families[c].internal_name))
return (cpu_family_t *) &cpu_families[c];
c++;
}
return NULL;
}
uint8_t
cpu_is_eligible(const cpu_family_t *cpu_family, int cpu, int machine)
{
/* Get machine. */
const machine_t *machine_s = &machines[machine];
/* Add implicit CPU package compatibility. */
uint32_t packages = machine_s->cpu_package;
if (packages & CPU_PKG_SOCKET3)
packages |= CPU_PKG_SOCKET1;
else if (packages & CPU_PKG_SLOT1)
packages |= CPU_PKG_SOCKET370;
if (!(cpu_family->package & packages)) /* package type */
return 0;
const CPU *cpu_s = &cpu_family->cpus[cpu];
if (machine_s->cpu_block & cpu_s->cpu_type) /* CPU type blocklist */
return 0;
uint32_t bus_speed = cpu_s->rspeed / cpu_s->multi;
if (machine_s->cpu_min_bus && (bus_speed < (machine_s->cpu_min_bus - 840907))) /* minimum bus speed with ~0.84 MHz (for 8086) tolerance */
return 0;
if (machine_s->cpu_max_bus && (bus_speed > (machine_s->cpu_max_bus + 840907))) /* maximum bus speed with ~0.84 MHz (for 8086) tolerance */
return 0;
if (machine_s->cpu_min_voltage && (cpu_s->voltage < (machine_s->cpu_min_voltage - 100))) /* minimum voltage with 0.1V tolerance */
return 0;
if (machine_s->cpu_max_voltage && (cpu_s->voltage > (machine_s->cpu_max_voltage + 100))) /* maximum voltage with 0.1V tolerance */
return 0;
/* Account for CPUs that use a different internal multiplier than specified by jumpers. */
double multi = cpu_s->multi;
if (cpu_s->cpu_flags & CPU_FIXED_MULTIPLIER) {
multi = machine_s->cpu_min_multi;
} else if (cpu_family->package & CPU_PKG_SOCKET5_7) {
if (multi == 1.75) /* K5 */
multi = 2.5;
else if ((multi == 2.0) && (cpu_s->cpu_type & CPU_5K86)) /* K5 */
multi = 3.0;
else if ((multi == 2.0) && (cpu_s->cpu_type & (CPU_K6_2P | CPU_K6_3P))) /* K6-2+ / K6-3+ */
multi = 2.5;
else if (multi == (7.0 / 3.0)) /* WinChip 2A */
multi = 5.0;
else if (multi == (8.0 / 3.0)) /* WinChip 2A */
multi = 5.5;
else if ((multi == 3.0) && (cpu_s->cpu_type & (CPU_Cx6x86 | CPU_Cx6x86L))) /* 6x86(L) */
multi = 1.5;
else if (multi == (10.0 / 3.0)) /* WinChip 2A */
multi = 2.0;
else if (multi == 3.5) /* standard set by the Pentium MMX */
multi = 1.5;
else if ((multi == 4.0) && (cpu_s->cpu_type & (CPU_WINCHIP | CPU_WINCHIP2))) /* WinChip (2) */
multi = 1.5;
else if ((multi == 4.0) && (cpu_s->cpu_type & (CPU_Cx6x86 | CPU_Cx6x86L))) /* 6x86(L) */
multi = 3.0;
else if (multi == 6.0) /* K6-2 */
multi = 2.0;
}
if (multi < machine_s->cpu_min_multi) /* minimum multiplier */
return 0;
if (machine_s->cpu_max_multi && (multi > machine_s->cpu_max_multi)) /* maximum multiplier */
return 0;
return 1;
}
uint8_t
cpu_family_is_eligible(const cpu_family_t *cpu_family, int machine)
{
int c = 0;
while (cpu_family->cpus[c].cpu_type) {
if (cpu_is_eligible(cpu_family, c, machine))
return 1;
c++;
}
return 0;
}
int fpu_get_type(const cpu_family_t *cpu_family, int cpu, const char *internal_name)
{
const CPU *cpu_s = &cpu_family->cpus[cpu];
const FPU *fpus = cpu_s->fpus;
int fpu_type = fpus[0].type;
int c = 0;
@@ -330,9 +434,9 @@ int fpu_get_type(int machine, int cpu_manufacturer, int cpu, const char *interna
return fpu_type;
}
const char *fpu_get_internal_name(int machine, int cpu_manufacturer, int cpu, int type)
const char *fpu_get_internal_name(const cpu_family_t *cpu_family, int cpu, int type)
{
CPU *cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu];
const CPU *cpu_s = &cpu_family->cpus[cpu];
const FPU *fpus = cpu_s->fpus;
int c = 0;
@@ -346,17 +450,17 @@ const char *fpu_get_internal_name(int machine, int cpu_manufacturer, int cpu, in
return fpus[0].internal_name;
}
const char *fpu_get_name_from_index(int machine, int cpu_manufacturer, int cpu, int c)
const char *fpu_get_name_from_index(const cpu_family_t *cpu_family, int cpu, int c)
{
CPU *cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu];
const CPU *cpu_s = &cpu_family->cpus[cpu];
const FPU *fpus = cpu_s->fpus;
return fpus[c].name;
}
int fpu_get_type_from_index(int machine, int cpu_manufacturer, int cpu, int c)
int fpu_get_type_from_index(const cpu_family_t *cpu_family, int cpu, int c)
{
CPU *cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu];
const CPU *cpu_s = &cpu_family->cpus[cpu];
const FPU *fpus = cpu_s->fpus;
return fpus[c].type;
@@ -365,15 +469,8 @@ int fpu_get_type_from_index(int machine, int cpu_manufacturer, int cpu, int c)
void
cpu_set(void)
{
if (!machines[machine].cpu[cpu_manufacturer].cpus)
{
/*CPU is invalid, set to default*/
cpu_manufacturer = 0;
cpu = 0;
}
cpu_effective = cpu;
cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective];
cpu_s = (CPU *) &cpu_f->cpus[cpu_effective];
#ifdef USE_ACYCS
acycs = 0;
@@ -421,11 +518,8 @@ cpu_set(void)
#endif
hasfpu = (fpu_type != FPU_NONE);
hascache = (cpu_s->cpu_type >= CPU_486SLC) || (cpu_s->cpu_type == CPU_IBM386SLC || cpu_s->cpu_type == CPU_IBM486SLC || cpu_s->cpu_type == CPU_IBM486BL);
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
cpu_isintel = !strcmp(cpu_f->manufacturer, "Intel");
cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx486DX2 || cpu_s->cpu_type == CPU_Cx486DX4 || cpu_s->cpu_type == CPU_Cx5x86 || cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86MX || cpu_s->cpu_type == CPU_Cx6x86L || cpu_s->cpu_type == CPU_CxGX1);
#else
cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx486DX2 || cpu_s->cpu_type == CPU_Cx486DX4 || cpu_s->cpu_type == CPU_Cx5x86);
#endif
cpu_16bitbus = (cpu_s->cpu_type == CPU_286 || cpu_s->cpu_type == CPU_386SX || cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_IBM386SLC || cpu_s->cpu_type == CPU_IBM486SLC );
cpu_64bitbus = (cpu_s->cpu_type >= CPU_WINCHIP);
@@ -588,34 +682,34 @@ cpu_set(void)
if (fpu_type == FPU_287)
{
#ifdef USE_DYNAREC
x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16;
x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32;
x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16;
x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32;
x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16;
x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32;
x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16;
x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32;
x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16;
x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32;
x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32;
x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16;
x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32;
x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32;
x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16;
x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32;
x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32;
x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16;
x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32;
x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32;
x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32;
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32;
#endif
x86_opcodes_d9_a16 = ops_fpu_287_d9_a16;
x86_opcodes_d9_a32 = ops_fpu_287_d9_a32;
x86_opcodes_da_a16 = ops_fpu_287_da_a16;
x86_opcodes_da_a32 = ops_fpu_287_da_a32;
x86_opcodes_db_a16 = ops_fpu_287_db_a16;
x86_opcodes_db_a16 = ops_fpu_287_db_a16;
x86_opcodes_db_a32 = ops_fpu_287_db_a32;
x86_opcodes_dc_a16 = ops_fpu_287_dc_a16;
x86_opcodes_dc_a16 = ops_fpu_287_dc_a16;
x86_opcodes_dc_a32 = ops_fpu_287_dc_a32;
x86_opcodes_dd_a16 = ops_fpu_287_dd_a16;
x86_opcodes_dd_a16 = ops_fpu_287_dd_a16;
x86_opcodes_dd_a32 = ops_fpu_287_dd_a32;
x86_opcodes_de_a16 = ops_fpu_287_de_a16;
x86_opcodes_de_a16 = ops_fpu_287_de_a16;
x86_opcodes_de_a32 = ops_fpu_287_de_a32;
x86_opcodes_df_a16 = ops_fpu_287_df_a16;
x86_opcodes_df_a16 = ops_fpu_287_df_a16;
x86_opcodes_df_a32 = ops_fpu_287_df_a32;
}
timing_rr = 2; /*register dest - register src*/
@@ -698,34 +792,34 @@ cpu_set(void)
if (fpu_type == FPU_287) /*In case we get Deskpro 386 emulation*/
{
#ifdef USE_DYNAREC
x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16;
x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32;
x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16;
x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32;
x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16;
x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32;
x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16;
x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32;
x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16;
x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32;
x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32;
x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16;
x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32;
x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32;
x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16;
x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32;
x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32;
x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16;
x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32;
x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32;
x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32;
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32;
#endif
x86_opcodes_d9_a16 = ops_fpu_287_d9_a16;
x86_opcodes_d9_a32 = ops_fpu_287_d9_a32;
x86_opcodes_da_a16 = ops_fpu_287_da_a16;
x86_opcodes_da_a32 = ops_fpu_287_da_a32;
x86_opcodes_db_a16 = ops_fpu_287_db_a16;
x86_opcodes_db_a16 = ops_fpu_287_db_a16;
x86_opcodes_db_a32 = ops_fpu_287_db_a32;
x86_opcodes_dc_a16 = ops_fpu_287_dc_a16;
x86_opcodes_dc_a16 = ops_fpu_287_dc_a16;
x86_opcodes_dc_a32 = ops_fpu_287_dc_a32;
x86_opcodes_dd_a16 = ops_fpu_287_dd_a16;
x86_opcodes_dd_a16 = ops_fpu_287_dd_a16;
x86_opcodes_dd_a32 = ops_fpu_287_dd_a32;
x86_opcodes_de_a16 = ops_fpu_287_de_a16;
x86_opcodes_de_a16 = ops_fpu_287_de_a16;
x86_opcodes_de_a32 = ops_fpu_287_de_a32;
x86_opcodes_df_a16 = ops_fpu_287_df_a16;
x86_opcodes_df_a16 = ops_fpu_287_df_a16;
x86_opcodes_df_a32 = ops_fpu_287_df_a32;
}
timing_rr = 2; /*register dest - register src*/
@@ -1294,9 +1388,9 @@ cpu_set(void)
cpu_features = CPU_FEATURE_RDTSC;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_686);
codegen_timing_set(&codegen_timing_686);
#endif
ccr4 = 0x80;
ccr4 = 0x80;
break;
@@ -1321,7 +1415,7 @@ cpu_set(void)
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE;
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_686);
codegen_timing_set(&codegen_timing_686);
#endif
break;
@@ -1377,9 +1471,9 @@ cpu_set(void)
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE;
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_686);
codegen_timing_set(&codegen_timing_686);
#endif
ccr4 = 0x80;
ccr4 = 0x80;
break;
#endif
@@ -1570,7 +1664,7 @@ cpu_set(void)
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_PAE | CR4_MCE | CR4_PCE;
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_p6);
codegen_timing_set(&codegen_timing_p6);
#endif
break;
@@ -1625,7 +1719,7 @@ cpu_set(void)
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_PAE | CR4_MCE | CR4_PCE;
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_p6);
codegen_timing_set(&codegen_timing_p6);
#endif
break;
@@ -1680,7 +1774,7 @@ cpu_set(void)
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PAE | CR4_PCE | CR4_OSFXSR;
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_p6);
codegen_timing_set(&codegen_timing_p6);
#endif
break;
@@ -1773,7 +1867,7 @@ cpu_current_pc(char *bufp)
void
cpu_CPUID(void)
{
switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type)
switch (cpu_s->cpu_type)
{
case CPU_RAPIDCAD:
case CPU_i486DX:
@@ -2241,7 +2335,7 @@ cpu_CPUID(void)
break;
case 0x80000006: /*L2 Cache information*/
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_K6_3P)
if (cpu_s->cpu_type == CPU_K6_3P)
ECX = 0x01004220;
else
ECX = 0x00804220;
@@ -2483,7 +2577,7 @@ cpu_CPUID(void)
void cpu_ven_reset(void)
{
switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type)
switch (cpu_s->cpu_type)
{
#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
case CPU_K5:
@@ -2523,7 +2617,7 @@ void cpu_ven_reset(void)
void cpu_RDMSR()
{
switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type)
switch (cpu_s->cpu_type)
{
case CPU_IBM386SLC:
EAX = EDX = 0;
@@ -2915,7 +3009,7 @@ void cpu_RDMSR()
EDX = tsc >> 32;
break;
case 0x17:
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type != CPU_PENTIUM2D) goto i686_invalid_rdmsr;
if (cpu_s->cpu_type != CPU_PENTIUM2D) goto i686_invalid_rdmsr;
EAX = ecx17_msr & 0xffffffff;
EDX = ecx17_msr >> 32;
break;
@@ -2953,7 +3047,7 @@ void cpu_RDMSR()
EAX |= ((1 << 25) | (0 << 24) | (1 << 23) | (0 << 22));
else
EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (1 << 22));
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type != CPU_PENTIUMPRO) {
if (cpu_s->cpu_type != CPU_PENTIUMPRO) {
if (cpu_busspeed >= 84000000)
EAX |= (1 << 19);
}
@@ -2987,18 +3081,18 @@ void cpu_RDMSR()
EDX = ecx11e_msr >> 32;
break;
case 0x174:
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr;
if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr;
EAX &= 0xFFFF0000;
EAX |= cs_msr;
EDX = 0x00000000;
break;
case 0x175:
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr;
if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr;
EAX = esp_msr;
EDX = 0x00000000;
break;
case 0x176:
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr;
if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr;
EAX = eip_msr;
EDX = 0x00000000;
break;
@@ -3021,12 +3115,12 @@ void cpu_RDMSR()
case 0x208: case 0x209: case 0x20A: case 0x20B: case 0x20C: case 0x20D: case 0x20E: case 0x20F:
if (ECX & 1)
{
EAX = mtrr_physmask_msr[(ECX - 0x200) >> 1] & 0xffffffff;
EAX = mtrr_physmask_msr[(ECX - 0x200) >> 1] & 0xffffffff;
EDX = mtrr_physmask_msr[(ECX - 0x200) >> 1] >> 32;
}
else
{
EAX = mtrr_physbase_msr[(ECX - 0x200) >> 1] & 0xffffffff;
EAX = mtrr_physbase_msr[(ECX - 0x200) >> 1] & 0xffffffff;
EDX = mtrr_physbase_msr[(ECX - 0x200) >> 1] >> 32;
}
break;
@@ -3103,7 +3197,7 @@ void cpu_WRMSR()
uint64_t temp;
cpu_log("WRMSR %08X %08X%08X\n", ECX, EDX, EAX);
switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type)
switch (cpu_s->cpu_type)
{
case CPU_IBM386SLC:
switch (ECX)
@@ -3169,14 +3263,14 @@ void cpu_WRMSR()
cpu_features |= CPU_FEATURE_CX8;
else
cpu_features &= ~CPU_FEATURE_CX8;
if ((EAX & (1 << 20)) && machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type >= CPU_WINCHIP2)
if ((EAX & (1 << 20)) && cpu_s->cpu_type >= CPU_WINCHIP2)
cpu_features |= CPU_FEATURE_3DNOW;
else
cpu_features &= ~CPU_FEATURE_3DNOW;
if (EAX & (1 << 29))
CPUID = 0;
else
CPUID = machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpuid_model;
CPUID = cpu_s->cpuid_model;
break;
case 0x108:
msr.fcr2 = EAX | ((uint64_t)EDX << 32);
@@ -3460,7 +3554,7 @@ void cpu_WRMSR()
tsc = EAX | ((uint64_t)EDX << 32);
break;
case 0x17:
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type != CPU_PENTIUM2D) goto i686_invalid_wrmsr;
if (cpu_s->cpu_type != CPU_PENTIUM2D) goto i686_invalid_wrmsr;
ecx17_msr = EAX | ((uint64_t)EDX << 32);
break;
case 0x1B:
@@ -3492,15 +3586,15 @@ void cpu_WRMSR()
ecx11e_msr = EAX | ((uint64_t)EDX << 32);
break;
case 0x174:
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr;
if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr;
cs_msr = EAX & 0xFFFF;
break;
case 0x175:
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr;
if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr;
esp_msr = EAX;
break;
case 0x176:
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr;
if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr;
eip_msr = EAX;
break;
case 0x179:
@@ -3638,10 +3732,10 @@ static void cpu_write(uint16_t addr, uint8_t val, void *priv)
{
ccr4 = val;
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type >= CPU_Cx6x86)
if (cpu_s->cpu_type >= CPU_Cx6x86)
{
if (val & 0x80)
CPUID = machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpuid_model;
CPUID = cpu_s->cpuid_model;
else
CPUID = 0;
}
@@ -3678,11 +3772,11 @@ static uint8_t cpu_read(uint16_t addr, void *priv)
case 0xe8: return ((ccr3 & 0xf0) == 0x10) ? ccr4 : 0xff;
case 0xe9: return ((ccr3 & 0xf0) == 0x10) ? ccr5 : 0xff;
case 0xea: return ((ccr3 & 0xf0) == 0x10) ? ccr6 : 0xff;
case 0xfe: return machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cyrix_id & 0xff;
case 0xff: return machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cyrix_id >> 8;
case 0xfe: return cpu_s->cyrix_id & 0xff;
case 0xff: return cpu_s->cyrix_id >> 8;
}
if ((cyrix_addr & 0xf0) == 0xc0) return 0xff;
if (cyrix_addr == 0x20 && machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_Cx5x86) return 0xff;
if (cyrix_addr == 0x20 && cpu_s->cpu_type == CPU_Cx5x86) return 0xff;
}
return 0xff;
}
@@ -3710,7 +3804,7 @@ x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f)
void
cpu_update_waitstates(void)
{
cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective];
cpu_s = (CPU *) &cpu_f->cpus[cpu_effective];
if (is486)
cpu_prefetch_width = 16;

View File

@@ -32,63 +32,83 @@ enum {
};
enum {
CPU_8088, /* 808x class CPUs */
CPU_8086,
CPU_8088 = (1ULL << 0), /* 808x class CPUs */
CPU_8086 = (1ULL << 1),
#ifdef USE_NEC_808X
CPU_V20, /* NEC 808x class CPUs - future proofing */
CPU_V30,
CPU_V20 = (1ULL << 2), /* NEC 808x class CPUs - future proofing */
CPU_V30 = (1ULL << 3),
#endif
CPU_286, /* 286 class CPUs */
CPU_386SX, /* 386 class CPUs */
CPU_386DX,
CPU_IBM386SLC,
CPU_IBM486SLC,
CPU_IBM486BL,
CPU_RAPIDCAD,
CPU_486SLC,
CPU_486DLC,
CPU_i486SX, /* 486 class CPUs */
CPU_Am486SX,
CPU_Cx486S,
CPU_i486SX2,
CPU_Am486SX2,
CPU_i486DX,
CPU_i486DX2,
CPU_Am486DX,
CPU_Am486DX2,
CPU_Cx486DX,
CPU_Cx486DX2,
CPU_iDX4,
CPU_Am486DX4,
CPU_Cx486DX4,
CPU_Am5x86,
CPU_Cx5x86,
CPU_P24T,
CPU_WINCHIP, /* 586 class CPUs */
CPU_WINCHIP2,
CPU_PENTIUM,
CPU_PENTIUMMMX,
#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)))
CPU_Cx6x86,
CPU_Cx6x86MX,
CPU_Cx6x86L,
CPU_CxGX1,
#endif
#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
CPU_K5,
CPU_5K86,
#endif
CPU_K6,
CPU_K6_2,
CPU_K6_2C,
CPU_K6_3,
CPU_K6_2P,
CPU_K6_3P,
CPU_CYRIX3S,
CPU_PENTIUMPRO, /* 686 class CPUs */
CPU_PENTIUM2,
CPU_PENTIUM2D,
CPU_MAX /* Only really needed to close the enum in a way independent of the #ifdef's. */
CPU_286 = (1ULL << 4), /* 286 class CPUs */
CPU_386SX = (1ULL << 5), /* 386 class CPUs */
CPU_386DX = (1ULL << 6),
CPU_IBM386SLC = (1ULL << 7),
CPU_IBM486SLC = (1ULL << 8),
CPU_IBM486BL = (1ULL << 9),
CPU_RAPIDCAD = (1ULL << 10),
CPU_486SLC = (1ULL << 11),
CPU_486DLC = (1ULL << 12),
CPU_i486SX = (1ULL << 13), /* 486 class CPUs */
CPU_Am486SX = (1ULL << 14),
CPU_Cx486S = (1ULL << 15),
CPU_i486SX2 = (1ULL << 16),
CPU_Am486SX2 = (1ULL << 17),
CPU_i486DX = (1ULL << 18),
CPU_i486DX2 = (1ULL << 19),
CPU_Am486DX = (1ULL << 20),
CPU_Am486DX2 = (1ULL << 21),
CPU_Cx486DX = (1ULL << 22),
CPU_Cx486DX2 = (1ULL << 23),
CPU_iDX4 = (1ULL << 24),
CPU_Am486DX4 = (1ULL << 25),
CPU_Cx486DX4 = (1ULL << 26),
CPU_Am5x86 = (1ULL << 27),
CPU_Cx5x86 = (1ULL << 28),
CPU_P24T = (1ULL << 29),
CPU_WINCHIP = (1ULL << 30), /* 586 class CPUs */
CPU_WINCHIP2 = (1ULL << 31),
CPU_PENTIUM = (1ULL << 32),
CPU_PENTIUMMMX = (1ULL << 33),
CPU_Cx6x86 = (1ULL << 34),
CPU_Cx6x86MX = (1ULL << 35),
CPU_Cx6x86L = (1ULL << 36),
CPU_CxGX1 = (1ULL << 37),
CPU_K5 = (1ULL << 38),
CPU_5K86 = (1ULL << 39),
CPU_K6 = (1ULL << 40),
CPU_K6_2 = (1ULL << 41),
CPU_K6_2C = (1ULL << 42),
CPU_K6_3 = (1ULL << 43),
CPU_K6_2P = (1ULL << 44),
CPU_K6_3P = (1ULL << 45),
CPU_CYRIX3S = (1ULL << 46),
CPU_PENTIUMPRO = (1ULL << 47), /* 686 class CPUs */
CPU_PENTIUM2 = (1ULL << 48),
CPU_PENTIUM2D = (1ULL << 49)
};
enum {
CPU_PKG_8088 = (1 << 0),
CPU_PKG_8088_EUROPC = (1 << 1),
CPU_PKG_8086 = (1 << 2),
CPU_PKG_286 = (1 << 3),
CPU_PKG_386SX = (1 << 4),
CPU_PKG_386DX = (1 << 5),
CPU_PKG_M6117 = (1 << 6),
CPU_PKG_386SLC_IBM = (1 << 7),
CPU_PKG_486SLC = (1 << 8),
CPU_PKG_486SLC_IBM = (1 << 9),
CPU_PKG_486BL = (1 << 10),
CPU_PKG_486DLC = (1 << 11),
CPU_PKG_SOCKET1 = (1 << 12),
CPU_PKG_SOCKET3 = (1 << 13),
CPU_PKG_SOCKET3_PC330 = (1 << 14),
CPU_PKG_STPC = (1 << 15),
CPU_PKG_SOCKET4 = (1 << 16),
CPU_PKG_SOCKET5_7 = (1 << 17),
CPU_PKG_SOCKET8 = (1 << 18),
CPU_PKG_SLOT1 = (1 << 19),
CPU_PKG_SLOT2 = (1 << 20),
CPU_PKG_SOCKET370 = (1 << 21)
};
@@ -101,6 +121,7 @@ enum {
#define CPU_SUPPORTS_DYNAREC 1
#define CPU_REQUIRES_DYNAREC 2
#define CPU_ALTERNATE_XTAL 4
#define CPU_FIXED_MULTIPLIER 8
#if (defined __amd64__ || defined _M_X64)
#define LOOKUP_INV -1LL
@@ -110,17 +131,18 @@ enum {
typedef struct {
const char *name;
const char *internal_name;
const int type;
const char *name;
const char *internal_name;
const int type;
} FPU;
typedef struct {
const char *name;
int cpu_type;
uint64_t cpu_type;
const FPU *fpus;
int rspeed;
double multi;
uint16_t voltage;
uint32_t edx_reset;
uint32_t cpuid_model;
uint16_t cyrix_id;
@@ -130,57 +152,25 @@ typedef struct {
int8_t atclk_div;
} CPU;
typedef struct {
const uint32_t package;
const char *manufacturer;
const char *name;
const char *internal_name;
const CPU cpus[32];
} cpu_family_t;
typedef struct {
const char *family;
const int rspeed;
const double multi;
} cpu_legacy_table_t;
typedef struct {
const char *machine;
const cpu_legacy_table_t **tables;
} cpu_legacy_machine_t;
extern CPU cpus_8088[];
extern CPU cpus_8086[];
extern CPU cpus_286[];
extern CPU cpus_i386SX[];
extern CPU cpus_i386DX[];
extern CPU cpus_Am386SX[];
extern CPU cpus_Am386DX[];
#if defined(DEV_BRANCH) && defined(USE_M6117)
extern CPU cpus_ALiM6117[];
#endif
extern CPU cpus_486SLC[];
extern CPU cpus_486DLC[];
extern CPU cpus_IBM386SLC[];
extern CPU cpus_IBM486SLC[];
extern CPU cpus_IBM486BL[];
extern CPU cpus_i486S1[];
extern CPU cpus_Am486S1[];
extern CPU cpus_Cx486S1[];
extern CPU cpus_i486[];
extern CPU cpus_i486_PC330[];
extern CPU cpus_Am486[];
extern CPU cpus_Cx486[];
#if defined(DEV_BRANCH) && defined(USE_STPC)
extern CPU cpus_STPCDX[];
extern CPU cpus_STPCDX2[];
#endif
extern CPU cpus_WinChip[];
extern CPU cpus_WinChip_SS7[];
extern CPU cpus_Pentium5V[];
extern CPU cpus_Pentium5V50[];
extern CPU cpus_PentiumS5[];
extern CPU cpus_Pentium3V[];
extern CPU cpus_Pentium[];
#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
extern CPU cpus_K5[];
#endif
extern CPU cpus_K56[];
extern CPU cpus_K56_SS7[];
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
extern CPU cpus_6x863V[];
extern CPU cpus_6x86[];
extern CPU cpus_6x86SS7[];
#endif
extern CPU cpus_Cyrix3[];
extern CPU cpus_PentiumPro[];
extern CPU cpus_PentiumII66[];
extern CPU cpus_PentiumII[];
extern CPU cpus_PentiumIID[];
extern CPU cpus_Xeon[];
extern CPU cpus_Celeron[];
#define C_FLAG 0x0001
@@ -381,6 +371,12 @@ COMPILE_TIME_ASSERT(sizeof(cpu_state_t) <= 128)
/* Global variables. */
extern const cpu_family_t cpu_families[];
extern const cpu_legacy_machine_t cpu_legacy_table[];
extern cpu_family_t *cpu_f;
extern CPU *cpu_s;
extern int cpu_isintel;
extern int cpu_iscyrix;
extern int cpu_16bitbus, cpu_64bitbus;
extern int cpu_busspeed, cpu_pci_speed;
@@ -502,17 +498,6 @@ extern int cpu_end_block_after_ins;
extern uint16_t cpu_fast_off_count, cpu_fast_off_val;
extern uint32_t cpu_fast_off_flags;
extern CPU cpus_pcjr[]; // FIXME: should be in machine file!
extern CPU cpus_europc[]; // FIXME: should be in machine file!
extern CPU cpus_pc1512[]; // FIXME: should be in machine file!
extern CPU cpus_ibmat[]; // FIXME: should be in machine file!
extern CPU cpus_ibmxt286[]; // FIXME: should be in machine file!
extern CPU cpus_ps1_m2011[]; // FIXME: should be in machine file!
extern CPU cpus_ps2_m30_286[]; // FIXME: should be in machine file!
#if 0
extern CPU cpus_acer[]; // FIXME: should be in machine file!
#endif
/* Functions. */
extern int cpu_has_feature(int feature);
@@ -565,7 +550,7 @@ extern void resetx86(void);
extern void refreshread(void);
extern void resetreadlookup(void);
extern void softresetx86(void);
extern void x86_int(int num);
extern void x86_int(int num);
extern void x86_int_sw(int num);
extern int x86_int_sw_rm(int num);
extern void x86gpf(char *s, uint16_t error);
@@ -590,10 +575,13 @@ extern int sysexit(uint32_t fetchdat);
extern int syscall(uint32_t fetchdat);
extern int sysret(uint32_t fetchdat);
extern int fpu_get_type(int machine, int cpu_manufacturer, int cpu, const char *internal_name);
extern const char *fpu_get_internal_name(int machine, int cpu_manufacturer, int cpu, int type);
extern const char *fpu_get_name_from_index(int machine, int cpu_manufacturer, int cpu, int c);
extern int fpu_get_type_from_index(int machine, int cpu_manufacturer, int cpu, int c);
extern cpu_family_t *cpu_get_family(const char *internal_name);
extern uint8_t cpu_is_eligible(const cpu_family_t *cpu_family, int cpu, int machine);
extern uint8_t cpu_family_is_eligible(const cpu_family_t *cpu_family, int machine);
extern int fpu_get_type(const cpu_family_t *cpu_family, int cpu, const char *internal_name);
extern const char *fpu_get_internal_name(const cpu_family_t *cpu_family, int cpu, int type);
extern const char *fpu_get_name_from_index(const cpu_family_t *cpu_family, int cpu, int c);
extern int fpu_get_type_from_index(const cpu_family_t *cpu_family, int cpu, int c);
void cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg);
void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg);

File diff suppressed because it is too large Load Diff

View File

@@ -19,7 +19,7 @@ static int opAAA(uint32_t fetchdat)
static int opAAD(uint32_t fetchdat)
{
int base = getbytef();
if (cpu_manufacturer != MANU_INTEL) base = 10;
if (!cpu_isintel) base = 10;
AL = (AH * base) + AL;
AH = 0;
setznp16(AX);
@@ -31,7 +31,7 @@ static int opAAD(uint32_t fetchdat)
static int opAAM(uint32_t fetchdat)
{
int base = getbytef();
if (!base || cpu_manufacturer != MANU_INTEL) base = 10;
if (!base || !cpu_isintel) base = 10;
AH = AL / base;
AL %= base;
setznp16(AX);

View File

@@ -36,60 +36,5 @@ uint16_t
hwm_get_vcore()
{
/* Determine Vcore for the active CPU. */
CPU *cpu = &machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective];
switch (cpu->cpu_type) {
case CPU_WINCHIP:
case CPU_WINCHIP2:
#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
case CPU_K5:
case CPU_5K86:
#endif
#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)))
case CPU_Cx6x86:
#endif
return 3520;
case CPU_PENTIUMMMX:
return ((cpu->cpuid_model & 0xf000) == 0x1000) ? 3300 : 2800;
#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)))
case CPU_Cx6x86MX:
return (cpu->rspeed == 208333333) ? 2700 : 2900;
case CPU_Cx6x86L:
#endif
case CPU_PENTIUM2:
return 2800;
case CPU_K6_2C:
if (cpu->multi == 5.0)
return 2400;
else if (cpu->rspeed >= 550000000)
return 2300;
else
return 2200;
case CPU_K6:
if ((cpu->cpuid_model & 0x0f0) == 0x070)
return 2200;
else if (cpu->multi <= 3.0)
return 2900;
else
return 3200;
case CPU_K6_2:
case CPU_K6_3:
return 2200;
case CPU_PENTIUM2D:
case CPU_CYRIX3S:
return 2050;
case CPU_K6_2P:
case CPU_K6_3P:
return 2000;
default:
return 3300;
}
return cpu_s->voltage;
}

View File

@@ -734,7 +734,7 @@ static void
kbd_poll(void *priv)
{
atkbd_t *dev = (atkbd_t *)priv;
uint16_t irq_table[4] = { 0x0000, 0x0002, 0x1000, 0xffff };
uint16_t irq_table[4] = { 0x0002, 0x0002, 0x1000, 0xffff };
int i, channel;
uint16_t val, irq;

View File

@@ -102,8 +102,7 @@ extern int sound_is_float, /* (C) sound uses FP values */
SSI2001, /* (C) sound option */
voodoo_enabled; /* (C) video option */
extern uint32_t mem_size; /* (C) memory size */
extern int cpu_manufacturer, /* (C) cpu manufacturer */
cpu, /* (C) cpu type */
extern int cpu, /* (C) cpu type */
cpu_use_dynarec, /* (C) cpu uses/needs Dyna */
fpu_type; /* (C) fpu type */
extern int time_sync; /* (C) enable time sync */

View File

@@ -75,7 +75,6 @@ typedef struct {
/* Machine cateogory */
int machine, /* Machine */
cpu_manufacturer, /* CPU manufacturer */
cpu, /* CPU */
#ifdef USE_DYNAREC
cpu_use_dynarec, /* CPU recompiler enabled */
@@ -145,12 +144,14 @@ extern void config_dump(void);
extern void config_delete_var(char *head, char *name);
extern int config_get_int(char *head, char *name, int def);
extern double config_get_double(char *head, char *name, double def);
extern int config_get_hex16(char *head, char *name, int def);
extern int config_get_hex20(char *head, char *name, int def);
extern int config_get_mac(char *head, char *name, int def);
extern char *config_get_string(char *head, char *name, char *def);
extern wchar_t *config_get_wstring(char *head, char *name, wchar_t *def);
extern void config_set_int(char *head, char *name, int val);
extern void config_set_double(char *head, char *name, double val);
extern void config_set_hex16(char *head, char *name, int val);
extern void config_set_hex20(char *head, char *name, int val);
extern void config_set_mac(char *head, char *name, int val);

View File

@@ -96,7 +96,7 @@
#define IDS_2120 2120 // "No ROMs found"
#define IDS_2121 2121 // "Save changes\nThis will hard..."
#define IDS_2122 2122 // "Discard changes\nAll changes..."
#define IDS_2123 2123 // "Cancel\nGo back to the..."
#define IDS_2123 2123 // "Do you want to save the settings?"
#define IDS_2124 2124 // "About 86Box"
#define IDS_2125 2125 // "86Box v" EMU_VERSION
#define IDS_2126 2126 // "An emulator of old computers..."

View File

@@ -85,6 +85,8 @@
#define IS_ARCH(m, a) (machines[(m)].flags & (a)) ? 1 : 0;
#define MACHINE_MULTIPLIER_FIXED -1, -1
enum {
MACHINE_TYPE_NONE = 0,
@@ -142,14 +144,14 @@ typedef struct _machine_ {
const char *name;
const char *internal_name;
const char type;
struct {
const char *name;
#ifdef EMU_CPU_H
CPU *cpus;
#else
void *cpus;
#endif
} cpu[5];
uint32_t cpu_package;
uint64_t cpu_block;
uint32_t cpu_min_bus;
uint32_t cpu_max_bus;
uint16_t cpu_min_voltage;
uint16_t cpu_max_voltage;
double cpu_min_multi;
double cpu_max_multi;
int flags;
uint32_t min_ram, max_ram;
int ram_granularity;

View File

@@ -25,6 +25,7 @@ extern const device_t fdc37c663_device;
extern const device_t fdc37c665_device;
extern const device_t fdc37c666_device;
extern const device_t fdc37c669_device;
extern const device_t fdc37c669_370_device;
extern const device_t fdc37c931apm_device;
extern const device_t fdc37c931apm_compaq_device;
extern const device_t fdc37c932fr_device;

View File

@@ -0,0 +1,4 @@
void ddc_init(void);
void ddc_i2c_change(int new_clock, int new_data);
int ddc_read_clock(void);
int ddc_read_data(void);

View File

@@ -57,7 +57,7 @@ typedef struct svga_t
firstline, lastline, firstline_draw, lastline_draw,
displine, fullchange, x_add, y_add, pan,
vram_display_mask, vidclock,
hwcursor_on, dac_hwcursor_on, overlay_on;
hwcursor_on, dac_hwcursor_on, overlay_on, set_override;
/*The three variables below allow us to implement memory maps like that seen on a 1MB Trio64 :
0MB-1MB - VRAM
@@ -77,7 +77,7 @@ typedef struct svga_t
extra_banks[2],
banked_mask,
ca, overscan_color,
*map8, pallook[256];
*map8, pallook[512];
PALETTE vgapal;

View File

@@ -27,6 +27,7 @@ extern int scrollcache;
extern uint8_t edatlookup[4][4];
void svga_render_null(svga_t *svga);
void svga_render_blank(svga_t *svga);
void svga_render_overscan_left(svga_t *svga);
void svga_render_overscan_right(svga_t *svga);

View File

@@ -0,0 +1,18 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Voodoo Banshee and 3 specific emulation.
*
*
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
*
* Copyright 2008-2020 Sarah Walker.
*/
void banshee_set_overlay_addr(void *p, uint32_t addr);

View File

@@ -0,0 +1,18 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Voodoo Banshee and 3 specific emulation.
*
*
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
*
* Copyright 2008-2020 Sarah Walker.
*/
void voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val);

View File

@@ -0,0 +1,20 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* 3DFX Voodoo emulation.
*
*
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
*
* Copyright 2008-2020 Sarah Walker.
*/
void voodoo_v2_blit_start(voodoo_t *voodoo);
void voodoo_v2_blit_data(voodoo_t *voodoo, uint32_t data);
void voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params);

View File

@@ -5,15 +5,16 @@
fbzColorPath
*/
#ifdef __linux__
# include <sys/mman.h>
# include <unistd.h>
#if defined(__linux__) || defined(__APPLE__)
#include <sys/mman.h>
#include <unistd.h>
#endif
#if WIN64
# include <windows.h>
#define BITMAP windows_BITMAP
#include <windows.h>
#undef BITMAP
#endif
#include <intrin.h>
#include <xmmintrin.h>
#define BLOCK_NUM 8
@@ -32,45 +33,51 @@ typedef struct voodoo_x86_data_t
uint32_t fbzColorPath;
uint32_t textureMode[2];
uint32_t tLOD[2];
uint32_t trexInit1;
uint32_t trexInit1;
int is_tiled;
} voodoo_x86_data_t;
//static voodoo_x86_data_t voodoo_x86_data[2][BLOCK_NUM];
static int last_block[2] = {0, 0};
static int next_block_to_write[2] = {0, 0};
static int last_block[4] = {0, 0};
static int next_block_to_write[4] = {0, 0};
#define addbyte(val) \
if (block_pos < BLOCK_SIZE) \
code_block[block_pos++] = val; \
if (block_pos >= BLOCK_SIZE) \
fatal("Over!\n")
#define addbyte(val) \
do { \
code_block[block_pos++] = val; \
if (block_pos >= BLOCK_SIZE) \
fatal("Over!\n"); \
} while (0)
#define addword(val) \
*(uint16_t *)&code_block[block_pos] = val; \
block_pos += 2; \
if (block_pos >= BLOCK_SIZE) \
fatal("Over!\n")
#define addword(val) \
do { \
*(uint16_t *)&code_block[block_pos] = val; \
block_pos += 2; \
if (block_pos >= BLOCK_SIZE) \
fatal("Over!\n"); \
} while (0)
#define addlong(val) \
*(uint32_t *)&code_block[block_pos] = val; \
block_pos += 4; \
if (block_pos >= BLOCK_SIZE) \
fatal("Over!\n")
#define addlong(val) \
do { \
*(uint32_t *)&code_block[block_pos] = val; \
block_pos += 4; \
if (block_pos >= BLOCK_SIZE) \
fatal("Over!\n"); \
} while (0)
#define addquad(val) \
*(uint64_t *)&code_block[block_pos] = val; \
block_pos += 8; \
if (block_pos >= BLOCK_SIZE) \
fatal("Over!\n")
#define addquad(val) \
do { \
*(uint64_t *)&code_block[block_pos] = val; \
block_pos += 8; \
if (block_pos >= BLOCK_SIZE) \
fatal("Over!\n"); \
} while (0)
static __m128i xmm_01_w;// = 0x0001000100010001ull;
static __m128i xmm_ff_w;// = 0x00ff00ff00ff00ffull;
static __m128i xmm_ff_b;// = 0x00000000ffffffffull;
static uint32_t zero = 0;
static __m128i alookup[257], aminuslookup[256];
static __m128i minus_254;// = 0xff02ff02ff02ff02ull;
static __m128i bilinear_lookup[256*2];
@@ -157,10 +164,11 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v
addbyte(0x89); /*MOV state->tex_s, EBX*/
addbyte(0x9f);
addlong(offsetof(voodoo_state_t, tex_s));
addbyte(0x0f); /*MOVZX EAX, logtable[RAX]*/
addbyte(0x41); /*MOVZX EAX, R9(logtable)[RAX]*/
addbyte(0x0f);
addbyte(0xb6);
addbyte(0x80);
addlong((uint32_t)(uintptr_t)logtable);
addbyte(0x04);
addbyte(0x01);
addbyte(0x09); /*OR EAX, EDX*/
addbyte(0xd0);
addbyte(0x03); /*ADD EAX, state->lod*/
@@ -334,11 +342,10 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v
addbyte(1);
if (state->clamp_t[tmu])
{
addbyte(0x0f); /*CMOVS EDX, zero*/
addbyte(0x41); /*CMOVS EDX, R10(alookup[0](zero))*/
addbyte(0x0f);
addbyte(0x48);
addbyte(0x14);
addbyte(0x25);
addlong((uint32_t)(uintptr_t)&zero);
addbyte(0x12);
addbyte(0x3b); /*CMP EDX, params->tex_h_mask[ESI]*/
addbyte(0x96);
addlong(offsetof(voodoo_params_t, tex_h_mask[tmu]));
@@ -348,11 +355,10 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v
addlong(offsetof(voodoo_params_t, tex_h_mask[tmu]));
addbyte(0x85); /*TEST EBX,EBX*/
addbyte(0xdb);
addbyte(0x0f); /*CMOVS EBX, zero*/
addbyte(0x41); /*CMOVS EBX, R10(alookup[0](zero))*/
addbyte(0x0f);
addbyte(0x48);
addbyte(0x1c);
addbyte(0x25);
addlong((uint32_t)(uintptr_t)&zero);
addbyte(0x1a);
addbyte(0x3b); /*CMP EBX, params->tex_h_mask[ESI]*/
addbyte(0x9e);
addlong(offsetof(voodoo_params_t, tex_h_mask[tmu]));
@@ -395,11 +401,10 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v
addbyte(0x8b); /*MOV ebp_store2, RSI*/
addbyte(0xb7);
addlong(offsetof(voodoo_state_t, ebp_store));
addbyte(0x0f); /*CMOVS EAX, zero*/
addbyte(0x41); /*CMOVS EAX, R10(alookup[0](zero))*/
addbyte(0x0f);
addbyte(0x48);
addbyte(0x04);
addbyte(0x25);
addlong((uint32_t)(uintptr_t)&zero);
addbyte(0x02);
addbyte(0x78); /*JS + - clamp on 0*/
addbyte(2+3+2+ 5+5+2);
addbyte(0x3b); /*CMP EAX, EBP*/
@@ -610,11 +615,10 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v
{
addbyte(0x85); /*TEST EAX, EAX*/
addbyte(0xc0);
addbyte(0x0f); /*CMOVS EAX, zero*/
addbyte(0x41); /*CMOVS EAX, R10(alookup[0](zero))*/
addbyte(0x0f);
addbyte(0x48);
addbyte(0x04);
addbyte(0x25);
addlong((uint32_t)(uintptr_t)&zero);
addbyte(0x02);
addbyte(0x3b); /*CMP EAX, params->tex_w_mask[ESI+ECX*4]*/
addbyte(0x84);
addbyte(0x8e);
@@ -637,11 +641,10 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v
{
addbyte(0x85); /*TEST EBX, EBX*/
addbyte(0xdb);
addbyte(0x0f); /*CMOVS EBX, zero*/
addbyte(0x41); /*CMOVS EBX, R10(alookup[0](zero))*/
addbyte(0x0f);
addbyte(0x48);
addbyte(0x1c);
addbyte(0x25);
addlong((uint32_t)(uintptr_t)&zero);
addbyte(0x1a);
addbyte(0x3b); /*CMP EBX, params->tex_h_mask[ESI+ECX*4]*/
addbyte(0x9c);
addbyte(0x8e);
@@ -707,11 +710,48 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
addbyte(0x57); /*PUSH RDI*/
addbyte(0x56); /*PUSH RSI*/
addbyte(0x53); /*PUSH RBX*/
addbyte(0x41); /*PUSH R12*/
addbyte(0x54);
addbyte(0x41); /*PUSH R13*/
addbyte(0x55);
addbyte(0x41); /*PUSH R14*/
addbyte(0x56);
addbyte(0x41); /*PUSH R15*/
addbyte(0x57);
addbyte(0x49); /*MOV R15, xmm_01_w*/
addbyte(0xbf);
addquad((uint64_t)(uintptr_t)&xmm_01_w);
addbyte(0x66); /*MOVDQA XMM8, [R15]*/
addbyte(0x45);
addbyte(0x0f);
addbyte(0x6f);
addbyte(0x07 | (0 << 3));
addbyte(0x49); /*MOV R15, xmm_ff_w*/
addbyte(0xbf);
addquad((uint64_t)(uintptr_t)&xmm_ff_w);
addbyte(0x66); /*MOVDQA XMM9, [R15]*/
addbyte(0x45);
addbyte(0x0f);
addbyte(0x6f);
addbyte(0x07 | (1 << 3));
addbyte(0x49); /*MOV R15, xmm_ff_b*/
addbyte(0xbf);
addquad((uint64_t)(uintptr_t)&xmm_ff_b);
addbyte(0x66); /*MOVDQA XMM10, [R15]*/
addbyte(0x45);
addbyte(0x0f);
addbyte(0x6f);
addbyte(0x07 | (2 << 3));
addbyte(0x49); /*MOV R15, minus_254*/
addbyte(0xbf);
addquad((uint64_t)(uintptr_t)&minus_254);
addbyte(0x66); /*MOVDQA XMM11, [R15]*/
addbyte(0x45);
addbyte(0x0f);
addbyte(0x6f);
addbyte(0x07 | (3 << 3));
#if WIN64
addbyte(0x48); /*MOV RDI, RCX (voodoo_state)*/
addbyte(0x89);
@@ -723,17 +763,56 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
addbyte(0x89);
addbyte(0xce);
#else
addbyte(0x49); /*MOV R9, RCX (real_y)*/
addbyte(0x49); /*MOV R14, RCX (real_y)*/
addbyte(0x89);
addbyte(0xc9);
addbyte(0xce);
addbyte(0x49); /*MOV R15, RSI (voodoo_state)*/
addbyte(0x89);
addbyte(0xf7);
#endif
addbyte(0x49); /*MOV R9, logtable*/
addbyte(0xb8 | (9 & 7));
addquad((uint64_t)(uintptr_t)&logtable);
addbyte(0x49); /*MOV R10, alookup*/
addbyte(0xb8 | (10 & 7));
addquad((uint64_t)(uintptr_t)&alookup);
addbyte(0x49); /*MOV R11, aminuslookup*/
addbyte(0xb8 | (11 & 7));
addquad((uint64_t)(uintptr_t)&aminuslookup);
addbyte(0x49); /*MOV R12, xmm_00_ff_w*/
addbyte(0xb8 | (12 & 7));
addquad((uint64_t)(uintptr_t)&xmm_00_ff_w);
addbyte(0x49); /*MOV R13, i_00_ff_w*/
addbyte(0xb8 | (13 & 7));
addquad((uint64_t)(uintptr_t)&i_00_ff_w);
loop_jump_pos = block_pos;
addbyte(0x4c); /*MOV RSI, R15*/
addbyte(0x89);
addbyte(0xfe);
if (params->col_tiled || params->aux_tiled)
{
addbyte(0x8b); /*MOV EAX, state->x[EDI]*/
addbyte(0x87);
addlong(offsetof(voodoo_state_t, x));
addbyte(0x89); /*MOV EBX, EAX*/
addbyte(0xc3);
addbyte(0x83); /*AND EAX, 63*/
addbyte(0xe0);
addbyte(63);
addbyte(0xc1); /*SHR EBX, 6*/
addbyte(0xeb);
addbyte(6);
addbyte(0xc1); /*SHL EBX, 11 - tile is 128*32, << 12, div 2 because word index*/
addbyte(0xe3);
addbyte(11);
addbyte(0x01); /*ADD EAX, EBX*/
addbyte(0xd8);
addbyte(0x89); /*MOV state->x_tiled[EDI], EAX*/
addbyte(0x87);
addlong(offsetof(voodoo_state_t, x_tiled));
}
addbyte(0x66); /*PXOR XMM2, XMM2*/
addbyte(0x0f);
addbyte(0xef);
@@ -851,7 +930,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
{
addbyte(0x8b); /*MOV EBX, state->x[EDI]*/
addbyte(0x9f);
addlong(offsetof(voodoo_state_t, x));
if (params->aux_tiled)
addlong(offsetof(voodoo_state_t, x_tiled));
else
addlong(offsetof(voodoo_state_t, x));
addbyte(0x48); /*MOV RCX, aux_mem[RDI]*/
addbyte(0x8b);
addbyte(0x8f);
@@ -1075,27 +1157,26 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
}
if (params->textureMode[1] & TEXTUREMODE_TRILINEAR)
{
addbyte(0x66); /*PXOR XMM0, xmm_00_ff_w[EBX]*/
addbyte(0x0f);
addbyte(0xef);
addbyte(0x83);
addlong((uint32_t)(uintptr_t)&xmm_00_ff_w[0]);
}
else if (!tc_reverse_blend_1)
{
addbyte(0x66); /*PXOR XMM0, xmm_ff_w*/
addbyte(0x66); /*PXOR XMM0, R12(xmm_00_ff_w)[EBX]*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xef);
addbyte(0x04);
addbyte(0x25);
addlong((uint32_t)(uintptr_t)&xmm_ff_w);
addbyte(0x1c);
}
addbyte(0x66); /*PADDW XMM0, xmm_01_w*/
else if (!tc_reverse_blend_1)
{
addbyte(0x66); /*PXOR XMM0, XMM9(xmm_ff_w)*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xef);
addbyte(0xc1);
}
addbyte(0x66); /*PADDW XMM0, XMM8(xmm_01_w)*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xfd);
addbyte(0x04);
addbyte(0x25);
addlong((uint32_t)(uintptr_t)&xmm_01_w);
addbyte(0xc0);
addbyte(0xf3); /*MOVQ XMM1, XMM2*/
addbyte(0x0f);
addbyte(0x7e);
@@ -1213,10 +1294,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
}
if (params->textureMode[1] & TEXTUREMODE_TRILINEAR)
{
addbyte(0x33); /*XOR EAX, i_00_ff_w[ECX*4]*/
addbyte(0x04);
addbyte(0x41); /*XOR EAX, R13(i_00_ff_w)[ECX*4]*/
addbyte(0x33);
addbyte(0x44);
addbyte(0x8d);
addlong((uint32_t)(uintptr_t)i_00_ff_w);
addbyte(0);
}
else if (!tc_reverse_blend_1)
{
@@ -1399,27 +1481,26 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
}
if (params->textureMode[0] & TEXTUREMODE_TRILINEAR)
{
addbyte(0x66); /*PXOR XMM4, xmm_00_ff_w[EBX]*/
addbyte(0x0f);
addbyte(0xef);
addbyte(0xa3);
addlong((uint32_t)(uintptr_t)&xmm_00_ff_w[0]);
}
else if (!tc_reverse_blend)
{
addbyte(0x66); /*PXOR XMM4, FF*/
addbyte(0x66); /*PXOR XMM4, R12(xmm_00_ff_w)[EBX]*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xef);
addbyte(0x24);
addbyte(0x25);
addlong((uint32_t)(uintptr_t)&xmm_ff_w);
addbyte(0x1c);
}
addbyte(0x66); /*PADDW XMM4, 1*/
else if (!tc_reverse_blend)
{
addbyte(0x66); /*PXOR XMM4, XMM9(xmm_ff_w)*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xef);
addbyte(0xe1);
}
addbyte(0x66); /*PADDW XMM4, XMM8(xmm_01_w)*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xfd);
addbyte(0x24);
addbyte(0x25);
addlong((uint32_t)(uintptr_t)&xmm_01_w);
addbyte(0xe0);
addbyte(0xf3); /*MOVQ XMM5, XMM1*/
addbyte(0x0f);
addbyte(0x7e);
@@ -1483,11 +1564,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
}
if (tc_invert_output)
{
addbyte(0x66); /*PXOR XMM1, FF*/
addbyte(0x66); /*PXOR XMM1, XMM9(xmm_ff_w)*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xef);
addbyte(0x0d);
addlong((uint32_t)(uintptr_t)&xmm_ff_w);
addbyte(0xc9);
}
addbyte(0x66); /*PACKUSWB XMM0, XMM0*/
@@ -1581,10 +1662,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
}
if (params->textureMode[0] & TEXTUREMODE_TRILINEAR)
{
addbyte(0x33); /*XOR EBX, i_00_ff_w[ECX*4]*/
addbyte(0x1c);
addbyte(0x41); /*XOR EBX, R13(i_00_ff_w)[ECX*4]*/
addbyte(0x33);
addbyte(0x5c);
addbyte(0x8d);
addlong((uint32_t)(uintptr_t)i_00_ff_w);
addbyte(0);
}
else if (!tca_reverse_blend)
{
@@ -2131,19 +2213,17 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
addbyte(0xe0);
if (!cc_reverse_blend)
{
addbyte(0x66); /*PXOR XMM3, 0xff*/
addbyte(0x66); /*PXOR XMM3, XMM9(xmm_ff_w)*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xef);
addbyte(0x1c);
addbyte(0x25);
addlong((uint32_t)(uintptr_t)&xmm_ff_w);
addbyte(0xd9);
}
addbyte(0x66); /*PADDW XMM3, 1*/
addbyte(0x66); /*PADDW XMM3, XMM8(xmm_01_w)*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xfd);
addbyte(0x1c);
addbyte(0x25);
addlong((uint32_t)(uintptr_t)&xmm_01_w);
addbyte(0xd8);
addbyte(0x66); /*PMULLW XMM0, XMM3*/
addbyte(0x0f);
addbyte(0xd5);
@@ -2182,12 +2262,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
if (cc_invert_output)
{
addbyte(0x66); /*PXOR XMM0, 0xff*/
addbyte(0x66); /*PXOR XMM0, XMM10(xmm_ff_b)*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xef);
addbyte(0x04);
addbyte(0x25);
addlong((uint32_t)(uintptr_t)&xmm_ff_b);
addbyte(0xc2);
}
if (params->fogMode & FOG_ENABLE)
@@ -2344,11 +2423,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
addbyte(0xc0);
addbyte(0x66); /*PMULLW XMM3, alookup+4[EAX*8]*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xd5);
addbyte(0x1c);
addbyte(0xc5);
addlong(((uintptr_t)alookup) + 16);
addbyte(0x5c);
addbyte(0xc2);
addbyte(16);
addbyte(0x66); /*PSRAW XMM3, 7*/
addbyte(0x0f);
addbyte(0x71);
@@ -2437,7 +2517,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
addquad((uintptr_t)rgb565);
addbyte(0x8b); /*MOV EAX, state->x[EDI]*/
addbyte(0x87);
addlong(offsetof(voodoo_state_t, x));
if (params->col_tiled)
addlong(offsetof(voodoo_state_t, x_tiled));
else
addlong(offsetof(voodoo_state_t, x));
addbyte(0x48); /*MOV RBP, fb_mem*/
addbyte(0x8b);
addbyte(0xaf);
@@ -2477,22 +2560,22 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
addbyte(0xe4);
break;
case AFUNC_ASRC_ALPHA:
addbyte(0x66); /*PMULLW XMM4, alookup[EDX*8]*/
addbyte(0x66); /*PMULLW XMM4, R10(alookup)[EDX*8]*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xd5);
addbyte(0x24);
addbyte(0xd5);
addlong((uint32_t)(uintptr_t)alookup);
addbyte(0xd2);
addbyte(0xf3); /*MOVQ XMM5, XMM4*/
addbyte(0x0f);
addbyte(0x7e);
addbyte(0xec);
addbyte(0x66); /*PADDW XMM4, alookup[1*8]*/
addbyte(0x66); /*PADDW XMM4, R10(alookup)[1*8]*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xfd);
addbyte(0x24);
addbyte(0x25);
addlong((uint32_t)(uintptr_t)alookup + 16);
addbyte(0x62);
addbyte(8*2);
addbyte(0x66); /*PSRLW XMM5, 8*/
addbyte(0x0f);
addbyte(0x71);
@@ -2517,12 +2600,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
addbyte(0x0f);
addbyte(0x7e);
addbyte(0xec);
addbyte(0x66); /*PADDW XMM4, alookup[1*8]*/
addbyte(0x66); /*PADDW XMM4, R10(alookup)[1*8]*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xfd);
addbyte(0x24);
addbyte(0x25);
addlong((uint32_t)(uintptr_t)alookup + 16);
addbyte(0x62);
addbyte(8*2);
addbyte(0x66); /*PSRLW XMM5, 8*/
addbyte(0x0f);
addbyte(0x71);
@@ -2543,22 +2626,22 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
case AFUNC_AONE:
break;
case AFUNC_AOMSRC_ALPHA:
addbyte(0x66); /*PMULLW XMM4, aminuslookup[EDX*8]*/
addbyte(0x66); /*PMULLW XMM4, R11(aminuslookup)[EDX*8]*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xd5);
addbyte(0x24);
addbyte(0xd5);
addlong((uint32_t)(uintptr_t)aminuslookup);
addbyte(0xd3);
addbyte(0xf3); /*MOVQ XMM5, XMM4*/
addbyte(0x0f);
addbyte(0x7e);
addbyte(0xec);
addbyte(0x66); /*PADDW XMM4, alookup[1*8]*/
addbyte(0x66); /*PADDW XMM4, R10(alookup)[1*8]*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xfd);
addbyte(0x24);
addbyte(0x25);
addlong((uint32_t)(uintptr_t)alookup + 16);
addbyte(0x62);
addbyte(8*2);
addbyte(0x66); /*PSRLW XMM5, 8*/
addbyte(0x0f);
addbyte(0x71);
@@ -2575,12 +2658,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
addbyte(8);
break;
case AFUNC_AOM_COLOR:
addbyte(0xf3); /*MOVQ XMM5, xmm_ff_w*/
addbyte(0xf3); /*MOVQ XMM5, XMM9(xmm_ff_w)*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0x7e);
addbyte(0x2c);
addbyte(0x25);
addlong((uint32_t)(uintptr_t)&xmm_ff_w);
addbyte(0xe9);
addbyte(0x66); /*PSUBW XMM5, XMM0*/
addbyte(0x0f);
addbyte(0xf9);
@@ -2594,11 +2676,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
addbyte(0x7e);
addbyte(0xec);
addbyte(0x66); /*PADDW XMM4, alookup[1*8]*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xfd);
addbyte(0x24);
addbyte(0x25);
addlong((uint32_t)(uintptr_t)alookup + 16);
addbyte(0x62);
addbyte(8*2);
addbyte(0x66); /*PSRLW XMM5, 8*/
addbyte(0x0f);
addbyte(0x71);
@@ -2621,22 +2703,21 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
addbyte(0xe4);
break;
case AFUNC_ASATURATE:
addbyte(0x66); /*PMULLW XMM4, minus_254*/
addbyte(0x66); /*PMULLW XMM4, XMM11(minus_254)*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xd5);
addbyte(0x24);
addbyte(0xd5);
addlong((uint32_t)(uintptr_t)&minus_254);
addbyte(0xe3);
addbyte(0xf3); /*MOVQ XMM5, XMM4*/
addbyte(0x0f);
addbyte(0x7e);
addbyte(0xec);
addbyte(0x66); /*PADDW XMM4, alookup[1*8]*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xfd);
addbyte(0x24);
addbyte(0x25);
addlong((uint32_t)(uintptr_t)alookup + 16);
addbyte(0x62);
addbyte(8*2);
addbyte(0x66); /*PSRLW XMM5, 8*/
addbyte(0x0f);
addbyte(0x71);
@@ -2662,22 +2743,22 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
addbyte(0xc0);
break;
case AFUNC_ASRC_ALPHA:
addbyte(0x66); /*PMULLW XMM0, alookup[EDX*8]*/
addbyte(0x66); /*PMULLW XMM0, R10(alookup)[EDX*8]*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xd5);
addbyte(0x04);
addbyte(0xd5);
addlong((uint32_t)(uintptr_t)alookup);
addbyte(0xd2);
addbyte(0xf3); /*MOVQ XMM5, XMM0*/
addbyte(0x0f);
addbyte(0x7e);
addbyte(0xe8);
addbyte(0x66); /*PADDW XMM0, alookup[1*8]*/
addbyte(0x66); /*PADDW XMM0, R10(alookup)[1*8]*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xfd);
addbyte(0x04);
addbyte(0x25);
addlong((uint32_t)(uintptr_t)alookup + 16);
addbyte(0x42);
addbyte(8*2);
addbyte(0x66); /*PSRLW XMM5, 8*/
addbyte(0x0f);
addbyte(0x71);
@@ -2702,12 +2783,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
addbyte(0x0f);
addbyte(0x7e);
addbyte(0xe8);
addbyte(0x66); /*PADDW XMM0, alookup[1*8]*/
addbyte(0x66); /*PADDW XMM0, R10(alookup)[1*8]*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xfd);
addbyte(0x04);
addbyte(0x25);
addlong((uint32_t)(uintptr_t)alookup + 16);
addbyte(0x42);
addbyte(8*2);
addbyte(0x66); /*PSRLW XMM5, 8*/
addbyte(0x0f);
addbyte(0x71);
@@ -2728,22 +2809,22 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
case AFUNC_AONE:
break;
case AFUNC_AOMSRC_ALPHA:
addbyte(0x66); /*PMULLW XMM0, aminuslookup[EDX*8]*/
addbyte(0x66); /*PMULLW XMM0, R11(aminuslookup)[EDX*8]*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xd5);
addbyte(0x04);
addbyte(0xd5);
addlong((uint32_t)(uintptr_t)aminuslookup);
addbyte(0xd3);
addbyte(0xf3); /*MOVQ XMM5, XMM0*/
addbyte(0x0f);
addbyte(0x7e);
addbyte(0xe8);
addbyte(0x66); /*PADDW XMM0, alookup[1*8]*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xfd);
addbyte(0x04);
addbyte(0x25);
addlong((uint32_t)(uintptr_t)alookup + 16);
addbyte(0x42);
addbyte(8*2);
addbyte(0x66); /*PSRLW XMM5, 8*/
addbyte(0x0f);
addbyte(0x71);
@@ -2760,12 +2841,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
addbyte(8);
break;
case AFUNC_AOM_COLOR:
addbyte(0xf3); /*MOVQ XMM5, xmm_ff_w*/
addbyte(0xf3); /*MOVQ XMM5, XMM9(xmm_ff_w)*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0x7e);
addbyte(0x2c);
addbyte(0x25);
addlong((uint32_t)(uintptr_t)&xmm_ff_w);
addbyte(0xe9);
addbyte(0x66); /*PSUBW XMM5, XMM6*/
addbyte(0x0f);
addbyte(0xf9);
@@ -2779,11 +2859,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
addbyte(0x7e);
addbyte(0xe8);
addbyte(0x66); /*PADDW XMM0, alookup[1*8]*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xfd);
addbyte(0x04);
addbyte(0x25);
addlong((uint32_t)(uintptr_t)alookup + 16);
addbyte(0x42);
addbyte(8*2);
addbyte(0x66); /*PSRLW XMM5, 8*/
addbyte(0x0f);
addbyte(0x71);
@@ -2822,8 +2902,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
addbyte(0x8b); /*MOV EDX, state->x[EDI]*/
addbyte(0x97);
addlong(offsetof(voodoo_state_t, x));
if (params->col_tiled)
addlong(offsetof(voodoo_state_t, x_tiled));
else
addlong(offsetof(voodoo_state_t, x));
addbyte(0x66); /*MOV EAX, XMM0*/
addbyte(0x0f);
addbyte(0x7e);
@@ -2889,7 +2972,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
}
addbyte(0x8b); /*MOV EDX, state->x[EDI]*/
addbyte(0x97);
addlong(offsetof(voodoo_state_t, x));
if (voodoo->col_tiled)
addlong(offsetof(voodoo_state_t, x_tiled));
else
addlong(offsetof(voodoo_state_t, x));
addbyte(0x4c); /*ADD RSI, R8*/
addbyte(0x01);
addbyte(0xc6);
@@ -2975,6 +3061,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE))
{
addbyte(0x8b); /*MOV EDX, state->x[EDI]*/
addbyte(0x97);
if (params->aux_tiled)
addlong(offsetof(voodoo_state_t, x_tiled));
else
addlong(offsetof(voodoo_state_t, x));
addbyte(0x66); /*MOV AX, new_depth*/
addbyte(0x8b);
addbyte(0x87);
@@ -3234,6 +3326,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
addbyte(0x5f);
addbyte(0x41); /*POP R14*/
addbyte(0x5e);
addbyte(0x41); /*POP R13*/
addbyte(0x5d);
addbyte(0x41); /*POP R12*/
addbyte(0x5c);
addbyte(0x5b); /*POP RBX*/
addbyte(0x5e); /*POP RSI*/
addbyte(0x5f); /*POP RDI*/
@@ -3241,7 +3337,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
addbyte(0xC3); /*RET*/
}
static int voodoo_recomp = 0;
int voodoo_recomp = 0;
static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int odd_even)
{
int c;
@@ -3251,7 +3347,7 @@ static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params,
for (c = 0; c < 8; c++)
{
data = &voodoo_x86_data[odd_even + c*2]; //&voodoo_x86_data[odd_even][b];
data = &voodoo_x86_data[odd_even + c*4]; //&voodoo_x86_data[odd_even][b];
if (state->xdir == data->xdir &&
params->alphaMode == data->alphaMode &&
@@ -3262,7 +3358,8 @@ static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params,
params->textureMode[0] == data->textureMode[0] &&
params->textureMode[1] == data->textureMode[1] &&
(params->tLOD[0] & LOD_MASK) == data->tLOD[0] &&
(params->tLOD[1] & LOD_MASK) == data->tLOD[1])
(params->tLOD[1] & LOD_MASK) == data->tLOD[1] &&
((params->col_tiled || params->aux_tiled) ? 1 : 0) == data->is_tiled)
{
last_block[odd_even] = b;
return data->code_block;
@@ -3271,7 +3368,7 @@ static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params,
b = (b + 1) & 7;
}
voodoo_recomp++;
data = &voodoo_x86_data[odd_even + next_block_to_write[odd_even]*2];
data = &voodoo_x86_data[odd_even + next_block_to_write[odd_even]*4];
// code_block = data->code_block;
voodoo_generate(data->code_block, voodoo, params, state, depth_op);
@@ -3286,36 +3383,21 @@ voodoo_recomp++;
data->textureMode[1] = params->textureMode[1];
data->tLOD[0] = params->tLOD[0] & LOD_MASK;
data->tLOD[1] = params->tLOD[1] & LOD_MASK;
data->is_tiled = (params->col_tiled || params->aux_tiled) ? 1 : 0;
next_block_to_write[odd_even] = (next_block_to_write[odd_even] + 1) & 7;
return data->code_block;
}
static void voodoo_codegen_init(voodoo_t *voodoo)
void voodoo_codegen_init(voodoo_t *voodoo)
{
int c;
#ifdef __linux__
void *start;
size_t len;
long pagesize = sysconf(_SC_PAGESIZE);
long pagemask = ~(pagesize - 1);
#endif
#if WIN64
voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM * 2, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM * 4, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#else
voodoo->codegen_data = malloc(sizeof(voodoo_x86_data_t) * BLOCK_NUM * 2);
#endif
#ifdef __linux__
start = (void *)((long)voodoo->codegen_data & pagemask);
len = ((sizeof(voodoo_x86_data_t) * BLOCK_NUM * 2) + pagesize) & pagemask;
if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
{
perror("mprotect");
exit(-1);
}
voodoo->codegen_data = mmap(0, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0);
#endif
for (c = 0; c < 256; c++)
@@ -3340,12 +3422,12 @@ static void voodoo_codegen_init(voodoo_t *voodoo)
xmm_00_ff_w[1] = _mm_set_epi32(0, 0, 0xff | (0xff << 16), 0xff | (0xff << 16));
}
static void voodoo_codegen_close(voodoo_t *voodoo)
void voodoo_codegen_close(voodoo_t *voodoo)
{
#if WIN64
VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE);
#else
free(voodoo->codegen_data);
munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4);
#endif
}

View File

@@ -5,15 +5,16 @@
fbzColorPath
*/
#ifdef __linux__
# include <sys/mman.h>
# include <unistd.h>
#if defined(__linux__) || defined(__APPLE__)
#include <sys/mman.h>
#include <unistd.h>
#endif
#if defined WIN32 || defined _WIN32 || defined _WIN32
# include <windows.h>
#define BITMAP windows_BITMAP
#include <windows.h>
#undef BITMAP
#endif
#include <intrin.h>
#include <xmmintrin.h>
#define BLOCK_NUM 8
@@ -32,35 +33,43 @@ typedef struct voodoo_x86_data_t
uint32_t fbzColorPath;
uint32_t textureMode[2];
uint32_t tLOD[2];
uint32_t trexInit1;
uint32_t trexInit1;
int is_tiled;
} voodoo_x86_data_t;
static int last_block[2] = {0, 0};
static int next_block_to_write[2] = {0, 0};
static int last_block[4] = {0, 0};
static int next_block_to_write[4] = {0, 0};
#define addbyte(val) \
if (block_pos < BLOCK_SIZE) \
code_block[block_pos++] = val; \
if (block_pos >= BLOCK_SIZE) \
fatal("Over!\n")
#define addbyte(val) \
do { \
code_block[block_pos++] = val; \
if (block_pos >= BLOCK_SIZE) \
fatal("Over!\n"); \
} while (0)
#define addword(val) \
*(uint16_t *)&code_block[block_pos] = val; \
block_pos += 2; \
if (block_pos >= BLOCK_SIZE) \
fatal("Over!\n")
#define addword(val) \
do { \
*(uint16_t *)&code_block[block_pos] = val; \
block_pos += 2; \
if (block_pos >= BLOCK_SIZE) \
fatal("Over!\n"); \
} while (0)
#define addlong(val) \
*(uint32_t *)&code_block[block_pos] = val; \
block_pos += 4; \
if (block_pos >= BLOCK_SIZE) \
fatal("Over!\n")
#define addlong(val) \
do { \
*(uint32_t *)&code_block[block_pos] = val; \
block_pos += 4; \
if (block_pos >= BLOCK_SIZE) \
fatal("Over!\n"); \
} while (0)
#define addquad(val) \
*(uint64_t *)&code_block[block_pos] = val; \
block_pos += 8; \
if (block_pos >= BLOCK_SIZE) \
fatal("Over!\n")
#define addquad(val) \
do { \
*(uint64_t *)&code_block[block_pos] = val; \
block_pos += 8; \
if (block_pos >= BLOCK_SIZE) \
fatal("Over!\n"); \
} while (0)
static __m128i xmm_01_w;// = 0x0001000100010001ull;
@@ -694,6 +703,28 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
addbyte(0x74);
addbyte(0x24);
addbyte(8+16);
if (params->col_tiled || params->aux_tiled)
{
addbyte(0x8b); /*MOV EAX, state->x[EDI]*/
addbyte(0x87);
addlong(offsetof(voodoo_state_t, x));
addbyte(0x89); /*MOV EBX, EAX*/
addbyte(0xc3);
addbyte(0x83); /*AND EAX, 63*/
addbyte(0xe0);
addbyte(63);
addbyte(0xc1); /*SHR EBX, 6*/
addbyte(0xeb);
addbyte(6);
addbyte(0xc1); /*SHL EBX, 11 - tile is 128*32, << 12, div 2 because word index*/
addbyte(0xe3);
addbyte(11);
addbyte(0x01); /*ADD EAX, EBX*/
addbyte(0xd8);
addbyte(0x89); /*MOV state->x_tiled[EDI], EAX*/
addbyte(0x87);
addlong(offsetof(voodoo_state_t, x_tiled));
}
addbyte(0x66); /*PXOR XMM2, XMM2*/
addbyte(0x0f);
addbyte(0xef);
@@ -826,7 +857,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
{
addbyte(0x8b); /*MOV EBX, state->x[EDI]*/
addbyte(0x9f);
addlong(offsetof(voodoo_state_t, x));
if (voodoo->aux_tiled)
addlong(offsetof(voodoo_state_t, x_tiled));
else
addlong(offsetof(voodoo_state_t, x));
addbyte(0x8b);/*MOV ECX, aux_mem[EDI]*/
addbyte(0x8f);
addlong(offsetof(voodoo_state_t, aux_mem));
@@ -2436,7 +2470,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
{
addbyte(0x8b); /*MOV EAX, state->x[EDI]*/
addbyte(0x87);
addlong(offsetof(voodoo_state_t, x));
if (params->col_tiled)
addlong(offsetof(voodoo_state_t, x_tiled));
else
addlong(offsetof(voodoo_state_t, x));
addbyte(0x8b); /*MOV EBP, fb_mem*/
addbyte(0xaf);
addlong(offsetof(voodoo_state_t, fb_mem));
@@ -2815,8 +2852,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
addbyte(0x8b); /*MOV EDX, state->x[EDI]*/
addbyte(0x97);
addlong(offsetof(voodoo_state_t, x));
if (params->col_tiled)
addlong(offsetof(voodoo_state_t, x_tiled));
else
addlong(offsetof(voodoo_state_t, x));
addbyte(0x66); /*MOV EAX, XMM0*/
addbyte(0x0f);
addbyte(0x7e);
@@ -2884,7 +2924,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
}
addbyte(0x8b); /*MOV EDX, state->x[EDI]*/
addbyte(0x97);
addlong(offsetof(voodoo_state_t, x));
if (params->col_tiled)
addlong(offsetof(voodoo_state_t, x_tiled));
else
addlong(offsetof(voodoo_state_t, x));
if (dither2x2)
{
addbyte(0xc1); /*SHL ECX, 2*/
@@ -2968,6 +3011,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE))
{
addbyte(0x8b); /*MOV EDX, state->x[EDI]*/
addbyte(0x97);
if (params->aux_tiled)
addlong(offsetof(voodoo_state_t, x_tiled));
else
addlong(offsetof(voodoo_state_t, x));
addbyte(0x66); /*MOV AX, new_depth*/
addbyte(0x8b);
addbyte(0x87);
@@ -3227,7 +3276,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
if (params->textureMode[1] & TEXTUREMODE_TRILINEAR)
cs = cs;
}
static int voodoo_recomp = 0;
int voodoo_recomp = 0;
static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int odd_even)
{
@@ -3238,7 +3287,7 @@ static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params,
for (c = 0; c < 8; c++)
{
data = &codegen_data[odd_even + b*2];
data = &codegen_data[odd_even + b*4];
if (state->xdir == data->xdir &&
params->alphaMode == data->alphaMode &&
@@ -3249,7 +3298,8 @@ static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params,
params->textureMode[0] == data->textureMode[0] &&
params->textureMode[1] == data->textureMode[1] &&
(params->tLOD[0] & LOD_MASK) == data->tLOD[0] &&
(params->tLOD[1] & LOD_MASK) == data->tLOD[1])
(params->tLOD[1] & LOD_MASK) == data->tLOD[1] &&
((params->col_tiled || params->aux_tiled) ? 1 : 0) == data->is_tiled)
{
last_block[odd_even] = b;
return data->code_block;
@@ -3258,7 +3308,7 @@ static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params,
b = (b + 1) & 7;
}
voodoo_recomp++;
data = &codegen_data[odd_even + next_block_to_write[odd_even]*2];
data = &codegen_data[odd_even + next_block_to_write[odd_even]*4];
// code_block = data->code_block;
voodoo_generate(data->code_block, voodoo, params, state, depth_op);
@@ -3273,16 +3323,17 @@ voodoo_recomp++;
data->textureMode[1] = params->textureMode[1];
data->tLOD[0] = params->tLOD[0] & LOD_MASK;
data->tLOD[1] = params->tLOD[1] & LOD_MASK;
data->is_tiled = (params->col_tiled || params->aux_tiled) ? 1 : 0;
next_block_to_write[odd_even] = (next_block_to_write[odd_even] + 1) & 7;
return data->code_block;
}
static void voodoo_codegen_init(voodoo_t *voodoo)
void voodoo_codegen_init(voodoo_t *voodoo)
{
int c;
#ifdef __linux__
#if defined(__linux__) || defined(__APPLE__)
void *start;
size_t len;
long pagesize = sysconf(_SC_PAGESIZE);
@@ -3290,19 +3341,9 @@ static void voodoo_codegen_init(voodoo_t *voodoo)
#endif
#if defined WIN32 || defined _WIN32 || defined _WIN32
voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM*2, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#else
voodoo->codegen_data = malloc(sizeof(voodoo_x86_data_t) * BLOCK_NUM*2);
#endif
#ifdef __linux__
start = (void *)((long)voodoo->codegen_data & pagemask);
len = ((sizeof(voodoo_x86_data_t) * BLOCK_NUM*2) + pagesize) & pagemask;
if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
{
perror("mprotect");
exit(-1);
}
voodoo->codegen_data = mmap(0, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0);
#endif
for (c = 0; c < 256; c++)
@@ -3327,11 +3368,11 @@ static void voodoo_codegen_init(voodoo_t *voodoo)
xmm_00_ff_w[1] = _mm_set_epi32(0, 0, 0xff | (0xff << 16), 0xff | (0xff << 16));
}
static void voodoo_codegen_close(voodoo_t *voodoo)
void voodoo_codegen_close(voodoo_t *voodoo)
{
#if defined WIN32 || defined _WIN32 || defined _WIN32
VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE);
#else
free(voodoo->codegen_data);
munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4);
#endif
}

View File

@@ -0,0 +1,516 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Voodoo Graphics, 2, Banshee, 3 emulation.
*
*
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* leilei
*
* Copyright 2008-2020 Sarah Walker.
*/
#ifdef CLAMP
#undef CLAMP
#endif
#define CLAMP(x) (((x) < 0) ? 0 : (((x) > 0xff) ? 0xff : (x)))
#define CLAMP16(x) (((x) < 0) ? 0 : (((x) > 0xffff) ? 0xffff : (x)))
#define LOD_MAX 8
#define TEX_DIRTY_SHIFT 10
#define TEX_CACHE_MAX 64
enum
{
VOODOO_1 = 0,
VOODOO_SB50,
VOODOO_2,
VOODOO_BANSHEE,
VOODOO_3
};
typedef union int_float
{
uint32_t i;
float f;
} int_float;
typedef struct rgbvoodoo_t
{
uint8_t b, g, r;
uint8_t pad;
} rgbvoodoo_t;
typedef struct rgba8_t
{
uint8_t b, g, r, a;
} rgba8_t;
typedef union rgba_u
{
struct
{
uint8_t b, g, r, a;
} rgba;
uint32_t u;
} rgba_u;
#define FIFO_SIZE 65536
#define FIFO_MASK (FIFO_SIZE - 1)
#define FIFO_ENTRY_SIZE (1 << 31)
#define FIFO_ENTRIES (voodoo->fifo_write_idx - voodoo->fifo_read_idx)
#define FIFO_FULL ((voodoo->fifo_write_idx - voodoo->fifo_read_idx) >= FIFO_SIZE-4)
#define FIFO_EMPTY (voodoo->fifo_read_idx == voodoo->fifo_write_idx)
#define FIFO_TYPE 0xff000000
#define FIFO_ADDR 0x00ffffff
enum
{
FIFO_INVALID = (0x00 << 24),
FIFO_WRITEL_REG = (0x01 << 24),
FIFO_WRITEW_FB = (0x02 << 24),
FIFO_WRITEL_FB = (0x03 << 24),
FIFO_WRITEL_TEX = (0x04 << 24),
FIFO_WRITEL_2DREG = (0x05 << 24)
};
#define PARAM_SIZE 1024
#define PARAM_MASK (PARAM_SIZE - 1)
#define PARAM_ENTRY_SIZE (1 << 31)
#define PARAM_ENTRIES(x) (voodoo->params_write_idx - voodoo->params_read_idx[x])
#define PARAM_FULL(x) ((voodoo->params_write_idx - voodoo->params_read_idx[x]) >= PARAM_SIZE)
#define PARAM_EMPTY(x) (voodoo->params_read_idx[x] == voodoo->params_write_idx)
typedef struct
{
uint32_t addr_type;
uint32_t val;
} fifo_entry_t;
typedef struct voodoo_params_t
{
int command;
int32_t vertexAx, vertexAy, vertexBx, vertexBy, vertexCx, vertexCy;
uint32_t startR, startG, startB, startZ, startA;
int32_t dBdX, dGdX, dRdX, dAdX, dZdX;
int32_t dBdY, dGdY, dRdY, dAdY, dZdY;
int64_t startW, dWdX, dWdY;
struct
{
int64_t startS, startT, startW, p1;
int64_t dSdX, dTdX, dWdX, p2;
int64_t dSdY, dTdY, dWdY, p3;
} tmu[2];
uint32_t color0, color1;
uint32_t fbzMode;
uint32_t fbzColorPath;
uint32_t fogMode;
rgbvoodoo_t fogColor;
struct
{
uint8_t fog, dfog;
} fogTable[64];
uint32_t alphaMode;
uint32_t zaColor;
int chromaKey_r, chromaKey_g, chromaKey_b;
uint32_t chromaKey;
uint32_t textureMode[2];
uint32_t tLOD[2];
uint32_t texBaseAddr[2], texBaseAddr1[2], texBaseAddr2[2], texBaseAddr38[2];
uint32_t tex_base[2][LOD_MAX+2];
uint32_t tex_end[2][LOD_MAX+2];
int tex_width[2];
int tex_w_mask[2][LOD_MAX+2];
int tex_w_nmask[2][LOD_MAX+2];
int tex_h_mask[2][LOD_MAX+2];
int tex_shift[2][LOD_MAX+2];
int tex_lod[2][LOD_MAX+2];
int tex_entry[2];
int detail_max[2], detail_bias[2], detail_scale[2];
uint32_t draw_offset, aux_offset;
int tformat[2];
int clipLeft, clipRight, clipLowY, clipHighY;
int clipLeft1, clipRight1, clipLowY1, clipHighY1;
int sign;
uint32_t front_offset;
uint32_t swapbufferCMD;
uint32_t stipple;
int col_tiled, aux_tiled;
int row_width, aux_row_width;
} voodoo_params_t;
typedef struct texture_t
{
uint32_t base;
uint32_t tLOD;
volatile int refcount, refcount_r[4];
int is16;
uint32_t palette_checksum;
uint32_t addr_start[4], addr_end[4];
uint32_t *data;
} texture_t;
typedef struct vert_t
{
float sVx, sVy;
float sRed, sGreen, sBlue, sAlpha;
float sVz, sWb;
float sW0, sS0, sT0;
float sW1, sS1, sT1;
} vert_t;
typedef struct clip_t
{
int x_min, x_max;
int y_min, y_max;
} clip_t;
typedef struct voodoo_t
{
mem_mapping_t mapping;
int pci_enable;
uint8_t dac_data[8];
int dac_reg, dac_reg_ff;
uint8_t dac_readdata;
uint16_t dac_pll_regs[16];
float pixel_clock;
uint64_t line_time;
voodoo_params_t params;
uint32_t fbiInit0, fbiInit1, fbiInit2, fbiInit3, fbiInit4;
uint32_t fbiInit5, fbiInit6, fbiInit7; /*Voodoo 2*/
uint32_t initEnable;
uint32_t lfbMode;
uint32_t memBaseAddr;
int_float fvertexAx, fvertexAy, fvertexBx, fvertexBy, fvertexCx, fvertexCy;
uint32_t front_offset, back_offset;
uint32_t fb_read_offset, fb_write_offset;
int row_width, aux_row_width;
int block_width;
int col_tiled, aux_tiled;
uint8_t *fb_mem, *tex_mem[2];
uint16_t *tex_mem_w[2];
int rgb_sel;
uint32_t trexInit1[2];
uint32_t tmuConfig;
mutex_t *swap_mutex;
int swap_count;
int disp_buffer, draw_buffer;
pc_timer_t timer;
int line;
svga_t *svga;
uint32_t backPorch;
uint32_t videoDimensions;
uint32_t hSync, vSync;
int h_total, v_total, v_disp;
int h_disp;
int v_retrace;
struct
{
uint32_t y[4], i[4], q[4];
} nccTable[2][2];
rgba_u palette[2][256];
rgba_u ncc_lookup[2][2][256];
int ncc_dirty[2];
thread_t *fifo_thread;
thread_t *render_thread[4];
event_t *wake_fifo_thread;
event_t *wake_main_thread;
event_t *fifo_not_full_event;
event_t *render_not_full_event[4];
event_t *wake_render_thread[4];
int voodoo_busy;
int render_voodoo_busy[4];
int render_threads;
int odd_even_mask;
int pixel_count[4], texel_count[4], tri_count, frame_count;
int pixel_count_old[4], texel_count_old[4];
int wr_count, rd_count, tex_count;
int retrace_count;
int swap_interval;
uint32_t swap_offset;
int swap_pending;
int bilinear_enabled;
int fb_size;
uint32_t fb_mask;
int texture_size;
uint32_t texture_mask;
int dual_tmus;
int type;
fifo_entry_t fifo[FIFO_SIZE];
volatile int fifo_read_idx, fifo_write_idx;
volatile int cmd_read, cmd_written, cmd_written_fifo;
voodoo_params_t params_buffer[PARAM_SIZE];
volatile int params_read_idx[4], params_write_idx;
uint32_t cmdfifo_base, cmdfifo_end, cmdfifo_size;
int cmdfifo_rp;
volatile int cmdfifo_depth_rd, cmdfifo_depth_wr;
volatile int cmdfifo_enabled;
uint32_t cmdfifo_amin, cmdfifo_amax;
int cmdfifo_holecount;
uint32_t sSetupMode;
vert_t verts[4];
unsigned int vertex_ages[3];
unsigned int vertex_next_age;
int num_verticies;
int cull_pingpong;
int flush;
int scrfilter;
int scrfilterEnabled;
int scrfilterThreshold;
int scrfilterThresholdOld;
uint32_t last_write_addr;
uint32_t fbiPixelsIn;
uint32_t fbiChromaFail;
uint32_t fbiZFuncFail;
uint32_t fbiAFuncFail;
uint32_t fbiPixelsOut;
uint32_t bltSrcBaseAddr;
uint32_t bltDstBaseAddr;
int bltSrcXYStride, bltDstXYStride;
uint32_t bltSrcChromaRange, bltDstChromaRange;
int bltSrcChromaMinR, bltSrcChromaMinG, bltSrcChromaMinB;
int bltSrcChromaMaxR, bltSrcChromaMaxG, bltSrcChromaMaxB;
int bltDstChromaMinR, bltDstChromaMinG, bltDstChromaMinB;
int bltDstChromaMaxR, bltDstChromaMaxG, bltDstChromaMaxB;
int bltClipRight, bltClipLeft;
int bltClipHighY, bltClipLowY;
int bltSrcX, bltSrcY;
int bltDstX, bltDstY;
int bltSizeX, bltSizeY;
int bltRop[4];
uint16_t bltColorFg, bltColorBg;
uint32_t bltCommand;
uint32_t leftOverlayBuf;
struct
{
int dst_x, dst_y;
int cur_x;
int size_x, size_y;
int x_dir, y_dir;
int dst_stride;
} blt;
struct
{
uint32_t bresError0, bresError1;
uint32_t clip0Min, clip0Max;
uint32_t clip1Min, clip1Max;
uint32_t colorBack, colorFore;
uint32_t command, commandExtra;
uint32_t dstBaseAddr;
uint32_t dstFormat;
uint32_t dstSize;
uint32_t dstXY;
uint32_t rop;
uint32_t srcBaseAddr;
uint32_t srcFormat;
uint32_t srcSize;
uint32_t srcXY;
uint32_t colorPattern[64];
int bres_error_0, bres_error_1;
uint32_t colorPattern8[64], colorPattern16[64], colorPattern24[64];
int cur_x, cur_y;
uint32_t dstBaseAddr_tiled;
uint32_t dstColorkeyMin, dstColorkeyMax;
int dstSizeX, dstSizeY;
int dstX, dstY;
int dst_stride;
int patoff_x, patoff_y;
uint8_t rops[4];
uint32_t srcBaseAddr_tiled;
uint32_t srcColorkeyMin, srcColorkeyMax;
int srcSizeX, srcSizeY;
int srcX, srcY;
int src_stride;
int old_srcX;
/*Used for handling packed 24bpp host data*/
int host_data_remainder;
uint32_t old_host_data;
/*Polyfill coordinates*/
int lx[2], rx[2];
int ly[2], ry[2];
/*Polyfill state*/
int error[2];
int dx[2], dy[2];
int x_inc[2]; /*y_inc is always 1 for polyfill*/
int lx_cur, rx_cur;
clip_t clip[2];
uint8_t host_data[16384];
int host_data_count;
int host_data_size_src, host_data_size_dest;
int src_stride_src, src_stride_dest;
int src_bpp;
} banshee_blt;
struct
{
uint32_t vidOverlayStartCoords;
uint32_t vidOverlayEndScreenCoords;
uint32_t vidOverlayDudx, vidOverlayDudxOffsetSrcWidth;
uint32_t vidOverlayDvdy, vidOverlayDvdyOffset;
//uint32_t vidDesktopOverlayStride;
int start_x, start_y;
int end_x, end_y;
int size_x, size_y;
int overlay_bytes;
unsigned int src_y;
} overlay;
rgbvoodoo_t clutData[33];
int clutData_dirty;
rgbvoodoo_t clutData256[256];
uint32_t video_16to32[0x10000];
uint8_t dirty_line[2048];
int dirty_line_low, dirty_line_high;
int fb_write_buffer, fb_draw_buffer;
int buffer_cutoff;
uint32_t tile_base, tile_stride;
int tile_stride_shift, tile_x, tile_x_real;
int read_time, write_time, burst_time;
pc_timer_t wake_timer;
/* screen filter tables */
uint8_t thefilter[256][256];
uint8_t thefilterg[256][256];
uint8_t thefilterb[256][256];
uint16_t purpleline[256][3];
texture_t texture_cache[2][TEX_CACHE_MAX];
uint8_t texture_present[2][16384];
int texture_last_removed;
uint32_t palette_checksum[2];
int palette_dirty[2];
uint64_t time;
int render_time[4];
int use_recompiler;
void *codegen_data;
struct voodoo_set_t *set;
uint8_t *vram, *changedvram;
void *p;
} voodoo_t;
typedef struct voodoo_set_t
{
voodoo_t *voodoos[2];
mem_mapping_t snoop_mapping;
int nr_cards;
} voodoo_set_t;
extern rgba8_t rgb332[0x100], ai44[0x100], rgb565[0x10000], argb1555[0x10000], argb4444[0x10000], ai88[0x10000];
void voodoo_generate_vb_filters(voodoo_t *voodoo, int fcr, int fcg);
void voodoo_recalc(voodoo_t *voodoo);
void voodoo_update_ncc(voodoo_t *voodoo, int tmu);
void *voodoo_2d3d_card_init(int type);
void voodoo_card_close(voodoo_t *voodoo);

View File

@@ -0,0 +1,24 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Voodoo Graphics, 2, Banshee, 3 emulation.
*
*
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* leilei
*
* Copyright 2008-2020 Sarah Walker.
*/
void voodoo_update_ncc(voodoo_t *voodoo, int tmu);
void voodoo_pixelclock_update(voodoo_t *voodoo);
void voodoo_generate_filter_v1(voodoo_t *voodoo);
void voodoo_generate_filter_v2(voodoo_t *voodoo);
void voodoo_threshold_check(voodoo_t *voodoo);
void voodoo_callback(void *p);

View File

@@ -1,4 +1,22 @@
uint8_t dither_rb[256][4][4] =
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Voodoo Graphics and 2 specific emulation.
*
*
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* leilei
*
* Copyright 2008-2020 Sarah Walker.
*/
static const uint8_t dither_rb[256][4][4] =
{
{
{0, 0, 0, 0},
@@ -1538,7 +1556,7 @@ uint8_t dither_rb[256][4][4] =
},
};
uint8_t dither_g[256][4][4] =
static const uint8_t dither_g[256][4][4] =
{
{
{0, 0, 0, 0},
@@ -3078,7 +3096,7 @@ uint8_t dither_g[256][4][4] =
},
};
uint8_t dither_rb2x2[256][2][2] =
static const uint8_t dither_rb2x2[256][2][2] =
{
{
{0, 0},
@@ -4106,7 +4124,7 @@ uint8_t dither_rb2x2[256][2][2] =
},
};
uint8_t dither_g2x2[256][2][2] =
static const uint8_t dither_g2x2[256][2][2] =
{
{
{0, 0},

View File

@@ -0,0 +1,22 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Voodoo Graphics, 2, Banshee, 3 emulation.
*
*
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* leilei
*
* Copyright 2008-2020 Sarah Walker.
*/
uint16_t voodoo_fb_readw(uint32_t addr, void *p);
uint32_t voodoo_fb_readl(uint32_t addr, void *p);
void voodoo_fb_writew(uint32_t addr, uint16_t val, void *p);
void voodoo_fb_writel(uint32_t addr, uint32_t val, void *p);

View File

@@ -0,0 +1,26 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Voodoo Graphics, 2, Banshee, 3 emulation.
*
*
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* leilei
*
* Copyright 2008-2020 Sarah Walker.
*/
void voodoo_wake_fifo_thread(voodoo_t *voodoo);
void voodoo_wake_fifo_thread_now(voodoo_t *voodoo);
void voodoo_wake_timer(void *p);
void voodoo_queue_command(voodoo_t *voodoo, uint32_t addr_type, uint32_t val);
void voodoo_flush(voodoo_t *voodoo);
void voodoo_wake_fifo_threads(voodoo_set_t *set, voodoo_t *voodoo);
void voodoo_wait_for_swap_complete(voodoo_t *voodoo);
void voodoo_fifo_thread(void *param);

View File

@@ -0,0 +1,19 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Voodoo Graphics, 2, Banshee, 3 emulation.
*
*
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* leilei
*
* Copyright 2008-2020 Sarah Walker.
*/
void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p);

View File

@@ -0,0 +1,691 @@
enum
{
SST_status = 0x000,
SST_intrCtrl = 0x004,
SST_vertexAx = 0x008,
SST_vertexAy = 0x00c,
SST_vertexBx = 0x010,
SST_vertexBy = 0x014,
SST_vertexCx = 0x018,
SST_vertexCy = 0x01c,
SST_startR = 0x0020,
SST_startG = 0x0024,
SST_startB = 0x0028,
SST_startZ = 0x002c,
SST_startA = 0x0030,
SST_startS = 0x0034,
SST_startT = 0x0038,
SST_startW = 0x003c,
SST_dRdX = 0x0040,
SST_dGdX = 0x0044,
SST_dBdX = 0x0048,
SST_dZdX = 0x004c,
SST_dAdX = 0x0050,
SST_dSdX = 0x0054,
SST_dTdX = 0x0058,
SST_dWdX = 0x005c,
SST_dRdY = 0x0060,
SST_dGdY = 0x0064,
SST_dBdY = 0x0068,
SST_dZdY = 0x006c,
SST_dAdY = 0x0070,
SST_dSdY = 0x0074,
SST_dTdY = 0x0078,
SST_dWdY = 0x007c,
SST_triangleCMD = 0x0080,
SST_fvertexAx = 0x088,
SST_fvertexAy = 0x08c,
SST_fvertexBx = 0x090,
SST_fvertexBy = 0x094,
SST_fvertexCx = 0x098,
SST_fvertexCy = 0x09c,
SST_fstartR = 0x00a0,
SST_fstartG = 0x00a4,
SST_fstartB = 0x00a8,
SST_fstartZ = 0x00ac,
SST_fstartA = 0x00b0,
SST_fstartS = 0x00b4,
SST_fstartT = 0x00b8,
SST_fstartW = 0x00bc,
SST_fdRdX = 0x00c0,
SST_fdGdX = 0x00c4,
SST_fdBdX = 0x00c8,
SST_fdZdX = 0x00cc,
SST_fdAdX = 0x00d0,
SST_fdSdX = 0x00d4,
SST_fdTdX = 0x00d8,
SST_fdWdX = 0x00dc,
SST_fdRdY = 0x00e0,
SST_fdGdY = 0x00e4,
SST_fdBdY = 0x00e8,
SST_fdZdY = 0x00ec,
SST_fdAdY = 0x00f0,
SST_fdSdY = 0x00f4,
SST_fdTdY = 0x00f8,
SST_fdWdY = 0x00fc,
SST_ftriangleCMD = 0x0100,
SST_fbzColorPath = 0x104,
SST_fogMode = 0x108,
SST_alphaMode = 0x10c,
SST_fbzMode = 0x110,
SST_lfbMode = 0x114,
SST_clipLeftRight = 0x118,
SST_clipLowYHighY = 0x11c,
SST_nopCMD = 0x120,
SST_fastfillCMD = 0x124,
SST_swapbufferCMD = 0x128,
SST_fogColor = 0x12c,
SST_zaColor = 0x130,
SST_chromaKey = 0x134,
SST_userIntrCMD = 0x13c,
SST_stipple = 0x140,
SST_color0 = 0x144,
SST_color1 = 0x148,
SST_fbiPixelsIn = 0x14c,
SST_fbiChromaFail = 0x150,
SST_fbiZFuncFail = 0x154,
SST_fbiAFuncFail = 0x158,
SST_fbiPixelsOut = 0x15c,
SST_fogTable00 = 0x160,
SST_fogTable01 = 0x164,
SST_fogTable02 = 0x168,
SST_fogTable03 = 0x16c,
SST_fogTable04 = 0x170,
SST_fogTable05 = 0x174,
SST_fogTable06 = 0x178,
SST_fogTable07 = 0x17c,
SST_fogTable08 = 0x180,
SST_fogTable09 = 0x184,
SST_fogTable0a = 0x188,
SST_fogTable0b = 0x18c,
SST_fogTable0c = 0x190,
SST_fogTable0d = 0x194,
SST_fogTable0e = 0x198,
SST_fogTable0f = 0x19c,
SST_fogTable10 = 0x1a0,
SST_fogTable11 = 0x1a4,
SST_fogTable12 = 0x1a8,
SST_fogTable13 = 0x1ac,
SST_fogTable14 = 0x1b0,
SST_fogTable15 = 0x1b4,
SST_fogTable16 = 0x1b8,
SST_fogTable17 = 0x1bc,
SST_fogTable18 = 0x1c0,
SST_fogTable19 = 0x1c4,
SST_fogTable1a = 0x1c8,
SST_fogTable1b = 0x1cc,
SST_fogTable1c = 0x1d0,
SST_fogTable1d = 0x1d4,
SST_fogTable1e = 0x1d8,
SST_fogTable1f = 0x1dc,
SST_cmdFifoBaseAddr = 0x1e0,
SST_cmdFifoBump = 0x1e4,
SST_cmdFifoRdPtr = 0x1e8,
SST_cmdFifoAMin = 0x1ec,
SST_cmdFifoAMax = 0x1f0,
SST_cmdFifoDepth = 0x1f4,
SST_cmdFifoHoles = 0x1f8,
SST_colBufferAddr = 0x1ec, /*Banshee*/
SST_colBufferStride = 0x1f0, /*Banshee*/
SST_auxBufferAddr = 0x1f4, /*Banshee*/
SST_auxBufferStride = 0x1f8, /*Banshee*/
SST_clipLeftRight1 = 0x200, /*Banshee*/
SST_clipTopBottom1 = 0x204, /*Banshee*/
SST_fbiInit4 = 0x200,
SST_vRetrace = 0x204,
SST_backPorch = 0x208,
SST_videoDimensions = 0x20c,
SST_fbiInit0 = 0x210,
SST_fbiInit1 = 0x214,
SST_fbiInit2 = 0x218,
SST_fbiInit3 = 0x21c,
SST_hSync = 0x220,
SST_vSync = 0x224,
SST_clutData = 0x228,
SST_dacData = 0x22c,
SST_scrFilter = 0x230,
SST_hvRetrace = 0x240,
SST_fbiInit5 = 0x244,
SST_fbiInit6 = 0x248,
SST_fbiInit7 = 0x24c,
SST_swapPending = 0x24c, /*Banshee*/
SST_leftOverlayBuf = 0x250, /*Banshee*/
SST_sSetupMode = 0x260,
SST_sVx = 0x264,
SST_sVy = 0x268,
SST_sARGB = 0x26c,
SST_sRed = 0x270,
SST_sGreen = 0x274,
SST_sBlue = 0x278,
SST_sAlpha = 0x27c,
SST_sVz = 0x280,
SST_sWb = 0x284,
SST_sW0 = 0x288,
SST_sS0 = 0x28c,
SST_sT0 = 0x290,
SST_sW1 = 0x294,
SST_sS1 = 0x298,
SST_sT1 = 0x29c,
SST_sDrawTriCMD = 0x2a0,
SST_sBeginTriCMD = 0x2a4,
SST_bltSrcBaseAddr = 0x2c0,
SST_bltDstBaseAddr = 0x2c4,
SST_bltXYStrides = 0x2c8,
SST_bltSrcChromaRange = 0x2cc,
SST_bltDstChromaRange = 0x2d0,
SST_bltClipX = 0x2d4,
SST_bltClipY = 0x2d8,
SST_bltSrcXY = 0x2e0,
SST_bltDstXY = 0x2e4,
SST_bltSize = 0x2e8,
SST_bltRop = 0x2ec,
SST_bltColor = 0x2f0,
SST_bltCommand = 0x2f8,
SST_bltData = 0x2fc,
SST_textureMode = 0x300,
SST_tLOD = 0x304,
SST_tDetail = 0x308,
SST_texBaseAddr = 0x30c,
SST_texBaseAddr1 = 0x310,
SST_texBaseAddr2 = 0x314,
SST_texBaseAddr38 = 0x318,
SST_trexInit1 = 0x320,
SST_nccTable0_Y0 = 0x324,
SST_nccTable0_Y1 = 0x328,
SST_nccTable0_Y2 = 0x32c,
SST_nccTable0_Y3 = 0x330,
SST_nccTable0_I0 = 0x334,
SST_nccTable0_I1 = 0x338,
SST_nccTable0_I2 = 0x33c,
SST_nccTable0_I3 = 0x340,
SST_nccTable0_Q0 = 0x344,
SST_nccTable0_Q1 = 0x348,
SST_nccTable0_Q2 = 0x34c,
SST_nccTable0_Q3 = 0x350,
SST_nccTable1_Y0 = 0x354,
SST_nccTable1_Y1 = 0x358,
SST_nccTable1_Y2 = 0x35c,
SST_nccTable1_Y3 = 0x360,
SST_nccTable1_I0 = 0x364,
SST_nccTable1_I1 = 0x368,
SST_nccTable1_I2 = 0x36c,
SST_nccTable1_I3 = 0x370,
SST_nccTable1_Q0 = 0x374,
SST_nccTable1_Q1 = 0x378,
SST_nccTable1_Q2 = 0x37c,
SST_nccTable1_Q3 = 0x380,
SST_remap_status = 0x000 | 0x400,
SST_remap_vertexAx = 0x008 | 0x400,
SST_remap_vertexAy = 0x00c | 0x400,
SST_remap_vertexBx = 0x010 | 0x400,
SST_remap_vertexBy = 0x014 | 0x400,
SST_remap_vertexCx = 0x018 | 0x400,
SST_remap_vertexCy = 0x01c | 0x400,
SST_remap_startR = 0x0020 | 0x400,
SST_remap_startG = 0x002c | 0x400,
SST_remap_startB = 0x0038 | 0x400,
SST_remap_startZ = 0x0044 | 0x400,
SST_remap_startA = 0x0050 | 0x400,
SST_remap_startS = 0x005c | 0x400,
SST_remap_startT = 0x0068 | 0x400,
SST_remap_startW = 0x0074 | 0x400,
SST_remap_dRdX = 0x0024 | 0x400,
SST_remap_dGdX = 0x0030 | 0x400,
SST_remap_dBdX = 0x003c | 0x400,
SST_remap_dZdX = 0x0048 | 0x400,
SST_remap_dAdX = 0x0054 | 0x400,
SST_remap_dSdX = 0x0060 | 0x400,
SST_remap_dTdX = 0x006c | 0x400,
SST_remap_dWdX = 0x0078 | 0x400,
SST_remap_dRdY = 0x0028 | 0x400,
SST_remap_dGdY = 0x0034 | 0x400,
SST_remap_dBdY = 0x0040 | 0x400,
SST_remap_dZdY = 0x004c | 0x400,
SST_remap_dAdY = 0x0058 | 0x400,
SST_remap_dSdY = 0x0064 | 0x400,
SST_remap_dTdY = 0x0070 | 0x400,
SST_remap_dWdY = 0x007c | 0x400,
SST_remap_triangleCMD = 0x0080 | 0x400,
SST_remap_fvertexAx = 0x088 | 0x400,
SST_remap_fvertexAy = 0x08c | 0x400,
SST_remap_fvertexBx = 0x090 | 0x400,
SST_remap_fvertexBy = 0x094 | 0x400,
SST_remap_fvertexCx = 0x098 | 0x400,
SST_remap_fvertexCy = 0x09c | 0x400,
SST_remap_fstartR = 0x00a0 | 0x400,
SST_remap_fstartG = 0x00ac | 0x400,
SST_remap_fstartB = 0x00b8 | 0x400,
SST_remap_fstartZ = 0x00c4 | 0x400,
SST_remap_fstartA = 0x00d0 | 0x400,
SST_remap_fstartS = 0x00dc | 0x400,
SST_remap_fstartT = 0x00e8 | 0x400,
SST_remap_fstartW = 0x00f4 | 0x400,
SST_remap_fdRdX = 0x00a4 | 0x400,
SST_remap_fdGdX = 0x00b0 | 0x400,
SST_remap_fdBdX = 0x00bc | 0x400,
SST_remap_fdZdX = 0x00c8 | 0x400,
SST_remap_fdAdX = 0x00d4 | 0x400,
SST_remap_fdSdX = 0x00e0 | 0x400,
SST_remap_fdTdX = 0x00ec | 0x400,
SST_remap_fdWdX = 0x00f8 | 0x400,
SST_remap_fdRdY = 0x00a8 | 0x400,
SST_remap_fdGdY = 0x00b4 | 0x400,
SST_remap_fdBdY = 0x00c0 | 0x400,
SST_remap_fdZdY = 0x00cc | 0x400,
SST_remap_fdAdY = 0x00d8 | 0x400,
SST_remap_fdSdY = 0x00e4 | 0x400,
SST_remap_fdTdY = 0x00f0 | 0x400,
SST_remap_fdWdY = 0x00fc | 0x400,
};
enum
{
LFB_WRITE_FRONT = 0x0000,
LFB_WRITE_BACK = 0x0010,
LFB_WRITE_MASK = 0x0030
};
enum
{
LFB_READ_FRONT = 0x0000,
LFB_READ_BACK = 0x0040,
LFB_READ_AUX = 0x0080,
LFB_READ_MASK = 0x00c0
};
enum
{
LFB_FORMAT_RGB565 = 0,
LFB_FORMAT_RGB555 = 1,
LFB_FORMAT_ARGB1555 = 2,
LFB_FORMAT_ARGB8888 = 5,
LFB_FORMAT_DEPTH = 15,
LFB_FORMAT_MASK = 15
};
enum
{
LFB_WRITE_COLOUR = 1,
LFB_WRITE_DEPTH = 2
};
enum
{
FBZ_CHROMAKEY = (1 << 1),
FBZ_W_BUFFER = (1 << 3),
FBZ_DEPTH_ENABLE = (1 << 4),
FBZ_DITHER = (1 << 8),
FBZ_RGB_WMASK = (1 << 9),
FBZ_DEPTH_WMASK = (1 << 10),
FBZ_DITHER_2x2 = (1 << 11),
FBZ_DRAW_FRONT = 0x0000,
FBZ_DRAW_BACK = 0x4000,
FBZ_DRAW_MASK = 0xc000,
FBZ_DEPTH_BIAS = (1 << 16),
FBZ_DEPTH_SOURCE = (1 << 20),
FBZ_PARAM_ADJUST = (1 << 26)
};
enum
{
TEX_RGB332 = 0x0,
TEX_Y4I2Q2 = 0x1,
TEX_A8 = 0x2,
TEX_I8 = 0x3,
TEX_AI8 = 0x4,
TEX_PAL8 = 0x5,
TEX_APAL8 = 0x6,
TEX_ARGB8332 = 0x8,
TEX_A8Y4I2Q2 = 0x9,
TEX_R5G6B5 = 0xa,
TEX_ARGB1555 = 0xb,
TEX_ARGB4444 = 0xc,
TEX_A8I8 = 0xd,
TEX_APAL88 = 0xe
};
enum
{
TEXTUREMODE_NCC_SEL = (1 << 5),
TEXTUREMODE_TCLAMPS = (1 << 6),
TEXTUREMODE_TCLAMPT = (1 << 7),
TEXTUREMODE_TRILINEAR = (1 << 30)
};
enum
{
FBIINIT0_VGA_PASS = 1,
FBIINIT0_GRAPHICS_RESET = (1 << 1)
};
enum
{
FBIINIT1_MULTI_SST = (1 << 2), /*Voodoo Graphics only*/
FBIINIT1_VIDEO_RESET = (1 << 8),
FBIINIT1_SLI_ENABLE = (1 << 23)
};
enum
{
FBIINIT2_SWAP_ALGORITHM_MASK = (3 << 9)
};
enum
{
FBIINIT2_SWAP_ALGORITHM_DAC_VSYNC = (0 << 9),
FBIINIT2_SWAP_ALGORITHM_DAC_DATA = (1 << 9),
FBIINIT2_SWAP_ALGORITHM_PCI_FIFO_STALL = (2 << 9),
FBIINIT2_SWAP_ALGORITHM_SLI_SYNC = (3 << 9)
};
enum
{
FBIINIT3_REMAP = 1
};
enum
{
FBIINIT5_MULTI_CVG = (1 << 14)
};
enum
{
FBIINIT7_CMDFIFO_ENABLE = (1 << 8)
};
enum
{
CC_LOCALSELECT_ITER_RGB = 0,
CC_LOCALSELECT_TEX = 1,
CC_LOCALSELECT_COLOR1 = 2,
CC_LOCALSELECT_LFB = 3
};
enum
{
CCA_LOCALSELECT_ITER_A = 0,
CCA_LOCALSELECT_COLOR0 = 1,
CCA_LOCALSELECT_ITER_Z = 2
};
enum
{
C_SEL_ITER_RGB = 0,
C_SEL_TEX = 1,
C_SEL_COLOR1 = 2,
C_SEL_LFB = 3
};
enum
{
A_SEL_ITER_A = 0,
A_SEL_TEX = 1,
A_SEL_COLOR1 = 2,
A_SEL_LFB = 3
};
enum
{
CC_MSELECT_ZERO = 0,
CC_MSELECT_CLOCAL = 1,
CC_MSELECT_AOTHER = 2,
CC_MSELECT_ALOCAL = 3,
CC_MSELECT_TEX = 4,
CC_MSELECT_TEXRGB = 5
};
enum
{
CCA_MSELECT_ZERO = 0,
CCA_MSELECT_ALOCAL = 1,
CCA_MSELECT_AOTHER = 2,
CCA_MSELECT_ALOCAL2 = 3,
CCA_MSELECT_TEX = 4
};
enum
{
TC_MSELECT_ZERO = 0,
TC_MSELECT_CLOCAL = 1,
TC_MSELECT_AOTHER = 2,
TC_MSELECT_ALOCAL = 3,
TC_MSELECT_DETAIL = 4,
TC_MSELECT_LOD_FRAC = 5
};
enum
{
TCA_MSELECT_ZERO = 0,
TCA_MSELECT_CLOCAL = 1,
TCA_MSELECT_AOTHER = 2,
TCA_MSELECT_ALOCAL = 3,
TCA_MSELECT_DETAIL = 4,
TCA_MSELECT_LOD_FRAC = 5
};
enum
{
CC_ADD_CLOCAL = 1,
CC_ADD_ALOCAL = 2
};
enum
{
CCA_ADD_CLOCAL = 1,
CCA_ADD_ALOCAL = 2
};
enum
{
AFUNC_AZERO = 0x0,
AFUNC_ASRC_ALPHA = 0x1,
AFUNC_A_COLOR = 0x2,
AFUNC_ADST_ALPHA = 0x3,
AFUNC_AONE = 0x4,
AFUNC_AOMSRC_ALPHA = 0x5,
AFUNC_AOM_COLOR = 0x6,
AFUNC_AOMDST_ALPHA = 0x7,
AFUNC_ASATURATE = 0xf
};
enum
{
AFUNC_ACOLORBEFOREFOG = 0xf
};
enum
{
AFUNC_NEVER = 0,
AFUNC_LESSTHAN = 1,
AFUNC_EQUAL = 2,
AFUNC_LESSTHANEQUAL = 3,
AFUNC_GREATERTHAN = 4,
AFUNC_NOTEQUAL = 5,
AFUNC_GREATERTHANEQUAL = 6,
AFUNC_ALWAYS = 7
};
enum
{
DEPTHOP_NEVER = 0,
DEPTHOP_LESSTHAN = 1,
DEPTHOP_EQUAL = 2,
DEPTHOP_LESSTHANEQUAL = 3,
DEPTHOP_GREATERTHAN = 4,
DEPTHOP_NOTEQUAL = 5,
DEPTHOP_GREATERTHANEQUAL = 6,
DEPTHOP_ALWAYS = 7
};
enum
{
FOG_ENABLE = 0x01,
FOG_ADD = 0x02,
FOG_MULT = 0x04,
FOG_ALPHA = 0x08,
FOG_Z = 0x10,
FOG_W = 0x18,
FOG_CONSTANT = 0x20
};
enum
{
LOD_ODD = (1 << 18),
LOD_SPLIT = (1 << 19),
LOD_S_IS_WIDER = (1 << 20),
LOD_TMULTIBASEADDR = (1 << 24),
LOD_TMIRROR_S = (1 << 28),
LOD_TMIRROR_T = (1 << 29)
};
enum
{
CMD_INVALID = 0,
CMD_DRAWTRIANGLE,
CMD_FASTFILL,
CMD_SWAPBUF
};
enum
{
FBZCP_TEXTURE_ENABLED = (1 << 27)
};
enum
{
BLTCMD_SRC_TILED = (1 << 14),
BLTCMD_DST_TILED = (1 << 15)
};
enum
{
INITENABLE_SLI_MASTER_SLAVE = (1 << 11)
};
enum
{
SETUPMODE_RGB = (1 << 0),
SETUPMODE_ALPHA = (1 << 1),
SETUPMODE_Z = (1 << 2),
SETUPMODE_Wb = (1 << 3),
SETUPMODE_W0 = (1 << 4),
SETUPMODE_S0_T0 = (1 << 5),
SETUPMODE_W1 = (1 << 6),
SETUPMODE_S1_T1 = (1 << 7),
SETUPMODE_STRIP_MODE = (1 << 16),
SETUPMODE_CULLING_ENABLE = (1 << 17),
SETUPMODE_CULLING_SIGN = (1 << 18),
SETUPMODE_DISABLE_PINGPONG = (1 << 19)
};
#define TEXTUREMODE_MASK 0x3ffff000
#define TEXTUREMODE_PASSTHROUGH 0
#define TEXTUREMODE_LOCAL_MASK 0x00643000
#define TEXTUREMODE_LOCAL 0x00241000
#define SLI_ENABLED (voodoo->fbiInit1 & FBIINIT1_SLI_ENABLE)
#define TRIPLE_BUFFER ((voodoo->fbiInit2 & 0x10) || (voodoo->fbiInit5 & 0x600) == 0x400)
#define _rgb_sel ( params->fbzColorPath & 3)
#define a_sel ( (params->fbzColorPath >> 2) & 3)
#define cc_localselect ( params->fbzColorPath & (1 << 4))
#define cca_localselect ( (params->fbzColorPath >> 5) & 3)
#define cc_localselect_override ( params->fbzColorPath & (1 << 7))
#define cc_zero_other ( params->fbzColorPath & (1 << 8))
#define cc_sub_clocal ( params->fbzColorPath & (1 << 9))
#define cc_mselect ( (params->fbzColorPath >> 10) & 7)
#define cc_reverse_blend ( params->fbzColorPath & (1 << 13))
#define cc_add ( (params->fbzColorPath >> 14) & 3)
#define cc_add_alocal ( params->fbzColorPath & (1 << 15))
#define cc_invert_output ( params->fbzColorPath & (1 << 16))
#define cca_zero_other ( params->fbzColorPath & (1 << 17))
#define cca_sub_clocal ( params->fbzColorPath & (1 << 18))
#define cca_mselect ( (params->fbzColorPath >> 19) & 7)
#define cca_reverse_blend ( params->fbzColorPath & (1 << 22))
#define cca_add ( (params->fbzColorPath >> 23) & 3)
#define cca_invert_output ( params->fbzColorPath & (1 << 25))
#define tc_zero_other (params->textureMode[0] & (1 << 12))
#define tc_sub_clocal (params->textureMode[0] & (1 << 13))
#define tc_mselect ((params->textureMode[0] >> 14) & 7)
#define tc_reverse_blend (params->textureMode[0] & (1 << 17))
#define tc_add_clocal (params->textureMode[0] & (1 << 18))
#define tc_add_alocal (params->textureMode[0] & (1 << 19))
#define tc_invert_output (params->textureMode[0] & (1 << 20))
#define tca_zero_other (params->textureMode[0] & (1 << 21))
#define tca_sub_clocal (params->textureMode[0] & (1 << 22))
#define tca_mselect ((params->textureMode[0] >> 23) & 7)
#define tca_reverse_blend (params->textureMode[0] & (1 << 26))
#define tca_add_clocal (params->textureMode[0] & (1 << 27))
#define tca_add_alocal (params->textureMode[0] & (1 << 28))
#define tca_invert_output (params->textureMode[0] & (1 << 29))
#define tc_sub_clocal_1 (params->textureMode[1] & (1 << 13))
#define tc_mselect_1 ((params->textureMode[1] >> 14) & 7)
#define tc_reverse_blend_1 (params->textureMode[1] & (1 << 17))
#define tc_add_clocal_1 (params->textureMode[1] & (1 << 18))
#define tc_add_alocal_1 (params->textureMode[1] & (1 << 19))
#define tca_sub_clocal_1 (params->textureMode[1] & (1 << 22))
#define tca_mselect_1 ((params->textureMode[1] >> 23) & 7)
#define tca_reverse_blend_1 (params->textureMode[1] & (1 << 26))
#define tca_add_clocal_1 (params->textureMode[1] & (1 << 27))
#define tca_add_alocal_1 (params->textureMode[1] & (1 << 28))
#define src_afunc ( (params->alphaMode >> 8) & 0xf)
#define dest_afunc ( (params->alphaMode >> 12) & 0xf)
#define alpha_func ( (params->alphaMode >> 1) & 7)
#define a_ref ( params->alphaMode >> 24)
#define depth_op ( (params->fbzMode >> 5) & 7)
#define dither ( params->fbzMode & FBZ_DITHER)
#define dither2x2 (params->fbzMode & FBZ_DITHER_2x2)

View File

@@ -0,0 +1,338 @@
#if !(defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32) && !(defined __amd64__)
#define NO_CODEGEN
#endif
#ifndef NO_CODEGEN
void voodoo_codegen_init(voodoo_t *voodoo);
void voodoo_codegen_close(voodoo_t *voodoo);
#endif
#define DEPTH_TEST(comp_depth) \
do \
{ \
switch (depth_op) \
{ \
case DEPTHOP_NEVER: \
voodoo->fbiZFuncFail++; \
goto skip_pixel; \
case DEPTHOP_LESSTHAN: \
if (!(comp_depth < old_depth)) \
{ \
voodoo->fbiZFuncFail++; \
goto skip_pixel; \
} \
break; \
case DEPTHOP_EQUAL: \
if (!(comp_depth == old_depth)) \
{ \
voodoo->fbiZFuncFail++; \
goto skip_pixel; \
} \
break; \
case DEPTHOP_LESSTHANEQUAL: \
if (!(comp_depth <= old_depth)) \
{ \
voodoo->fbiZFuncFail++; \
goto skip_pixel; \
} \
break; \
case DEPTHOP_GREATERTHAN: \
if (!(comp_depth > old_depth)) \
{ \
voodoo->fbiZFuncFail++; \
goto skip_pixel; \
} \
break; \
case DEPTHOP_NOTEQUAL: \
if (!(comp_depth != old_depth)) \
{ \
voodoo->fbiZFuncFail++; \
goto skip_pixel; \
} \
break; \
case DEPTHOP_GREATERTHANEQUAL: \
if (!(comp_depth >= old_depth)) \
{ \
voodoo->fbiZFuncFail++; \
goto skip_pixel; \
} \
break; \
case DEPTHOP_ALWAYS: \
break; \
} \
} while (0)
#define APPLY_FOG(src_r, src_g, src_b, z, ia, w) \
do \
{ \
if (params->fogMode & FOG_CONSTANT) \
{ \
src_r += params->fogColor.r; \
src_g += params->fogColor.g; \
src_b += params->fogColor.b; \
} \
else \
{ \
int fog_r, fog_g, fog_b, fog_a = 0; \
int fog_idx; \
\
if (!(params->fogMode & FOG_ADD)) \
{ \
fog_r = params->fogColor.r; \
fog_g = params->fogColor.g; \
fog_b = params->fogColor.b; \
} \
else \
fog_r = fog_g = fog_b = 0; \
\
if (!(params->fogMode & FOG_MULT)) \
{ \
fog_r -= src_r; \
fog_g -= src_g; \
fog_b -= src_b; \
} \
\
switch (params->fogMode & (FOG_Z|FOG_ALPHA)) \
{ \
case 0: \
fog_idx = (w_depth >> 10) & 0x3f; \
\
fog_a = params->fogTable[fog_idx].fog; \
fog_a += (params->fogTable[fog_idx].dfog * ((w_depth >> 2) & 0xff)) >> 10; \
break; \
case FOG_Z: \
fog_a = (z >> 20) & 0xff; \
break; \
case FOG_ALPHA: \
fog_a = CLAMP(ia >> 12); \
break; \
case FOG_W: \
fog_a = CLAMP((w >> 32) & 0xff); \
break; \
} \
fog_a++; \
\
fog_r = (fog_r * fog_a) >> 8; \
fog_g = (fog_g * fog_a) >> 8; \
fog_b = (fog_b * fog_a) >> 8; \
\
if (params->fogMode & FOG_MULT) \
{ \
src_r = fog_r; \
src_g = fog_g; \
src_b = fog_b; \
} \
else \
{ \
src_r += fog_r; \
src_g += fog_g; \
src_b += fog_b; \
} \
} \
\
src_r = CLAMP(src_r); \
src_g = CLAMP(src_g); \
src_b = CLAMP(src_b); \
} while (0)
#define ALPHA_TEST(src_a) \
do \
{ \
switch (alpha_func) \
{ \
case AFUNC_NEVER: \
voodoo->fbiAFuncFail++; \
goto skip_pixel; \
case AFUNC_LESSTHAN: \
if (!(src_a < a_ref)) \
{ \
voodoo->fbiAFuncFail++; \
goto skip_pixel; \
} \
break; \
case AFUNC_EQUAL: \
if (!(src_a == a_ref)) \
{ \
voodoo->fbiAFuncFail++; \
goto skip_pixel; \
} \
break; \
case AFUNC_LESSTHANEQUAL: \
if (!(src_a <= a_ref)) \
{ \
voodoo->fbiAFuncFail++; \
goto skip_pixel; \
} \
break; \
case AFUNC_GREATERTHAN: \
if (!(src_a > a_ref)) \
{ \
voodoo->fbiAFuncFail++; \
goto skip_pixel; \
} \
break; \
case AFUNC_NOTEQUAL: \
if (!(src_a != a_ref)) \
{ \
voodoo->fbiAFuncFail++; \
goto skip_pixel; \
} \
break; \
case AFUNC_GREATERTHANEQUAL: \
if (!(src_a >= a_ref)) \
{ \
voodoo->fbiAFuncFail++; \
goto skip_pixel; \
} \
break; \
case AFUNC_ALWAYS: \
break; \
} \
} while (0)
#define ALPHA_BLEND(src_r, src_g, src_b, src_a) \
do \
{ \
int _a; \
int newdest_r = 0, newdest_g = 0, newdest_b = 0; \
\
switch (dest_afunc) \
{ \
case AFUNC_AZERO: \
newdest_r = newdest_g = newdest_b = 0; \
break; \
case AFUNC_ASRC_ALPHA: \
newdest_r = (dest_r * src_a) / 255; \
newdest_g = (dest_g * src_a) / 255; \
newdest_b = (dest_b * src_a) / 255; \
break; \
case AFUNC_A_COLOR: \
newdest_r = (dest_r * src_r) / 255; \
newdest_g = (dest_g * src_g) / 255; \
newdest_b = (dest_b * src_b) / 255; \
break; \
case AFUNC_ADST_ALPHA: \
newdest_r = (dest_r * dest_a) / 255; \
newdest_g = (dest_g * dest_a) / 255; \
newdest_b = (dest_b * dest_a) / 255; \
break; \
case AFUNC_AONE: \
newdest_r = dest_r; \
newdest_g = dest_g; \
newdest_b = dest_b; \
break; \
case AFUNC_AOMSRC_ALPHA: \
newdest_r = (dest_r * (255-src_a)) / 255; \
newdest_g = (dest_g * (255-src_a)) / 255; \
newdest_b = (dest_b * (255-src_a)) / 255; \
break; \
case AFUNC_AOM_COLOR: \
newdest_r = (dest_r * (255-src_r)) / 255; \
newdest_g = (dest_g * (255-src_g)) / 255; \
newdest_b = (dest_b * (255-src_b)) / 255; \
break; \
case AFUNC_AOMDST_ALPHA: \
newdest_r = (dest_r * (255-dest_a)) / 255; \
newdest_g = (dest_g * (255-dest_a)) / 255; \
newdest_b = (dest_b * (255-dest_a)) / 255; \
break; \
case AFUNC_ASATURATE: \
_a = MIN(src_a, 1-dest_a); \
newdest_r = (dest_r * _a) / 255; \
newdest_g = (dest_g * _a) / 255; \
newdest_b = (dest_b * _a) / 255; \
break; \
} \
\
switch (src_afunc) \
{ \
case AFUNC_AZERO: \
src_r = src_g = src_b = 0; \
break; \
case AFUNC_ASRC_ALPHA: \
src_r = (src_r * src_a) / 255; \
src_g = (src_g * src_a) / 255; \
src_b = (src_b * src_a) / 255; \
break; \
case AFUNC_A_COLOR: \
src_r = (src_r * dest_r) / 255; \
src_g = (src_g * dest_g) / 255; \
src_b = (src_b * dest_b) / 255; \
break; \
case AFUNC_ADST_ALPHA: \
src_r = (src_r * dest_a) / 255; \
src_g = (src_g * dest_a) / 255; \
src_b = (src_b * dest_a) / 255; \
break; \
case AFUNC_AONE: \
break; \
case AFUNC_AOMSRC_ALPHA: \
src_r = (src_r * (255-src_a)) / 255; \
src_g = (src_g * (255-src_a)) / 255; \
src_b = (src_b * (255-src_a)) / 255; \
break; \
case AFUNC_AOM_COLOR: \
src_r = (src_r * (255-dest_r)) / 255; \
src_g = (src_g * (255-dest_g)) / 255; \
src_b = (src_b * (255-dest_b)) / 255; \
break; \
case AFUNC_AOMDST_ALPHA: \
src_r = (src_r * (255-dest_a)) / 255; \
src_g = (src_g * (255-dest_a)) / 255; \
src_b = (src_b * (255-dest_a)) / 255; \
break; \
case AFUNC_ACOLORBEFOREFOG: \
fatal("AFUNC_ACOLORBEFOREFOG\n"); \
break; \
} \
\
src_r += newdest_r; \
src_g += newdest_g; \
src_b += newdest_b; \
\
src_r = CLAMP(src_r); \
src_g = CLAMP(src_g); \
src_b = CLAMP(src_b); \
} while(0)
void voodoo_render_thread_1(void *param);
void voodoo_render_thread_2(void *param);
void voodoo_render_thread_3(void *param);
void voodoo_render_thread_4(void *param);
void voodoo_queue_triangle(voodoo_t *voodoo, voodoo_params_t *params);
extern int voodoo_recomp;
extern int tris;
static __inline void voodoo_wake_render_thread(voodoo_t *voodoo)
{
thread_set_event(voodoo->wake_render_thread[0]); /*Wake up render thread if moving from idle*/
if (voodoo->render_threads >= 2)
thread_set_event(voodoo->wake_render_thread[1]); /*Wake up render thread if moving from idle*/
if (voodoo->render_threads == 4)
{
thread_set_event(voodoo->wake_render_thread[2]); /*Wake up render thread if moving from idle*/
thread_set_event(voodoo->wake_render_thread[3]); /*Wake up render thread if moving from idle*/
}
}
static __inline void voodoo_wait_for_render_thread_idle(voodoo_t *voodoo)
{
while (!PARAM_EMPTY(0) || (voodoo->render_threads >= 2 && !PARAM_EMPTY(1)) ||
(voodoo->render_threads == 4 && (!PARAM_EMPTY(2) || !PARAM_EMPTY(3))) ||
voodoo->render_voodoo_busy[0] || (voodoo->render_threads >= 2 && voodoo->render_voodoo_busy[1]) ||
(voodoo->render_threads == 4 && (voodoo->render_voodoo_busy[2] || voodoo->render_voodoo_busy[3])))
{
voodoo_wake_render_thread(voodoo);
if (!PARAM_EMPTY(0) || voodoo->render_voodoo_busy[0])
thread_wait_event(voodoo->render_not_full_event[0], 1);
if (voodoo->render_threads >= 2 && (!PARAM_EMPTY(1) || voodoo->render_voodoo_busy[1]))
thread_wait_event(voodoo->render_not_full_event[1], 1);
if (voodoo->render_threads == 4 && (!PARAM_EMPTY(2) || voodoo->render_voodoo_busy[2]))
thread_wait_event(voodoo->render_not_full_event[2], 1);
if (voodoo->render_threads == 4 && (!PARAM_EMPTY(3) || voodoo->render_voodoo_busy[3]))
thread_wait_event(voodoo->render_not_full_event[3], 1);
}
}

View File

@@ -0,0 +1,18 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Voodoo Graphics, 2, Banshee, 3 emulation.
*
*
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* leilei
*
* Copyright 2008-2020 Sarah Walker.
*/
void voodoo_triangle_setup(voodoo_t *voodoo);

View File

@@ -0,0 +1,36 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Voodoo Graphics, 2, Banshee, 3 emulation.
*
*
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* leilei
*
* Copyright 2008-2020 Sarah Walker.
*/
static const uint32_t texture_offset[LOD_MAX+3] =
{
0,
256*256,
256*256 + 128*128,
256*256 + 128*128 + 64*64,
256*256 + 128*128 + 64*64 + 32*32,
256*256 + 128*128 + 64*64 + 32*32 + 16*16,
256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8,
256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4,
256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2,
256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2 + 1*1,
256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2 + 1*1 + 1
};
void voodoo_recalc_tex(voodoo_t *voodoo, int tmu);
void voodoo_use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu);
void voodoo_tex_writel(uint32_t addr, uint32_t val, void *p);
void flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu);

View File

@@ -362,6 +362,10 @@ extern const device_t ps1vga_mca_device;
/* 3DFX Voodoo Graphics */
extern const device_t voodoo_device;
extern const device_t voodoo_banshee_device;
extern const device_t creative_voodoo_banshee_device;
extern const device_t voodoo_3_2000_device;
extern const device_t voodoo_3_3000_device;
/* Wyse 700 */
extern const device_t wy700_device;

View File

@@ -225,7 +225,8 @@ machine_at_micronics386_init(const machine_t *model)
static void
machine_at_scat_init(const machine_t *model, int is_v4)
{
machine_at_init(model);
machine_at_common_init(model);
device_add(&keyboard_at_ami_device);
device_add(&fdc_at_device);
if (is_v4)

View File

@@ -125,8 +125,8 @@ machine_at_p6bap_init(const machine_t *model)
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&via_apro133a_device); //Rebranded as ET82C693A
device_add(&via_vt82c596b_device); //Rebranded as ET82C696B
device_add(&via_apro133a_device); /* Rebranded as ET82C693A */
device_add(&via_vt82c596b_device); /* Rebranded as ET82C696B */
device_add(&w83977ef_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&sst_flash_39sf020_device);
@@ -356,7 +356,13 @@ machine_at_wcf681_init(const machine_t *model)
device_add(&w83977tf_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&sst_flash_39sf020_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
spd_register(SPD_TYPE_SDRAM, 0x3, 512);
device_add(&w83781d_device); /* fans: CPU, unused, unused; temperatures: System, unused, CPU */
hwm_values.voltages[1] = 2500; /* +2.5V */
hwm_values.fans[1] = 0; /* unused */
hwm_values.fans[2] = 0; /* unused */
hwm_values.temperatures[1] = 0; /* unused */
return ret;
}
@@ -387,8 +393,11 @@ machine_at_6via85x_init(const machine_t *model)
device_add(&via_vt82c686_sio_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&sst_flash_39sf020_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
device_add(&via_vt82c686_hwm_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 512);
device_add(&via_vt82c686_hwm_device); /* fans: CPU1, CPU2; temperatures: CPU, System, unused */
hwm_values.temperatures[0] += 2; /* CPU offset */
hwm_values.temperatures[1] += 2; /* System offset */
hwm_values.temperatures[2] = 0; /* unused */
return ret;
}
@@ -419,8 +428,11 @@ machine_at_603tcf_init(const machine_t *model)
device_add(&via_vt82c686_sio_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&sst_flash_39sf020_device);
spd_register(SPD_TYPE_SDRAM, 0x3, 256);
device_add(&via_vt82c686_hwm_device);
spd_register(SPD_TYPE_SDRAM, 0x3, 512);
device_add(&via_vt82c686_hwm_device); /* fans: 1, 2; temperatures: CPU, System, unused */
hwm_values.temperatures[0] += 2; /* CPU offset */
hwm_values.temperatures[1] += 2; /* System offset */
hwm_values.temperatures[2] = 0; /* unused */
return ret;
}

View File

@@ -913,7 +913,7 @@ machine_at_an430tx_init(const machine_t *model)
L"roms/machines/an430tx/P10-0095.BI1",
L"roms/machines/an430tx/P10-0095.BI2",
L"roms/machines/an430tx/P10-0095.BI3",
NULL,
L"roms/machines/an430tx/P10-0095.RCV",
0x3a000, 160);
if (bios_only || !ret)
@@ -924,11 +924,11 @@ machine_at_an430tx_init(const machine_t *model)
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); /* PIIX4 */
pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0);
device_add(&i430tx_device);
device_add(&piix4_device);
device_add(&keyboard_ps2_ami_pci_device);
@@ -1028,7 +1028,7 @@ machine_at_ficva502_init(const machine_t *model)
device_add(&via_vpx_device);
device_add(&via_vt82c586b_device);
device_add(&keyboard_ps2_pci_device);
device_add(&fdc37c669_device);
device_add(&fdc37c669_370_device);
device_add(&sst_flash_29ee010_device);
spd_register(SPD_TYPE_SDRAM, 0x3, 256);
@@ -1062,7 +1062,7 @@ machine_at_ficpa2012_init(const machine_t *model)
device_add(&via_vt82c586b_device);
device_add(&keyboard_ps2_pci_device);
device_add(&w83877f_device);
device_add(&sst_flash_39sf010_device);
device_add(&sst_flash_29ee010_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 512);
return ret;

View File

@@ -33,38 +33,6 @@
#include <86box/machine.h>
#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
#define MACHINE_CPUS_PENTIUM_S5 {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}
#define MACHINE_CPUS_PENTIUM_S73V {{ "Intel", cpus_Pentium3V}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"Cyrix", cpus_6x863V}, {"", NULL}}
#define MACHINE_CPUS_PENTIUM_S73VCH {{ "Intel", cpus_Pentium3V}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}, {"", NULL}}
#define MACHINE_CPUS_PENTIUM_S7 {{ "Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86}, {"", NULL}}
#define MACHINE_CPUS_PENTIUM_SS7 {{ "Intel", cpus_Pentium}, {"IDT", cpus_WinChip_SS7}, {"AMD", cpus_K56_SS7}, {"Cyrix", cpus_6x86SS7}, {"", NULL}}
#else
#define MACHINE_CPUS_PENTIUM_S5 {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}
#define MACHINE_CPUS_PENTIUM_S73V {{ "Intel", cpus_Pentium3V}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}
#define MACHINE_CPUS_PENTIUM_S73VCH {{ "Intel", cpus_Pentium3V}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}, {"", NULL}}
#define MACHINE_CPUS_PENTIUM_S7 {{ "Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"", NULL}, {"", NULL}}
#define MACHINE_CPUS_PENTIUM_SS7 {{ "Intel", cpus_Pentium}, {"IDT", cpus_WinChip_SS7}, {"AMD", cpus_K56_SS7}, {"", NULL}, {"", NULL}}
#endif
#else
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
#define MACHINE_CPUS_PENTIUM_S5 {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}
#define MACHINE_CPUS_PENTIUM_S73V {{ "Intel", cpus_Pentium3V}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x863V}, {"", NULL}, {"", NULL}}
#define MACHINE_CPUS_PENTIUM_S73VCH {{ "Intel", cpus_Pentium3V}, {"", NULL }, {"", NULL}, {"", NULL}, {"", NULL}}
#define MACHINE_CPUS_PENTIUM_S7 {{ "Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86}, {"", NULL}}
#define MACHINE_CPUS_PENTIUM_SS7 {{ "Intel", cpus_Pentium}, {"IDT", cpus_WinChip_SS7}, {"AMD", cpus_K56_SS7}, {"Cyrix", cpus_6x86SS7}, {"", NULL}}
#else
#define MACHINE_CPUS_PENTIUM_S5 {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}
#define MACHINE_CPUS_PENTIUM_S73V {{ "Intel", cpus_Pentium3V}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}
#define MACHINE_CPUS_PENTIUM_S73VCH {{ "Intel", cpus_Pentium3V}, {"", NULL }, {"", NULL}, {"", NULL}, {"", NULL}}
#define MACHINE_CPUS_PENTIUM_S7 {{ "Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"", NULL}, {"", NULL}}
#define MACHINE_CPUS_PENTIUM_S7_INTEL {{"Intel", cpus_Pentium}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}
#define MACHINE_CPUS_PENTIUM_SS7 {{ "Intel", cpus_Pentium}, {"IDT", cpus_WinChip_SS7}, {"AMD", cpus_K56_SS7}, {"", NULL}, {"", NULL}}
#endif
#endif
const machine_type_t machine_types[] = {
{ "None", MACHINE_TYPE_NONE },
{ "8088", MACHINE_TYPE_8088 },
@@ -82,341 +50,340 @@ const machine_type_t machine_types[] = {
{ "Slot 1", MACHINE_TYPE_SLOT1 },
{ "Slot 2", MACHINE_TYPE_SLOT2 },
{ "Socket 370", MACHINE_TYPE_SOCKET370 },
{ "Miscellaneous", MACHINE_TYPE_MISC },
{ "Miscellaneous", MACHINE_TYPE_MISC }
{ "Miscellaneous", MACHINE_TYPE_MISC }
};
const machine_t machines[] = {
/* 8088 Machines */
{ "[8088] IBM PC (1981)", "ibmpc", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC, 16, 64, 16, 0, machine_pc_init, NULL },
{ "[8088] IBM PC (1982)", "ibmpc82", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC, 256, 256, 256, 0, machine_pc82_init, NULL },
{ "[8088] IBM PCjr", "ibmpcjr", MACHINE_TYPE_8088, {{"Intel", cpus_pcjr}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC | MACHINE_VIDEO_FIXED, 128, 640, 128, 0, machine_pcjr_init, pcjr_get_device },
{ "[8088] IBM XT (1982)", "ibmxt", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC, 64, 256, 64, 0, machine_xt_init, NULL },
{ "[8088] IBM XT (1986)", "ibmxt86", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC, 256, 640, 64, 0, machine_xt86_init, NULL },
{ "[8088] American XT Computer", "americxt", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC, 64, 640, 64, 0, machine_xt_americxt_init, NULL },
{ "[8088] AMI XT clone", "amixt", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC, 64, 640, 64, 0, machine_xt_amixt_init, NULL },
{ "[8088] Compaq Portable", "portable", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC | MACHINE_VIDEO, 128, 640, 128, 0, machine_xt_compaq_portable_init, NULL },
{ "[8088] DTK XT clone", "dtk", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC, 64, 640, 64, 0, machine_xt_dtk_init, NULL },
{ "[8088] Generic XT clone", "genxt", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC, 64, 640, 64, 0, machine_genxt_init, NULL },
{ "[8088] Juko XT clone", "jukopc", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC, 64, 640, 64, 0, machine_xt_jukopc_init, NULL },
{ "[8088] OpenXT", "open_xt", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC, 64, 640, 64, 0, machine_xt_open_xt_init, NULL },
{ "[8088] Phoenix XT clone", "pxxt", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC, 64, 640, 64, 0, machine_xt_pxxt_init, NULL },
{ "[8088] Schneider EuroPC", "europc", MACHINE_TYPE_8088, {{"Siemens", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC | MACHINE_XTA | MACHINE_MOUSE, 512, 640, 128, 15, machine_europc_init, NULL },
{ "[8088] Tandy 1000", "tandy", MACHINE_TYPE_8088, {{"Intel", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC | MACHINE_VIDEO_FIXED, 128, 640, 128, 0, machine_tandy_init, tandy1k_get_device },
{ "[8088] Tandy 1000 HX", "tandy1000hx", MACHINE_TYPE_8088, {{"Intel", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC | MACHINE_VIDEO_FIXED, 256, 640, 128, 0, machine_tandy1000hx_init, tandy1k_hx_get_device },
{ "[8088] Toshiba T1000", "t1000", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC | MACHINE_VIDEO, 512, 1280, 768, 63, machine_xt_t1000_init, t1000_get_device },
{ "[8088] IBM PC (1981)", "ibmpc", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 16, 64, 16, 0, machine_pc_init, NULL },
{ "[8088] IBM PC (1982)", "ibmpc82", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 256, 256, 256, 0, machine_pc82_init, NULL },
{ "[8088] IBM PCjr", "ibmpcjr", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED, 128, 640, 128, 0, machine_pcjr_init, pcjr_get_device },
{ "[8088] IBM XT (1982)", "ibmxt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 256, 64, 0, machine_xt_init, NULL },
{ "[8088] IBM XT (1986)", "ibmxt86", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 256, 640, 64, 0, machine_xt86_init, NULL },
{ "[8088] American XT Computer", "americxt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_americxt_init, NULL },
{ "[8088] AMI XT clone", "amixt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_amixt_init, NULL },
{ "[8088] Compaq Portable", "portable", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO, 128, 640, 128, 0, machine_xt_compaq_portable_init, NULL },
{ "[8088] DTK XT clone", "dtk", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_dtk_init, NULL },
{ "[8088] Generic XT clone", "genxt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_genxt_init, NULL },
{ "[8088] Juko XT clone", "jukopc", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_jukopc_init, NULL },
{ "[8088] OpenXT", "open_xt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_open_xt_init, NULL },
{ "[8088] Phoenix XT clone", "pxxt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_pxxt_init, NULL },
{ "[8088] Schneider EuroPC", "europc", MACHINE_TYPE_8088, CPU_PKG_8088_EUROPC, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_XTA | MACHINE_MOUSE, 512, 640, 128, 15, machine_europc_init, NULL },
{ "[8088] Tandy 1000", "tandy", MACHINE_TYPE_8088, CPU_PKG_8088_EUROPC, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED, 128, 640, 128, 0, machine_tandy_init, tandy1k_get_device },
{ "[8088] Tandy 1000 HX", "tandy1000hx", MACHINE_TYPE_8088, CPU_PKG_8088_EUROPC, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED, 256, 640, 128, 0, machine_tandy1000hx_init, tandy1k_hx_get_device },
{ "[8088] Toshiba T1000", "t1000", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO, 512, 1280, 768, 63, machine_xt_t1000_init, t1000_get_device },
#if defined(DEV_BRANCH) && defined(USE_LASERXT)
{ "[8088] VTech Laser Turbo XT", "ltxt", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC, 256, 640, 256, 0, machine_xt_laserxt_init, NULL },
{ "[8088] VTech Laser Turbo XT", "ltxt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 256, 640, 256, 0, machine_xt_laserxt_init, NULL },
#endif
{ "[8088] Xi8088", "xi8088", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT | MACHINE_BUS_PS2, 64, 1024, 128, 127, machine_xt_xi8088_init, xi8088_get_device },
{ "[8088] Zenith Data SupersPort", "zdsupers", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC, 128, 640, 128, 0, machine_xt_zenith_init, NULL },
{ "[8088] Xi8088", "xi8088", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2, 64, 1024, 128, 127, machine_xt_xi8088_init, xi8088_get_device },
{ "[8088] Zenith Data SupersPort", "zdsupers", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 128, 0, machine_xt_zenith_init, NULL },
/* 8086 Machines */
{ "[8086] Amstrad PC1512", "pc1512", MACHINE_TYPE_8086, {{"Intel", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 512, 640, 128, 63, machine_pc1512_init, pc1512_get_device },
{ "[8086] Amstrad PC1640", "pc1640", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc1640_init, pc1640_get_device },
{ "[8086] Amstrad PC2086", "pc2086", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc2086_init, pc2086_get_device },
{ "[8086] Amstrad PC3086", "pc3086", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc3086_init, pc3086_get_device },
{ "[8086] Amstrad PC20(0)", "pc200", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC | MACHINE_VIDEO | MACHINE_MOUSE | MACHINE_NONMI, 512, 640, 128, 63, machine_pc200_init, pc200_get_device },
{ "[8086] Amstrad PPC512/640", "ppc512", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC | MACHINE_VIDEO | MACHINE_MOUSE | MACHINE_NONMI, 512, 640, 128, 63, machine_ppc512_init, ppc512_get_device },
{ "[8086] Compaq Deskpro", "deskpro", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC, 128, 640, 128, 0, machine_xt_compaq_deskpro_init, NULL },
{ "[8086] Olivetti M24", "olivetti_m24", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 128, 640, 128, 0, machine_olim24_init, m24_get_device },
{ "[8086] Schetmash Iskra-3104", "iskra3104", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC, 128, 640, 128, 0, machine_xt_iskra3104_init, NULL },
{ "[8086] Tandy 1000 SL/2", "tandy1000sl2", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC | MACHINE_VIDEO_FIXED, 512, 768, 128, 0, machine_tandy1000sl2_init, tandy1k_sl_get_device },
{ "[8086] Toshiba T1200", "t1200", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC | MACHINE_VIDEO, 1024, 2048,1024, 63, machine_xt_t1200_init, t1200_get_device },
{ "[8086] Amstrad PC1512", "pc1512", MACHINE_TYPE_8086, CPU_PKG_8086, 0, 8000000, 8000000, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 512, 640, 128, 63, machine_pc1512_init, pc1512_get_device },
{ "[8086] Amstrad PC1640", "pc1640", MACHINE_TYPE_8086, CPU_PKG_8086, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc1640_init, pc1640_get_device },
{ "[8086] Amstrad PC2086", "pc2086", MACHINE_TYPE_8086, CPU_PKG_8086, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc2086_init, pc2086_get_device },
{ "[8086] Amstrad PC3086", "pc3086", MACHINE_TYPE_8086, CPU_PKG_8086, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc3086_init, pc3086_get_device },
{ "[8086] Amstrad PC20(0)", "pc200", MACHINE_TYPE_8086, CPU_PKG_8086, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO | MACHINE_MOUSE | MACHINE_NONMI, 512, 640, 128, 63, machine_pc200_init, pc200_get_device },
{ "[8086] Amstrad PPC512/640", "ppc512", MACHINE_TYPE_8086, CPU_PKG_8086, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO | MACHINE_MOUSE | MACHINE_NONMI, 512, 640, 128, 63, machine_ppc512_init, ppc512_get_device },
{ "[8086] Compaq Deskpro", "deskpro", MACHINE_TYPE_8086, CPU_PKG_8086, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 128, 0, machine_xt_compaq_deskpro_init, NULL },
{ "[8086] Olivetti M24", "olivetti_m24", MACHINE_TYPE_8086, CPU_PKG_8086, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 128, 640, 128, 0, machine_olim24_init, m24_get_device },
{ "[8086] Schetmash Iskra-3104", "iskra3104", MACHINE_TYPE_8086, CPU_PKG_8086, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 128, 0, machine_xt_iskra3104_init, NULL },
{ "[8086] Tandy 1000 SL/2", "tandy1000sl2", MACHINE_TYPE_8086, CPU_PKG_8086, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED, 512, 768, 128, 0, machine_tandy1000sl2_init, tandy1k_sl_get_device },
{ "[8086] Toshiba T1200", "t1200", MACHINE_TYPE_8086, CPU_PKG_8086, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO, 1024, 2048,1024, 63, machine_xt_t1200_init, t1200_get_device },
#if defined(DEV_BRANCH) && defined(USE_LASERXT)
{ "[8086] VTech Laser XT3", "lxt3", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC, 256, 640, 256, 0, machine_xt_lxt3_init, NULL },
{ "[8086] VTech Laser XT3", "lxt3", MACHINE_TYPE_8086, CPU_PKG_8086, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 256, 640, 256, 0, machine_xt_lxt3_init, NULL },
#endif
/* 286 XT machines */
#if defined(DEV_BRANCH) && defined(USE_HEDAKA)
{ "[Citygate D30 XT] Hedaka HED-919", "hed919", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PC, 64, 1024, 64, 0, machine_xt_hed919_init, NULL },
{ "[Citygate D30 XT] Hedaka HED-919", "hed919", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 1024, 64, 0, machine_xt_hed919_init, NULL },
#endif
/* 286 AT machines */
{ "[ISA] IBM AT", "ibmat", MACHINE_TYPE_286, {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT, 256,15872, 128, 63, machine_at_ibm_init, NULL },
{ "[ISA] IBM PS/1 model 2011", "ibmps1es", MACHINE_TYPE_286, {{"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_XTA | MACHINE_VIDEO_FIXED, 512,16384, 512, 63, machine_ps1_m2011_init, NULL },
{ "[ISA] IBM PS/2 model 30-286", "ibmps2_m30_286", MACHINE_TYPE_286, {{"Intel", cpus_ps2_m30_286}, {"IBM",cpus_IBM486SLC},{"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_XTA | MACHINE_VIDEO_FIXED, 1, 16, 1, 127, machine_ps2_m30_286_init, NULL },
{ "[ISA] IBM XT Model 286", "ibmxt286", MACHINE_TYPE_286, {{"", cpus_ibmxt286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT, 256,15872, 128, 127, machine_at_ibmxt286_init, NULL },
{ "[ISA] AMI IBM AT", "ibmatami", MACHINE_TYPE_286, {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT, 256,15872, 128, 63, machine_at_ibmatami_init, NULL },
{ "[ISA] Commodore PC 30 III", "cmdpc30", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT, 640,16384, 128, 127, machine_at_cmdpc_init, NULL },
{ "[ISA] Compaq Portable II", "portableii", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT, 640,16384, 128, 127, machine_at_portableii_init, NULL },
{ "[ISA] Compaq Portable III", "portableiii", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT | MACHINE_VIDEO, 640,16384, 128, 127, machine_at_portableiii_init, at_cpqiii_get_device },
{ "[ISA] MR 286 clone", "mr286", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT | MACHINE_IDE, 512,16384, 128, 127, machine_at_mr286_init, NULL },
{ "[ISA] IBM AT", "ibmat", MACHINE_TYPE_286, CPU_PKG_286, 0, 6000000, 8000000, 0, 0, 0, 0, MACHINE_AT, 256,15872, 128, 63, machine_at_ibm_init, NULL },
{ "[ISA] IBM PS/1 model 2011", "ibmps1es", MACHINE_TYPE_286, CPU_PKG_286, 0, 10000000, 10000000, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_XTA | MACHINE_VIDEO_FIXED, 512,16384, 512, 63, machine_ps1_m2011_init, NULL },
{ "[ISA] IBM PS/2 model 30-286", "ibmps2_m30_286", MACHINE_TYPE_286, CPU_PKG_286 | CPU_PKG_486SLC_IBM, 0, 10000000, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_XTA | MACHINE_VIDEO_FIXED, 1, 16, 1, 127, machine_ps2_m30_286_init, NULL },
{ "[ISA] IBM XT Model 286", "ibmxt286", MACHINE_TYPE_286, CPU_PKG_286, 0, 6000000, 6000000, 0, 0, 0, 0, MACHINE_AT, 256,15872, 128, 127, machine_at_ibmxt286_init, NULL },
{ "[ISA] AMI IBM AT", "ibmatami", MACHINE_TYPE_286, CPU_PKG_286, 0, 6000000, 8000000, 0, 0, 0, 0, MACHINE_AT, 256,15872, 128, 63, machine_at_ibmatami_init, NULL },
{ "[ISA] Commodore PC 30 III", "cmdpc30", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 640,16384, 128, 127, machine_at_cmdpc_init, NULL },
{ "[ISA] Compaq Portable II", "portableii", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 640,16384, 128, 127, machine_at_portableii_init, NULL },
{ "[ISA] Compaq Portable III", "portableiii", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_VIDEO, 640,16384, 128, 127, machine_at_portableiii_init, at_cpqiii_get_device },
{ "[ISA] MR 286 clone", "mr286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE, 512,16384, 128, 127, machine_at_mr286_init, NULL },
#if defined(DEV_BRANCH) && defined(USE_OPEN_AT)
{ "[ISA] OpenAT", "open_at", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT, 256,15872, 128, 63, machine_at_open_at_init, NULL },
{ "[ISA] OpenAT", "open_at", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 256,15872, 128, 63, machine_at_open_at_init, NULL },
#endif
{ "[ISA] Phoenix IBM AT", "ibmatpx", MACHINE_TYPE_286, {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT, 256,15872, 128, 63, machine_at_ibmatpx_init, NULL },
{ "[ISA] Quadtel IBM AT", "ibmatquadtel", MACHINE_TYPE_286, {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT, 256,15872, 128, 63, machine_at_ibmatquadtel_init, NULL },
{ "[ISA] Siemens PCD-2L", "siemens", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT, 256,15872, 128, 63, machine_at_siemens_init, NULL },
{ "[ISA] Toshiba T3100e", "t3100e", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT | MACHINE_IDE | MACHINE_VIDEO_FIXED, 1024, 5120, 256, 63, machine_at_t3100e_init, NULL },
{ "[GC103] Quadtel 286 clone", "quadt286", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT, 512,16384, 128, 127, machine_at_quadt286_init, NULL },
{ "[GC103] Trigem 286M", "tg286m", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT | MACHINE_IDE, 512, 8192, 128, 127, machine_at_tg286m_init, NULL },
{ "[NEAT] AMI 286 clone", "ami286", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT, 512, 8192, 128, 127, machine_at_neat_ami_init, NULL },
{ "[NEAT] Phoenix 286 clone", "px286", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT, 512,16384, 128, 127, machine_at_px286_init, NULL },
{ "[SCAT] Award 286 clone", "award286", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT, 512,16384, 128, 127, machine_at_award286_init, NULL },
{ "[SCAT] GW-286CT GEAR", "gw286ct", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT, 512,16384, 128, 127, machine_at_gw286ct_init, NULL },
{ "[SCAT] Goldstar GDC-212M", "gdc212m", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT | MACHINE_IDE | MACHINE_BUS_PS2, 512, 4096, 512, 127, machine_at_gdc212m_init, NULL },
{ "[SCAT] Hyundai Super-286TR", "super286tr", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT, 512,16384, 128, 127, machine_at_super286tr_init, NULL },
{ "[SCAT] Samsung SPC-4200P", "spc4200p", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT | MACHINE_BUS_PS2, 512, 2048, 128, 127, machine_at_spc4200p_init, NULL },
{ "[SCAT] Samsung SPC-4216P", "spc4216p", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT | MACHINE_BUS_PS2, 1, 5, 1, 127, machine_at_spc4216p_init, NULL },
{ "[SCAT] Samsung Deskmaster 286", "deskmaster286", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT, 512,16384, 128, 127, machine_at_deskmaster286_init, NULL },
{ "[ISA] Phoenix IBM AT", "ibmatpx", MACHINE_TYPE_286, CPU_PKG_286, 0, 6000000, 8000000, 0, 0, 0, 0, MACHINE_AT, 256,15872, 128, 63, machine_at_ibmatpx_init, NULL },
{ "[ISA] Quadtel IBM AT", "ibmatquadtel", MACHINE_TYPE_286, CPU_PKG_286, 0, 6000000, 8000000, 0, 0, 0, 0, MACHINE_AT, 256,15872, 128, 63, machine_at_ibmatquadtel_init, NULL },
{ "[ISA] Siemens PCD-2L", "siemens", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 256,15872, 128, 63, machine_at_siemens_init, NULL },
{ "[ISA] Toshiba T3100e", "t3100e", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE | MACHINE_VIDEO_FIXED, 1024, 5120, 256, 63, machine_at_t3100e_init, NULL },
{ "[GC103] Quadtel 286 clone", "quadt286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512,16384, 128, 127, machine_at_quadt286_init, NULL },
{ "[GC103] Trigem 286M", "tg286m", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE, 512, 8192, 128, 127, machine_at_tg286m_init, NULL },
{ "[NEAT] AMI 286 clone", "ami286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_neat_ami_init, NULL },
{ "[NEAT] Phoenix 286 clone", "px286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512,16384, 128, 127, machine_at_px286_init, NULL },
{ "[SCAT] Award 286 clone", "award286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512,16384, 128, 127, machine_at_award286_init, NULL },
{ "[SCAT] GW-286CT GEAR", "gw286ct", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512,16384, 128, 127, machine_at_gw286ct_init, NULL },
{ "[SCAT] Goldstar GDC-212M", "gdc212m", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE | MACHINE_BUS_PS2, 512, 4096, 512, 127, machine_at_gdc212m_init, NULL },
{ "[SCAT] Hyundai Super-286TR", "super286tr", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512,16384, 128, 127, machine_at_super286tr_init, NULL },
{ "[SCAT] Samsung SPC-4200P", "spc4200p", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2, 512, 2048, 128, 127, machine_at_spc4200p_init, NULL },
{ "[SCAT] Samsung SPC-4216P", "spc4216p", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2, 1, 5, 1, 127, machine_at_spc4216p_init, NULL },
{ "[SCAT] Samsung Deskmaster 286", "deskmaster286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512,16384, 128, 127, machine_at_deskmaster286_init, NULL },
/* 286 machines that utilize the MCA bus */
{ "[MCA] IBM PS/2 model 50", "ibmps2_m50", MACHINE_TYPE_286, {{"Intel", cpus_ps2_m30_286}, {"IBM",cpus_IBM486SLC},{"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_MCA | MACHINE_BUS_PS2 | MACHINE_VIDEO, 1, 10, 1, 63, machine_ps2_model_50_init, NULL },
{ "[MCA] IBM PS/2 model 50", "ibmps2_m50", MACHINE_TYPE_286, CPU_PKG_286 | CPU_PKG_486SLC_IBM, 0, 10000000, 0, 0, 0, 0, 0, MACHINE_MCA | MACHINE_BUS_PS2 | MACHINE_VIDEO, 1, 10, 1, 63, machine_ps2_model_50_init, NULL },
/* 386SX machines */
{ "[ISA] IBM PS/1 model 2121", "ibmps1_2121", MACHINE_TYPE_386SX, {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO_FIXED, 2, 6, 1, 63, machine_ps1_m2121_init, NULL },
{ "[ISA] IBM PS/1 m.2121+ISA", "ibmps1_2121_isa", MACHINE_TYPE_386SX, {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 2, 6, 1, 63, machine_ps1_m2121_init, NULL },
{ "[ISA] IBM PS/1 model 2121", "ibmps1_2121", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO_FIXED, 2, 6, 1, 63, machine_ps1_m2121_init, NULL },
{ "[ISA] IBM PS/1 m.2121+ISA", "ibmps1_2121_isa", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 2, 6, 1, 63, machine_ps1_m2121_init, NULL },
#if defined(DEV_BRANCH) && defined(USE_M6117)
{ "[ALi M6117D] Acrosser AR-B1375", "arb1375", MACHINE_TYPE_386SX, {{"ALi", cpus_ALiM6117}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE, 1, 32, 1, 127, machine_at_arb1375_init, NULL },
{ "[ALi M6117D] Acrosser PJ-A511M", "pja511m", MACHINE_TYPE_386SX, {{"ALi", cpus_ALiM6117}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE, 1, 32, 1, 127, machine_at_pja511m_init, NULL },
{ "[ALi M6117D] Acrosser AR-B1375", "arb1375", MACHINE_TYPE_386SX, CPU_PKG_M6117, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE, 1, 32, 1, 127, machine_at_arb1375_init, NULL },
{ "[ALi M6117D] Acrosser PJ-A511M", "pja511m", MACHINE_TYPE_386SX, CPU_PKG_M6117, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE, 1, 32, 1, 127, machine_at_pja511m_init, NULL },
#endif
{ "[HT18] AMA-932J", "ama932j", MACHINE_TYPE_386SX, {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_AT | MACHINE_IDE | MACHINE_VIDEO, 512, 8192, 128, 127, machine_at_ama932j_init, at_ama932j_get_device },
{ "[Intel 82335] ADI 386SX", "adi386sx", MACHINE_TYPE_386SX, {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_AT, 512, 8192, 128, 127, machine_at_adi386sx_init, NULL },
{ "[Intel 82335] Shuttle 386SX", "shuttle386sx", MACHINE_TYPE_386SX, {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_AT, 512, 8192, 128, 127, machine_at_shuttle386sx_init, NULL },
{ "[NEAT] DTK 386SX clone", "dtk386", MACHINE_TYPE_386SX, {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_AT, 512, 8192, 128, 127, machine_at_neat_init, NULL },
{ "[OPTi 291] DTK PPM-3333P", "awardsx", MACHINE_TYPE_386SX, {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_AT, 1, 16, 1, 127, machine_at_awardsx_init, NULL },
{ "[SCAMP] Commodore SL386SX", "cbm_sl386sx25", MACHINE_TYPE_386SX, {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 1024, 8192, 512, 127,machine_at_commodore_sl386sx_init, at_commodore_sl386sx_get_device },
{ "[SCAT] KMX-C-02", "kmxc02", MACHINE_TYPE_386SX, {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_AT, 512,16384, 512, 127, machine_at_kmxc02_init, NULL },
{ "[WD76C10] Amstrad MegaPC", "megapc", MACHINE_TYPE_386SX, {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 1, 32, 1, 127, machine_at_wd76c10_init, NULL },
{ "[HT18] AMA-932J", "ama932j", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE | MACHINE_VIDEO, 512, 8192, 128, 127, machine_at_ama932j_init, at_ama932j_get_device },
{ "[Intel 82335] ADI 386SX", "adi386sx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_adi386sx_init, NULL },
{ "[Intel 82335] Shuttle 386SX", "shuttle386sx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_shuttle386sx_init, NULL },
{ "[NEAT] DTK 386SX clone", "dtk386", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_neat_init, NULL },
{ "[OPTi 291] DTK PPM-3333P", "awardsx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1, 16, 1, 127, machine_at_awardsx_init, NULL },
{ "[SCAMP] Commodore SL386SX", "cbm_sl386sx25", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 1024, 8192, 512, 127,machine_at_commodore_sl386sx_init, at_commodore_sl386sx_get_device },
{ "[SCAT] KMX-C-02", "kmxc02", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512,16384, 512, 127, machine_at_kmxc02_init, NULL },
{ "[WD76C10] Amstrad MegaPC", "megapc", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 1, 32, 1, 127, machine_at_wd76c10_init, NULL },
/* 386SX machines which utilize the MCA bus */
{ "[MCA] IBM PS/2 model 55SX", "ibmps2_m55sx", MACHINE_TYPE_386SX, {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"IBM",cpus_IBM486SLC},{"", NULL}}, MACHINE_MCA | MACHINE_BUS_PS2 | MACHINE_VIDEO, 1, 8, 1, 63, machine_ps2_model_55sx_init, NULL },
{ "[MCA] IBM PS/2 model 55SX", "ibmps2_m55sx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_MCA | MACHINE_BUS_PS2 | MACHINE_VIDEO, 1, 8, 1, 63, machine_ps2_model_55sx_init, NULL },
/* 386DX machines */
{ "[ACC 2168] AMI 386DX clone", "acc386", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_AT, 1, 16, 1, 127, machine_at_acc386_init, NULL },
{ "[C&T 386] ECS 386/32", "ecs386", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_AT, 1, 16, 1, 127, machine_at_ecs386_init, NULL },
{ "[ISA] Compaq Portable III (386)", "portableiii386", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_AT | MACHINE_IDE | MACHINE_VIDEO, 1, 14, 1, 127, machine_at_portableiii386_init, at_cpqiii_get_device },
{ "[ISA] Micronics 386 clone", "micronics386", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_AT, 512, 8192, 128, 127, machine_at_micronics386_init, NULL },
{ "[SiS 310] ASUS ISA-386C", "asus386", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_AT, 512,16384, 128, 127, machine_at_asus386_init, NULL },
{ "[UMC 491] US Technologies 386", "ustechnologies386", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_AT, 1, 16, 1, 127,machine_at_ustechnologies386_init, NULL },
{ "[ACC 2168] AMI 386DX clone", "acc386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1, 16, 1, 127, machine_at_acc386_init, NULL },
{ "[C&T 386] ECS 386/32", "ecs386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1, 16, 1, 127, machine_at_ecs386_init, NULL },
{ "[ISA] Compaq Portable III (386)", "portableiii386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE | MACHINE_VIDEO, 1, 14, 1, 127, machine_at_portableiii386_init, at_cpqiii_get_device },
{ "[ISA] Micronics 386 clone", "micronics386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_micronics386_init, NULL },
{ "[SiS 310] ASUS ISA-386C", "asus386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512,16384, 128, 127, machine_at_asus386_init, NULL },
{ "[UMC 491] US Technologies 386", "ustechnologies386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1, 16, 1, 127,machine_at_ustechnologies386_init, NULL },
/* 386DX machines which utilize the VLB bus */
{ "[OPTi 495] Award 386DX clone", "award386dx", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_VLB | MACHINE_IDE, 1, 32, 1, 127, machine_at_opti495_init, NULL },
{ "[OPTi 495] Dataexpert SX495 (386DX)", "ami386dx", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_VLB | MACHINE_IDE, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL },
{ "[OPTi 495] MR 386DX clone", "mr386dx", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_VLB | MACHINE_IDE, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL },
{ "[OPTi 495] Award 386DX clone", "award386dx", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1, 32, 1, 127, machine_at_opti495_init, NULL },
{ "[OPTi 495] Dataexpert SX495 (386DX)", "ami386dx", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL },
{ "[OPTi 495] MR 386DX clone", "mr386dx", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL },
/* 386DX machines which utilize the MCA bus */
{ "[MCA] IBM PS/2 model 70 (type 3)", "ibmps2_m70_type3", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"IBM",cpus_IBM486BL},{"", NULL}}, MACHINE_MCA | MACHINE_BUS_PS2 | MACHINE_VIDEO, 2, 16, 2, 63, machine_ps2_model_70_type3_init, NULL },
{ "[MCA] IBM PS/2 model 80", "ibmps2_m80", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"IBM",cpus_IBM486BL},{"", NULL}}, MACHINE_MCA | MACHINE_BUS_PS2 | MACHINE_VIDEO, 1, 12, 1, 63, machine_ps2_model_80_init, NULL },
{ "[MCA] IBM PS/2 model 70 (type 3)", "ibmps2_m70_type3", MACHINE_TYPE_386DX, CPU_PKG_386DX | CPU_PKG_486BL, 0, 0, 0, 0, 0, 0, 0, MACHINE_MCA | MACHINE_BUS_PS2 | MACHINE_VIDEO, 2, 16, 2, 63, machine_ps2_model_70_type3_init, NULL },
{ "[MCA] IBM PS/2 model 80", "ibmps2_m80", MACHINE_TYPE_386DX, CPU_PKG_386DX | CPU_PKG_486BL, 0, 0, 0, 0, 0, 0, 0, MACHINE_MCA | MACHINE_BUS_PS2 | MACHINE_VIDEO, 1, 12, 1, 63, machine_ps2_model_80_init, NULL },
/* 486 machines with just the ISA slot */
{ "[ACC 2168] Packard Bell PB410A", "pb410a", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 4, 36, 1, 127, machine_at_pb410a_init, NULL },
{ "[ACC 2168] Packard Bell PB410A", "pb410a", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 4, 36, 1, 127, machine_at_pb410a_init, NULL },
/* 486 machines */
{ "[ALi M1429G] Acer A1G", "acera1g", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 4, 36, 1, 127, machine_at_acera1g_init, at_acera1g_get_device },
{ "[ALi M1429] AMI WinBIOS 486", "win486", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_VLB | MACHINE_IDE, 1, 32, 1, 127, machine_at_winbios1429_init, NULL },
{ "[ALi M1429] Olystar LIL1429", "ali1429", MACHINE_TYPE_486, {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_VLB | MACHINE_IDE, 1, 32, 1, 127, machine_at_ali1429_init, NULL },
{ "[CS4031] AMI 486 CS4031", "cs4031", MACHINE_TYPE_486, {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_VLB, 1, 64, 1, 127, machine_at_cs4031_init, NULL },
{ "[OPTi 283] RYC Leopard LX", "rycleopardlx", MACHINE_TYPE_486, {{"IBM", cpus_IBM486SLC}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AT | MACHINE_IDE, 1, 16, 1, 127, machine_at_rycleopardlx_init, NULL },
{ "[OPTi 495] Award 486 clone", "award486", MACHINE_TYPE_486, {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_VLB | MACHINE_IDE, 1, 32, 1, 127, machine_at_opti495_init, NULL },
{ "[OPTi 495] Dataexpert SX495 (486)", "ami486", MACHINE_TYPE_486, {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_VLB | MACHINE_IDE, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL },
{ "[OPTi 495] MR 486 clone", "mr486", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_VLB | MACHINE_IDE, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL },
{ "[OPTi 802G] IBM PC 330 (type 6571)", "pc330_6571", MACHINE_TYPE_486, {{"Intel", cpus_i486_PC330}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_VLB | MACHINE_BUS_PS2 | MACHINE_IDE, 1, 64, 1, 127, machine_at_pc330_6571_init, NULL },
{ "[OPTi 895] Jetway J-403TG", "403tg", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_VLB, 1, 64, 1, 127, machine_at_403tg_init, NULL },
{ "[SiS 401] AMI 486 Clone", "sis401", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_AT | MACHINE_IDE, 1, 64, 1, 127, machine_at_sis401_init, NULL },
{ "[SiS 461] IBM PS/ValuePoint 433DX/Si", "valuepoint433", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE, 1, 64, 1, 127, machine_at_valuepoint433_init, NULL },
{ "[SiS 471] AMI 486 Clone", "ami471", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_VLB | MACHINE_IDE, 1, 64, 1, 127, machine_at_ami471_init, NULL },
{ "[SiS 471] AMI WinBIOS 486 clone", "win471", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_VLB | MACHINE_IDE, 1, 64, 1, 127, machine_at_win471_init, NULL },
{ "[SiS 471] AOpen Vi15G", "vi15g", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_VLB | MACHINE_IDE, 1, 64, 1, 127, machine_at_vi15g_init, NULL },
{ "[SiS 471] ASUS VL/I-486SV2G (GX4)", "vli486sv2g", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_VLB | MACHINE_IDE_DUAL, 1, 64, 1, 127, machine_at_vli486sv2g_init, NULL },
{ "[SiS 471] DTK PKM-0038S E-2", "dtk486", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_VLB | MACHINE_IDE, 1, 64, 1, 127, machine_at_dtk486_init, NULL },
{ "[SiS 471] Phoenix SiS 471", "px471", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_VLB | MACHINE_IDE, 1, 128, 1, 127, machine_at_px471_init, NULL },
{ "[VIA VT82C495] FIC 486-VC-HD", "486vchd", MACHINE_TYPE_486, {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_AT, 1, 32, 1, 127, machine_at_486vchd_init, NULL },
{ "[VLSI 82C480] IBM PS/1 model 2133", "ibmps1_2133", MACHINE_TYPE_486, {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_VLB | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_NONMI | MACHINE_VIDEO, 2, 32, 1, 127, machine_ps1_m2133_init, ps1_m2133_get_device },
{ "[ALi M1429G] Acer A1G", "acera1g", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 4, 36, 1, 127, machine_at_acera1g_init, at_acera1g_get_device },
{ "[ALi M1429] AMI WinBIOS 486", "win486", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1, 32, 1, 127, machine_at_winbios1429_init, NULL },
{ "[ALi M1429] Olystar LIL1429", "ali1429", MACHINE_TYPE_486, CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1, 32, 1, 127, machine_at_ali1429_init, NULL },
{ "[CS4031] AMI 486 CS4031", "cs4031", MACHINE_TYPE_486, CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB, 1, 64, 1, 127, machine_at_cs4031_init, NULL },
{ "[OPTi 283] RYC Leopard LX", "rycleopardlx", MACHINE_TYPE_486, CPU_PKG_486SLC_IBM, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE, 1, 16, 1, 127, machine_at_rycleopardlx_init, NULL },
{ "[OPTi 495] Award 486 clone", "award486", MACHINE_TYPE_486, CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1, 32, 1, 127, machine_at_opti495_init, NULL },
{ "[OPTi 495] Dataexpert SX495 (486)", "ami486", MACHINE_TYPE_486, CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL },
{ "[OPTi 495] MR 486 clone", "mr486", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL },
{ "[OPTi 802G] IBM PC 330 (type 6571)", "pc330_6571", MACHINE_TYPE_486, CPU_PKG_SOCKET3_PC330, 0, 25000000, 33333333, 0, 0, 2.0, 3.0, MACHINE_VLB | MACHINE_BUS_PS2 | MACHINE_IDE, 1, 64, 1, 127, machine_at_pc330_6571_init, NULL },
{ "[OPTi 895] Jetway J-403TG", "403tg", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB, 1, 64, 1, 127, machine_at_403tg_init, NULL },
{ "[SiS 401] AMI 486 Clone", "sis401", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE, 1, 64, 1, 127, machine_at_sis401_init, NULL },
{ "[SiS 461] IBM PS/ValuePoint 433DX/Si", "valuepoint433", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE, 1, 64, 1, 127, machine_at_valuepoint433_init, NULL },
{ "[SiS 471] AMI 486 Clone", "ami471", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1, 64, 1, 127, machine_at_ami471_init, NULL },
{ "[SiS 471] AMI WinBIOS 486 clone", "win471", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1, 64, 1, 127, machine_at_win471_init, NULL },
{ "[SiS 471] AOpen Vi15G", "vi15g", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1, 64, 1, 127, machine_at_vi15g_init, NULL },
{ "[SiS 471] ASUS VL/I-486SV2G (GX4)", "vli486sv2g", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE_DUAL, 1, 64, 1, 127, machine_at_vli486sv2g_init, NULL },
{ "[SiS 471] DTK PKM-0038S E-2", "dtk486", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1, 64, 1, 127, machine_at_dtk486_init, NULL },
{ "[SiS 471] Phoenix SiS 471", "px471", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1, 128, 1, 127, machine_at_px471_init, NULL },
{ "[VIA VT82C495] FIC 486-VC-HD", "486vchd", MACHINE_TYPE_486, CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1, 32, 1, 127, machine_at_486vchd_init, NULL },
{ "[VLSI 82C480] IBM PS/1 model 2133", "ibmps1_2133", MACHINE_TYPE_486, CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_NONMI | MACHINE_VIDEO, 2, 32, 1, 127, machine_ps1_m2133_init, ps1_m2133_get_device },
#if defined(DEV_BRANCH) && defined(USE_VECT486VL)
{ "[VLSI 82C480] HP Vectra 486VL", "vect486vl", MACHINE_TYPE_486, {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 2, 64, 1, 127, machine_at_vect486vl_init, at_vect486vl_get_device },
{ "[VLSI 82C480] HP Vectra 486VL", "vect486vl", MACHINE_TYPE_486, CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 2, 64, 1, 127, machine_at_vect486vl_init, at_vect486vl_get_device },
#endif
/* 486 machines with utilize the MCA bus */
#if defined(DEV_BRANCH) && defined(USE_PS2M70T4)
{ "[MCA] IBM PS/2 model 70 (type 4)", "ibmps2_m70_type4", MACHINE_TYPE_486, {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_MCA | MACHINE_BUS_PS2 | MACHINE_VIDEO, 2, 16, 2, 63, machine_ps2_model_70_type4_init, NULL },
{ "[MCA] IBM PS/2 model 70 (type 4)", "ibmps2_m70_type4", MACHINE_TYPE_486, CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_MCA | MACHINE_BUS_PS2 | MACHINE_VIDEO, 2, 16, 2, 63, machine_ps2_model_70_type4_init, NULL },
#endif
/* 486 machines which utilize the PCI bus */
#if defined(DEV_BRANCH) && defined(USE_M1489)
{ "[ALi M1489] ABIT AB-PB4", "abpb4", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_IDE_DUAL, 1, 64, 1, 255, machine_at_abpb4_init, NULL },
{ "[ALi M1489] ABIT AB-PB4", "abpb4", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1, 64, 1, 255, machine_at_abpb4_init, NULL },
#endif
{ "[i420EX] ASUS PVI-486AP4", "486ap4", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCIV | MACHINE_IDE_DUAL, 1, 128, 1, 127, machine_at_486ap4_init, NULL },
{ "[i420ZX] ASUS PCI/I-486SP3G", "486sp3g", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_IDE_DUAL, 1, 128, 1, 127, machine_at_486sp3g_init, NULL },
{ "[i420TX] Intel Classic/PCI", "alfredo", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2, 128, 2, 127, machine_at_alfredo_init, NULL },
{ "[SiS 496] Lucky Star LS-486E", "ls486e", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_IDE_DUAL, 1, 128, 1, 255, machine_at_ls486e_init, NULL },
{ "[SiS 496] Micronics M4Li", "m4li", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 1, 128, 1, 127, machine_at_m4li_init, NULL },
{ "[SiS 496] Rise Computer R418", "r418", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_IDE_DUAL, 1, 255, 1, 255, machine_at_r418_init, NULL },
{ "[SiS 496] Soyo 4SA2", "4sa2", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_IDE_DUAL, 1, 255, 1, 255, machine_at_4sa2_init, NULL },
{ "[SiS 496] Zida Tomato 4DP", "4dps", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_IDE_DUAL, 1, 255, 1, 255, machine_at_4dps_init, NULL },
{ "[i420EX] ASUS PVI-486AP4", "486ap4", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCIV | MACHINE_IDE_DUAL, 1, 128, 1, 127, machine_at_486ap4_init, NULL },
{ "[i420ZX] ASUS PCI/I-486SP3G", "486sp3g", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1, 128, 1, 127, machine_at_486sp3g_init, NULL },
{ "[i420TX] Intel Classic/PCI", "alfredo", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2, 128, 2, 127, machine_at_alfredo_init, NULL },
{ "[SiS 496] Lucky Star LS-486E", "ls486e", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1, 128, 1, 255, machine_at_ls486e_init, NULL },
{ "[SiS 496] Micronics M4Li", "m4li", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 1, 128, 1, 127, machine_at_m4li_init, NULL },
{ "[SiS 496] Rise Computer R418", "r418", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1, 255, 1, 255, machine_at_r418_init, NULL },
{ "[SiS 496] Soyo 4SA2", "4sa2", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1, 255, 1, 255, machine_at_4sa2_init, NULL },
{ "[SiS 496] Zida Tomato 4DP", "4dps", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1, 255, 1, 255, machine_at_4dps_init, NULL },
#if defined(DEV_BRANCH) && defined(USE_STPC)
{ "[STPC Client] ITOX STAR", "itoxstar", MACHINE_TYPE_486, {{"ST", cpus_STPCDX}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 255, machine_at_itoxstar_init, NULL },
{ "[STPC Consumer-II] Acrosser AR-B1479", "arb1479", MACHINE_TYPE_486, {{"ST", cpus_STPCDX2}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 32, 160, 8, 255, machine_at_arb1479_init, NULL },
{ "[STPC Elite] Advantech PCM-9340", "pcm9340", MACHINE_TYPE_486, {{"ST", cpus_STPCDX2}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 32, 96, 8, 255, machine_at_pcm9340_init, NULL },
{ "[STPC Atlas] AAEON PCM-5330", "pcm5330", MACHINE_TYPE_486, {{"ST", cpus_STPCDX2}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 32, 128, 32, 255, machine_at_pcm5330_init, NULL },
{ "[STPC Client] ITOX STAR", "itoxstar", MACHINE_TYPE_486, CPU_PKG_STPC, 0, 66666667, 75000000, 0, 0, 1.0, 1.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 255, machine_at_itoxstar_init, NULL },
{ "[STPC Consumer-II] Acrosser AR-B1479", "arb1479", MACHINE_TYPE_486, CPU_PKG_STPC, 0, 66666667, 66666667, 0, 0, 2.0, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 32, 160, 8, 255, machine_at_arb1479_init, NULL },
{ "[STPC Elite] Advantech PCM-9340", "pcm9340", MACHINE_TYPE_486, CPU_PKG_STPC, 0, 66666667, 66666667, 0, 0, 2.0, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 32, 96, 8, 255, machine_at_pcm9340_init, NULL },
{ "[STPC Atlas] AAEON PCM-5330", "pcm5330", MACHINE_TYPE_486, CPU_PKG_STPC, 0, 66666667, 66666667, 0, 0, 2.0, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 32, 128, 32, 255, machine_at_pcm5330_init, NULL },
#endif
#if defined(DEV_BRANCH) && defined(NO_SIO)
{ "[VIA VT82C496G] FIC VIP-IO2", "486vipio2", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCIV | MACHINE_IDE_DUAL, 1, 128, 1, 255, machine_at_486vipio2_init, NULL },
{ "[VIA VT82C496G] FIC VIP-IO2", "486vipio2", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCIV | MACHINE_IDE_DUAL, 1, 128, 1, 255, machine_at_486vipio2_init, NULL },
#endif
/* Socket 4 machines */
/* 430LX */
{ "[i430LX] ASUS P/I-P5MP3", "p5mp3", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE, 2, 192, 2, 127, machine_at_p5mp3_init, NULL },
{ "[i430LX] ASUS P/I-P5MP3", "p5mp3", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 0, 0, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE, 2, 192, 2, 127, machine_at_p5mp3_init, NULL },
#if defined(DEV_BRANCH) && defined(USE_DELLS4)
{ "[i430LX] Dell Dimension XPS P60", "dellxp60", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE, 2, 128, 2, 127, machine_at_dellxp60_init, NULL },
{ "[i430LX] Dell OptiPlex 560/L", "opti560l", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2, 128, 2, 127, machine_at_opti560l_init, NULL },
{ "[i430LX] Dell Dimension XPS P60", "dellxp60", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 0, 0, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE, 2, 128, 2, 127, machine_at_dellxp60_init, NULL },
{ "[i430LX] Dell OptiPlex 560/L", "opti560l", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 0, 0, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2, 128, 2, 127, machine_at_opti560l_init, NULL },
#endif
{ "[i430LX] IBM Ambra DP60 PCI", "ambradp60", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2, 128, 2, 127, machine_at_ambradp60_init, NULL },
{ "[i430LX] IBM PS/ValuePoint P60", "valuepointp60", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2, 128, 2, 127, machine_at_valuepointp60_init, NULL },
{ "[i430LX] Intel Premiere/PCI", "revenge", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2, 128, 2, 127, machine_at_batman_init, NULL },
{ "[i430LX] Micro Star 586MC1", "586mc1", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2, 128, 2, 127, machine_at_586mc1_init, NULL },
{ "[i430LX] Packard Bell PB520R", "pb520r", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8, 136, 2, 127, machine_at_pb520r_init, at_pb520r_get_device },
{ "[i430LX] IBM Ambra DP60 PCI", "ambradp60", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 0, 0, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2, 128, 2, 127, machine_at_ambradp60_init, NULL },
{ "[i430LX] IBM PS/ValuePoint P60", "valuepointp60", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 0, 0, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2, 128, 2, 127, machine_at_valuepointp60_init, NULL },
{ "[i430LX] Intel Premiere/PCI", "revenge", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 0, 0, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2, 128, 2, 127, machine_at_batman_init, NULL },
{ "[i430LX] Micro Star 586MC1", "586mc1", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 0, 0, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2, 128, 2, 127, machine_at_586mc1_init, NULL },
{ "[i430LX] Packard Bell PB520R", "pb520r", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 0, 0, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8, 136, 2, 127, machine_at_pb520r_init, at_pb520r_get_device },
/* OPTi 596/597 */
{ "[OPTi 597] AMI Excalibur VLB", "excalibur", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_VLB | MACHINE_IDE, 2, 64, 2, 127, machine_at_excalibur_init, NULL },
{ "[OPTi 597] AMI Excalibur VLB", "excalibur", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 0, 0, 1.0, 1.0, MACHINE_VLB | MACHINE_IDE, 2, 64, 2, 127, machine_at_excalibur_init, NULL },
/* Socket 5 machines */
/* 430NX */
{ "[i430NX] Intel Premiere/PCI II", "plato", MACHINE_TYPE_SOCKET5, MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2, 128, 2, 127, machine_at_plato_init, NULL },
{ "[i430NX] IBM Ambra DP90 PCI", "ambradp90", MACHINE_TYPE_SOCKET5, MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2, 128, 2, 127, machine_at_ambradp90_init, NULL },
{ "[i430NX] Gigabyte GA-586IP", "430nx", MACHINE_TYPE_SOCKET5, MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2, 128, 2, 127, machine_at_430nx_init, NULL },
{ "[i430NX] Intel Premiere/PCI II", "plato", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3520, 3520, 1.5, 1.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2, 128, 2, 127, machine_at_plato_init, NULL },
{ "[i430NX] IBM Ambra DP90 PCI", "ambradp90", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 1.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2, 128, 2, 127, machine_at_ambradp90_init, NULL },
{ "[i430NX] Gigabyte GA-586IP", "430nx", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 60000000, 66666667, 3520, 3520, 1.5, 1.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2, 128, 2, 127, machine_at_430nx_init, NULL },
/* 430FX */
{ "[i430FX] Acer V30", "acerv30", MACHINE_TYPE_SOCKET5, MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_acerv30_init, NULL },
{ "[i430FX] AMI Apollo", "apollo", MACHINE_TYPE_SOCKET5, MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_apollo_init, NULL },
{ "[i430FX] HP Vectra VL 5 Series 4", "vectra54", MACHINE_TYPE_SOCKET5, MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8, 128, 8, 511, machine_at_vectra54_init, at_vectra54_get_device },
{ "[i430FX] Intel Advanced/ZP", "zappa", MACHINE_TYPE_SOCKET5, MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_zappa_init, NULL },
{ "[i430FX] NEC PowerMate V", "powermate_v", MACHINE_TYPE_SOCKET5, MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_powermate_v_init, NULL },
{ "[i430FX] PC Partner MB500N", "mb500n", MACHINE_TYPE_SOCKET5, MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_mb500n_init, NULL },
{ "[i430FX] Acer V30", "acerv30", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_acerv30_init, NULL },
{ "[i430FX] AMI Apollo", "apollo", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_apollo_init, NULL },
{ "[i430FX] HP Vectra VL 5 Series 4", "vectra54", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8, 128, 8, 511, machine_at_vectra54_init, at_vectra54_get_device },
{ "[i430FX] Intel Advanced/ZP", "zappa", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_zappa_init, NULL },
{ "[i430FX] NEC PowerMate V", "powermate_v", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_powermate_v_init, NULL },
{ "[i430FX] PC Partner MB500N", "mb500n", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_mb500n_init, NULL },
/* Socket 7 machines */
/* 430FX */
{ "[i430FX] ASUS P/I-P54TP4XE", "p54tp4xe", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL },
{ "[i430FX] ASUS P/I-P54TP4XE (MR BIOS)", "mr586", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_mr586_init, NULL },
{ "[i430FX] Gateway 2000 Thor", "gw2katx", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_gw2katx_init, NULL },
{ "[i430FX] Intel Advanced/ATX", "thor", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_thor_init, NULL },
{ "[i430FX] Intel Advanced/ATX (MR BIOS)", "mrthor", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_mrthor_init, NULL },
{ "[i430FX] Intel Advanced/EV", "endeavor", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device },
{ "[i430FX] Packard Bell PB640", "pb640", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_pb640_init, at_pb640_get_device },
{ "[i430FX] QDI Chariot", "chariot", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73VCH, MACHINE_PCI | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_chariot_init, NULL },
{ "[i430FX] ASUS P/I-P54TP4XE", "p54tp4xe", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3600, 1.5, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL },
{ "[i430FX] ASUS P/I-P54TP4XE (MR BIOS)", "mr586", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3600, 1.5, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_mr586_init, NULL },
{ "[i430FX] Gateway 2000 Thor", "gw2katx", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_gw2katx_init, NULL },
{ "[i430FX] Intel Advanced/ATX", "thor", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_thor_init, NULL },
{ "[i430FX] Intel Advanced/ATX (MR BIOS)", "mrthor", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_mrthor_init, NULL },
{ "[i430FX] Intel Advanced/EV", "endeavor", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device },
{ "[i430FX] Packard Bell PB640", "pb640", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_pb640_init, at_pb640_get_device },
{ "[i430FX] QDI Chariot", "chariot", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, CPU_WINCHIP|CPU_WINCHIP2|CPU_Cx6x86|CPU_Cx6x86L|CPU_Cx6x86MX, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_chariot_init, NULL },
/* 430HX */
{ "[i430HX] Acer M3A", "acerm3a", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 192, 8, 127, machine_at_acerm3a_init, NULL },
{ "[i430HX] AOpen AP53", "ap53", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 127, machine_at_ap53_init, NULL },
{ "[i430HX] Biostar MB-8500TUC", "8500tuc", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 127, machine_at_8500tuc_init, NULL },
{ "[i430HX] SuperMicro Super P55T2S", "p55t2s", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 127, machine_at_p55t2s_init, NULL },
{ "[i430HX] Acer M3A", "acerm3a", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3300, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 192, 8, 127, machine_at_acerm3a_init, NULL },
{ "[i430HX] AOpen AP53", "ap53", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3450, 3520, 1.5, 2.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 127, machine_at_ap53_init, NULL },
{ "[i430HX] Biostar MB-8500TUC", "8500tuc", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 127, machine_at_8500tuc_init, NULL },
{ "[i430HX] SuperMicro Super P55T2S", "p55t2s", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3300, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 127, machine_at_p55t2s_init, NULL },
{ "[i430HX] Acer V35N", "acerv35n", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 192, 8, 127, machine_at_acerv35n_init, NULL },
{ "[i430HX] ASUS P/I-P55T2P4", "p55t2p4", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 256, 8, 127, machine_at_p55t2p4_init, NULL },
{ "[i430HX] Micronics M7S-Hi", "m7shi", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 511, machine_at_m7shi_init, NULL },
{ "[i430HX] Intel TC430HX", "tc430hx", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 255, machine_at_tc430hx_init, NULL },
{ "[i430HX] Toshiba Equium 5200D", "equium5200", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 192, 8, 127, machine_at_equium5200_init, NULL },
{ "[i430HX] Sony Vaio PCV-240", "pcv240", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 192, 8, 127, machine_at_pcv240_init, NULL },
{ "[i430HX] ASUS P/I-P65UP5 (C-P55T2D)", "p65up5_cp55t2d", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 127, machine_at_p65up5_cp55t2d_init, NULL },
{ "[i430HX] Acer V35N", "acerv35n", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 192, 8, 127, machine_at_acerv35n_init, NULL },
{ "[i430HX] ASUS P/I-P55T2P4", "p55t2p4", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 75000000, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 256, 8, 127, machine_at_p55t2p4_init, NULL },
{ "[i430HX] Micronics M7S-Hi", "m7shi", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 511, machine_at_m7shi_init, NULL },
{ "[i430HX] Intel TC430HX", "tc430hx", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 255, machine_at_tc430hx_init, NULL },
{ "[i430HX] Toshiba Equium 5200D", "equium5200", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 192, 8, 127, machine_at_equium5200_init, NULL },
{ "[i430HX] Sony Vaio PCV-240", "pcv240", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 192, 8, 127, machine_at_pcv240_init, NULL },
{ "[i430HX] ASUS P/I-P65UP5 (C-P55T2D)", "p65up5_cp55t2d", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 127, machine_at_p65up5_cp55t2d_init, NULL },
/* 430VX */
{ "[i430VX] ASUS P/I-P55TVP4", "p55tvp4", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_p55tvp4_init, NULL },
{ "[i430VX] Biostar MB-8500TVX-A", "8500tvxa", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_8500tvxa_init, NULL },
{ "[i430VX] Compaq Presario 4500", "presario4500", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_presario4500_init, NULL },
{ "[i430VX] Epox P55-VA", "p55va", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_p55va_init, NULL },
{ "[i430VX] Gateway 2000 Tigereye", "gw2kte", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_gw2kte_init, NULL },
{ "[i430VX] HP Brio 80xx", "brio80xx", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_brio80xx_init, NULL },
{ "[i430VX] Packard Bell PB680", "pb680", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_pb680_init, NULL },
{ "[i430VX] Shuttle HOT-557", "430vx", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_i430vx_init, NULL },
{ "[i430VX] ASUS P/I-P55TVP4", "p55tvp4", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_p55tvp4_init, NULL },
{ "[i430VX] Biostar MB-8500TVX-A", "8500tvxa", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2600, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_8500tvxa_init, NULL },
{ "[i430VX] Compaq Presario 4500", "presario4500", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_presario4500_init, NULL },
{ "[i430VX] Epox P55-VA", "p55va", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_p55va_init, NULL },
{ "[i430VX] Gateway 2000 Tigereye", "gw2kte", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_gw2kte_init, NULL },
{ "[i430VX] HP Brio 80xx", "brio80xx", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 66666667, 66666667, 2200, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_brio80xx_init, NULL },
{ "[i430VX] Packard Bell PB680", "pb680", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_pb680_init, NULL },
{ "[i430VX] Shuttle HOT-557", "430vx", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_i430vx_init, NULL },
/* 430TX */
{ "[i430TX] ADLink NuPRO-592", "nupro592", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 256, 8, 255, machine_at_nupro592_init, NULL },
{ "[i430TX] ASUS TX97", "tx97", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 256, 8, 255, machine_at_tx97_init, NULL },
{ "[i430TX] ADLink NuPRO-592", "nupro592", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 66666667, 66666667, 1900, 2800, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 256, 8, 255, machine_at_nupro592_init, NULL },
{ "[i430TX] ASUS TX97", "tx97", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 75000000, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 256, 8, 255, machine_at_tx97_init, NULL },
#if defined(DEV_BRANCH) && defined(NO_SIO)
{ "[i430TX] Intel AN430TX", "an430tx", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 256, 8, 255, machine_at_an430tx_init, NULL },
{ "[i430TX] Intel AN430TX", "an430tx", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 60000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 256, 8, 255, machine_at_an430tx_init, NULL },
#endif
{ "[i430TX] Intel YM430TX", "ym430tx", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 256, 8, 255, machine_at_ym430tx_init, NULL },
{ "[i430TX] PC Partner MB540N", "mb540n", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 256, 8, 255, machine_at_mb540n_init, NULL },
{ "[i430TX] SuperMicro Super P5MMS98", "p5mms98", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 256, 8, 255, machine_at_p5mms98_init, NULL },
{ "[i430TX] Intel YM430TX", "ym430tx", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 60000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 256, 8, 255, machine_at_ym430tx_init, NULL },
{ "[i430TX] PC Partner MB540N", "mb540n", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 60000000, 66666667, 2700, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 256, 8, 255, machine_at_mb540n_init, NULL },
{ "[i430TX] SuperMicro Super P5MMS98", "p5mms98", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2100, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 256, 8, 255, machine_at_p5mms98_init, NULL },
/* Apollo VPX */
{ "[VIA VPX] FIC VA-502", "ficva502", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 127, machine_at_ficva502_init, NULL },
{ "[VIA VPX] FIC VA-502", "ficva502", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 75000000, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 127, machine_at_ficva502_init, NULL },
/* Apollo VP3 */
{ "[VIA VP3] FIC PA-2012", "ficpa2012", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 127, machine_at_ficpa2012_init, NULL },
{ "[VIA VP3] FIC PA-2012", "ficpa2012", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 55000000, 75000000, 2100, 3520, 1.5, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 127, machine_at_ficpa2012_init, NULL },
/* Super Socket 7 machines */
/* Apollo MVP3 */
{ "[VIA MVP3] AOpen AX59 Pro", "ax59pro", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_ax59pro_init, NULL },
{ "[VIA MVP3] FIC VA-503+", "ficva503p", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_mvp3_init, NULL },
{ "[VIA MVP3] FIC VA-503A", "ficva503a", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_ficva503a_init, NULL },
{ "[VIA MVP3] AOpen AX59 Pro", "ax59pro", MACHINE_TYPE_SOCKETS7, CPU_PKG_SOCKET5_7, 0, 66666667, 124242424, 1300, 3520, 1.5, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_ax59pro_init, NULL },
{ "[VIA MVP3] FIC VA-503+", "ficva503p", MACHINE_TYPE_SOCKETS7, CPU_PKG_SOCKET5_7, 0, 66666667, 124242424, 2000, 3200, 1.5, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_mvp3_init, NULL },
{ "[VIA MVP3] FIC VA-503A", "ficva503a", MACHINE_TYPE_SOCKETS7, CPU_PKG_SOCKET5_7, 0, 66666667, 124242424, 1800, 3100, 1.5, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_ficva503a_init, NULL },
/* Socket 8 machines */
/* 440FX */
{ "[i440FX] Acer V60N", "v60n", MACHINE_TYPE_SOCKET8, {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 127, machine_at_v60n_init, NULL },
{ "[i440FX] ASUS P/I-P65UP5 (C-P6ND)", "p65up5_cp6nd", MACHINE_TYPE_SOCKET8, {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 127, machine_at_p65up5_cp6nd_init, NULL },
{ "[i440FX] Biostar MB-8600TTC", "8600ttc", MACHINE_TYPE_SOCKET8, {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 127, machine_at_8500ttc_init, NULL },
{ "[i440FX] Gigabyte GA-686NX", "686nx", MACHINE_TYPE_SOCKET8, {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 127, machine_at_686nx_init, NULL },
{ "[i440FX] Intel AP440FX", "ap440fx", MACHINE_TYPE_SOCKET8, {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_ap440fx_init, NULL },
{ "[i440FX] Intel VS440FX", "vs440fx", MACHINE_TYPE_SOCKET8, {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 127, machine_at_vs440fx_init, NULL },
{ "[i440FX] Micronics M6Mi", "m6mi", MACHINE_TYPE_SOCKET8, {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 127, machine_at_m6mi_init, NULL },
{ "[i440FX] PC Partner MB600N", "mb600n", MACHINE_TYPE_SOCKET8, {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 127, machine_at_mb600n_init, NULL },
{ "[i440FX] Acer V60N", "v60n", MACHINE_TYPE_SOCKET8, CPU_PKG_SOCKET8, 0, 60000000, 66666667, 2500, 3500, 2.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 127, machine_at_v60n_init, NULL },
{ "[i440FX] ASUS P/I-P65UP5 (C-P6ND)", "p65up5_cp6nd", MACHINE_TYPE_SOCKET8, CPU_PKG_SOCKET8, 0, 60000000, 66666667, 2100, 3500, 2.0, 4.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 127, machine_at_p65up5_cp6nd_init, NULL },
{ "[i440FX] Biostar MB-8600TTC", "8600ttc", MACHINE_TYPE_SOCKET8, CPU_PKG_SOCKET8, 0, 50000000, 66666667, 2900, 3300, 2.0, 3.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 127, machine_at_8500ttc_init, NULL },
{ "[i440FX] Gigabyte GA-686NX", "686nx", MACHINE_TYPE_SOCKET8, CPU_PKG_SOCKET8, 0, 60000000, 66666667, 2100, 3500, 2.5, 4.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 127, machine_at_686nx_init, NULL },
{ "[i440FX] Intel AP440FX", "ap440fx", MACHINE_TYPE_SOCKET8, CPU_PKG_SOCKET8, 0, 60000000, 66666667, 2100, 3500, 2.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 128, 8, 127, machine_at_ap440fx_init, NULL },
{ "[i440FX] Intel VS440FX", "vs440fx", MACHINE_TYPE_SOCKET8, CPU_PKG_SOCKET8, 0, 60000000, 66666667, 2100, 3500, 2.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 127, machine_at_vs440fx_init, NULL },
{ "[i440FX] Micronics M6Mi", "m6mi", MACHINE_TYPE_SOCKET8, CPU_PKG_SOCKET8, 0, 60000000, 66666667, 2900, 3300, 2.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 127, machine_at_m6mi_init, NULL },
{ "[i440FX] PC Partner MB600N", "mb600n", MACHINE_TYPE_SOCKET8, CPU_PKG_SOCKET8, 0, 60000000, 66666667, 2100, 3500, 2.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 127, machine_at_mb600n_init, NULL },
/* Slot 1 machines */
/* 440FX */
{ "[i440FX] ASUS P/I-P65UP5 (C-PKND)", "p65up5_cpknd", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII66}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 127, machine_at_p65up5_cpknd_init, NULL },
{ "[i440FX] ASUS KN97", "kn97", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII66}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 127, machine_at_kn97_init, NULL },
{ "[i440FX] ASUS P/I-P65UP5 (C-PKND)", "p65up5_cpknd", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 50000000, 66666667, 1800, 3500, 2.0, 5.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 127, machine_at_p65up5_cpknd_init, NULL },
{ "[i440FX] ASUS KN97", "kn97", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 60000000, 83333333, 1800, 3500, 2.0, 5.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 127, machine_at_kn97_init, NULL },
/* 440LX */
{ "[i440LX] ABIT LX6", "lx6", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII66}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_lx6_init, NULL },
{ "[i440LX] Micronics Spitfire", "spitfire", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII66}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_spitfire_init, NULL },
{ "[i440LX] ABIT LX6", "lx6", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 60000000, 100000000, 1500, 3500, 2.0, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_lx6_init, NULL },
{ "[i440LX] Micronics Spitfire", "spitfire", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 66666667, 1800, 3500, 3.5, 6.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_spitfire_init, NULL },
/* 440EX */
{ "[i440EX] QDI EXCELLENT II", "p6i440e2", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII66}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 255, machine_at_p6i440e2_init, NULL },
{ "[i440EX] QDI EXCELLENT II", "p6i440e2", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 83333333, 1800, 3500, 3.0, 8.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 255, machine_at_p6i440e2_init, NULL },
/* 440BX */
{ "[i440BX] ASUS P2B-LS", "p2bls", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_p2bls_init, NULL },
{ "[i440BX] ASUS P3B-F", "p3bf", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_p3bf_init, NULL },
{ "[i440BX] ABIT BF6", "bf6", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_bf6_init, NULL },
{ "[i440BX] AOpen AX6BC", "ax6bc", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_ax6bc_init, NULL },
{ "[i440BX] A-Trend ATC6310BXII", "atc6310bxii", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_atc6310bxii_init, NULL },
{ "[i440BX] Gigabyte GA-686BX", "ga686bx", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_ga686bx_init, NULL },
{ "[i440BX] Tyan Tsunami ATX", "tsunamiatx", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_SOUND, 8, 1024, 8, 255, machine_at_tsunamiatx_init, at_tsunamiatx_get_device },
{ "[i440BX] SuperMicro Super P6SBA", "p6sba", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_p6sba_init, NULL },
{ "[i440BX] ASUS P2B-LS", "p2bls", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 50000000, 112121212, 1800, 3500, 2.0, 6.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_p2bls_init, NULL },
{ "[i440BX] ASUS P3B-F", "p3bf", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 150000000, 1800, 3500, 2.0, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_p3bf_init, NULL },
{ "[i440BX] ABIT BF6", "bf6", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 133333333, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_bf6_init, NULL },
{ "[i440BX] AOpen AX6BC", "ax6bc", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 112121212, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_ax6bc_init, NULL },
{ "[i440BX] A-Trend ATC6310BXII", "atc6310bxii", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 133333333, 1800, 3500, 3.0, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_atc6310bxii_init, NULL },
{ "[i440BX] Gigabyte GA-686BX", "ga686bx", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 100000000, 1800, 3500, 3.0, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_ga686bx_init, NULL },
{ "[i440BX] Tyan Tsunami ATX", "tsunamiatx", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 112121212, 1800, 3500, 3.5, 5.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_SOUND, 8, 1024, 8, 255, machine_at_tsunamiatx_init, at_tsunamiatx_get_device },
{ "[i440BX] SuperMicro Super P6SBA", "p6sba", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 100000000, 1800, 3500, 3.0, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_p6sba_init, NULL },
#if defined(DEV_BRANCH) && defined(NO_SIO)
{ "[i440BX] Fujitsu ErgoPro x365", "ergox365", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 384, 8, 511, machine_at_ergox365_init, NULL },
{ "[i440BX] Fujitsu ErgoPro x365", "ergox365", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 100000000, 1800, 3500, 3.5, 5.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 384, 8, 511, machine_at_ergox365_init, NULL },
#endif
/* 440GX */
{ "[i440GX] Freeway FW-6400GX", "fw6400gx_s1", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 16, 2032, 16, 511, machine_at_fw6400gx_init, NULL },
{ "[i440GX] Freeway FW-6400GX", "fw6400gx_s1", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 100000000, 150000000, 1800, 3500, 3.0, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 16, 2032, 16, 511, machine_at_fw6400gx_init, NULL },
/* VIA Apollo Pro */
{ "[VIA Apollo Pro] FIC KA-6130", "ficka6130", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 255, machine_at_ficka6130_init, NULL },
{ "[VIA Apollo Pro] FIC KA-6130", "ficka6130", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 100000000, 1800, 3500, 3.5, 5.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 255, machine_at_ficka6130_init, NULL },
/* Slot 2 machines(Including Slot 1/2 Hybrids) */
/* 440GX */
{ "[i440GX] Gigabyte GA-6GXU", "6gxu", MACHINE_TYPE_SLOT2, {{"Intel", cpus_Xeon}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 16, 2048, 16, 511, machine_at_6gxu_init, NULL },
{ "[i440GX] Freeway FW-6400GX", "fw6400gx", MACHINE_TYPE_SLOT2, {{"Intel", cpus_Xeon}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 16, 2032, 16, 511, machine_at_fw6400gx_init, NULL },
{ "[i440GX] SuperMicro Super S2DGE", "s2dge", MACHINE_TYPE_SLOT2, {{"Intel", cpus_Xeon}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 16, 2048, 16, 511, machine_at_s2dge_init, NULL },
{ "[i440GX] Gigabyte GA-6GXU", "6gxu", MACHINE_TYPE_SLOT2, CPU_PKG_SLOT2, 0, 100000000, 133333333, 1800, 3500, 4.0, 6.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 16, 2048, 16, 511, machine_at_6gxu_init, NULL },
{ "[i440GX] Freeway FW-6400GX", "fw6400gx", MACHINE_TYPE_SLOT2, CPU_PKG_SLOT2, 0, 100000000, 150000000, 1800, 3500, 3.0, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 16, 2032, 16, 511, machine_at_fw6400gx_init, NULL },
{ "[i440GX] SuperMicro Super S2DGE", "s2dge", MACHINE_TYPE_SLOT2, CPU_PKG_SLOT2, 0, 66666667, 100000000, 1800, 3500, 3.0, 7.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 16, 2048, 16, 511, machine_at_s2dge_init, NULL },
/* PGA370 machines */
/* 440LX */
{ "[i440LX] SuperMicro Super 370SLM", "s370slm", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_s370slm_init, NULL },
{ "[i440LX] SuperMicro Super 370SLM", "s370slm", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 100000000, 1800, 3500, MACHINE_MULTIPLIER_FIXED, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_s370slm_init, NULL },
/* 440BX */
{ "[i440BX] AEWIN AW-O671R", "awo671r", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 255, machine_at_awo671r_init, NULL },
{ "[i440BX] ASUS CUBX", "cubx", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_cubx_init, NULL },
{ "[i440BX] A-Trend ATC7020BXII", "atc7020bxii", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_atc7020bxii_init, NULL },
{ "[i440BX] AmazePC AM-BX133", "ambx133", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_ambx133_init, NULL },
{ "[i440BX] TYAN Trinity 371", "trinity371", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_trinity371_init, NULL },
{ "[i440BX] AEWIN AW-O671R", "awo671r", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 133333333, 1800, 3500, 0, 0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 255, machine_at_awo671r_init, NULL },
{ "[i440BX] ASUS CUBX", "cubx", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1800, 3500, 2.0, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_cubx_init, NULL },
{ "[i440BX] A-Trend ATC7020BXII", "atc7020bxii", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 133333333, 1800, 3500, 3.0, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_atc7020bxii_init, NULL },
{ "[i440BX] AmazePC AM-BX133", "ambx133", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 133333333, 1800, 3500, 0, 0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_ambx133_init, NULL },
{ "[i440BX] Tyan Trinity 371", "trinity371", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 133333333, 1800, 3500, 3.5, 7.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_trinity371_init, NULL },
/* 440ZX */
{ "[i440ZX] Soltek SL-63A1", "63a", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 255, machine_at_63a_init, NULL },
{ "[i440ZX] Soltek SL-63A1", "63a", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 100000000, 1800, 3500, 2.0, 7.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 255, machine_at_63a_init, NULL },
/* VIA Apollo Pro */
{ "[VIA Apollo Pro] PC Partner APAS3", "apas3", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_apas3_init, NULL },
{ "[VIA Apollo Pro133A] Aewin WCF-681", "wcf681", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_wcf681_init, NULL },
{ "[VIA Apollo Pro133A] Acorp 6VIA85X", "6via85x", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_6via85x_init, NULL },
{ "[VIA Apollo Pro133A] ECS P6BAP", "p6bap", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_p6bap_init, NULL },
{ "[VIA Apollo ProMedia] Jetway 603TCF", "603tcf", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 512, 8, 255, machine_at_603tcf_init, NULL },
{ "[VIA Apollo Pro] PC Partner APAS3", "apas3", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 100000000, 1800, 3500, 3.0, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 768, 8, 255, machine_at_apas3_init, NULL },
{ "[VIA Apollo Pro133A] AEWIN WCF-681", "wcf681", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 133333333, 1800, 3500, 0, 0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_wcf681_init, NULL },
{ "[VIA Apollo Pro133A] Acorp 6VIA85X", "6via85x", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 133333333, 1800, 3500, MACHINE_MULTIPLIER_FIXED, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1536, 8, 255, machine_at_6via85x_init, NULL },
{ "[VIA Apollo Pro133A] ECS P6BAP", "p6bap", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1800, 3500, 2.0, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1536, 8, 255, machine_at_p6bap_init, NULL },
{ "[VIA Apollo ProMedia] Jetway 603TCF", "603tcf", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1800, 3500, 2.0, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_603tcf_init, NULL },
/* Miscellaneous/Fake/Hypervisor machines */
{ "[i440BX] Microsoft Virtual PC 2007", "vpc2007", MACHINE_TYPE_MISC, {{"Intel", cpus_PentiumIID}, {"Intel/PGA370", cpus_Celeron},{"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_vpc2007_init, NULL },
{ "[i440BX] Microsoft Virtual PC 2007", "vpc2007", MACHINE_TYPE_MISC, CPU_PKG_SLOT1, CPU_PENTIUM2 | CPU_CYRIX3S, 0, 0, 0, 0, 0, 0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8, 1024, 8, 255, machine_at_vpc2007_init, NULL },
{ NULL, NULL, MACHINE_TYPE_NONE, {{"", 0}, {"", 0}, {"", 0}, {"", 0}, {"", 0}}, 0, 0, 0, 0, 0, NULL, NULL }
{ NULL, NULL, MACHINE_TYPE_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL }
};

View File

@@ -40,8 +40,8 @@ enum
{
BLOCK_MAIN1,
BLOCK_MAIN2,
BLOCK_MAIN3,
BLOCK_MAIN4,
BLOCK_MAIN3,
BLOCK_MAIN4,
BLOCK_DATA1,
BLOCK_DATA2,
BLOCK_BOOT,
@@ -185,7 +185,7 @@ flash_write(uint32_t addr, uint8_t val, void *p)
switch (dev->command) {
case CMD_ERASE_SETUP:
if (val == CMD_ERASE_CONFIRM) {
for (i = 0; i < 3; i++) {
for (i = 0; i < 6; i++) {
if ((i == dev->program_addr) && (addr >= dev->block_start[i]) && (addr <= dev->block_end[i]))
memset(&(dev->array[dev->block_start[i]]), 0xff, dev->block_len[i]);
}
@@ -197,7 +197,7 @@ flash_write(uint32_t addr, uint8_t val, void *p)
case CMD_PROGRAM_SETUP:
case CMD_PROGRAM_SETUP_ALT:
if (((addr & bb_mask) != (dev->block_start[4] & bb_mask)) && (addr == dev->program_addr))
if (((addr & bb_mask) != (dev->block_start[6] & bb_mask)) && (addr == dev->program_addr))
dev->array[addr] = val;
dev->command = CMD_READ_STATUS;
dev->status = 0x80;
@@ -210,7 +210,7 @@ flash_write(uint32_t addr, uint8_t val, void *p)
dev->status = 0;
break;
case CMD_ERASE_SETUP:
for (i = 0; i < 3; i++) {
for (i = 0; i < 7; i++) {
if ((addr >= dev->block_start[i]) && (addr <= dev->block_end[i]))
dev->program_addr = i;
}
@@ -242,7 +242,7 @@ flash_writew(uint32_t addr, uint16_t val, void *p)
if (dev->flags & FLAG_WORD) switch (dev->command) {
case CMD_ERASE_SETUP:
if (val == CMD_ERASE_CONFIRM) {
for (i = 0; i < 3; i++) {
for (i = 0; i < 6; i++) {
if ((i == dev->program_addr) && (addr >= dev->block_start[i]) && (addr <= dev->block_end[i]))
memset(&(dev->array[dev->block_start[i]]), 0xff, dev->block_len[i]);
}
@@ -254,7 +254,7 @@ flash_writew(uint32_t addr, uint16_t val, void *p)
case CMD_PROGRAM_SETUP:
case CMD_PROGRAM_SETUP_ALT:
if (((addr & bb_mask) != (dev->block_start[4] & bb_mask)) && (addr == dev->program_addr))
if (((addr & bb_mask) != (dev->block_start[6] & bb_mask)) && (addr == dev->program_addr))
*(uint16_t *) (&dev->array[addr]) = val;
dev->command = CMD_READ_STATUS;
dev->status = 0x80;
@@ -267,7 +267,7 @@ flash_writew(uint32_t addr, uint16_t val, void *p)
dev->status = 0;
break;
case CMD_ERASE_SETUP:
for (i = 0; i < 3; i++) {
for (i = 0; i < 7; i++) {
if ((addr >= dev->block_start[i]) && (addr <= dev->block_end[i]))
dev->program_addr = i;
}
@@ -381,53 +381,52 @@ intel_flash_init(const device_t *info)
dev->array = (uint8_t *) malloc(biosmask + 1);
memset(dev->array, 0xff, biosmask + 1);
switch(biosmask){
switch (biosmask) {
case 0x7ffff:
if (dev->flags & FLAG_WORD)
dev->flash_id = (dev->flags & FLAG_BXB) ? 0x4471 : 0x4470;
else
dev->flash_id =(dev->flags & FLAG_BXB) ? 0x8A : 0x89;
if (dev->flags & FLAG_WORD)
dev->flash_id = (dev->flags & FLAG_BXB) ? 0x4471 :0x4470;
else
dev->flash_id =(dev->flags & FLAG_BXB) ? 0x8A : 0x89;
/* The block lengths are the same both flash types. */
dev->block_len[BLOCK_MAIN1] = 0x20000;
dev->block_len[BLOCK_MAIN2] = 0x20000;
dev->block_len[BLOCK_MAIN3] = 0x20000;
dev->block_len[BLOCK_MAIN4] = 0x18000;
dev->block_len[BLOCK_DATA1] = 0x02000;
dev->block_len[BLOCK_DATA2] = 0x02000;
dev->block_len[BLOCK_BOOT] = 0x04000;
/* The block lengths are the same both flash types. */
dev->block_len[BLOCK_MAIN1] = 0x20000;
dev->block_len[BLOCK_MAIN2] = 0x20000;
dev->block_len[BLOCK_MAIN3] = 0x20000;
dev->block_len[BLOCK_MAIN4] = 0x18000;
dev->block_len[BLOCK_DATA1] = 0x02000;
dev->block_len[BLOCK_DATA2] = 0x02000;
dev->block_len[BLOCK_BOOT] = 0x04000;
if (dev->flags & FLAG_BXB) { /* 28F004BX-T/28F400BX-B */
dev->block_start[BLOCK_BOOT] = 0x00000; /* MAIN BLOCK 1 */
dev->block_end[BLOCK_BOOT] = 0x1ffff;
dev->block_start[BLOCK_DATA2] = 0x20000; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_DATA2] = 0x3ffff;
dev->block_start[BLOCK_DATA1] = 0x40000; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_DATA1] = 0x5ffff;
dev->block_start[BLOCK_MAIN4] = 0x60000; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0x77fff;
dev->block_start[BLOCK_MAIN3] = 0x78000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_MAIN3] = 0x79fff;
dev->block_start[BLOCK_MAIN2] = 0x7a000; /* DATA AREA 2 BLOCK */
dev->block_end[BLOCK_MAIN2] = 0x7bfff;
dev->block_start[BLOCK_MAIN1] = 0x7c000; /* BOOT BLOCK */
dev->block_end[BLOCK_MAIN1] = 0x7ffff;
} else {
dev->block_start[BLOCK_MAIN1] = 0x00000; /* MAIN BLOCK 1 */
dev->block_end[BLOCK_MAIN1] = 0x1ffff;
dev->block_start[BLOCK_MAIN2] = 0x20000; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_MAIN2] = 0x3ffff;
dev->block_start[BLOCK_MAIN3] = 0x40000; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_MAIN3] = 0x5ffff;
dev->block_start[BLOCK_MAIN4] = 0x60000; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0x77fff;
dev->block_start[BLOCK_DATA1] = 0x78000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_DATA1] = 0x79fff;
dev->block_start[BLOCK_DATA2] = 0x7a000; /* DATA AREA 2 BLOCK */
dev->block_end[BLOCK_DATA2] = 0x7bfff;
dev->block_start[BLOCK_BOOT] = 0x7c000; /* BOOT BLOCK */
dev->block_end[BLOCK_BOOT] = 0x7ffff;
if (dev->flags & FLAG_BXB) { /* 28F004BX-T/28F400BX-B */
dev->block_start[BLOCK_BOOT] = 0x00000; /* MAIN BLOCK 1 */
dev->block_end[BLOCK_BOOT] = 0x1ffff;
dev->block_start[BLOCK_DATA2] = 0x20000; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_DATA2] = 0x3ffff;
dev->block_start[BLOCK_DATA1] = 0x40000; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_DATA1] = 0x5ffff;
dev->block_start[BLOCK_MAIN4] = 0x60000; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0x77fff;
dev->block_start[BLOCK_MAIN3] = 0x78000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_MAIN3] = 0x79fff;
dev->block_start[BLOCK_MAIN2] = 0x7a000; /* DATA AREA 2 BLOCK */
dev->block_end[BLOCK_MAIN2] = 0x7bfff;
dev->block_start[BLOCK_MAIN1] = 0x7c000; /* BOOT BLOCK */
dev->block_end[BLOCK_MAIN1] = 0x7ffff;
} else {
dev->block_start[BLOCK_MAIN1] = 0x00000; /* MAIN BLOCK 1 */
dev->block_end[BLOCK_MAIN1] = 0x1ffff;
dev->block_start[BLOCK_MAIN2] = 0x20000; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_MAIN2] = 0x3ffff;
dev->block_start[BLOCK_MAIN3] = 0x40000; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_MAIN3] = 0x5ffff;
dev->block_start[BLOCK_MAIN4] = 0x60000; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0x77fff;
dev->block_start[BLOCK_DATA1] = 0x78000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_DATA1] = 0x79fff;
dev->block_start[BLOCK_DATA2] = 0x7a000; /* DATA AREA 2 BLOCK */
dev->block_end[BLOCK_DATA2] = 0x7bfff;
dev->block_start[BLOCK_BOOT] = 0x7c000; /* BOOT BLOCK */
dev->block_end[BLOCK_BOOT] = 0x7ffff;
}
break;
@@ -440,6 +439,8 @@ intel_flash_init(const device_t *info)
/* The block lengths are the same both flash types. */
dev->block_len[BLOCK_MAIN1] = 0x20000;
dev->block_len[BLOCK_MAIN2] = 0x18000;
dev->block_len[BLOCK_MAIN3] = 0x00000;
dev->block_len[BLOCK_MAIN4] = 0x00000;
dev->block_len[BLOCK_DATA1] = 0x02000;
dev->block_len[BLOCK_DATA2] = 0x02000;
dev->block_len[BLOCK_BOOT] = 0x04000;
@@ -449,6 +450,10 @@ intel_flash_init(const device_t *info)
dev->block_end[BLOCK_MAIN1] = 0x3ffff;
dev->block_start[BLOCK_MAIN2] = 0x08000; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_MAIN2] = 0x1ffff;
dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_MAIN3] = 0xfffff;
dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0xfffff;
dev->block_start[BLOCK_DATA1] = 0x06000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_DATA1] = 0x07fff;
dev->block_start[BLOCK_DATA2] = 0x04000; /* DATA AREA 2 BLOCK */
@@ -460,6 +465,10 @@ intel_flash_init(const device_t *info)
dev->block_end[BLOCK_MAIN1] = 0x1ffff;
dev->block_start[BLOCK_MAIN2] = 0x20000; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_MAIN2] = 0x37fff;
dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_MAIN3] = 0xfffff;
dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0xfffff;
dev->block_start[BLOCK_DATA1] = 0x38000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_DATA1] = 0x39fff;
dev->block_start[BLOCK_DATA2] = 0x3a000; /* DATA AREA 2 BLOCK */
@@ -467,14 +476,16 @@ intel_flash_init(const device_t *info)
dev->block_start[BLOCK_BOOT] = 0x3c000; /* BOOT BLOCK */
dev->block_end[BLOCK_BOOT] = 0x3ffff;
}
break;
break;
default:
default:
dev->flash_id = (type & FLAG_BXB) ? 0x95 : 0x94;
/* The block lengths are the same both flash types. */
dev->block_len[BLOCK_MAIN1] = 0x1c000;
dev->block_len[BLOCK_MAIN2] = 0x00000;
dev->block_len[BLOCK_MAIN3] = 0x00000;
dev->block_len[BLOCK_MAIN4] = 0x00000;
dev->block_len[BLOCK_DATA1] = 0x01000;
dev->block_len[BLOCK_DATA2] = 0x01000;
dev->block_len[BLOCK_BOOT] = 0x02000;
@@ -484,6 +495,10 @@ intel_flash_init(const device_t *info)
dev->block_end[BLOCK_MAIN1] = 0x1ffff;
dev->block_start[BLOCK_MAIN2] = 0xfffff; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_MAIN2] = 0xfffff;
dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_MAIN3] = 0xfffff;
dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0xfffff;
dev->block_start[BLOCK_DATA1] = 0x02000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_DATA1] = 0x02fff;
dev->block_start[BLOCK_DATA2] = 0x03000; /* DATA AREA 2 BLOCK */
@@ -495,6 +510,10 @@ intel_flash_init(const device_t *info)
dev->block_end[BLOCK_MAIN1] = 0x1bfff;
dev->block_start[BLOCK_MAIN2] = 0xfffff; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_MAIN2] = 0xfffff;
dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_MAIN3] = 0xfffff;
dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0xfffff;
dev->block_start[BLOCK_DATA1] = 0x1c000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_DATA1] = 0x1cfff;
dev->block_start[BLOCK_DATA2] = 0x1d000; /* DATA AREA 2 BLOCK */
@@ -502,8 +521,8 @@ intel_flash_init(const device_t *info)
dev->block_start[BLOCK_BOOT] = 0x1e000; /* BOOT BLOCK */
dev->block_end[BLOCK_BOOT] = 0x1ffff;
}
break;
}
break;
}
intel_flash_add_mappings(dev);

View File

@@ -549,8 +549,6 @@ addreadlookup(uint32_t virt, uint32_t phys)
uint32_t a;
#endif
return;
if (virt == 0xffffffff) return;
if (readlookup2[virt>>12] != (uintptr_t) LOOKUP_INV) return;
@@ -586,8 +584,6 @@ addwritelookup(uint32_t virt, uint32_t phys)
uint32_t a;
#endif
return;
if (virt == 0xffffffff) return;
if (page_lookup[virt >> 12]) return;

View File

@@ -364,8 +364,8 @@ bios_add(void)
{
int temp_cpu_type, temp_cpu_16bitbus = 1;
if (AT) {
temp_cpu_type = machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type;
if (AT && cpu_s) {
temp_cpu_type = cpu_s->cpu_type;
temp_cpu_16bitbus = (temp_cpu_type == CPU_286 || temp_cpu_type == CPU_386SX || temp_cpu_type == CPU_486SLC || temp_cpu_type == CPU_IBM386SLC || temp_cpu_type == CPU_IBM486SLC );
}
@@ -471,7 +471,7 @@ bios_load_linear_combined2(wchar_t *fn1, wchar_t *fn2, wchar_t *fn3, wchar_t *fn
ret &= bios_load_aux_linear(fn2, 0x000c0000, 65536, off);
ret &= bios_load_aux_linear(fn4, 0x000e0000, sz - 196608, off);
if (fn5 != NULL)
ret &= bios_load_aux_linear(fn5, 0x000ec000, 16384, off);
ret &= bios_load_aux_linear(fn5, 0x000ec000, 16384, 0);
return ret;
}

View File

@@ -136,9 +136,8 @@ int sound_is_float = 1, /* (C) sound uses FP values */
SSI2001 = 0, /* (C) sound option */
voodoo_enabled = 0; /* (C) video option */
uint32_t mem_size = 0; /* (C) memory size */
int cpu_manufacturer = 0, /* (C) cpu manufacturer */
cpu_use_dynarec = 0, /* (C) cpu uses/needs Dyna */
cpu = 3, /* (C) cpu type */
int cpu_use_dynarec = 0, /* (C) cpu uses/needs Dyna */
cpu = 0, /* (C) cpu type */
fpu_type = 0; /* (C) fpu type */
int time_sync = 0; /* (C) enable time sync */
int confirm_reset = 1, /* (C) enable reset confirmation */
@@ -538,8 +537,8 @@ usage:
void
pc_speed_changed(void)
{
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type >= CPU_286)
pit_set_clock(machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed);
if (cpu_s->cpu_type >= CPU_286)
pit_set_clock(cpu_s->rspeed);
else
pit_set_clock(14318184.0);
}
@@ -928,8 +927,8 @@ pc_close(thread_t *ptr)
void
pc_thread(void *param)
{
wchar_t temp[200], wcpu[2048];
wchar_t wmachine[2048];
wchar_t temp[200], wcpufamily[2048], wcpu[2048];
wchar_t wmachine[2048], *wcp;
uint64_t start_time, end_time;
uint32_t old_time, new_time;
int done, drawits, frames;
@@ -957,7 +956,7 @@ pc_thread(void *param)
/* Run a block of code. */
startblit();
clockrate = machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed;
clockrate = cpu_s->rspeed;
if (is386) {
#ifdef USE_DYNAREC
@@ -966,7 +965,7 @@ pc_thread(void *param)
else
#endif
exec386(clockrate/100);
} else if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type >= CPU_286) {
} else if (cpu_s->cpu_type >= CPU_286) {
exec386(clockrate/100);
} else {
execx86(clockrate/100);
@@ -991,11 +990,16 @@ pc_thread(void *param)
if (title_update) {
mbstowcs(wmachine, machine_getname(), strlen(machine_getname())+1);
mbstowcs(wcpu, machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].name,
strlen(machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].name)+1);
mbstowcs(wcpufamily, cpu_f->name,
strlen(cpu_f->name)+1);
wcp = wcschr(wcpufamily, L'(');
if (wcp) /* remove parentheses */
*(wcp - 1) = L'\0';
mbstowcs(wcpu, cpu_s->name,
strlen(cpu_s->name)+1);
swprintf(temp, sizeof_w(temp),
L"%ls v%ls - %i%% - %ls - %ls - %ls",
EMU_NAME_W,EMU_VERSION_W,fps,wmachine,wcpu,
L"%ls v%ls - %i%% - %ls - %ls/%ls - %ls",
EMU_NAME_W,EMU_VERSION_W,fps,wmachine,wcpufamily,wcpu,
(!mouse_capture) ? plat_get_string(IDS_2077)
: (mouse_get_buttons() > 2) ? plat_get_string(IDS_2078) : plat_get_string(IDS_2079));

View File

@@ -196,6 +196,9 @@ pic_update_pending(void)
pic.irr |= (1 << pic2.icw3);
else
pic.irr &= ~(1 << pic2.icw3);
pic.int_pending = (find_best_interrupt(&pic) != -1);
return;
}
if (find_best_interrupt(&pic) != -1) {

View File

@@ -953,7 +953,7 @@ void
pit_set_clock(int clock)
{
/* Set default CPU/crystal clock and xt_cpu_multi. */
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type >= CPU_286) {
if (cpu_s->cpu_type >= CPU_286) {
if (clock == 66666666)
cpuclock = 200000000.0 / 3.0;
else if (clock == 33333333)
@@ -973,9 +973,9 @@ pit_set_clock(int clock)
CGACONST = (8ULL << 32ULL);
xt_cpu_multi = 3ULL;
switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed) {
switch (cpu_s->rspeed) {
case 7159092:
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_flags & CPU_ALTERNATE_XTAL) {
if (cpu_s->cpu_flags & CPU_ALTERNATE_XTAL) {
cpuclock = 28636368.0;
xt_cpu_multi = 4ULL;
} else
@@ -999,7 +999,7 @@ pit_set_clock(int clock)
break;
default:
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_flags & CPU_ALTERNATE_XTAL) {
if (cpu_s->cpu_flags & CPU_ALTERNATE_XTAL) {
cpuclock = 28636368.0;
xt_cpu_multi = 6ULL;
}
@@ -1021,7 +1021,7 @@ pit_set_clock(int clock)
xt_cpu_multi <<= 32ULL;
/* Delay for empty I/O ports. */
io_delay = (int) round(((double) machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed) / 3000000.0);
io_delay = (int) round(((double) cpu_s->rspeed) / 3000000.0);
MDACONST = (uint64_t) (cpuclock / 2032125.0 * (double)(1ull << 32));
HERCCONST = MDACONST;

View File

@@ -281,7 +281,7 @@ fdc37c669_init(const device_t *info)
dev->uart[0] = device_add_inst(&ns16550_device, 1);
dev->uart[1] = device_add_inst(&ns16550_device, 2);
io_sethandler(0x3f0, 0x0002,
io_sethandler(info->local ? 0x370 : 0x3f0, 0x0002,
fdc37c669_read, NULL, NULL, fdc37c669_write, NULL, NULL, dev);
fdc37c669_reset(dev);
@@ -298,3 +298,13 @@ const device_t fdc37c669_device = {
{ NULL }, NULL, NULL,
NULL
};
const device_t fdc37c669_370_device = {
"SMC FDC37C669 Super I/O (Port 370h)",
0,
1,
fdc37c669_init, fdc37c669_close, NULL,
{ NULL }, NULL, NULL,
NULL
};

View File

@@ -32,6 +32,7 @@
#include <86box/rom.h>
#include <86box/plat.h>
#include <86box/video.h>
#include <86box/vid_ddc.h>
#include <86box/vid_svga.h>
#include <86box/vid_svga_render.h>
#include <86box/vid_ati_eeprom.h>
@@ -1737,6 +1738,7 @@ static void mach64_vblank_start(svga_t *svga)
uint8_t mach64_ext_readb(uint32_t addr, void *p)
{
mach64_t *mach64 = (mach64_t *)p;
uint8_t gpio_state;
uint8_t ret;
if (!(addr & 0x400))
@@ -1866,11 +1868,27 @@ uint8_t mach64_ext_readb(uint32_t addr, void *p)
else
ret = ati68860_ramdac_in(addr & 3, mach64->svga.ramdac, &mach64->svga);
break;
case 0xc4: case 0xc5: case 0xc6: case 0xc7:
if (mach64->type == MACH64_VT2)
mach64->dac_cntl |= (4 << 24);
case 0xc4: case 0xc5: case 0xc6:
READ8(addr, mach64->dac_cntl);
break;
case 0xc7:
READ8(addr, mach64->dac_cntl);
if (mach64->type == MACH64_VT2) {
gpio_state = 6;
if ((ret & (1 << 4)) && !(ret & (1 << 1)))
gpio_state &= ~(1 << 1);
if (!(ret & (1 << 4)) && !ddc_read_data())
gpio_state &= ~(1 << 1);
if ((ret & (1 << 5)) && !(ret & (1 << 2)))
gpio_state &= ~(1 << 2);
if (!(ret & (1 << 5)) && !ddc_read_clock())
gpio_state &= ~(1 << 2);
ret = (ret & ~6) | gpio_state;
}
break;
case 0xd0: case 0xd1: case 0xd2: case 0xd3:
READ8(addr, mach64->gen_test_cntl);
@@ -2169,6 +2187,7 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p)
{
mach64_t *mach64 = (mach64_t *)p;
svga_t *svga = &mach64->svga;
int data, clk;
mach64_log("mach64_ext_writeb : addr %08X val %02X\n", addr, val);
@@ -2360,7 +2379,10 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p)
WRITE8(addr, mach64->dac_cntl, val);
svga_set_ramdac_type(svga, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT);
ati68860_set_ramdac_type(mach64->svga.ramdac, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT);
break;
data = (val & (1 << 4)) ? ((val & (1 << 1)) ? 1 : 0) : 1;
clk = (val & (1 << 5)) ? ((val & (1 << 2)) ? 1 : 0) : 1;
ddc_i2c_change(clk, data);
break;
case 0xd0: case 0xd1: case 0xd2: case 0xd3:
WRITE8(addr, mach64->gen_test_cntl, val);
@@ -3346,6 +3368,8 @@ static void *mach64_common_init(const device_t *info)
mach64->fifo_not_full_event = thread_create_event();
mach64->fifo_thread = thread_create(fifo_thread, mach64);
ddc_init();
return mach64;
}

334
src/video/vid_ddc.c Normal file
View File

@@ -0,0 +1,334 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* DDC monitor emulation.
*
*
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
*
* Copyright 2008-2020 Sarah Walker.
*/
#include <stdlib.h>
#include <stddef.h>
#include <wchar.h>
#include <math.h>
#include <86box/86box.h>
#include "cpu.h"
#include <86box/vid_ddc.h>
static uint8_t edid_data[128] =
{
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, /*Fixed header pattern*/
0x09, 0xf8, /*Manufacturer "BOX" - apparently unassigned by UEFI - and it has to be big endian*/
0x00, 0x00, /*Product code*/
0x12, 0x34, 0x56, 0x78, /*Serial number*/
0x01, 9, /*Manufacturer week and year*/
0x01, 0x03, /*EDID version (1.3)*/
0x08, /*Analogue input, separate sync*/
34, 0, /*Landscape, 4:3*/
0, /*Gamma*/
0x08, /*RGB colour*/
0x81, 0xf1, 0xa3, 0x57, 0x53, 0x9f, 0x27, 0x0a, 0x50, /*Chromaticity*/
0xff, 0xff, 0xff, /*Established timing bitmap*/
0x00, 0x00, /*Standard timing information*/
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
/*Detailed mode descriptions*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, /*No extensions*/
0x00
};
/*This should probably be split off into a separate I2C module*/
enum
{
TRANSMITTER_MONITOR = 1,
TRANSMITTER_HOST = -1
};
enum
{
I2C_IDLE = 0,
I2C_RECEIVE,
I2C_RECEIVE_WAIT,
I2C_TRANSMIT_START,
I2C_TRANSMIT,
I2C_ACKNOWLEDGE,
I2C_TRANSACKNOWLEDGE,
I2C_TRANSMIT_WAIT
};
enum
{
PROM_IDLE = 0,
PROM_RECEIVEADDR,
PROM_RECEIVEDATA,
PROM_SENDDATA,
PROM_INVALID
};
static struct
{
int clock, data;
int state;
int last_data;
int pos;
int transmit;
uint8_t byte;
} i2c;
static struct
{
int state;
int addr;
int rw;
} prom;
static void prom_stop(void)
{
// pclog("prom_stop()\n");
prom.state = PROM_IDLE;
i2c.transmit = TRANSMITTER_HOST;
}
static void prom_next_byte(void)
{
// pclog("prom_next_byte(%d)\n", prom.addr);
i2c.byte = edid_data[(prom.addr++) & 0x7F];
}
static void prom_write(uint8_t byte)
{
// pclog("prom_write: byte=%02x\n", byte);
switch (prom.state)
{
case PROM_IDLE:
if ((byte & 0xfe) != 0xa0)
{
// pclog("I2C address not PROM\n");
prom.state = PROM_INVALID;
break;
}
prom.rw = byte & 1;
if (prom.rw)
{
prom.state = PROM_SENDDATA;
i2c.transmit = TRANSMITTER_MONITOR;
i2c.byte = edid_data[(prom.addr++) & 0x7F];
// pclog("PROM - %02X from %02X\n",i2c.byte, prom.addr-1);
// pclog("Transmitter now PROM\n");
}
else
{
prom.state = PROM_RECEIVEADDR;
i2c.transmit = TRANSMITTER_HOST;
}
// pclog("PROM R/W=%i\n",promrw);
return;
case PROM_RECEIVEADDR:
// pclog("PROM addr=%02X\n",byte);
prom.addr = byte;
if (prom.rw)
prom.state = PROM_SENDDATA;
else
prom.state = PROM_RECEIVEDATA;
break;
case PROM_RECEIVEDATA:
// pclog("PROM write %02X %02X\n",promaddr,byte);
break;
case PROM_SENDDATA:
break;
}
}
void ddc_i2c_change(int new_clock, int new_data)
{
// pclog("I2C update clock %i->%i data %i->%i state %i\n",i2c.clock,new_clock,i2c.last_data,new_data,i2c.state);
switch (i2c.state)
{
case I2C_IDLE:
if (i2c.clock && new_clock)
{
if (i2c.last_data && !new_data) /*Start bit*/
{
// pclog("Start bit received\n");
i2c.state = I2C_RECEIVE;
i2c.pos = 0;
}
}
break;
case I2C_RECEIVE_WAIT:
if (!i2c.clock && new_clock)
i2c.state = I2C_RECEIVE;
case I2C_RECEIVE:
if (!i2c.clock && new_clock)
{
i2c.byte <<= 1;
if (new_data)
i2c.byte |= 1;
else
i2c.byte &= 0xFE;
i2c.pos++;
if (i2c.pos == 8)
{
prom_write(i2c.byte);
i2c.state = I2C_ACKNOWLEDGE;
}
}
else if (i2c.clock && new_clock && new_data && !i2c.last_data) /*Stop bit*/
{
// pclog("Stop bit received\n");
i2c.state = I2C_IDLE;
prom_stop();
}
else if (i2c.clock && new_clock && !new_data && i2c.last_data) /*Start bit*/
{
// pclog("Start bit received\n");
i2c.pos = 0;
prom.state = PROM_IDLE;
}
break;
case I2C_ACKNOWLEDGE:
if (!i2c.clock && new_clock)
{
// pclog("Acknowledging transfer\n");
new_data = 0;
i2c.pos = 0;
if (i2c.transmit == TRANSMITTER_HOST)
i2c.state = I2C_RECEIVE_WAIT;
else
i2c.state = I2C_TRANSMIT;
}
break;
case I2C_TRANSACKNOWLEDGE:
if (!i2c.clock && new_clock)
{
if (new_data) /*It's not acknowledged - must be end of transfer*/
{
// pclog("End of transfer\n");
i2c.state = I2C_IDLE;
prom_stop();
}
else /*Next byte to transfer*/
{
i2c.state = I2C_TRANSMIT_START;
prom_next_byte();
i2c.pos = 0;
// pclog("Next byte - %02X\n",i2c.byte);
}
}
break;
case I2C_TRANSMIT_WAIT:
if (i2c.clock && new_clock)
{
if (i2c.last_data && !new_data) /*Start bit*/
{
prom_next_byte();
i2c.pos = 0;
// pclog("Next byte - %02X\n",i2c.byte);
}
if (!i2c.last_data && new_data) /*Stop bit*/
{
// pclog("Stop bit received\n");
i2c.state = I2C_IDLE;
prom_stop();
}
}
break;
case I2C_TRANSMIT_START:
if (!i2c.clock && new_clock)
i2c.state = I2C_TRANSMIT;
if (i2c.clock && new_clock && !i2c.last_data && new_data) /*Stop bit*/
{
// pclog("Stop bit received\n");
i2c.state = I2C_IDLE;
prom_stop();
}
case I2C_TRANSMIT:
if (!i2c.clock && new_clock)
{
i2c.clock = new_clock;
// if (!i2c.pos)
// pclog("Transmit byte %02x\n", i2c.byte);
i2c.data = new_data = i2c.byte & 0x80;
// pclog("Transmit bit %i %i\n", i2c.byte, i2c.pos);
i2c.byte <<= 1;
i2c.pos++;
return;
}
if (i2c.clock && !new_clock && i2c.pos == 8)
{
i2c.state = I2C_TRANSACKNOWLEDGE;
// pclog("Acknowledge mode\n");
}
break;
}
if (!i2c.clock && new_clock)
i2c.data = new_data;
i2c.last_data = new_data;
i2c.clock = new_clock;
}
int ddc_read_clock(void)
{
return i2c.clock;
}
int ddc_read_data(void)
{
if (i2c.state == I2C_TRANSMIT || i2c.state == I2C_ACKNOWLEDGE)
return i2c.data;
if (i2c.state == I2C_RECEIVE_WAIT)
return 0; /*ACK*/
return 1;
}
void ddc_init(void)
{
int c;
uint8_t checksum = 0;
for (c = 0; c < 127; c++)
checksum += edid_data[c];
edid_data[127] = 256 - checksum;
i2c.clock = 1;
i2c.data = 1;
}

View File

@@ -2664,7 +2664,7 @@ s3_accel_in(uint16_t port, void *p)
wake_fifo_thread(s3);
temp = 0;
if ((s3->chip >= S3_86C928) && s3_enable_fifo(s3)) {
if (!FIFO_EMPTY || s3->busy || s3->force_busy)
if (!FIFO_EMPTY || s3->force_busy)
temp |= 0x02; /*Hardware busy*/
else
temp |= 0x04; /*FIFO empty*/

View File

@@ -32,6 +32,7 @@
#include <86box/device.h>
#include <86box/plat.h>
#include <86box/video.h>
#include <86box/vid_ddc.h>
#include <86box/vid_svga.h>
#include <86box/vid_svga_render.h>
@@ -283,6 +284,8 @@ typedef struct virge_t
int virge_busy;
uint8_t subsys_stat, subsys_cntl, advfunc_cntl;
uint8_t serialport;
} virge_t;
static video_timings_t timing_diamond_stealth3d_2000_vlb = {VIDEO_BUS, 2, 2, 3, 28, 28, 45};
@@ -361,6 +364,11 @@ enum
#define INT_3DF_EMP (1 << 6)
#define INT_MASK 0xff
#define SERIAL_PORT_SCW (1 << 0)
#define SERIAL_PORT_SDW (1 << 1)
#define SERIAL_PORT_SCR (1 << 2)
#define SERIAL_PORT_SDR (1 << 3)
#ifdef ENABLE_S3_VIRGE_LOG
int s3_virge_do_log = ENABLE_S3_VIRGE_LOG;
@@ -883,6 +891,14 @@ s3_virge_mmio_read(uint32_t addr, void *p)
case 0x83d8: case 0x83d9: case 0x83da: case 0x83db:
case 0x83dc: case 0x83dd: case 0x83de: case 0x83df:
return s3_virge_in(addr & 0x3ff, virge);
case 0xff20: case 0xff21:
ret = virge->serialport & ~(SERIAL_PORT_SCR | SERIAL_PORT_SDR);
if ((virge->serialport & SERIAL_PORT_SCW) && ddc_read_clock())
ret |= SERIAL_PORT_SCR;
if ((virge->serialport & SERIAL_PORT_SDW) && ddc_read_data())
ret |= SERIAL_PORT_SDR;
return ret;
}
return 0xff;
}
@@ -1161,6 +1177,11 @@ static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p)
case 0x83dc: case 0x83dd: case 0x83de: case 0x83df:
s3_virge_out(addr & 0x3ff, val, virge);
break;
case 0xff20:
virge->serialport = val;
ddc_i2c_change((val & SERIAL_PORT_SCW) ? 1 : 0, (val & SERIAL_PORT_SDW) ? 1 : 0);
break;
}
}
}
@@ -1176,7 +1197,8 @@ s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p)
if ((addr & 0xfffe) == 0x83d4) {
s3_virge_mmio_write(addr, val, virge);
s3_virge_mmio_write(addr + 1, val >> 8, virge);
}
} else if ((addr & 0xfffe) == 0xff20)
s3_virge_mmio_write(addr, val, virge);
}
}
@@ -1626,6 +1648,10 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p)
if (virge->s3d_tri.cmd_set & CMD_SET_AE)
queue_triangle(virge);
break;
case 0xff20:
s3_virge_mmio_write(addr, val, virge);
break;
}
}
}
@@ -3819,6 +3845,8 @@ static void *s3_virge_init(const device_t *info)
virge->fifo_not_full_event = thread_create_event();
virge->fifo_thread = thread_create(fifo_thread, virge);
ddc_init();
return virge;
}

View File

@@ -447,6 +447,8 @@ svga_recalctimings(svga_t *svga)
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
svga->ca_adj = 0;
svga->rowcount = svga->crtc[9] & 31;
svga->hdisp_time = svga->hdisp;
svga->render = svga_render_blank;
@@ -517,7 +519,6 @@ svga_recalctimings(svga_t *svga)
}
svga->linedbl = svga->crtc[9] & 0x80;
svga->rowcount = svga->crtc[9] & 31;
svga->char_width = (svga->seqregs[1] & 1) ? 8 : 9;
if (enable_overscan) {

View File

@@ -28,6 +28,16 @@
#include <86box/vid_svga.h>
#include <86box/vid_svga_render.h>
void
svga_render_null(svga_t *svga)
{
if ((svga->displine + svga->y_add) < 0)
return;
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
}
void
svga_render_blank(svga_t *svga)

View File

@@ -123,6 +123,7 @@ video_cards[] = {
{ "cl_gd5440_pci", &gd5440_pci_device },
{ "cl_gd5446_pci", &gd5446_pci_device },
{ "cl_gd5480_pci", &gd5480_pci_device },
{ "ctl3d_banshee_pci", &creative_voodoo_banshee_device },
{ "stealth32_pci", &et4000w32p_pci_device },
{ "stealth3d_2000_pci", &s3_virge_pci_device },
{ "stealth3d_3000_pci", &s3_virge_988_pci_device },
@@ -148,6 +149,9 @@ video_cards[] = {
{ "virge375_vbe20_pci", &s3_virge_375_4_pci_device },
{ "cl_gd5446_stb_pci", &gd5446_stb_pci_device },
{ "tgui9440_pci", &tgui9440_pci_device },
{ "voodoo3_2k_pci", &voodoo_3_2000_device },
{ "voodoo3_3k_pci", &voodoo_3_3000_device },
{ "voodoo_banshee_pci", &voodoo_banshee_device },
{ "mach64gx_vlb", &mach64gx_vlb_device },
{ "et4000w32p_vlb", &et4000w32p_cardex_vlb_device },
#if defined(DEV_BRANCH) && defined(USE_CL5422)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,554 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* 3DFX Voodoo emulation.
*
*
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
*
* Copyright 2008-2020 Sarah Walker.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <wchar.h>
#include <math.h>
#include <86box/86box.h>
#include "cpu.h"
#include <86box/machine.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/pci.h>
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/plat.h>
#include <86box/video.h>
#include <86box/vid_svga.h>
#include <86box/vid_voodoo_common.h>
#include <86box/vid_voodoo_blitter.h>
#include <86box/vid_voodoo_dither.h>
#include <86box/vid_voodoo_regs.h>
#include <86box/vid_voodoo_render.h>
enum
{
BLIT_COMMAND_SCREEN_TO_SCREEN = 0,
BLIT_COMMAND_CPU_TO_SCREEN = 1,
BLIT_COMMAND_RECT_FILL = 2,
BLIT_COMMAND_SGRAM_FILL = 3
};
enum
{
BLIT_SRC_1BPP = (0 << 3),
BLIT_SRC_1BPP_BYTE_PACKED = (1 << 3),
BLIT_SRC_16BPP = (2 << 3),
BLIT_SRC_24BPP = (3 << 3),
BLIT_SRC_24BPP_DITHER_2X2 = (4 << 3),
BLIT_SRC_24BPP_DITHER_4X4 = (5 << 3)
};
enum
{
BLIT_SRC_RGB_ARGB = (0 << 6),
BLIT_SRC_RGB_ABGR = (1 << 6),
BLIT_SRC_RGB_RGBA = (2 << 6),
BLIT_SRC_RGB_BGRA = (3 << 6)
};
enum
{
BLIT_COMMAND_MASK = 7,
BLIT_SRC_FORMAT = (7 << 3),
BLIT_SRC_RGB_FORMAT = (3 << 6),
BLIT_SRC_CHROMA = (1 << 10),
BLIT_DST_CHROMA = (1 << 12),
BLIT_CLIPPING_ENABLED = (1 << 16)
};
enum
{
BLIT_ROP_DST_PASS = (1 << 0),
BLIT_ROP_SRC_PASS = (1 << 1)
};
#ifdef ENABLE_VOODOOBLT_LOG
int voodooblt_do_log = ENABLE_VOODOOBLT_LOG;
static void
voodooblt_log(const char *fmt, ...)
{
va_list ap;
if (voodooblt_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define voodooblt_log(fmt, ...)
#endif
#define MIX(src_dat, dst_dat, rop) \
switch (rop) \
{ \
case 0x0: dst_dat = 0; break; \
case 0x1: dst_dat = ~(src_dat | dst_dat); break; \
case 0x2: dst_dat = ~src_dat & dst_dat; break; \
case 0x3: dst_dat = ~src_dat; break; \
case 0x4: dst_dat = src_dat & ~dst_dat; break; \
case 0x5: dst_dat = ~dst_dat; break; \
case 0x6: dst_dat = src_dat ^ dst_dat; break; \
case 0x7: dst_dat = ~(src_dat & dst_dat); break; \
case 0x8: dst_dat = src_dat & dst_dat; break; \
case 0x9: dst_dat = ~(src_dat ^ dst_dat); break; \
case 0xa: dst_dat = dst_dat; break; \
case 0xb: dst_dat = ~src_dat | dst_dat; break; \
case 0xc: dst_dat = src_dat; break; \
case 0xd: dst_dat = src_dat | ~dst_dat; break; \
case 0xe: dst_dat = src_dat | dst_dat; break; \
case 0xf: dst_dat = 0xffff; break; \
}
void voodoo_v2_blit_start(voodoo_t *voodoo)
{
uint64_t dat64;
int size_x = ABS(voodoo->bltSizeX), size_y = ABS(voodoo->bltSizeY);
int x_dir = (voodoo->bltSizeX > 0) ? 1 : -1;
int y_dir = (voodoo->bltSizeY > 0) ? 1 : -1;
int dst_x;
int src_y = voodoo->bltSrcY & 0x7ff, dst_y = voodoo->bltDstY & 0x7ff;
int src_stride = (voodoo->bltCommand & BLTCMD_SRC_TILED) ? ((voodoo->bltSrcXYStride & 0x3f) * 32*2) : (voodoo->bltSrcXYStride & 0xff8);
int dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32*2) : (voodoo->bltDstXYStride & 0xff8);
uint32_t src_base_addr = (voodoo->bltCommand & BLTCMD_SRC_TILED) ? ((voodoo->bltSrcBaseAddr & 0x3ff) << 12) : (voodoo->bltSrcBaseAddr & 0x3ffff8);
uint32_t dst_base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) : (voodoo->bltDstBaseAddr & 0x3ffff8);
int x, y;
/* voodooblt_log("blit_start: command=%08x srcX=%i srcY=%i dstX=%i dstY=%i sizeX=%i sizeY=%i color=%04x,%04x\n",
voodoo->bltCommand, voodoo->bltSrcX, voodoo->bltSrcY, voodoo->bltDstX, voodoo->bltDstY, voodoo->bltSizeX, voodoo->bltSizeY, voodoo->bltColorFg, voodoo->bltColorBg);*/
voodoo_wait_for_render_thread_idle(voodoo);
switch (voodoo->bltCommand & BLIT_COMMAND_MASK)
{
case BLIT_COMMAND_SCREEN_TO_SCREEN:
for (y = 0; y <= size_y; y++)
{
uint16_t *src = (uint16_t *)&voodoo->fb_mem[src_base_addr + src_y*src_stride];
uint16_t *dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + dst_y*dst_stride];
int src_x = voodoo->bltSrcX, dst_x = voodoo->bltDstX;
for (x = 0; x <= size_x; x++)
{
uint16_t src_dat = src[src_x];
uint16_t dst_dat = dst[dst_x];
int rop = 0;
if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED)
{
if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight ||
dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY)
goto skip_pixel_blit;
}
if (voodoo->bltCommand & BLIT_SRC_CHROMA)
{
int r = (src_dat >> 11);
int g = (src_dat >> 5) & 0x3f;
int b = src_dat & 0x1f;
if (r >= voodoo->bltSrcChromaMinR && r <= voodoo->bltSrcChromaMaxR &&
g >= voodoo->bltSrcChromaMinG && g <= voodoo->bltSrcChromaMaxG &&
b >= voodoo->bltSrcChromaMinB && b <= voodoo->bltSrcChromaMaxB)
rop |= BLIT_ROP_SRC_PASS;
}
if (voodoo->bltCommand & BLIT_DST_CHROMA)
{
int r = (dst_dat >> 11);
int g = (dst_dat >> 5) & 0x3f;
int b = dst_dat & 0x1f;
if (r >= voodoo->bltDstChromaMinR && r <= voodoo->bltDstChromaMaxR &&
g >= voodoo->bltDstChromaMinG && g <= voodoo->bltDstChromaMaxG &&
b >= voodoo->bltDstChromaMinB && b <= voodoo->bltDstChromaMaxB)
rop |= BLIT_ROP_DST_PASS;
}
MIX(src_dat, dst_dat, voodoo->bltRop[rop]);
dst[dst_x] = dst_dat;
skip_pixel_blit:
src_x += x_dir;
dst_x += x_dir;
}
src_y += y_dir;
dst_y += y_dir;
}
break;
case BLIT_COMMAND_CPU_TO_SCREEN:
voodoo->blt.dst_x = voodoo->bltDstX;
voodoo->blt.dst_y = voodoo->bltDstY;
voodoo->blt.cur_x = 0;
voodoo->blt.size_x = size_x;
voodoo->blt.size_y = size_y;
voodoo->blt.x_dir = x_dir;
voodoo->blt.y_dir = y_dir;
voodoo->blt.dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32*2) : (voodoo->bltDstXYStride & 0xff8);
break;
case BLIT_COMMAND_RECT_FILL:
for (y = 0; y <= size_y; y++)
{
uint16_t *dst;
int dst_x = voodoo->bltDstX;
if (SLI_ENABLED)
{
if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (voodoo->blt.dst_y & 1)) ||
((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(voodoo->blt.dst_y & 1)))
goto skip_line_fill;
dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + (dst_y >> 1) * dst_stride];
}
else
dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + dst_y*dst_stride];
for (x = 0; x <= size_x; x++)
{
if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED)
{
if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight ||
dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY)
goto skip_pixel_fill;
}
dst[dst_x] = voodoo->bltColorFg;
skip_pixel_fill:
dst_x += x_dir;
}
skip_line_fill:
dst_y += y_dir;
}
break;
case BLIT_COMMAND_SGRAM_FILL:
/*32x32 tiles - 2kb*/
dst_y = voodoo->bltDstY & 0x3ff;
size_x = voodoo->bltSizeX & 0x1ff; //512*8 = 4kb
size_y = voodoo->bltSizeY & 0x3ff;
dat64 = voodoo->bltColorFg | ((uint64_t)voodoo->bltColorFg << 16) |
((uint64_t)voodoo->bltColorFg << 32) | ((uint64_t)voodoo->bltColorFg << 48);
for (y = 0; y <= size_y; y++)
{
uint64_t *dst;
/*This may be wrong*/
if (!y)
{
dst_x = voodoo->bltDstX & 0x1ff;
size_x = 511 - dst_x;
}
else if (y < size_y)
{
dst_x = 0;
size_x = 511;
}
else
{
dst_x = 0;
size_x = voodoo->bltSizeX & 0x1ff;
}
dst = (uint64_t *)&voodoo->fb_mem[(dst_y*512*8 + dst_x*8) & voodoo->fb_mask];
for (x = 0; x <= size_x; x++)
dst[x] = dat64;
dst_y++;
}
break;
default:
fatal("bad blit command %08x\n", voodoo->bltCommand);
}
}
void voodoo_v2_blit_data(voodoo_t *voodoo, uint32_t data)
{
int src_bits = 32;
uint32_t base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) : (voodoo->bltDstBaseAddr & 0x3ffff8);
uint32_t addr;
uint16_t *dst;
if ((voodoo->bltCommand & BLIT_COMMAND_MASK) != BLIT_COMMAND_CPU_TO_SCREEN)
return;
if (SLI_ENABLED)
{
addr = base_addr + (voodoo->blt.dst_y >> 1) * voodoo->blt.dst_stride;
dst = (uint16_t *)&voodoo->fb_mem[addr];
}
else
{
addr = base_addr + voodoo->blt.dst_y*voodoo->blt.dst_stride;
dst = (uint16_t *)&voodoo->fb_mem[addr];
}
if (addr >= voodoo->front_offset && voodoo->row_width)
{
int y = (addr - voodoo->front_offset) / voodoo->row_width;
if (y < voodoo->v_disp)
voodoo->dirty_line[y] = 2;
}
while (src_bits && voodoo->blt.cur_x <= voodoo->blt.size_x)
{
int r = 0, g = 0, b = 0;
uint16_t src_dat = 0, dst_dat;
int x = (voodoo->blt.x_dir > 0) ? (voodoo->blt.dst_x + voodoo->blt.cur_x) : (voodoo->blt.dst_x - voodoo->blt.cur_x);
int rop = 0;
switch (voodoo->bltCommand & BLIT_SRC_FORMAT)
{
case BLIT_SRC_1BPP: case BLIT_SRC_1BPP_BYTE_PACKED:
src_dat = (data & 1) ? voodoo->bltColorFg : voodoo->bltColorBg;
data >>= 1;
src_bits--;
break;
case BLIT_SRC_16BPP:
switch (voodoo->bltCommand & BLIT_SRC_RGB_FORMAT)
{
case BLIT_SRC_RGB_ARGB: case BLIT_SRC_RGB_RGBA:
src_dat = data & 0xffff;
break;
case BLIT_SRC_RGB_ABGR: case BLIT_SRC_RGB_BGRA:
src_dat = ((data & 0xf800) >> 11) | (data & 0x07c0) | ((data & 0x0038) << 11);
break;
}
data >>= 16;
src_bits -= 16;
break;
case BLIT_SRC_24BPP: case BLIT_SRC_24BPP_DITHER_2X2: case BLIT_SRC_24BPP_DITHER_4X4:
switch (voodoo->bltCommand & BLIT_SRC_RGB_FORMAT)
{
case BLIT_SRC_RGB_ARGB:
r = (data >> 16) & 0xff;
g = (data >> 8) & 0xff;
b = data & 0xff;
break;
case BLIT_SRC_RGB_ABGR:
r = data & 0xff;
g = (data >> 8) & 0xff;
b = (data >> 16) & 0xff;
break;
case BLIT_SRC_RGB_RGBA:
r = (data >> 24) & 0xff;
g = (data >> 16) & 0xff;
b = (data >> 8) & 0xff;
break;
case BLIT_SRC_RGB_BGRA:
r = (data >> 8) & 0xff;
g = (data >> 16) & 0xff;
b = (data >> 24) & 0xff;
break;
}
switch (voodoo->bltCommand & BLIT_SRC_FORMAT)
{
case BLIT_SRC_24BPP:
src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8);
break;
case BLIT_SRC_24BPP_DITHER_2X2:
r = dither_rb2x2[r][voodoo->blt.dst_y & 1][x & 1];
g = dither_g2x2[g][voodoo->blt.dst_y & 1][x & 1];
b = dither_rb2x2[b][voodoo->blt.dst_y & 1][x & 1];
src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8);
break;
case BLIT_SRC_24BPP_DITHER_4X4:
r = dither_rb[r][voodoo->blt.dst_y & 3][x & 3];
g = dither_g[g][voodoo->blt.dst_y & 3][x & 3];
b = dither_rb[b][voodoo->blt.dst_y & 3][x & 3];
src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8);
break;
}
src_bits = 0;
break;
}
if (SLI_ENABLED)
{
if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (voodoo->blt.dst_y & 1)) ||
((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(voodoo->blt.dst_y & 1)))
goto skip_pixel;
}
if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED)
{
if (x < voodoo->bltClipLeft || x >= voodoo->bltClipRight ||
voodoo->blt.dst_y < voodoo->bltClipLowY || voodoo->blt.dst_y >= voodoo->bltClipHighY)
goto skip_pixel;
}
dst_dat = dst[x];
if (voodoo->bltCommand & BLIT_SRC_CHROMA)
{
r = (src_dat >> 11);
g = (src_dat >> 5) & 0x3f;
b = src_dat & 0x1f;
if (r >= voodoo->bltSrcChromaMinR && r <= voodoo->bltSrcChromaMaxR &&
g >= voodoo->bltSrcChromaMinG && g <= voodoo->bltSrcChromaMaxG &&
b >= voodoo->bltSrcChromaMinB && b <= voodoo->bltSrcChromaMaxB)
rop |= BLIT_ROP_SRC_PASS;
}
if (voodoo->bltCommand & BLIT_DST_CHROMA)
{
r = (dst_dat >> 11);
g = (dst_dat >> 5) & 0x3f;
b = dst_dat & 0x1f;
if (r >= voodoo->bltDstChromaMinR && r <= voodoo->bltDstChromaMaxR &&
g >= voodoo->bltDstChromaMinG && g <= voodoo->bltDstChromaMaxG &&
b >= voodoo->bltDstChromaMinB && b <= voodoo->bltDstChromaMaxB)
rop |= BLIT_ROP_DST_PASS;
}
MIX(src_dat, dst_dat, voodoo->bltRop[rop]);
dst[x] = dst_dat;
skip_pixel:
voodoo->blt.cur_x++;
}
if (voodoo->blt.cur_x > voodoo->blt.size_x)
{
voodoo->blt.size_y--;
if (voodoo->blt.size_y >= 0)
{
voodoo->blt.cur_x = 0;
voodoo->blt.dst_y += voodoo->blt.y_dir;
}
}
}
void voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params)
{
int y;
int low_y, high_y;
if (params->fbzMode & (1 << 17))
{
high_y = voodoo->v_disp - params->clipLowY;
low_y = voodoo->v_disp - params->clipHighY;
}
else
{
low_y = params->clipLowY;
high_y = params->clipHighY;
}
if (params->fbzMode & FBZ_RGB_WMASK)
{
int r, g, b;
uint16_t col;
r = ((params->color1 >> 16) >> 3) & 0x1f;
g = ((params->color1 >> 8) >> 2) & 0x3f;
b = (params->color1 >> 3) & 0x1f;
col = b | (g << 5) | (r << 11);
if (SLI_ENABLED)
{
for (y = low_y; y < high_y; y += 2)
{
uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + (y >> 1) * voodoo->row_width) & voodoo->fb_mask];
int x;
for (x = params->clipLeft; x < params->clipRight; x++)
cbuf[x] = col;
}
}
else
{
for (y = low_y; y < high_y; y++)
{
if (voodoo->col_tiled)
{
uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + (y >> 5) * voodoo->row_width + (y & 31) * 128) & voodoo->fb_mask];
int x;
for (x = params->clipLeft; x < params->clipRight; x++)
{
int x2 = (x & 63) | ((x >> 6) * 128*32/2);
cbuf[x2] = col;
}
}
else
{
uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + y * voodoo->row_width) & voodoo->fb_mask];
int x;
for (x = params->clipLeft; x < params->clipRight; x++)
cbuf[x] = col;
}
}
}
}
if (params->fbzMode & FBZ_DEPTH_WMASK)
{
if (SLI_ENABLED)
{
for (y = low_y; y < high_y; y += 2)
{
uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (y >> 1) * voodoo->row_width) & voodoo->fb_mask];
int x;
for (x = params->clipLeft; x < params->clipRight; x++)
abuf[x] = params->zaColor & 0xffff;
}
}
else
{
for (y = low_y; y < high_y; y++)
{
if (voodoo->aux_tiled)
{
uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (y >> 5) * voodoo->aux_row_width + (y & 31) * 128) & voodoo->fb_mask];
int x;
for (x = params->clipLeft; x < params->clipRight; x++)
{
int x2 = (x & 63) | ((x >> 6) * 128*32/2);
abuf[x2] = params->zaColor & 0xffff;
}
}
else
{
uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + y * voodoo->aux_row_width) & voodoo->fb_mask];
int x;
for (x = params->clipLeft; x < params->clipRight; x++)
abuf[x] = params->zaColor & 0xffff;
}
}
}
}
}

View File

@@ -0,0 +1,663 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* 3DFX Voodoo emulation.
*
*
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
*
* Copyright 2008-2020 Sarah Walker.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <wchar.h>
#include <math.h>
#include <86box/86box.h>
#include "cpu.h"
#include <86box/machine.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/plat.h>
#include <86box/video.h>
#include <86box/vid_svga.h>
#include <86box/vid_voodoo_common.h>
#include <86box/vid_voodoo_display.h>
#include <86box/vid_voodoo_regs.h>
#include <86box/vid_voodoo_render.h>
#ifdef ENABLE_VOODOODISP_LOG
int voodoodisp_do_log = ENABLE_VOODOODISP_LOG;
static void
voodoodisp_log(const char *fmt, ...)
{
va_list ap;
if (voodoodisp_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define voodoodisp_log(fmt, ...)
#endif
void voodoo_update_ncc(voodoo_t *voodoo, int tmu)
{
int tbl;
for (tbl = 0; tbl < 2; tbl++)
{
int col;
for (col = 0; col < 256; col++)
{
int y = (col >> 4), i = (col >> 2) & 3, q = col & 3;
int i_r, i_g, i_b;
int q_r, q_g, q_b;
y = (voodoo->nccTable[tmu][tbl].y[y >> 2] >> ((y & 3) * 8)) & 0xff;
i_r = (voodoo->nccTable[tmu][tbl].i[i] >> 18) & 0x1ff;
if (i_r & 0x100)
i_r |= 0xfffffe00;
i_g = (voodoo->nccTable[tmu][tbl].i[i] >> 9) & 0x1ff;
if (i_g & 0x100)
i_g |= 0xfffffe00;
i_b = voodoo->nccTable[tmu][tbl].i[i] & 0x1ff;
if (i_b & 0x100)
i_b |= 0xfffffe00;
q_r = (voodoo->nccTable[tmu][tbl].q[q] >> 18) & 0x1ff;
if (q_r & 0x100)
q_r |= 0xfffffe00;
q_g = (voodoo->nccTable[tmu][tbl].q[q] >> 9) & 0x1ff;
if (q_g & 0x100)
q_g |= 0xfffffe00;
q_b = voodoo->nccTable[tmu][tbl].q[q] & 0x1ff;
if (q_b & 0x100)
q_b |= 0xfffffe00;
voodoo->ncc_lookup[tmu][tbl][col].rgba.r = CLAMP(y + i_r + q_r);
voodoo->ncc_lookup[tmu][tbl][col].rgba.g = CLAMP(y + i_g + q_g);
voodoo->ncc_lookup[tmu][tbl][col].rgba.b = CLAMP(y + i_b + q_b);
voodoo->ncc_lookup[tmu][tbl][col].rgba.a = 0xff;
}
}
}
void voodoo_pixelclock_update(voodoo_t *voodoo)
{
int m = (voodoo->dac_pll_regs[0] & 0x7f) + 2;
int n1 = ((voodoo->dac_pll_regs[0] >> 8) & 0x1f) + 2;
int n2 = ((voodoo->dac_pll_regs[0] >> 13) & 0x07);
float t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2);
double clock_const;
int line_length;
if ((voodoo->dac_data[6] & 0xf0) == 0x20 ||
(voodoo->dac_data[6] & 0xf0) == 0x60 ||
(voodoo->dac_data[6] & 0xf0) == 0x70)
t /= 2.0f;
line_length = (voodoo->hSync & 0xff) + ((voodoo->hSync >> 16) & 0x3ff);
// voodoodisp_log("Pixel clock %f MHz hsync %08x line_length %d\n", t, voodoo->hSync, line_length);
voodoo->pixel_clock = t;
clock_const = cpuclock / t;
voodoo->line_time = (uint64_t)((double)line_length * clock_const * (double)(1ull << 32));
}
static void voodoo_calc_clutData(voodoo_t *voodoo)
{
int c;
for (c = 0; c < 256; c++)
{
voodoo->clutData256[c].r = (voodoo->clutData[c >> 3].r*(8-(c & 7)) +
voodoo->clutData[(c >> 3)+1].r*(c & 7)) >> 3;
voodoo->clutData256[c].g = (voodoo->clutData[c >> 3].g*(8-(c & 7)) +
voodoo->clutData[(c >> 3)+1].g*(c & 7)) >> 3;
voodoo->clutData256[c].b = (voodoo->clutData[c >> 3].b*(8-(c & 7)) +
voodoo->clutData[(c >> 3)+1].b*(c & 7)) >> 3;
}
for (c = 0; c < 65536; c++)
{
int r = (c >> 8) & 0xf8;
int g = (c >> 3) & 0xfc;
int b = (c << 3) & 0xf8;
// r |= (r >> 5);
// g |= (g >> 6);
// b |= (b >> 5);
voodoo->video_16to32[c] = (voodoo->clutData256[r].r << 16) | (voodoo->clutData256[g].g << 8) | voodoo->clutData256[b].b;
}
}
#define FILTDIV 256
static int FILTCAP, FILTCAPG, FILTCAPB = 0; /* color filter threshold values */
void voodoo_generate_filter_v1(voodoo_t *voodoo)
{
int g, h;
float difference, diffg, diffb;
float thiscol, thiscolg, thiscolb, lined;
float fcr, fcg, fcb;
fcr = FILTCAP * 5;
fcg = FILTCAPG * 6;
fcb = FILTCAPB * 5;
for (g=0;g<FILTDIV;g++) // pixel 1
{
for (h=0;h<FILTDIV;h++) // pixel 2
{
difference = (float)(h - g);
diffg = difference;
diffb = difference;
thiscol = thiscolg = thiscolb = g;
if (difference > FILTCAP)
difference = FILTCAP;
if (difference < -FILTCAP)
difference = -FILTCAP;
if (diffg > FILTCAPG)
diffg = FILTCAPG;
if (diffg < -FILTCAPG)
diffg = -FILTCAPG;
if (diffb > FILTCAPB)
diffb = FILTCAPB;
if (diffb < -FILTCAPB)
diffb = -FILTCAPB;
// hack - to make it not bleed onto black
//if (g == 0){
//difference = diffg = diffb = 0;
//}
if ((difference < fcr) || (-difference > -fcr))
thiscol = g + (difference / 2);
if ((diffg < fcg) || (-diffg > -fcg))
thiscolg = g + (diffg / 2); /* need these divides so we can actually undither! */
if ((diffb < fcb) || (-diffb > -fcb))
thiscolb = g + (diffb / 2);
if (thiscol < 0)
thiscol = 0;
if (thiscol > FILTDIV-1)
thiscol = FILTDIV-1;
if (thiscolg < 0)
thiscolg = 0;
if (thiscolg > FILTDIV-1)
thiscolg = FILTDIV-1;
if (thiscolb < 0)
thiscolb = 0;
if (thiscolb > FILTDIV-1)
thiscolb = FILTDIV-1;
voodoo->thefilter[g][h] = thiscol;
voodoo->thefilterg[g][h] = thiscolg;
voodoo->thefilterb[g][h] = thiscolb;
}
lined = g + 4;
if (lined > 255)
lined = 255;
voodoo->purpleline[g][0] = lined;
voodoo->purpleline[g][2] = lined;
lined = g + 0;
if (lined > 255)
lined = 255;
voodoo->purpleline[g][1] = lined;
}
}
void voodoo_generate_filter_v2(voodoo_t *voodoo)
{
int g, h;
float difference;
float thiscol, thiscolg, thiscolb;
float clr, clg, clb = 0;
float fcr, fcg, fcb = 0;
// pre-clamping
fcr = FILTCAP;
fcg = FILTCAPG;
fcb = FILTCAPB;
if (fcr > 32) fcr = 32;
if (fcg > 32) fcg = 32;
if (fcb > 32) fcb = 32;
for (g=0;g<256;g++) // pixel 1 - our target pixel we want to bleed into
{
for (h=0;h<256;h++) // pixel 2 - our main pixel
{
float avg;
float avgdiff;
difference = (float)(g - h);
avg = (float)((g + g + g + g + h) / 5);
avgdiff = avg - (float)((g + h + h + h + h) / 5);
if (avgdiff < 0) avgdiff *= -1;
if (difference < 0) difference *= -1;
thiscol = thiscolg = thiscolb = g;
// try lighten
if (h > g)
{
clr = clg = clb = avgdiff;
if (clr>fcr) clr=fcr;
if (clg>fcg) clg=fcg;
if (clb>fcb) clb=fcb;
thiscol = g + clr;
thiscolg = g + clg;
thiscolb = g + clb;
if (thiscol>g+FILTCAP)
thiscol=g+FILTCAP;
if (thiscolg>g+FILTCAPG)
thiscolg=g+FILTCAPG;
if (thiscolb>g+FILTCAPB)
thiscolb=g+FILTCAPB;
if (thiscol>g+avgdiff)
thiscol=g+avgdiff;
if (thiscolg>g+avgdiff)
thiscolg=g+avgdiff;
if (thiscolb>g+avgdiff)
thiscolb=g+avgdiff;
}
if (difference > FILTCAP)
thiscol = g;
if (difference > FILTCAPG)
thiscolg = g;
if (difference > FILTCAPB)
thiscolb = g;
// clamp
if (thiscol < 0) thiscol = 0;
if (thiscolg < 0) thiscolg = 0;
if (thiscolb < 0) thiscolb = 0;
if (thiscol > 255) thiscol = 255;
if (thiscolg > 255) thiscolg = 255;
if (thiscolb > 255) thiscolb = 255;
// add to the table
voodoo->thefilter[g][h] = (thiscol);
voodoo->thefilterg[g][h] = (thiscolg);
voodoo->thefilterb[g][h] = (thiscolb);
// debug the ones that don't give us much of a difference
//if (difference < FILTCAP)
//voodoodisp_log("Voodoofilter: %ix%i - %f difference, %f average difference, R=%f, G=%f, B=%f\n", g, h, difference, avgdiff, thiscol, thiscolg, thiscolb);
}
}
}
void voodoo_threshold_check(voodoo_t *voodoo)
{
int r, g, b;
if (!voodoo->scrfilterEnabled)
return; /* considered disabled; don't check and generate */
/* Check for changes, to generate anew table */
if (voodoo->scrfilterThreshold != voodoo->scrfilterThresholdOld)
{
r = (voodoo->scrfilterThreshold >> 16) & 0xFF;
g = (voodoo->scrfilterThreshold >> 8 ) & 0xFF;
b = voodoo->scrfilterThreshold & 0xFF;
FILTCAP = r;
FILTCAPG = g;
FILTCAPB = b;
voodoodisp_log("Voodoo Filter Threshold Check: %06x - RED %i GREEN %i BLUE %i\n", voodoo->scrfilterThreshold, r, g, b);
voodoo->scrfilterThresholdOld = voodoo->scrfilterThreshold;
if (voodoo->type == VOODOO_2)
voodoo_generate_filter_v2(voodoo);
else
voodoo_generate_filter_v1(voodoo);
if (voodoo->type >= VOODOO_BANSHEE)
voodoo_generate_vb_filters(voodoo, FILTCAP, FILTCAPG);
}
}
static void voodoo_filterline_v1(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src, int line)
{
int x;
// Scratchpad for avoiding feedback streaks
uint8_t fil3[(voodoo->h_disp) * 3];
/* 16 to 32-bit */
for (x=0; x<column;x++)
{
fil[x*3] = ((src[x] & 31) << 3);
fil[x*3+1] = (((src[x] >> 5) & 63) << 2);
fil[x*3+2] = (((src[x] >> 11) & 31) << 3);
// Copy to our scratchpads
fil3[x*3+0] = fil[x*3+0];
fil3[x*3+1] = fil[x*3+1];
fil3[x*3+2] = fil[x*3+2];
}
/* lines */
if (line & 1)
{
for (x=0; x<column;x++)
{
fil[x*3] = voodoo->purpleline[fil[x*3]][0];
fil[x*3+1] = voodoo->purpleline[fil[x*3+1]][1];
fil[x*3+2] = voodoo->purpleline[fil[x*3+2]][2];
}
}
/* filtering time */
for (x=1; x<column;x++)
{
fil3[(x)*3] = voodoo->thefilterb[fil[x*3]][fil[ (x-1) *3]];
fil3[(x)*3+1] = voodoo->thefilterg[fil[x*3+1]][fil[ (x-1) *3+1]];
fil3[(x)*3+2] = voodoo->thefilter[fil[x*3+2]][fil[ (x-1) *3+2]];
}
for (x=1; x<column;x++)
{
fil[(x)*3] = voodoo->thefilterb[fil3[x*3]][fil3[ (x-1) *3]];
fil[(x)*3+1] = voodoo->thefilterg[fil3[x*3+1]][fil3[ (x-1) *3+1]];
fil[(x)*3+2] = voodoo->thefilter[fil3[x*3+2]][fil3[ (x-1) *3+2]];
}
for (x=1; x<column;x++)
{
fil3[(x)*3] = voodoo->thefilterb[fil[x*3]][fil[ (x-1) *3]];
fil3[(x)*3+1] = voodoo->thefilterg[fil[x*3+1]][fil[ (x-1) *3+1]];
fil3[(x)*3+2] = voodoo->thefilter[fil[x*3+2]][fil[ (x-1) *3+2]];
}
for (x=0; x<column-1;x++)
{
fil[(x)*3] = voodoo->thefilterb[fil3[x*3]][fil3[ (x+1) *3]];
fil[(x)*3+1] = voodoo->thefilterg[fil3[x*3+1]][fil3[ (x+1) *3+1]];
fil[(x)*3+2] = voodoo->thefilter[fil3[x*3+2]][fil3[ (x+1) *3+2]];
}
}
static void voodoo_filterline_v2(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src, int line)
{
int x;
// Scratchpad for blending filter
uint8_t fil3[(voodoo->h_disp) * 3];
/* 16 to 32-bit */
for (x=0; x<column;x++)
{
// Blank scratchpads
fil3[x*3+0] = fil[x*3+0] = ((src[x] & 31) << 3);
fil3[x*3+1] = fil[x*3+1] = (((src[x] >> 5) & 63) << 2);
fil3[x*3+2] = fil[x*3+2] = (((src[x] >> 11) & 31) << 3);
}
/* filtering time */
for (x=1; x<column-3;x++)
{
fil3[(x+3)*3] = voodoo->thefilterb [((src[x+3] & 31) << 3)] [((src[x] & 31) << 3)];
fil3[(x+3)*3+1] = voodoo->thefilterg [(((src[x+3] >> 5) & 63) << 2)] [(((src[x] >> 5) & 63) << 2)];
fil3[(x+3)*3+2] = voodoo->thefilter [(((src[x+3] >> 11) & 31) << 3)] [(((src[x] >> 11) & 31) << 3)];
fil[(x+2)*3] = voodoo->thefilterb [fil3[(x+2)*3]][((src[x] & 31) << 3)];
fil[(x+2)*3+1] = voodoo->thefilterg [fil3[(x+2)*3+1]][(((src[x] >> 5) & 63) << 2)];
fil[(x+2)*3+2] = voodoo->thefilter [fil3[(x+2)*3+2]][(((src[x] >> 11) & 31) << 3)];
fil3[(x+1)*3] = voodoo->thefilterb [fil[(x+1)*3]][((src[x] & 31) << 3)];
fil3[(x+1)*3+1] = voodoo->thefilterg [fil[(x+1)*3+1]][(((src[x] >> 5) & 63) << 2)];
fil3[(x+1)*3+2] = voodoo->thefilter [fil[(x+1)*3+2]][(((src[x] >> 11) & 31) << 3)];
fil[(x-1)*3] = voodoo->thefilterb [fil3[(x-1)*3]][((src[x] & 31) << 3)];
fil[(x-1)*3+1] = voodoo->thefilterg [fil3[(x-1)*3+1]][(((src[x] >> 5) & 63) << 2)];
fil[(x-1)*3+2] = voodoo->thefilter [fil3[(x-1)*3+2]][(((src[x] >> 11) & 31) << 3)];
}
// unroll for edge cases
fil3[(column-3)*3] = voodoo->thefilterb [((src[column-3] & 31) << 3)] [((src[column] & 31) << 3)];
fil3[(column-3)*3+1] = voodoo->thefilterg [(((src[column-3] >> 5) & 63) << 2)] [(((src[column] >> 5) & 63) << 2)];
fil3[(column-3)*3+2] = voodoo->thefilter [(((src[column-3] >> 11) & 31) << 3)] [(((src[column] >> 11) & 31) << 3)];
fil3[(column-2)*3] = voodoo->thefilterb [((src[column-2] & 31) << 3)] [((src[column] & 31) << 3)];
fil3[(column-2)*3+1] = voodoo->thefilterg [(((src[column-2] >> 5) & 63) << 2)] [(((src[column] >> 5) & 63) << 2)];
fil3[(column-2)*3+2] = voodoo->thefilter [(((src[column-2] >> 11) & 31) << 3)] [(((src[column] >> 11) & 31) << 3)];
fil3[(column-1)*3] = voodoo->thefilterb [((src[column-1] & 31) << 3)] [((src[column] & 31) << 3)];
fil3[(column-1)*3+1] = voodoo->thefilterg [(((src[column-1] >> 5) & 63) << 2)] [(((src[column] >> 5) & 63) << 2)];
fil3[(column-1)*3+2] = voodoo->thefilter [(((src[column-1] >> 11) & 31) << 3)] [(((src[column] >> 11) & 31) << 3)];
fil[(column-2)*3] = voodoo->thefilterb [fil3[(column-2)*3]][((src[column] & 31) << 3)];
fil[(column-2)*3+1] = voodoo->thefilterg [fil3[(column-2)*3+1]][(((src[column] >> 5) & 63) << 2)];
fil[(column-2)*3+2] = voodoo->thefilter [fil3[(column-2)*3+2]][(((src[column] >> 11) & 31) << 3)];
fil[(column-1)*3] = voodoo->thefilterb [fil3[(column-1)*3]][((src[column] & 31) << 3)];
fil[(column-1)*3+1] = voodoo->thefilterg [fil3[(column-1)*3+1]][(((src[column] >> 5) & 63) << 2)];
fil[(column-1)*3+2] = voodoo->thefilter [fil3[(column-1)*3+2]][(((src[column] >> 11) & 31) << 3)];
fil3[(column-1)*3] = voodoo->thefilterb [fil[(column-1)*3]][((src[column] & 31) << 3)];
fil3[(column-1)*3+1] = voodoo->thefilterg [fil[(column-1)*3+1]][(((src[column] >> 5) & 63) << 2)];
fil3[(column-1)*3+2] = voodoo->thefilter [fil[(column-1)*3+2]][(((src[column] >> 11) & 31) << 3)];
}
void voodoo_callback(void *p)
{
voodoo_t *voodoo = (voodoo_t *)p;
if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS)
{
if (voodoo->line < voodoo->v_disp)
{
voodoo_t *draw_voodoo;
int draw_line;
if (SLI_ENABLED)
{
if (voodoo == voodoo->set->voodoos[1])
goto skip_draw;
if (((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) ? 1 : 0) == (voodoo->line & 1))
draw_voodoo = voodoo;
else
draw_voodoo = voodoo->set->voodoos[1];
draw_line = voodoo->line >> 1;
}
else
{
if (!(voodoo->fbiInit0 & 1))
goto skip_draw;
draw_voodoo = voodoo;
draw_line = voodoo->line;
}
if (draw_voodoo->dirty_line[draw_line])
{
uint32_t *p = &buffer32->line[voodoo->line + 8][8];
uint16_t *src = (uint16_t *)&draw_voodoo->fb_mem[draw_voodoo->front_offset + draw_line*draw_voodoo->row_width];
int x;
draw_voodoo->dirty_line[draw_line] = 0;
if (voodoo->line < voodoo->dirty_line_low)
{
voodoo->dirty_line_low = voodoo->line;
video_wait_for_buffer();
}
if (voodoo->line > voodoo->dirty_line_high)
voodoo->dirty_line_high = voodoo->line;
/* Draw left overscan. */
for (x = 0; x < 8; x++)
buffer32->line[voodoo->line + 8][x] = 0x00000000;
if (voodoo->scrfilter && voodoo->scrfilterEnabled)
{
uint8_t fil[(voodoo->h_disp) * 3]; /* interleaved 24-bit RGB */
if (voodoo->type == VOODOO_2)
voodoo_filterline_v2(voodoo, fil, voodoo->h_disp, src, voodoo->line);
else
voodoo_filterline_v1(voodoo, fil, voodoo->h_disp, src, voodoo->line);
for (x = 0; x < voodoo->h_disp; x++)
{
p[x] = (voodoo->clutData256[fil[x*3]].b << 0 | voodoo->clutData256[fil[x*3+1]].g << 8 | voodoo->clutData256[fil[x*3+2]].r << 16);
}
}
else
{
for (x = 0; x < voodoo->h_disp; x++)
{
p[x] = draw_voodoo->video_16to32[src[x]];
}
}
/* Draw right overscan. */
for (x = 0; x < 8; x++)
buffer32->line[voodoo->line + 8][voodoo->h_disp + x + 8] = 0x00000000;
}
}
}
skip_draw:
if (voodoo->line == voodoo->v_disp)
{
// voodoodisp_log("retrace %i %i %08x %i\n", voodoo->retrace_count, voodoo->swap_interval, voodoo->swap_offset, voodoo->swap_pending);
voodoo->retrace_count++;
if (SLI_ENABLED && (voodoo->fbiInit2 & FBIINIT2_SWAP_ALGORITHM_MASK) == FBIINIT2_SWAP_ALGORITHM_SLI_SYNC)
{
if (voodoo == voodoo->set->voodoos[0])
{
voodoo_t *voodoo_1 = voodoo->set->voodoos[1];
thread_wait_mutex(voodoo->swap_mutex);
/*Only swap if both Voodoos are waiting for buffer swap*/
if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval) &&
voodoo_1->swap_pending && (voodoo_1->retrace_count > voodoo_1->swap_interval))
{
memset(voodoo->dirty_line, 1, 1024);
voodoo->retrace_count = 0;
voodoo->front_offset = voodoo->swap_offset;
if (voodoo->swap_count > 0)
voodoo->swap_count--;
voodoo->swap_pending = 0;
memset(voodoo_1->dirty_line, 1, 1024);
voodoo_1->retrace_count = 0;
voodoo_1->front_offset = voodoo_1->swap_offset;
if (voodoo_1->swap_count > 0)
voodoo_1->swap_count--;
voodoo_1->swap_pending = 0;
thread_release_mutex(voodoo->swap_mutex);
thread_set_event(voodoo->wake_fifo_thread);
thread_set_event(voodoo_1->wake_fifo_thread);
voodoo->frame_count++;
voodoo_1->frame_count++;
}
else
thread_release_mutex(voodoo->swap_mutex);
}
}
else
{
thread_wait_mutex(voodoo->swap_mutex);
if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval))
{
voodoo->front_offset = voodoo->swap_offset;
if (voodoo->swap_count > 0)
voodoo->swap_count--;
voodoo->swap_pending = 0;
thread_release_mutex(voodoo->swap_mutex);
memset(voodoo->dirty_line, 1, 1024);
voodoo->retrace_count = 0;
thread_set_event(voodoo->wake_fifo_thread);
voodoo->frame_count++;
}
else
thread_release_mutex(voodoo->swap_mutex);
}
voodoo->v_retrace = 1;
}
voodoo->line++;
if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS)
{
if (voodoo->line == voodoo->v_disp)
{
if (voodoo->dirty_line_high > voodoo->dirty_line_low)
svga_doblit(0, voodoo->v_disp, voodoo->h_disp, voodoo->v_disp-1, voodoo->svga);
if (voodoo->clutData_dirty)
{
voodoo->clutData_dirty = 0;
voodoo_calc_clutData(voodoo);
}
voodoo->dirty_line_high = -1;
voodoo->dirty_line_low = 2000;
}
}
if (voodoo->line >= voodoo->v_total)
{
voodoo->line = 0;
voodoo->v_retrace = 0;
}
if (voodoo->line_time)
timer_advance_u64(&voodoo->timer, voodoo->line_time);
else
timer_advance_u64(&voodoo->timer, TIMER_USEC * 32);
}

493
src/video/vid_voodoo_fb.c Normal file
View File

@@ -0,0 +1,493 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* 3DFX Voodoo emulation.
*
*
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
*
* Copyright 2008-2020 Sarah Walker.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <wchar.h>
#include <math.h>
#include <86box/86box.h>
#include "cpu.h"
#include <86box/machine.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/plat.h>
#include <86box/video.h>
#include <86box/vid_svga.h>
#include <86box/vid_voodoo_common.h>
#include <86box/vid_voodoo_dither.h>
#include <86box/vid_voodoo_regs.h>
#include <86box/vid_voodoo_render.h>
#include <86box/vid_voodoo_fb.h>
#ifdef ENABLE_VOODOO_FB_LOG
int voodoo_fb_do_log = ENABLE_VOODOO_FB_LOG;
static void
voodoo_fb_log(const char *fmt, ...)
{
va_list ap;
if (voodoo_fb_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define voodoo_fb_log(fmt, ...)
#endif
uint16_t voodoo_fb_readw(uint32_t addr, void *p)
{
voodoo_t *voodoo = (voodoo_t *)p;
int x, y;
uint32_t read_addr;
uint16_t temp;
if (voodoo->type >= VOODOO_BANSHEE)
{
x = addr & 0xffe;
y = (addr >> 12) & 0x3ff;
}
else
{
x = addr & 0x7fe;
y = (addr >> 11) & 0x3ff;
}
if (SLI_ENABLED)
{
voodoo_set_t *set = voodoo->set;
if (y & 1)
voodoo = set->voodoos[1];
else
voodoo = set->voodoos[0];
y >>= 1;
}
if (voodoo->col_tiled)
read_addr = voodoo->fb_read_offset + (x & 127) + (x >> 7) * 128*32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width;
else
read_addr = voodoo->fb_read_offset + x + (y * voodoo->row_width);
if (read_addr > voodoo->fb_mask)
return 0xffff;
temp = *(uint16_t *)(&voodoo->fb_mem[read_addr & voodoo->fb_mask]);
// voodoo_fb_log("voodoo_fb_readw : %08X %08X %i %i %08X %08X %08x:%08x %i\n", addr, temp, x, y, read_addr, *(uint32_t *)(&voodoo->fb_mem[4]), cs, pc, fb_reads++);
return temp;
}
uint32_t voodoo_fb_readl(uint32_t addr, void *p)
{
voodoo_t *voodoo = (voodoo_t *)p;
int x, y;
uint32_t read_addr;
uint32_t temp;
if (voodoo->type >= VOODOO_BANSHEE)
{
x = addr & 0xffe;
y = (addr >> 12) & 0x3ff;
}
else
{
x = addr & 0x7fe;
y = (addr >> 11) & 0x3ff;
}
if (SLI_ENABLED)
{
voodoo_set_t *set = voodoo->set;
if (y & 1)
voodoo = set->voodoos[1];
else
voodoo = set->voodoos[0];
y >>= 1;
}
if (voodoo->col_tiled)
read_addr = voodoo->fb_read_offset + (x & 127) + (x >> 7) * 128*32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width;
else
read_addr = voodoo->fb_read_offset + x + (y * voodoo->row_width);
if (read_addr > voodoo->fb_mask)
return 0xffffffff;
temp = *(uint32_t *)(&voodoo->fb_mem[read_addr & voodoo->fb_mask]);
// voodoo_fb_log("voodoo_fb_readl : %08X %08x %08X x=%i y=%i %08X %08X %08x:%08x %i ro=%08x rw=%i\n", addr, read_addr, temp, x, y, read_addr, *(uint32_t *)(&voodoo->fb_mem[4]), cs, pc, fb_reads++, voodoo->fb_read_offset, voodoo->row_width);
return temp;
}
static inline uint16_t do_dither(voodoo_params_t *params, rgba8_t col, int x, int y)
{
int r, g, b;
if (dither)
{
if (dither2x2)
{
r = dither_rb2x2[col.r][y & 1][x & 1];
g = dither_g2x2[col.g][y & 1][x & 1];
b = dither_rb2x2[col.b][y & 1][x & 1];
}
else
{
r = dither_rb[col.r][y & 3][x & 3];
g = dither_g[col.g][y & 3][x & 3];
b = dither_rb[col.b][y & 3][x & 3];
}
}
else
{
r = col.r >> 3;
g = col.g >> 2;
b = col.b >> 3;
}
return b | (g << 5) | (r << 11);
}
void voodoo_fb_writew(uint32_t addr, uint16_t val, void *p)
{
voodoo_t *voodoo = (voodoo_t *)p;
voodoo_params_t *params = &voodoo->params;
int x, y;
uint32_t write_addr, write_addr_aux;
rgba8_t colour_data;
uint16_t depth_data;
uint8_t alpha_data;
int write_mask = 0;
colour_data.r = colour_data.g = colour_data.b = colour_data.a = 0;
depth_data = voodoo->params.zaColor & 0xffff;
alpha_data = voodoo->params.zaColor >> 24;
// while (!RB_EMPTY)
// thread_reset_event(voodoo->not_full_event);
// voodoo_fb_log("voodoo_fb_writew : %08X %04X\n", addr, val);
switch (voodoo->lfbMode & LFB_FORMAT_MASK)
{
case LFB_FORMAT_RGB565:
colour_data = rgb565[val];
alpha_data = 0xff;
write_mask = LFB_WRITE_COLOUR;
break;
case LFB_FORMAT_RGB555:
colour_data = argb1555[val];
alpha_data = 0xff;
write_mask = LFB_WRITE_COLOUR;
break;
case LFB_FORMAT_ARGB1555:
colour_data = argb1555[val];
alpha_data = colour_data.a;
write_mask = LFB_WRITE_COLOUR;
break;
case LFB_FORMAT_DEPTH:
depth_data = val;
write_mask = LFB_WRITE_DEPTH;
break;
default:
fatal("voodoo_fb_writew : bad LFB format %08X\n", voodoo->lfbMode);
}
if (voodoo->type >= VOODOO_BANSHEE)
{
x = addr & 0xffe;
y = (addr >> 12) & 0x3ff;
}
else
{
x = addr & 0x7fe;
y = (addr >> 11) & 0x3ff;
}
if (SLI_ENABLED)
{
if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (y & 1)) ||
((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(y & 1)))
return;
y >>= 1;
}
if (voodoo->fb_write_offset == voodoo->params.front_offset && y < 2048)
voodoo->dirty_line[y] = 1;
if (voodoo->col_tiled)
write_addr = voodoo->fb_write_offset + (x & 127) + (x >> 7) * 128*32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width;
else
write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width);
if (voodoo->aux_tiled)
write_addr_aux = voodoo->params.aux_offset + (x & 127) + (x >> 7) * 128*32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width;
else
write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width);
// voodoo_fb_log("fb_writew %08x %i %i %i %08x\n", addr, x, y, voodoo->row_width, write_addr);
if (voodoo->lfbMode & 0x100)
{
{
rgba8_t write_data = colour_data;
uint16_t new_depth = depth_data;
if (params->fbzMode & FBZ_DEPTH_ENABLE)
{
uint16_t old_depth = *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]);
DEPTH_TEST(new_depth);
}
if ((params->fbzMode & FBZ_CHROMAKEY) &&
write_data.r == params->chromaKey_r &&
write_data.g == params->chromaKey_g &&
write_data.b == params->chromaKey_b)
goto skip_pixel;
if (params->fogMode & FOG_ENABLE)
{
int32_t z = new_depth << 12;
int64_t w_depth = (int64_t)(int32_t)new_depth;
int32_t ia = alpha_data << 12;
APPLY_FOG(write_data.r, write_data.g, write_data.b, z, ia, w_depth);
}
if (params->alphaMode & 1)
ALPHA_TEST(alpha_data);
if (params->alphaMode & (1 << 4))
{
uint16_t dat = *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]);
int dest_r, dest_g, dest_b, dest_a;
dest_r = (dat >> 8) & 0xf8;
dest_g = (dat >> 3) & 0xfc;
dest_b = (dat << 3) & 0xf8;
dest_r |= (dest_r >> 5);
dest_g |= (dest_g >> 6);
dest_b |= (dest_b >> 5);
dest_a = 0xff;
ALPHA_BLEND(write_data.r, write_data.g, write_data.b, alpha_data);
}
if (params->fbzMode & FBZ_RGB_WMASK)
*(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, write_data, x >> 1, y);
if (params->fbzMode & FBZ_DEPTH_WMASK)
*(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = new_depth;
skip_pixel:
x = x;
}
}
else
{
if (write_mask & LFB_WRITE_COLOUR)
*(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, colour_data, x >> 1, y);
if (write_mask & LFB_WRITE_DEPTH)
*(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = depth_data;
}
}
void voodoo_fb_writel(uint32_t addr, uint32_t val, void *p)
{
voodoo_t *voodoo = (voodoo_t *)p;
voodoo_params_t *params = &voodoo->params;
int x, y;
uint32_t write_addr, write_addr_aux;
rgba8_t colour_data[2];
uint16_t depth_data[2];
uint8_t alpha_data[2];
int write_mask = 0, count = 1;
depth_data[0] = depth_data[1] = voodoo->params.zaColor & 0xffff;
alpha_data[0] = alpha_data[1] = voodoo->params.zaColor >> 24;
// while (!RB_EMPTY)
// thread_reset_event(voodoo->not_full_event);
// voodoo_fb_log("voodoo_fb_writel : %08X %08X\n", addr, val);
switch (voodoo->lfbMode & LFB_FORMAT_MASK)
{
case LFB_FORMAT_RGB565:
colour_data[0] = rgb565[val & 0xffff];
colour_data[1] = rgb565[val >> 16];
write_mask = LFB_WRITE_COLOUR;
count = 2;
break;
case LFB_FORMAT_RGB555:
colour_data[0] = argb1555[val & 0xffff];
colour_data[1] = argb1555[val >> 16];
write_mask = LFB_WRITE_COLOUR;
count = 2;
break;
case LFB_FORMAT_ARGB1555:
colour_data[0] = argb1555[val & 0xffff];
alpha_data[0] = colour_data[0].a;
colour_data[1] = argb1555[val >> 16];
alpha_data[1] = colour_data[1].a;
write_mask = LFB_WRITE_COLOUR;
count = 2;
break;
case LFB_FORMAT_ARGB8888:
colour_data[0].b = val & 0xff;
colour_data[0].g = (val >> 8) & 0xff;
colour_data[0].r = (val >> 16) & 0xff;
alpha_data[0] = (val >> 24) & 0xff;
write_mask = LFB_WRITE_COLOUR;
addr >>= 1;
break;
case LFB_FORMAT_DEPTH:
depth_data[0] = val;
depth_data[1] = val >> 16;
write_mask = LFB_WRITE_DEPTH;
count = 2;
break;
default:
fatal("voodoo_fb_writel : bad LFB format %08X\n", voodoo->lfbMode);
}
if (voodoo->type >= VOODOO_BANSHEE)
{
x = addr & 0xffe;
y = (addr >> 12) & 0x3ff;
}
else
{
x = addr & 0x7fe;
y = (addr >> 11) & 0x3ff;
}
if (SLI_ENABLED)
{
if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (y & 1)) ||
((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(y & 1)))
return;
y >>= 1;
}
if (voodoo->fb_write_offset == voodoo->params.front_offset && y < 2048)
voodoo->dirty_line[y] = 1;
if (voodoo->col_tiled)
write_addr = voodoo->fb_write_offset + (x & 127) + (x >> 7) * 128*32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width;
else
write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width);
if (voodoo->aux_tiled)
write_addr_aux = voodoo->params.aux_offset + (x & 127) + (x >> 7) * 128*32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width;
else
write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width);
// voodoo_fb_log("fb_writel %08x x=%i y=%i rw=%i %08x wo=%08x\n", addr, x, y, voodoo->row_width, write_addr, voodoo->fb_write_offset);
if (voodoo->lfbMode & 0x100)
{
int c;
for (c = 0; c < count; c++)
{
rgba8_t write_data = colour_data[c];
uint16_t new_depth = depth_data[c];
if (params->fbzMode & FBZ_DEPTH_ENABLE)
{
uint16_t old_depth = *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]);
DEPTH_TEST(new_depth);
}
if ((params->fbzMode & FBZ_CHROMAKEY) &&
write_data.r == params->chromaKey_r &&
write_data.g == params->chromaKey_g &&
write_data.b == params->chromaKey_b)
goto skip_pixel;
if (params->fogMode & FOG_ENABLE)
{
int32_t z = new_depth << 12;
int64_t w_depth = new_depth;
int32_t ia = alpha_data[c] << 12;
APPLY_FOG(write_data.r, write_data.g, write_data.b, z, ia, w_depth);
}
if (params->alphaMode & 1)
ALPHA_TEST(alpha_data[c]);
if (params->alphaMode & (1 << 4))
{
uint16_t dat = *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]);
int dest_r, dest_g, dest_b, dest_a;
dest_r = (dat >> 8) & 0xf8;
dest_g = (dat >> 3) & 0xfc;
dest_b = (dat << 3) & 0xf8;
dest_r |= (dest_r >> 5);
dest_g |= (dest_g >> 6);
dest_b |= (dest_b >> 5);
dest_a = 0xff;
ALPHA_BLEND(write_data.r, write_data.g, write_data.b, alpha_data[c]);
}
if (params->fbzMode & FBZ_RGB_WMASK)
*(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, write_data, (x >> 1) + c, y);
if (params->fbzMode & FBZ_DEPTH_WMASK)
*(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = new_depth;
skip_pixel:
write_addr += 2;
write_addr_aux += 2;
}
}
else
{
int c;
for (c = 0; c < count; c++)
{
if (write_mask & LFB_WRITE_COLOUR)
*(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, colour_data[c], (x >> 1) + c, y);
if (write_mask & LFB_WRITE_DEPTH)
*(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = depth_data[c];
write_addr += 2;
write_addr_aux += 2;
}
}
}

530
src/video/vid_voodoo_fifo.c Normal file
View File

@@ -0,0 +1,530 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* 3DFX Voodoo emulation.
*
*
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
*
* Copyright 2008-2020 Sarah Walker.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <wchar.h>
#include <math.h>
#include <86box/86box.h>
#include "cpu.h"
#include <86box/machine.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/plat.h>
#include <86box/video.h>
#include <86box/vid_svga.h>
#include <86box/vid_voodoo_common.h>
#include <86box/vid_voodoo_banshee_blitter.h>
#include <86box/vid_voodoo_fb.h>
#include <86box/vid_voodoo_fifo.h>
#include <86box/vid_voodoo_reg.h>
#include <86box/vid_voodoo_regs.h>
#include <86box/vid_voodoo_render.h>
#include <86box/vid_voodoo_texture.h>
#ifdef ENABLE_VOODOO_FIFO_LOG
int voodoo_fifo_do_log = ENABLE_VOODOO_FIFO_LOG;
static void
voodoo_fifo_log(const char *fmt, ...)
{
va_list ap;
if (voodoo_fifo_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define voodoo_fifo_log(fmt, ...)
#endif
#define WAKE_DELAY (TIMER_USEC * 100)
void voodoo_wake_fifo_thread(voodoo_t *voodoo)
{
if (!timer_is_enabled(&voodoo->wake_timer))
{
/*Don't wake FIFO thread immediately - if we do that it will probably
process one word and go back to sleep, requiring it to be woken on
almost every write. Instead, wait a short while so that the CPU
emulation writes more data so we have more batched-up work.*/
timer_set_delay_u64(&voodoo->wake_timer, WAKE_DELAY);
}
}
void voodoo_wake_fifo_thread_now(voodoo_t *voodoo)
{
thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/
}
void voodoo_wake_timer(void *p)
{
voodoo_t *voodoo = (voodoo_t *)p;
thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/
}
void voodoo_queue_command(voodoo_t *voodoo, uint32_t addr_type, uint32_t val)
{
fifo_entry_t *fifo = &voodoo->fifo[voodoo->fifo_write_idx & FIFO_MASK];
while (FIFO_FULL)
{
thread_reset_event(voodoo->fifo_not_full_event);
if (FIFO_FULL)
{
thread_wait_event(voodoo->fifo_not_full_event, 1); /*Wait for room in ringbuffer*/
if (FIFO_FULL)
voodoo_wake_fifo_thread_now(voodoo);
}
}
fifo->val = val;
fifo->addr_type = addr_type;
voodoo->fifo_write_idx++;
if (FIFO_ENTRIES > 0xe000)
voodoo_wake_fifo_thread(voodoo);
}
void voodoo_flush(voodoo_t *voodoo)
{
voodoo->flush = 1;
while (!FIFO_EMPTY)
{
voodoo_wake_fifo_thread_now(voodoo);
thread_wait_event(voodoo->fifo_not_full_event, 1);
}
voodoo_wait_for_render_thread_idle(voodoo);
voodoo->flush = 0;
}
void voodoo_wake_fifo_threads(voodoo_set_t *set, voodoo_t *voodoo)
{
voodoo_wake_fifo_thread(voodoo);
if (SLI_ENABLED && voodoo->type != VOODOO_2 && set->voodoos[0] == voodoo)
voodoo_wake_fifo_thread(set->voodoos[1]);
}
void voodoo_wait_for_swap_complete(voodoo_t *voodoo)
{
while (voodoo->swap_pending)
{
thread_wait_event(voodoo->wake_fifo_thread, -1);
thread_reset_event(voodoo->wake_fifo_thread);
thread_wait_mutex(voodoo->swap_mutex);
if ((voodoo->swap_pending && voodoo->flush) || FIFO_FULL)
{
/*Main thread is waiting for FIFO to empty, so skip vsync wait and just swap*/
memset(voodoo->dirty_line, 1, sizeof(voodoo->dirty_line));
voodoo->front_offset = voodoo->params.front_offset;
if (voodoo->swap_count > 0)
voodoo->swap_count--;
voodoo->swap_pending = 0;
thread_release_mutex(voodoo->swap_mutex);;
break;
}
else
thread_release_mutex(voodoo->swap_mutex);;
}
}
static uint32_t cmdfifo_get(voodoo_t *voodoo)
{
uint32_t val;
while (voodoo->cmdfifo_depth_rd == voodoo->cmdfifo_depth_wr)
{
thread_wait_event(voodoo->wake_fifo_thread, -1);
thread_reset_event(voodoo->wake_fifo_thread);
}
val = *(uint32_t *)&voodoo->fb_mem[voodoo->cmdfifo_rp & voodoo->fb_mask];
voodoo->cmdfifo_depth_rd++;
voodoo->cmdfifo_rp += 4;
// voodoo_fifo_log(" CMDFIFO get %08x\n", val);
return val;
}
static inline float cmdfifo_get_f(voodoo_t *voodoo)
{
union
{
uint32_t i;
float f;
} tempif;
tempif.i = cmdfifo_get(voodoo);
return tempif.f;
}
enum
{
CMDFIFO3_PC_MASK_RGB = (1 << 10),
CMDFIFO3_PC_MASK_ALPHA = (1 << 11),
CMDFIFO3_PC_MASK_Z = (1 << 12),
CMDFIFO3_PC_MASK_Wb = (1 << 13),
CMDFIFO3_PC_MASK_W0 = (1 << 14),
CMDFIFO3_PC_MASK_S0_T0 = (1 << 15),
CMDFIFO3_PC_MASK_W1 = (1 << 16),
CMDFIFO3_PC_MASK_S1_T1 = (1 << 17),
CMDFIFO3_PC = (1 << 28)
};
void voodoo_fifo_thread(void *param)
{
voodoo_t *voodoo = (voodoo_t *)param;
while (1)
{
thread_set_event(voodoo->fifo_not_full_event);
thread_wait_event(voodoo->wake_fifo_thread, -1);
thread_reset_event(voodoo->wake_fifo_thread);
voodoo->voodoo_busy = 1;
while (!FIFO_EMPTY)
{
uint64_t start_time = plat_timer_read();
uint64_t end_time;
fifo_entry_t *fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK];
switch (fifo->addr_type & FIFO_TYPE)
{
case FIFO_WRITEL_REG:
while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_REG)
{
voodoo_reg_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo);
fifo->addr_type = FIFO_INVALID;
voodoo->fifo_read_idx++;
if (FIFO_EMPTY)
break;
fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK];
}
break;
case FIFO_WRITEW_FB:
voodoo_wait_for_render_thread_idle(voodoo);
while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEW_FB)
{
voodoo_fb_writew(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo);
fifo->addr_type = FIFO_INVALID;
voodoo->fifo_read_idx++;
if (FIFO_EMPTY)
break;
fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK];
}
break;
case FIFO_WRITEL_FB:
voodoo_wait_for_render_thread_idle(voodoo);
while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_FB)
{
voodoo_fb_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo);
fifo->addr_type = FIFO_INVALID;
voodoo->fifo_read_idx++;
if (FIFO_EMPTY)
break;
fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK];
}
break;
case FIFO_WRITEL_TEX:
while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_TEX)
{
if (!(fifo->addr_type & 0x400000))
voodoo_tex_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo);
fifo->addr_type = FIFO_INVALID;
voodoo->fifo_read_idx++;
if (FIFO_EMPTY)
break;
fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK];
}
break;
case FIFO_WRITEL_2DREG:
while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_2DREG)
{
voodoo_2d_reg_writel(voodoo, fifo->addr_type & FIFO_ADDR, fifo->val);
fifo->addr_type = FIFO_INVALID;
voodoo->fifo_read_idx++;
if (FIFO_EMPTY)
break;
fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK];
}
break;
default:
fatal("Unknown fifo entry %08x\n", fifo->addr_type);
}
if (FIFO_ENTRIES > 0xe000)
thread_set_event(voodoo->fifo_not_full_event);
end_time = plat_timer_read();
voodoo->time += end_time - start_time;
}
while (voodoo->cmdfifo_enabled && voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr)
{
uint64_t start_time = plat_timer_read();
uint64_t end_time;
uint32_t header = cmdfifo_get(voodoo);
uint32_t addr;
uint32_t mask;
int smode;
int num;
int num_verticies;
int v_num;
// voodoo_fifo_log(" CMDFIFO header %08x at %08x\n", header, voodoo->cmdfifo_rp);
switch (header & 7)
{
case 0:
// voodoo_fifo_log("CMDFIFO0\n");
switch ((header >> 3) & 7)
{
case 0: /*NOP*/
break;
case 3: /*JMP local frame buffer*/
voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc;
// voodoo_fifo_log("JMP to %08x %04x\n", voodoo->cmdfifo_rp, header);
break;
default:
fatal("Bad CMDFIFO0 %08x\n", header);
}
break;
case 1:
num = header >> 16;
addr = (header & 0x7ff8) >> 1;
// voodoo_fifo_log("CMDFIFO1 addr=%08x\n",addr);
while (num--)
{
uint32_t val = cmdfifo_get(voodoo);
if ((addr & (1 << 13)) && voodoo->type >= VOODOO_BANSHEE)
{
// if (voodoo->type != VOODOO_BANSHEE)
// fatal("CMDFIFO1: Not Banshee\n");
// voodoo_fifo_log("CMDFIFO1: write %08x %08x\n", addr, val);
voodoo_2d_reg_writel(voodoo, addr, val);
}
else
{
if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD ||
(addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD)
voodoo->cmd_written_fifo++;
if (voodoo->type >= VOODOO_BANSHEE && (addr & 0x3ff) == SST_swapbufferCMD)
voodoo->cmd_written_fifo++;
voodoo_reg_writel(addr, val, voodoo);
}
if (header & (1 << 15))
addr += 4;
}
break;
case 2:
if (voodoo->type < VOODOO_BANSHEE)
fatal("CMDFIFO2: Not Banshee\n");
mask = (header >> 3);
addr = 8;
while (mask)
{
if (mask & 1)
{
uint32_t val = cmdfifo_get(voodoo);
voodoo_2d_reg_writel(voodoo, addr, val);
}
addr += 4;
mask >>= 1;
}
break;
case 3:
num = (header >> 29) & 7;
mask = header;//(header >> 10) & 0xff;
smode = (header >> 22) & 0xf;
voodoo_reg_writel(SST_sSetupMode, ((header >> 10) & 0xff) | (smode << 16), voodoo);
num_verticies = (header >> 6) & 0xf;
v_num = 0;
if (((header >> 3) & 7) == 2)
v_num = 1;
// voodoo_fifo_log("CMDFIFO3: num=%i verts=%i mask=%02x\n", num, num_verticies, (header >> 10) & 0xff);
// voodoo_fifo_log("CMDFIFO3 %02x %i\n", (header >> 10), (header >> 3) & 7);
while (num_verticies--)
{
voodoo->verts[3].sVx = cmdfifo_get_f(voodoo);
voodoo->verts[3].sVy = cmdfifo_get_f(voodoo);
if (mask & CMDFIFO3_PC_MASK_RGB)
{
if (header & CMDFIFO3_PC)
{
uint32_t val = cmdfifo_get(voodoo);
voodoo->verts[3].sBlue = (float)(val & 0xff);
voodoo->verts[3].sGreen = (float)((val >> 8) & 0xff);
voodoo->verts[3].sRed = (float)((val >> 16) & 0xff);
voodoo->verts[3].sAlpha = (float)((val >> 24) & 0xff);
}
else
{
voodoo->verts[3].sRed = cmdfifo_get_f(voodoo);
voodoo->verts[3].sGreen = cmdfifo_get_f(voodoo);
voodoo->verts[3].sBlue = cmdfifo_get_f(voodoo);
}
}
if ((mask & CMDFIFO3_PC_MASK_ALPHA) && !(header & CMDFIFO3_PC))
voodoo->verts[3].sAlpha = cmdfifo_get_f(voodoo);
if (mask & CMDFIFO3_PC_MASK_Z)
voodoo->verts[3].sVz = cmdfifo_get_f(voodoo);
if (mask & CMDFIFO3_PC_MASK_Wb)
voodoo->verts[3].sWb = cmdfifo_get_f(voodoo);
if (mask & CMDFIFO3_PC_MASK_W0)
voodoo->verts[3].sW0 = cmdfifo_get_f(voodoo);
if (mask & CMDFIFO3_PC_MASK_S0_T0)
{
voodoo->verts[3].sS0 = cmdfifo_get_f(voodoo);
voodoo->verts[3].sT0 = cmdfifo_get_f(voodoo);
}
if (mask & CMDFIFO3_PC_MASK_W1)
voodoo->verts[3].sW1 = cmdfifo_get_f(voodoo);
if (mask & CMDFIFO3_PC_MASK_S1_T1)
{
voodoo->verts[3].sS1 = cmdfifo_get_f(voodoo);
voodoo->verts[3].sT1 = cmdfifo_get_f(voodoo);
}
if (v_num)
voodoo_reg_writel(SST_sDrawTriCMD, 0, voodoo);
else
voodoo_reg_writel(SST_sBeginTriCMD, 0, voodoo);
v_num++;
if (v_num == 3 && ((header >> 3) & 7) == 0)
v_num = 0;
}
break;
case 4:
num = (header >> 29) & 7;
mask = (header >> 15) & 0x3fff;
addr = (header & 0x7ff8) >> 1;
// voodoo_fifo_log("CMDFIFO4 addr=%08x\n",addr);
while (mask)
{
if (mask & 1)
{
uint32_t val = cmdfifo_get(voodoo);
if ((addr & (1 << 13)) && voodoo->type >= VOODOO_BANSHEE)
{
if (voodoo->type < VOODOO_BANSHEE)
fatal("CMDFIFO1: Not Banshee\n");
// voodoo_fifo_log("CMDFIFO1: write %08x %08x\n", addr, val);
voodoo_2d_reg_writel(voodoo, addr, val);
}
else
{
if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD ||
(addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD)
voodoo->cmd_written_fifo++;
if (voodoo->type >= VOODOO_BANSHEE && (addr & 0x3ff) == SST_swapbufferCMD)
voodoo->cmd_written_fifo++;
voodoo_reg_writel(addr, val, voodoo);
}
}
addr += 4;
mask >>= 1;
}
while (num--)
cmdfifo_get(voodoo);
break;
case 5:
// if (header & 0x3fc00000)
// fatal("CMDFIFO packet 5 has byte disables set %08x\n", header);
num = (header >> 3) & 0x7ffff;
addr = cmdfifo_get(voodoo) & 0xffffff;
if (!num)
num = 1;
// voodoo_fifo_log("CMDFIFO5 addr=%08x num=%i\n", addr, num);
switch (header >> 30)
{
case 0: /*Linear framebuffer (Banshee)*/
if (voodoo->texture_present[0][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT])
{
// voodoo_fifo_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT);
flush_texture_cache(voodoo, addr & voodoo->texture_mask, 0);
}
if (voodoo->texture_present[1][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT])
{
// voodoo_fifo_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT);
flush_texture_cache(voodoo, addr & voodoo->texture_mask, 1);
}
while (num--)
{
uint32_t val = cmdfifo_get(voodoo);
if (addr <= voodoo->fb_mask)
*(uint32_t *)&voodoo->fb_mem[addr] = val;
addr += 4;
}
break;
case 2: /*Framebuffer*/
while (num--)
{
uint32_t val = cmdfifo_get(voodoo);
voodoo_fb_writel(addr, val, voodoo);
addr += 4;
}
break;
case 3: /*Texture*/
while (num--)
{
uint32_t val = cmdfifo_get(voodoo);
voodoo_tex_writel(addr, val, voodoo);
addr += 4;
}
break;
default:
fatal("CMDFIFO packet 5 bad space %08x %08x\n", header, voodoo->cmdfifo_rp);
}
break;
default:
fatal("Bad CMDFIFO packet %08x %08x\n", header, voodoo->cmdfifo_rp);
}
end_time = plat_timer_read();
voodoo->time += end_time - start_time;
}
voodoo->voodoo_busy = 0;
}
}

1365
src/video/vid_voodoo_reg.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,240 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* 3DFX Voodoo emulation.
*
*
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
*
* Copyright 2008-2020 Sarah Walker.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <wchar.h>
#include <math.h>
#include <86box/86box.h>
#include "cpu.h"
#include <86box/machine.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/plat.h>
#include <86box/video.h>
#include <86box/vid_svga.h>
#include <86box/vid_voodoo_common.h>
#include <86box/vid_voodoo_regs.h>
#include <86box/vid_voodoo_render.h>
#include <86box/vid_voodoo_setup.h>
void voodoo_triangle_setup(voodoo_t *voodoo)
{
float dxAB, dxBC, dyAB, dyBC;
float area;
int va = 0, vb = 1, vc = 2;
vert_t verts[3];
verts[0] = voodoo->verts[0];
verts[1] = voodoo->verts[1];
verts[2] = voodoo->verts[2];
if (verts[0].sVy < verts[1].sVy)
{
if (verts[1].sVy < verts[2].sVy)
{
/* V1>V0, V2>V1, V2>V1>V0*/
va = 0; /*OK*/
vb = 1;
vc = 2;
}
else
{
/* V1>V0, V1>V2*/
if (verts[0].sVy < verts[2].sVy)
{
/* V1>V0, V1>V2, V2>V0, V1>V2>V0*/
va = 0;
vb = 2;
vc = 1;
}
else
{
/* V1>V0, V1>V2, V0>V2, V1>V0>V2*/
va = 2;
vb = 0;
vc = 1;
}
}
}
else
{
if (verts[1].sVy < verts[2].sVy)
{
/* V0>V1, V2>V1*/
if (verts[0].sVy < verts[2].sVy)
{
/* V0>V1, V2>V1, V2>V0, V2>V0>V1*/
va = 1;
vb = 0;
vc = 2;
}
else
{
/* V0>V1, V2>V1, V0>V2, V0>V2>V1*/
va = 1;
vb = 2;
vc = 0;
}
}
else
{
/*V0>V1>V2*/
va = 2;
vb = 1;
vc = 0;
}
}
dxAB = verts[0].sVx - verts[1].sVx;
dxBC = verts[1].sVx - verts[2].sVx;
dyAB = verts[0].sVy - verts[1].sVy;
dyBC = verts[1].sVy - verts[2].sVy;
area = dxAB * dyBC - dxBC * dyAB;
if (area == 0.0)
return;
if (voodoo->sSetupMode & SETUPMODE_CULLING_ENABLE)
{
int cull_sign = voodoo->sSetupMode & SETUPMODE_CULLING_SIGN;
int sign = (area < 0.0);
if ((voodoo->sSetupMode & (SETUPMODE_CULLING_ENABLE | SETUPMODE_DISABLE_PINGPONG))
== SETUPMODE_CULLING_ENABLE && voodoo->cull_pingpong)
cull_sign = !cull_sign;
if (cull_sign && sign)
return;
if (!cull_sign && !sign)
return;
}
dxAB = verts[va].sVx - verts[vb].sVx;
dxBC = verts[vb].sVx - verts[vc].sVx;
dyAB = verts[va].sVy - verts[vb].sVy;
dyBC = verts[vb].sVy - verts[vc].sVy;
area = dxAB * dyBC - dxBC * dyAB;
dxAB /= area;
dxBC /= area;
dyAB /= area;
dyBC /= area;
voodoo->params.vertexAx = (int32_t)(int16_t)((int32_t)(verts[va].sVx * 16.0f) & 0xffff);
voodoo->params.vertexAy = (int32_t)(int16_t)((int32_t)(verts[va].sVy * 16.0f) & 0xffff);
voodoo->params.vertexBx = (int32_t)(int16_t)((int32_t)(verts[vb].sVx * 16.0f) & 0xffff);
voodoo->params.vertexBy = (int32_t)(int16_t)((int32_t)(verts[vb].sVy * 16.0f) & 0xffff);
voodoo->params.vertexCx = (int32_t)(int16_t)((int32_t)(verts[vc].sVx * 16.0f) & 0xffff);
voodoo->params.vertexCy = (int32_t)(int16_t)((int32_t)(verts[vc].sVy * 16.0f) & 0xffff);
if (voodoo->params.vertexAy > voodoo->params.vertexBy || voodoo->params.vertexBy > voodoo->params.vertexCy)
fatal("triangle_setup wrong order %d %d %d\n", voodoo->params.vertexAy, voodoo->params.vertexBy, voodoo->params.vertexCy);
if (voodoo->sSetupMode & SETUPMODE_RGB)
{
voodoo->params.startR = (int32_t)(verts[va].sRed * 4096.0f);
voodoo->params.dRdX = (int32_t)(((verts[va].sRed - verts[vb].sRed) * dyBC - (verts[vb].sRed - verts[vc].sRed) * dyAB) * 4096.0f);
voodoo->params.dRdY = (int32_t)(((verts[vb].sRed - verts[vc].sRed) * dxAB - (verts[va].sRed - verts[vb].sRed) * dxBC) * 4096.0f);
voodoo->params.startG = (int32_t)(verts[va].sGreen * 4096.0f);
voodoo->params.dGdX = (int32_t)(((verts[va].sGreen - verts[vb].sGreen) * dyBC - (verts[vb].sGreen - verts[vc].sGreen) * dyAB) * 4096.0f);
voodoo->params.dGdY = (int32_t)(((verts[vb].sGreen - verts[vc].sGreen) * dxAB - (verts[va].sGreen - verts[vb].sGreen) * dxBC) * 4096.0f);
voodoo->params.startB = (int32_t)(verts[va].sBlue * 4096.0f);
voodoo->params.dBdX = (int32_t)(((verts[va].sBlue - verts[vb].sBlue) * dyBC - (verts[vb].sBlue - verts[vc].sBlue) * dyAB) * 4096.0f);
voodoo->params.dBdY = (int32_t)(((verts[vb].sBlue - verts[vc].sBlue) * dxAB - (verts[va].sBlue - verts[vb].sBlue) * dxBC) * 4096.0f);
}
if (voodoo->sSetupMode & SETUPMODE_ALPHA)
{
voodoo->params.startA = (int32_t)(verts[va].sAlpha * 4096.0f);
voodoo->params.dAdX = (int32_t)(((verts[va].sAlpha - verts[vb].sAlpha) * dyBC - (verts[vb].sAlpha - verts[vc].sAlpha) * dyAB) * 4096.0f);
voodoo->params.dAdY = (int32_t)(((verts[vb].sAlpha - verts[vc].sAlpha) * dxAB - (verts[va].sAlpha - verts[vb].sAlpha) * dxBC) * 4096.0f);
}
if (voodoo->sSetupMode & SETUPMODE_Z)
{
voodoo->params.startZ = (int32_t)(verts[va].sVz * 4096.0f);
voodoo->params.dZdX = (int32_t)(((verts[va].sVz - verts[vb].sVz) * dyBC - (verts[vb].sVz - verts[vc].sVz) * dyAB) * 4096.0f);
voodoo->params.dZdY = (int32_t)(((verts[vb].sVz - verts[vc].sVz) * dxAB - (verts[va].sVz - verts[vb].sVz) * dxBC) * 4096.0f);
}
if (voodoo->sSetupMode & SETUPMODE_Wb)
{
voodoo->params.startW = (int64_t)(verts[va].sWb * 4294967296.0f);
voodoo->params.dWdX = (int64_t)(((verts[va].sWb - verts[vb].sWb) * dyBC - (verts[vb].sWb - verts[vc].sWb) * dyAB) * 4294967296.0f);
voodoo->params.dWdY = (int64_t)(((verts[vb].sWb - verts[vc].sWb) * dxAB - (verts[va].sWb - verts[vb].sWb) * dxBC) * 4294967296.0f);
voodoo->params.tmu[0].startW = voodoo->params.tmu[1].startW = voodoo->params.startW;
voodoo->params.tmu[0].dWdX = voodoo->params.tmu[1].dWdX = voodoo->params.dWdX;
voodoo->params.tmu[0].dWdY = voodoo->params.tmu[1].dWdY = voodoo->params.dWdY;
}
if (voodoo->sSetupMode & SETUPMODE_W0)
{
voodoo->params.tmu[0].startW = (int64_t)(verts[va].sW0 * 4294967296.0f);
voodoo->params.tmu[0].dWdX = (int64_t)(((verts[va].sW0 - verts[vb].sW0) * dyBC - (verts[vb].sW0 - verts[vc].sW0) * dyAB) * 4294967296.0f);
voodoo->params.tmu[0].dWdY = (int64_t)(((verts[vb].sW0 - verts[vc].sW0) * dxAB - (verts[va].sW0 - verts[vb].sW0) * dxBC) * 4294967296.0f);
voodoo->params.tmu[1].startW = voodoo->params.tmu[0].startW;
voodoo->params.tmu[1].dWdX = voodoo->params.tmu[0].dWdX;
voodoo->params.tmu[1].dWdY = voodoo->params.tmu[0].dWdY;
}
if (voodoo->sSetupMode & SETUPMODE_S0_T0)
{
voodoo->params.tmu[0].startS = (int64_t)(verts[va].sS0 * 4294967296.0f);
voodoo->params.tmu[0].dSdX = (int64_t)(((verts[va].sS0 - verts[vb].sS0) * dyBC - (verts[vb].sS0 - verts[vc].sS0) * dyAB) * 4294967296.0f);
voodoo->params.tmu[0].dSdY = (int64_t)(((verts[vb].sS0 - verts[vc].sS0) * dxAB - (verts[va].sS0 - verts[vb].sS0) * dxBC) * 4294967296.0f);
voodoo->params.tmu[0].startT = (int64_t)(verts[va].sT0 * 4294967296.0f);
voodoo->params.tmu[0].dTdX = (int64_t)(((verts[va].sT0 - verts[vb].sT0) * dyBC - (verts[vb].sT0 - verts[vc].sT0) * dyAB) * 4294967296.0f);
voodoo->params.tmu[0].dTdY = (int64_t)(((verts[vb].sT0 - verts[vc].sT0) * dxAB - (verts[va].sT0 - verts[vb].sT0) * dxBC) * 4294967296.0f);
voodoo->params.tmu[1].startS = voodoo->params.tmu[0].startS;
voodoo->params.tmu[1].dSdX = voodoo->params.tmu[0].dSdX;
voodoo->params.tmu[1].dSdY = voodoo->params.tmu[0].dSdY;
voodoo->params.tmu[1].startT = voodoo->params.tmu[0].startT;
voodoo->params.tmu[1].dTdX = voodoo->params.tmu[0].dTdX;
voodoo->params.tmu[1].dTdY = voodoo->params.tmu[0].dTdY;
}
if (voodoo->sSetupMode & SETUPMODE_W1)
{
voodoo->params.tmu[1].startW = (int64_t)(verts[va].sW1 * 4294967296.0f);
voodoo->params.tmu[1].dWdX = (int64_t)(((verts[va].sW1 - verts[vb].sW1) * dyBC - (verts[vb].sW1 - verts[vc].sW1) * dyAB) * 4294967296.0f);
voodoo->params.tmu[1].dWdY = (int64_t)(((verts[vb].sW1 - verts[vc].sW1) * dxAB - (verts[va].sW1 - verts[vb].sW1) * dxBC) * 4294967296.0f);
}
if (voodoo->sSetupMode & SETUPMODE_S1_T1)
{
voodoo->params.tmu[1].startS = (int64_t)(verts[va].sS1 * 4294967296.0f);
voodoo->params.tmu[1].dSdX = (int64_t)(((verts[va].sS1 - verts[vb].sS1) * dyBC - (verts[vb].sS1 - verts[vc].sS1) * dyAB) * 4294967296.0f);
voodoo->params.tmu[1].dSdY = (int64_t)(((verts[vb].sS1 - verts[vc].sS1) * dxAB - (verts[va].sS1 - verts[vb].sS1) * dxBC) * 4294967296.0f);
voodoo->params.tmu[1].startT = (int64_t)(verts[va].sT1 * 4294967296.0f);
voodoo->params.tmu[1].dTdX = (int64_t)(((verts[va].sT1 - verts[vb].sT1) * dyBC - (verts[vb].sT1 - verts[vc].sT1) * dyAB) * 4294967296.0f);
voodoo->params.tmu[1].dTdY = (int64_t)(((verts[vb].sT1 - verts[vc].sT1) * dxAB - (verts[va].sT1 - verts[vb].sT1) * dxBC) * 4294967296.0f);
}
voodoo->params.sign = (area < 0.0);
if (voodoo->ncc_dirty[0])
voodoo_update_ncc(voodoo, 0);
if (voodoo->ncc_dirty[1])
voodoo_update_ncc(voodoo, 1);
voodoo->ncc_dirty[0] = voodoo->ncc_dirty[1] = 0;
voodoo_queue_triangle(voodoo, &voodoo->params);
}

View File

@@ -0,0 +1,627 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* 3DFX Voodoo emulation.
*
*
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
*
* Copyright 2008-2020 Sarah Walker.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <wchar.h>
#include <math.h>
#include <86box/86box.h>
#include "cpu.h"
#include <86box/machine.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/plat.h>
#include <86box/video.h>
#include <86box/vid_svga.h>
#include <86box/vid_voodoo_common.h>
#include <86box/vid_voodoo_dither.h>
#include <86box/vid_voodoo_regs.h>
#include <86box/vid_voodoo_render.h>
#include <86box/vid_voodoo_texture.h>
#ifdef ENABLE_VOODOO_TEXTURE_LOG
int voodoo_texture_do_log = ENABLE_VOODOO_TEXTURE_LOG;
static void
voodoo_texture_log(const char *fmt, ...)
{
va_list ap;
if (voodoo_texture_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define voodoo_texture_log(fmt, ...)
#endif
void voodoo_recalc_tex(voodoo_t *voodoo, int tmu)
{
int aspect = (voodoo->params.tLOD[tmu] >> 21) & 3;
int width = 256, height = 256;
int shift = 8;
int lod;
uint32_t base = voodoo->params.texBaseAddr[tmu];
uint32_t offset = 0;
int tex_lod = 0;
uint32_t offsets[LOD_MAX+3];
int widths[LOD_MAX+3], heights[LOD_MAX+3], shifts[LOD_MAX+3];
if (voodoo->params.tLOD[tmu] & LOD_S_IS_WIDER)
height >>= aspect;
else
{
width >>= aspect;
shift -= aspect;
}
for (lod = 0; lod <= LOD_MAX + 2; lod++)
{
offsets[lod] = offset;
widths[lod] = width >> lod;
heights[lod] = height >> lod;
shifts[lod] = shift - lod;
if (!widths[lod])
widths[lod] = 1;
if (!heights[lod])
heights[lod] = 1;
if (shifts[lod] < 0)
shifts[lod] = 0;
if (!(voodoo->params.tLOD[tmu] & LOD_SPLIT) ||
((lod & 1) && (voodoo->params.tLOD[tmu] & LOD_ODD)) ||
(!(lod & 1) && !(voodoo->params.tLOD[tmu] & LOD_ODD)))
{
if (voodoo->params.tformat[tmu] & 8)
offset += (width >> lod) * (height >> lod) * 2;
else
offset += (width >> lod) * (height >> lod);
}
}
if ((voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR) && (voodoo->params.tLOD[tmu] & LOD_ODD))
tex_lod++; /*Skip LOD 0*/
// voodoo_texture_log("TMU %i: %08x\n", tmu, voodoo->params.textureMode[tmu]);
for (lod = 0; lod <= LOD_MAX+1; lod++)
{
if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR)
{
switch (tex_lod)
{
case 0:
base = voodoo->params.texBaseAddr[tmu];
break;
case 1:
base = voodoo->params.texBaseAddr1[tmu];
break;
case 2:
base = voodoo->params.texBaseAddr2[tmu];
break;
default:
base = voodoo->params.texBaseAddr38[tmu];
break;
}
}
voodoo->params.tex_base[tmu][lod] = base + offsets[tex_lod];
if (voodoo->params.tformat[tmu] & 8)
voodoo->params.tex_end[tmu][lod] = base + offsets[tex_lod] + (widths[tex_lod] * heights[tex_lod] * 2);
else
voodoo->params.tex_end[tmu][lod] = base + offsets[tex_lod] + (widths[tex_lod] * heights[tex_lod]);
voodoo->params.tex_w_mask[tmu][lod] = widths[tex_lod] - 1;
voodoo->params.tex_w_nmask[tmu][lod] = ~(widths[tex_lod] - 1);
voodoo->params.tex_h_mask[tmu][lod] = heights[tex_lod] - 1;
voodoo->params.tex_shift[tmu][lod] = shifts[tex_lod];
voodoo->params.tex_lod[tmu][lod] = tex_lod;
if (!(voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR) ||
((lod & 1) && (voodoo->params.tLOD[tmu] & LOD_ODD)) ||
(!(lod & 1) && !(voodoo->params.tLOD[tmu] & LOD_ODD)))
{
if (!(voodoo->params.tLOD[tmu] & LOD_ODD) || lod != 0)
{
if (voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR)
tex_lod += 2;
else
tex_lod++;
}
}
}
voodoo->params.tex_width[tmu] = width;
}
#define makergba(r, g, b, a) ((b) | ((g) << 8) | ((r) << 16) | ((a) << 24))
void voodoo_use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu)
{
int c, d;
int lod;
int lod_min, lod_max;
uint32_t addr = 0, addr_end;
uint32_t palette_checksum;
lod_min = (params->tLOD[tmu] >> 2) & 15;
lod_max = (params->tLOD[tmu] >> 8) & 15;
if (params->tformat[tmu] == TEX_PAL8 || params->tformat[tmu] == TEX_APAL8 || params->tformat[tmu] == TEX_APAL88)
{
if (voodoo->palette_dirty[tmu])
{
palette_checksum = 0;
for (c = 0; c < 256; c++)
palette_checksum ^= voodoo->palette[tmu][c].u;
voodoo->palette_checksum[tmu] = palette_checksum;
voodoo->palette_dirty[tmu] = 0;
}
else
palette_checksum = voodoo->palette_checksum[tmu];
}
else
palette_checksum = 0;
if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD) && (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR))
addr = params->texBaseAddr1[tmu];
else
addr = params->texBaseAddr[tmu];
/*Try to find texture in cache*/
for (c = 0; c < TEX_CACHE_MAX; c++)
{
if (voodoo->texture_cache[tmu][c].base == addr &&
voodoo->texture_cache[tmu][c].tLOD == (params->tLOD[tmu] & 0xf00fff) &&
voodoo->texture_cache[tmu][c].palette_checksum == palette_checksum)
{
params->tex_entry[tmu] = c;
voodoo->texture_cache[tmu][c].refcount++;
return;
}
}
/*Texture not found, search for unused texture*/
do
{
for (c = 0; c < TEX_CACHE_MAX; c++)
{
voodoo->texture_last_removed++;
voodoo->texture_last_removed &= (TEX_CACHE_MAX-1);
if (voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount == voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount_r[0] &&
(voodoo->render_threads == 1 || voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount == voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount_r[1]))
break;
}
if (c == TEX_CACHE_MAX)
voodoo_wait_for_render_thread_idle(voodoo);
} while (c == TEX_CACHE_MAX);
if (c == TEX_CACHE_MAX)
fatal("Texture cache full!\n");
c = voodoo->texture_last_removed;
if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD) && (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR))
voodoo->texture_cache[tmu][c].base = params->texBaseAddr1[tmu];
else
voodoo->texture_cache[tmu][c].base = params->texBaseAddr[tmu];
voodoo->texture_cache[tmu][c].tLOD = params->tLOD[tmu] & 0xf00fff;
lod_min = (params->tLOD[tmu] >> 2) & 15;
lod_max = (params->tLOD[tmu] >> 8) & 15;
// voodoo_texture_log(" add new texture to %i tformat=%i %08x LOD=%i-%i tmu=%i\n", c, voodoo->params.tformat[tmu], params->texBaseAddr[tmu], lod_min, lod_max, tmu);
lod_min = MIN(lod_min, 8);
lod_max = MIN(lod_max, 8);
for (lod = lod_min; lod <= lod_max; lod++)
{
uint32_t *base = &voodoo->texture_cache[tmu][c].data[texture_offset[lod]];
uint32_t tex_addr = params->tex_base[tmu][lod] & voodoo->texture_mask;
int x, y;
int shift = 8 - params->tex_lod[tmu][lod];
rgba_u *pal;
//voodoo_texture_log(" LOD %i : %08x - %08x %i %i,%i\n", lod, params->tex_base[tmu][lod] & voodoo->texture_mask, addr, voodoo->params.tformat[tmu], voodoo->params.tex_w_mask[tmu][lod],voodoo->params.tex_h_mask[tmu][lod]);
switch (params->tformat[tmu])
{
case TEX_RGB332:
for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++)
{
for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++)
{
uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask];
base[x] = makergba(rgb332[dat].r, rgb332[dat].g, rgb332[dat].b, 0xff);
}
tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]);
base += (1 << shift);
}
break;
case TEX_Y4I2Q2:
pal = voodoo->ncc_lookup[tmu][(voodoo->params.textureMode[tmu] & TEXTUREMODE_NCC_SEL) ? 1 : 0];
for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++)
{
for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++)
{
uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask];
base[x] = makergba(pal[dat].rgba.r, pal[dat].rgba.g, pal[dat].rgba.b, 0xff);
}
tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]);
base += (1 << shift);
}
break;
case TEX_A8:
for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++)
{
for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++)
{
uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask];
base[x] = makergba(dat, dat, dat, dat);
}
tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]);
base += (1 << shift);
}
break;
case TEX_I8:
for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++)
{
for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++)
{
uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask];
base[x] = makergba(dat, dat, dat, 0xff);
}
tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]);
base += (1 << shift);
}
break;
case TEX_AI8:
for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++)
{
for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++)
{
uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask];
base[x] = makergba((dat & 0x0f) | ((dat << 4) & 0xf0), (dat & 0x0f) | ((dat << 4) & 0xf0), (dat & 0x0f) | ((dat << 4) & 0xf0), (dat & 0xf0) | ((dat >> 4) & 0x0f));
}
tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]);
base += (1 << shift);
}
break;
case TEX_PAL8:
pal = voodoo->palette[tmu];
for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++)
{
for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++)
{
uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask];
base[x] = makergba(pal[dat].rgba.r, pal[dat].rgba.g, pal[dat].rgba.b, 0xff);
}
tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]);
base += (1 << shift);
}
break;
case TEX_APAL8:
pal = voodoo->palette[tmu];
for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++)
{
for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++)
{
uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask];
int r = ((pal[dat].rgba.r & 3) << 6) | ((pal[dat].rgba.g & 0xf0) >> 2) | (pal[dat].rgba.r & 3);
int g = ((pal[dat].rgba.g & 0xf) << 4) | ((pal[dat].rgba.b & 0xc0) >> 4) | ((pal[dat].rgba.g & 0xf) >> 2);
int b = ((pal[dat].rgba.b & 0x3f) << 2) | ((pal[dat].rgba.b & 0x30) >> 4);
int a = (pal[dat].rgba.r & 0xfc) | ((pal[dat].rgba.r & 0xc0) >> 6);
base[x] = makergba(r, g, b, a);
}
tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]);
base += (1 << shift);
}
break;
case TEX_ARGB8332:
for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++)
{
for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++)
{
uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask];
base[x] = makergba(rgb332[dat & 0xff].r, rgb332[dat & 0xff].g, rgb332[dat & 0xff].b, dat >> 8);
}
tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1));
base += (1 << shift);
}
break;
case TEX_A8Y4I2Q2:
pal = voodoo->ncc_lookup[tmu][(voodoo->params.textureMode[tmu] & TEXTUREMODE_NCC_SEL) ? 1 : 0];
for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++)
{
for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++)
{
uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask];
base[x] = makergba(pal[dat & 0xff].rgba.r, pal[dat & 0xff].rgba.g, pal[dat & 0xff].rgba.b, dat >> 8);
}
tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1));
base += (1 << shift);
}
break;
case TEX_R5G6B5:
for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++)
{
for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++)
{
uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask];
base[x] = makergba(rgb565[dat].r, rgb565[dat].g, rgb565[dat].b, 0xff);
}
tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1));
base += (1 << shift);
}
break;
case TEX_ARGB1555:
for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++)
{
for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++)
{
uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask];
base[x] = makergba(argb1555[dat].r, argb1555[dat].g, argb1555[dat].b, argb1555[dat].a);
}
tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1));
base += (1 << shift);
}
break;
case TEX_ARGB4444:
for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++)
{
for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++)
{
uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask];
base[x] = makergba(argb4444[dat].r, argb4444[dat].g, argb4444[dat].b, argb4444[dat].a);
}
tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1));
base += (1 << shift);
}
break;
case TEX_A8I8:
for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++)
{
for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++)
{
uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask];
base[x] = makergba(dat & 0xff, dat & 0xff, dat & 0xff, dat >> 8);
}
tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1));
base += (1 << shift);
}
break;
case TEX_APAL88:
pal = voodoo->palette[tmu];
for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++)
{
for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++)
{
uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask];
base[x] = makergba(pal[dat & 0xff].rgba.r, pal[dat & 0xff].rgba.g, pal[dat & 0xff].rgba.b, dat >> 8);
}
tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1));
base += (1 << shift);
}
break;
default:
fatal("Unknown texture format %i\n", params->tformat[tmu]);
}
}
voodoo->texture_cache[tmu][c].is16 = voodoo->params.tformat[tmu] & 8;
if (params->tformat[tmu] == TEX_PAL8 || params->tformat[tmu] == TEX_APAL8 || params->tformat[tmu] == TEX_APAL88)
voodoo->texture_cache[tmu][c].palette_checksum = palette_checksum;
else
voodoo->texture_cache[tmu][c].palette_checksum = 0;
if (lod_min == 0)
{
voodoo->texture_cache[tmu][c].addr_start[0] = voodoo->params.tex_base[tmu][0];
voodoo->texture_cache[tmu][c].addr_end[0] = voodoo->params.tex_end[tmu][0];
}
else
voodoo->texture_cache[tmu][c].addr_start[0] = voodoo->texture_cache[tmu][c].addr_end[0] = 0;
if (lod_min <= 1 && lod_max >= 1)
{
voodoo->texture_cache[tmu][c].addr_start[1] = voodoo->params.tex_base[tmu][1];
voodoo->texture_cache[tmu][c].addr_end[1] = voodoo->params.tex_end[tmu][1];
}
else
voodoo->texture_cache[tmu][c].addr_start[1] = voodoo->texture_cache[tmu][c].addr_end[1] = 0;
if (lod_min <= 2 && lod_max >= 2)
{
voodoo->texture_cache[tmu][c].addr_start[2] = voodoo->params.tex_base[tmu][2];
voodoo->texture_cache[tmu][c].addr_end[2] = voodoo->params.tex_end[tmu][2];
}
else
voodoo->texture_cache[tmu][c].addr_start[2] = voodoo->texture_cache[tmu][c].addr_end[2] = 0;
if (lod_max >= 3)
{
voodoo->texture_cache[tmu][c].addr_start[3] = voodoo->params.tex_base[tmu][(lod_min > 3) ? lod_min : 3];
voodoo->texture_cache[tmu][c].addr_end[3] = voodoo->params.tex_end[tmu][(lod_max < 8) ? lod_max : 8];
}
else
voodoo->texture_cache[tmu][c].addr_start[3] = voodoo->texture_cache[tmu][c].addr_end[3] = 0;
for (d = 0; d < 4; d++)
{
addr = voodoo->texture_cache[tmu][c].addr_start[d];
addr_end = voodoo->texture_cache[tmu][c].addr_end[d];
if (addr_end != 0)
{
for (; addr <= addr_end; addr += (1 << TEX_DIRTY_SHIFT))
voodoo->texture_present[tmu][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT] = 1;
}
}
params->tex_entry[tmu] = c;
voodoo->texture_cache[tmu][c].refcount++;
}
void flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu)
{
int wait_for_idle = 0;
int c;
memset(voodoo->texture_present[tmu], 0, sizeof(voodoo->texture_present[0]));
// voodoo_texture_log("Evict %08x %i\n", dirty_addr, sizeof(voodoo->texture_present));
for (c = 0; c < TEX_CACHE_MAX; c++)
{
if (voodoo->texture_cache[tmu][c].base != -1)
{
int d;
for (d = 0; d < 4; d++)
{
int addr_start = voodoo->texture_cache[tmu][c].addr_start[d];
int addr_end = voodoo->texture_cache[tmu][c].addr_end[d];
if (addr_end != 0)
{
int addr_start_masked = addr_start & voodoo->texture_mask & ~0x3ff;
int addr_end_masked = ((addr_end & voodoo->texture_mask) + 0x3ff) & ~0x3ff;
if (addr_end_masked < addr_start_masked)
addr_end_masked = voodoo->texture_mask+1;
if (dirty_addr >= addr_start_masked && dirty_addr < addr_end_masked)
{
// voodoo_texture_log(" Evict texture %i %08x\n", c, voodoo->texture_cache[tmu][c].base);
if (voodoo->texture_cache[tmu][c].refcount != voodoo->texture_cache[tmu][c].refcount_r[0] ||
(voodoo->render_threads == 2 && voodoo->texture_cache[tmu][c].refcount != voodoo->texture_cache[tmu][c].refcount_r[1]))
wait_for_idle = 1;
voodoo->texture_cache[tmu][c].base = -1;
}
else
{
for (; addr_start <= addr_end; addr_start += (1 << TEX_DIRTY_SHIFT))
voodoo->texture_present[tmu][(addr_start & voodoo->texture_mask) >> TEX_DIRTY_SHIFT] = 1;
}
}
}
}
}
if (wait_for_idle)
voodoo_wait_for_render_thread_idle(voodoo);
}
void voodoo_tex_writel(uint32_t addr, uint32_t val, void *p)
{
int lod, s, t;
voodoo_t *voodoo = (voodoo_t *)p;
int tmu;
if (addr & 0x400000)
return; /*TREX != 0*/
tmu = (addr & 0x200000) ? 1 : 0;
if (tmu && !voodoo->dual_tmus)
return;
if (voodoo->type < VOODOO_BANSHEE)
{
if (!(voodoo->params.tformat[tmu] & 8) && voodoo->type >= VOODOO_BANSHEE)
{
lod = (addr >> 16) & 0xf;
t = (addr >> 8) & 0xff;
}
else
{
lod = (addr >> 17) & 0xf;
t = (addr >> 9) & 0xff;
}
if (voodoo->params.tformat[tmu] & 8)
s = (addr >> 1) & 0xfe;
else
{
if ((voodoo->params.textureMode[tmu] & (1 << 31)) || voodoo->type >= VOODOO_BANSHEE)
s = addr & 0xfc;
else
s = (addr >> 1) & 0xfc;
}
if (lod > LOD_MAX)
return;
// if (addr >= 0x200000)
// return;
if (voodoo->params.tformat[tmu] & 8)
addr = voodoo->params.tex_base[tmu][lod] + s*2 + (t << voodoo->params.tex_shift[tmu][lod])*2;
else
addr = voodoo->params.tex_base[tmu][lod] + s + (t << voodoo->params.tex_shift[tmu][lod]);
}
else
addr = (addr & 0x1ffffc) + voodoo->params.tex_base[tmu][0];
if (voodoo->texture_present[tmu][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT])
{
// voodoo_texture_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT);
flush_texture_cache(voodoo, addr & voodoo->texture_mask, tmu);
}
if (voodoo->type == VOODOO_3 && voodoo->texture_present[tmu^1][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT])
{
// voodoo_texture_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT);
flush_texture_cache(voodoo, addr & voodoo->texture_mask, tmu^1);
}
*(uint32_t *)(&voodoo->tex_mem[tmu][addr & voodoo->texture_mask]) = val;
}

View File

@@ -346,12 +346,12 @@ BEGIN
WS_VSCROLL | WS_TABSTOP
LTEXT "Machine:",IDT_1701,7,27,60,10
PUSHBUTTON "Configure",IDC_CONFIGURE_MACHINE,214,26,46,12
COMBOBOX IDC_COMBO_CPU_TYPE,71,44,45,120,CBS_DROPDOWNLIST |
COMBOBOX IDC_COMBO_CPU_TYPE,71,44,110,120,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
LTEXT "CPU type:",IDT_1702,7,45,59,10
COMBOBOX IDC_COMBO_CPU,145,44,115,120,CBS_DROPDOWNLIST |
COMBOBOX IDC_COMBO_CPU,215,44,45,120,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
LTEXT "CPU:",IDT_1704,124,45,18,10
LTEXT "Speed:",IDT_1704,189,45,24,10
COMBOBOX IDC_COMBO_FPU,71,63,189,120,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP
LTEXT "FPU:",IDT_1707,7,63,59,10
@@ -994,7 +994,7 @@ BEGIN
IDS_2120 "No ROMs found"
IDS_2121 "Save changes\nThis will hard reset the emulated machine."
IDS_2122 "Discard changes\nAll changes made to the settings will be lost."
IDS_2123 "Cancel\nGo back to the Settings window."
IDS_2123 "Do you want to save the settings?"
IDS_2124 "About 86Box"
IDS_2125 "86Box v" EMU_VERSION
IDS_2126 "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information."
@@ -1027,9 +1027,9 @@ BEGIN
IDS_2133 LIB_NAME_FLUIDSYNTH " is required for FluidSynth MIDI output."
IDS_2134 "Entering fullscreen mode"
IDS_2135 "Don't show this message again"
IDS_2136 "Don't Exit"
IDS_2136 "Don't exit"
IDS_2137 "Reset"
IDS_2138 "Don't Reset"
IDS_2138 "Don't reset"
IDS_2139 "MO images (*.IM?;*.MDI)\0*.IM?;*.MDI\0All files (*.*)\0*.*\0"
END
@@ -1041,8 +1041,8 @@ BEGIN
IDS_4099 "MFM/RLL or ESDI CD-ROM drives never existed"
IDS_4100 "Custom..."
IDS_4101 "Custom (large)..."
IDS_4102 "Add New Hard Disk"
IDS_4103 "Add Existing Hard Disk"
IDS_4102 "Add new hard disk"
IDS_4103 "Add existing hard disk"
IDS_4104 "HDI disk images cannot be larger than 4 GB."
IDS_4105 "Disk images cannot be larger than 127 GB."
IDS_4106 "Hard disk images (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0All files (*.*)\0*.*\0"
@@ -1060,7 +1060,7 @@ BEGIN
IDS_4118 "The selected file will be overwritten. Are you sure you want to use it?"
IDS_4119 "Unsupported disk image"
IDS_4120 "Overwrite"
IDS_4121 "Don't Overwrite"
IDS_4121 "Don't overwrite"
IDS_4122 "Raw image (.img)"
IDS_4123 "HDI image (.hdi)"
IDS_4124 "HDX image (.hdx)"

View File

@@ -759,6 +759,7 @@ VIDOBJ := video.o \
vid_wy700.o \
vid_ega.o vid_ega_render.o \
vid_svga.o vid_svga_render.o \
vid_ddc.o \
vid_vga.o \
vid_ati_eeprom.o \
vid_ati18800.o vid_ati28800.o \
@@ -778,7 +779,13 @@ VIDOBJ := video.o \
vid_att20c49x_ramdac.o \
vid_s3.o vid_s3_virge.o \
vid_sdac_ramdac.o \
vid_voodoo.o
vid_voodoo.o vid_voodoo_banshee.o \
vid_voodoo_banshee_blitter.o \
vid_voodoo_blitter.o \
vid_voodoo_display.o vid_voodoo_fb.o \
vid_voodoo_fifo.o vid_voodoo_reg.o \
vid_voodoo_render.o vid_voodoo_setup.o \
vid_voodoo_texture.o
PLATOBJ := win.o \
win_dynld.o win_thread.o \
@@ -810,7 +817,7 @@ endif
ifneq ($(WX), n)
LIBS += $(WX_LIBS) -lm
endif
LIBS += -lpng -lz -lwsock32 -lshell32 -liphlpapi -lpsapi -lSDL2 -limm32 -lhid -lsetupapi -loleaut32 -lversion -lwinmm -static -lstdc++
LIBS += -lpng -lz -lwsock32 -lshell32 -liphlpapi -lpsapi -lSDL2 -limm32 -lhid -lsetupapi -loleaut32 -luxtheme -lversion -lwinmm -static -lstdc++
ifneq ($(X64), y)
LIBS += -Wl,--large-address-aware
endif

View File

@@ -83,13 +83,13 @@ discord_update_activity(int paused)
if (WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, plat_get_filename(config_name_w), -1, config_name, 128, NULL, NULL) > 0)
{
sprintf_s(activity.details, 128, "Running \"%s\"", config_name);
sprintf_s(activity.state, 128, "%s (%s)", strchr(machine_getname(), ']') + 2, machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].name);
sprintf_s(activity.state, 128, "%s (%s)", strchr(machine_getname(), ']') + 2, cpu_s->name);
}
else
{
temp = strchr(machine_getname(), ']') + 2;
strncpy(activity.details, temp, 127);
strncpy(activity.state, machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].name, 127);
strncpy(activity.state, cpu_s->name, 127);
}
activity.timestamps.start = time(NULL);

View File

@@ -20,6 +20,7 @@
#define BITMAP WINDOWS_BITMAP
#include <windows.h>
#include <windowsx.h>
#include <uxtheme.h>
#undef BITMAP
#ifdef ENABLE_SETTINGS_LOG
#include <assert.h>
@@ -76,7 +77,8 @@ static int first_cat = 0;
static int dpi = 96;
/* Machine category */
static int temp_machine_type, temp_machine, temp_cpu_m, temp_cpu, temp_wait_states, temp_fpu, temp_sync;
static int temp_machine_type, temp_machine, temp_cpu, temp_wait_states, temp_fpu, temp_sync;
static cpu_family_t *temp_cpu_f;
static uint32_t temp_mem_size;
#ifdef USE_DYNAREC
static int temp_dynarec;
@@ -128,6 +130,7 @@ static uint32_t displayed_category = 0;
extern int is486;
static int listtomachinetype[256], listtomachine[256];
static int listtocpufamily[256], listtocpu[256];
static int settings_list_to_device[2][20], settings_list_to_fdc[20];
static int settings_list_to_midi[20], settings_list_to_midi_in[20];
static int settings_list_to_hdc[20];
@@ -207,6 +210,17 @@ settings_show_window(HWND hdlg, int id, int condition)
}
static void
settings_listview_enable_styles(HWND hdlg, int id)
{
HWND h;
h = GetDlgItem(hdlg, id);
SetWindowTheme(h, L"Explorer", NULL);
ListView_SetExtendedListViewStyle(h, LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER);
}
static void
settings_listview_select(HWND hdlg, int id, int selection)
{
@@ -217,6 +231,17 @@ settings_listview_select(HWND hdlg, int id, int selection)
}
static void
settings_process_messages()
{
MSG msg;
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
static BOOL
image_list_init(HWND hdlg, int id, const uint8_t *icon_ids)
{
@@ -298,7 +323,7 @@ win_settings_init(void)
/* Machine category */
temp_machine_type = machines[machine].type;
temp_machine = machine;
temp_cpu_m = cpu_manufacturer;
temp_cpu_f = cpu_f;
temp_wait_states = cpu_waitstates;
temp_cpu = cpu;
temp_mem_size = mem_size;
@@ -418,7 +443,7 @@ win_settings_changed(void)
/* Machine category */
i = i || (machine != temp_machine);
i = i || (cpu_manufacturer != temp_cpu_m);
i = i || (cpu_f != temp_cpu_f);
i = i || (cpu_waitstates != temp_wait_states);
i = i || (cpu != temp_cpu);
i = i || (mem_size != temp_mem_size);
@@ -495,7 +520,7 @@ win_settings_changed(void)
static int
settings_msgbox_reset(void)
settings_msgbox_reset(int button)
{
int changed, i = 0;
HWND h;
@@ -506,7 +531,7 @@ settings_msgbox_reset(void)
h = hwndMain;
hwndMain = hwndParentDialog;
i = ui_msgbox_ex(MBX_QUESTION | MBX_LINKS, (wchar_t *) IDS_2051, NULL, (wchar_t *) IDS_2121, (wchar_t *) IDS_2122, (wchar_t *) IDS_2123);
i = ui_msgbox_ex(MBX_QUESTION | MBX_LINKS, (wchar_t *) (button ? IDS_2051 : IDS_2123), NULL, (wchar_t *) IDS_2121, (wchar_t *) IDS_2122, NULL);
hwndMain = h;
@@ -530,7 +555,7 @@ win_settings_save(void)
/* Machine category */
machine = temp_machine;
cpu_manufacturer = temp_cpu_m;
cpu_f = temp_cpu_f;
cpu_waitstates = temp_wait_states;
cpu = temp_cpu;
mem_size = temp_mem_size;
@@ -640,8 +665,8 @@ win_settings_machine_recalc_fpu(HWND hdlg)
settings_reset_content(hdlg, IDC_COMBO_FPU);
c = 0;
while (1) {
stransi = (char *) fpu_get_name_from_index(temp_machine, temp_cpu_m, temp_cpu, c);
type = fpu_get_type_from_index(temp_machine, temp_cpu_m, temp_cpu, c);
stransi = (char *) fpu_get_name_from_index(temp_cpu_f, temp_cpu, c);
type = fpu_get_type_from_index(temp_cpu_f, temp_cpu, c);
if (!stransi)
break;
@@ -655,25 +680,23 @@ win_settings_machine_recalc_fpu(HWND hdlg)
settings_enable_window(hdlg, IDC_COMBO_FPU, c > 1);
temp_fpu = fpu_get_type_from_index(temp_machine, temp_cpu_m, temp_cpu, settings_get_cur_sel(hdlg, IDC_COMBO_FPU));
temp_fpu = fpu_get_type_from_index(temp_cpu_f, temp_cpu, settings_get_cur_sel(hdlg, IDC_COMBO_FPU));
}
static void
win_settings_machine_recalc_cpu(HWND hdlg)
{
HWND h;
int cpu_type;
#ifdef USE_DYNAREC
int cpu_flags;
#endif
cpu_type = machines[temp_machine].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type;
cpu_type = temp_cpu_f->cpus[temp_cpu].cpu_type;
settings_enable_window(hdlg, IDC_COMBO_WS, (cpu_type >= CPU_286) && (cpu_type <= CPU_386DX));
#ifdef USE_DYNAREC
h = GetDlgItem(hdlg, IDC_CHECK_DYNAREC);
cpu_flags = machines[temp_machine].cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags;
cpu_flags = temp_cpu_f->cpus[temp_cpu].cpu_flags;
if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) && (cpu_flags & CPU_REQUIRES_DYNAREC))
fatal("Attempting to select a CPU that requires the recompiler and does not support it at the same time\n");
if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) {
@@ -681,10 +704,12 @@ win_settings_machine_recalc_cpu(HWND hdlg)
temp_dynarec = 0;
if (cpu_flags & CPU_REQUIRES_DYNAREC)
temp_dynarec = 1;
SendMessage(h, BM_SETCHECK, temp_dynarec, 0);
EnableWindow(h, FALSE);
} else
EnableWindow(h, TRUE);
settings_set_check(hdlg, IDC_CHECK_DYNAREC, temp_dynarec);
settings_enable_window(hdlg, IDC_CHECK_DYNAREC, FALSE);
} else {
settings_set_check(hdlg, IDC_CHECK_DYNAREC, temp_dynarec);
settings_enable_window(hdlg, IDC_CHECK_DYNAREC, TRUE);
}
#endif
win_settings_machine_recalc_fpu(hdlg);
@@ -694,24 +719,39 @@ win_settings_machine_recalc_cpu(HWND hdlg)
static void
win_settings_machine_recalc_cpu_m(HWND hdlg)
{
int c;
int c, i, first_eligible = -1, current_eligible = 0, last_eligible = 0;
LPTSTR lptsTemp;
char *stransi;
lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR));
settings_reset_content(hdlg, IDC_COMBO_CPU);
c = 0;
while (machines[temp_machine].cpu[temp_cpu_m].cpus[c].cpu_type != -1) {
stransi = (char *) machines[temp_machine].cpu[temp_cpu_m].cpus[c].name;
mbstowcs(lptsTemp, stransi, strlen(stransi) + 1);
settings_add_string(hdlg, IDC_COMBO_CPU, (LPARAM)(LPCSTR)lptsTemp);
c = i = 0;
while (temp_cpu_f->cpus[c].cpu_type != 0) {
if (cpu_is_eligible(temp_cpu_f, c, temp_machine)) {
stransi = (char *) temp_cpu_f->cpus[c].name;
mbstowcs(lptsTemp, stransi, strlen(stransi) + 1);
settings_add_string(hdlg, IDC_COMBO_CPU, (LPARAM)(LPCSTR)lptsTemp);
if (first_eligible == -1)
first_eligible = i;
if (temp_cpu == c)
current_eligible = i;
last_eligible = i;
listtocpu[i++] = c;
}
c++;
}
settings_enable_window(hdlg, IDC_COMBO_CPU, c != 1);
if (temp_cpu >= c)
temp_cpu = (c - 1);
settings_set_cur_sel(hdlg, IDC_COMBO_CPU, temp_cpu);
if (i == 0)
fatal("No eligible CPUs for the selected family\n");
settings_enable_window(hdlg, IDC_COMBO_CPU, i != 1);
if (current_eligible < first_eligible)
current_eligible = first_eligible;
else if (current_eligible > last_eligible)
current_eligible = last_eligible;
temp_cpu = listtocpu[current_eligible];
settings_set_cur_sel(hdlg, IDC_COMBO_CPU, current_eligible);
win_settings_machine_recalc_cpu(hdlg);
@@ -723,9 +763,9 @@ static void
win_settings_machine_recalc_machine(HWND hdlg)
{
HWND h;
int c, is_at;
int c, i, current_eligible, is_at;
LPTSTR lptsTemp;
const char *stransi;
char *stransi;
UDACCEL accel;
device_t *d;
@@ -735,18 +775,31 @@ win_settings_machine_recalc_machine(HWND hdlg)
settings_enable_window(hdlg, IDC_CONFIGURE_MACHINE, d && d->config);
settings_reset_content(hdlg, IDC_COMBO_CPU_TYPE);
c = 0;
while (machines[temp_machine].cpu[c].cpus != NULL && c < 4) {
stransi = machines[temp_machine].cpu[c].name;
mbstowcs(lptsTemp, stransi, strlen(stransi) + 1);
settings_add_string(hdlg, IDC_COMBO_CPU_TYPE, (LPARAM)(LPCSTR)lptsTemp);
c = i = 0;
current_eligible = -1;
while (cpu_families[c].package != 0) {
if (cpu_family_is_eligible(&cpu_families[c], temp_machine)) {
stransi = malloc(strlen((char *) cpu_families[c].manufacturer) + strlen((char *) cpu_families[c].name) + 2);
sprintf(stransi, "%s %s", (char *) cpu_families[c].manufacturer, (char *) cpu_families[c].name);
mbstowcs(lptsTemp, stransi, strlen(stransi) + 1);
free(stransi);
settings_add_string(hdlg, IDC_COMBO_CPU_TYPE, (LPARAM)(LPCSTR)lptsTemp);
if (&cpu_families[c] == temp_cpu_f)
current_eligible = i;
listtocpufamily[i++] = c;
}
c++;
}
if (i == 0)
fatal("No eligible CPU families for the selected machine\n");
settings_enable_window(hdlg, IDC_COMBO_CPU_TYPE, TRUE);
if (temp_cpu_m >= c)
temp_cpu_m = (c - 1);
settings_set_cur_sel(hdlg, IDC_COMBO_CPU_TYPE, temp_cpu_m);
settings_enable_window(hdlg, IDC_COMBO_CPU_TYPE, c != 1);
if (current_eligible == -1) {
temp_cpu_f = (cpu_family_t *) &cpu_families[listtocpufamily[0]];
settings_set_cur_sel(hdlg, IDC_COMBO_CPU_TYPE, 0);
} else {
settings_set_cur_sel(hdlg, IDC_COMBO_CPU_TYPE, current_eligible);
}
settings_enable_window(hdlg, IDC_COMBO_CPU_TYPE, i != 1);
win_settings_machine_recalc_cpu_m(hdlg);
@@ -909,20 +962,20 @@ win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
break;
case IDC_COMBO_CPU_TYPE:
if (HIWORD(wParam) == CBN_SELCHANGE) {
temp_cpu_m = settings_get_cur_sel(hdlg, IDC_COMBO_CPU_TYPE);
temp_cpu_f = (cpu_family_t *) &cpu_families[listtocpufamily[settings_get_cur_sel(hdlg, IDC_COMBO_CPU_TYPE)]];
temp_cpu = 0;
win_settings_machine_recalc_cpu_m(hdlg);
}
break;
case IDC_COMBO_CPU:
if (HIWORD(wParam) == CBN_SELCHANGE) {
temp_cpu = settings_get_cur_sel(hdlg, IDC_COMBO_CPU);
temp_cpu = listtocpu[settings_get_cur_sel(hdlg, IDC_COMBO_CPU)];
win_settings_machine_recalc_cpu(hdlg);
}
break;
case IDC_COMBO_FPU:
if (HIWORD(wParam) == CBN_SELCHANGE) {
temp_fpu = fpu_get_type_from_index(temp_machine, temp_cpu_m, temp_cpu,
temp_fpu = fpu_get_type_from_index(temp_cpu_f, temp_cpu,
settings_get_cur_sel(hdlg, IDC_COMBO_FPU));
}
break;
@@ -1039,6 +1092,8 @@ win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
}
c++;
settings_process_messages();
}
settings_enable_window(hdlg, IDC_COMBO_VIDEO, !(machines[temp_machine].flags & MACHINE_VIDEO_ONLY));
@@ -2566,7 +2621,6 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM
uint8_t channel = 0;
uint8_t id = 0;
wchar_t *twcs;
MSG msg;
int img_format, block_size;
WCHAR text_buf[256];
RECT rect;
@@ -2808,10 +2862,7 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM
fwrite(big_buf, 1, 1048576, f);
SendMessage(h, PBM_SETPOS, (WPARAM) (i + 1), (LPARAM) 0);
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
settings_process_messages();
}
}
@@ -3360,6 +3411,8 @@ win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPar
lv1_current_sel = -1;
recalc_location_controls(hdlg, 0, 0);
settings_listview_enable_styles(hdlg, IDC_LIST_HARD_DISKS);
ignore_change = 0;
return TRUE;
@@ -3372,13 +3425,6 @@ win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPar
lv1_current_sel = get_selected_hard_disk(hdlg);
if (lv1_current_sel == old_sel)
return FALSE;
else if (lv1_current_sel == -1) {
ignore_change = 1;
lv1_current_sel = old_sel;
settings_listview_select(hdlg, IDC_LIST_HARD_DISKS, lv1_current_sel);
ignore_change = 0;
return FALSE;
}
ignore_change = 1;
settings_set_cur_sel(hdlg, IDC_COMBO_HD_BUS, temp_hdd[lv1_current_sel].bus - 1);
recalc_location_controls(hdlg, 0, 0);
@@ -3521,6 +3567,7 @@ win_settings_floppy_drives_recalc_list(HWND hdlg)
lvI.iSubItem = 1;
lvI.pszText = plat_get_string(temp_fdd_turbo[i] ? IDS_2060 : IDS_2061);
lvI.iItem = i;
lvI.iImage = 0;
if (ListView_SetItem(hwndList, &lvI) == -1)
@@ -3528,6 +3575,8 @@ win_settings_floppy_drives_recalc_list(HWND hdlg)
lvI.iSubItem = 2;
lvI.pszText = plat_get_string(temp_fdd_check_bpb[i] ? IDS_2060 : IDS_2061);
lvI.iItem = i;
lvI.iImage = 0;
if (ListView_SetItem(hwndList, &lvI) == -1)
return FALSE;
@@ -4236,8 +4285,8 @@ mo_recalc_location_controls(HWND hdlg, int assign_id)
switch(bus) {
case MO_BUS_ATAPI: /* ATAPI */
settings_show_window(hdlg, IDT_1772, TRUE);
settings_show_window(hdlg, IDC_COMBO_MO_CHANNEL_IDE, TRUE);
settings_show_window(hdlg, IDT_1772, TRUE);
settings_show_window(hdlg, IDC_COMBO_MO_CHANNEL_IDE, TRUE);
if (assign_id)
temp_mo_drives[lv1_current_sel].ide_channel = next_free_ide_channel();
@@ -4245,8 +4294,8 @@ mo_recalc_location_controls(HWND hdlg, int assign_id)
settings_set_cur_sel(hdlg, IDC_COMBO_MO_CHANNEL_IDE, temp_mo_drives[lv1_current_sel].ide_channel);
break;
case MO_BUS_SCSI: /* SCSI */
settings_show_window(hdlg, IDT_1771, TRUE);
settings_show_window(hdlg, IDC_COMBO_MO_ID, TRUE);
settings_show_window(hdlg, IDT_1771, TRUE);
settings_show_window(hdlg, IDC_COMBO_MO_ID, TRUE);
if (assign_id)
next_free_scsi_id((uint8_t *) &temp_mo_drives[lv1_current_sel].scsi_device_id);
@@ -4302,8 +4351,8 @@ zip_recalc_location_controls(HWND hdlg, int assign_id)
switch(bus) {
case ZIP_BUS_ATAPI: /* ATAPI */
settings_show_window(hdlg, IDT_1755, TRUE);
settings_show_window(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE, TRUE);
settings_show_window(hdlg, IDT_1755, TRUE);
settings_show_window(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE, TRUE);
if (assign_id)
temp_zip_drives[lv2_current_sel].ide_channel = next_free_ide_channel();
@@ -4311,8 +4360,8 @@ zip_recalc_location_controls(HWND hdlg, int assign_id)
settings_set_cur_sel(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE, temp_zip_drives[lv2_current_sel].ide_channel);
break;
case ZIP_BUS_SCSI: /* SCSI */
settings_show_window(hdlg, IDT_1754, TRUE);
settings_show_window(hdlg, IDC_COMBO_ZIP_ID, TRUE);
settings_show_window(hdlg, IDT_1754, TRUE);
settings_show_window(hdlg, IDC_COMBO_ZIP_ID, TRUE);
if (assign_id)
next_free_scsi_id((uint8_t *) &temp_zip_drives[lv2_current_sel].scsi_device_id);
@@ -4418,6 +4467,8 @@ win_settings_floppy_and_cdrom_drives_proc(HWND hdlg, UINT message, WPARAM wParam
settings_set_check(hdlg, IDC_CHECKTURBO, temp_fdd_turbo[lv1_current_sel]);
settings_set_check(hdlg, IDC_CHECKBPB, temp_fdd_check_bpb[lv1_current_sel]);
settings_listview_enable_styles(hdlg, IDC_LIST_FLOPPY_DRIVES);
lv2_current_sel = 0;
win_settings_cdrom_drives_init_columns(hdlg);
image_list_init(hdlg, IDC_LIST_CDROM_DRIVES, (const uint8_t *) cd_icons);
@@ -4440,6 +4491,8 @@ win_settings_floppy_and_cdrom_drives_proc(HWND hdlg, UINT message, WPARAM wParam
settings_set_cur_sel(hdlg, IDC_COMBO_CD_BUS, b);
cdrom_recalc_location_controls(hdlg, 0);
settings_listview_enable_styles(hdlg, IDC_LIST_CDROM_DRIVES);
ignore_change = 0;
return TRUE;
@@ -4452,13 +4505,6 @@ win_settings_floppy_and_cdrom_drives_proc(HWND hdlg, UINT message, WPARAM wParam
lv1_current_sel = get_selected_drive(hdlg, IDC_LIST_FLOPPY_DRIVES);
if (lv1_current_sel == old_sel)
return FALSE;
else if (lv1_current_sel == -1) {
ignore_change = 1;
lv1_current_sel = old_sel;
settings_listview_select(hdlg, IDC_LIST_FLOPPY_DRIVES, lv1_current_sel);
ignore_change = 0;
return FALSE;
}
ignore_change = 1;
settings_set_cur_sel(hdlg, IDC_COMBO_FD_TYPE, temp_fdd_types[lv1_current_sel]);
settings_set_check(hdlg, IDC_CHECKTURBO, temp_fdd_turbo[lv1_current_sel]);
@@ -4469,13 +4515,6 @@ win_settings_floppy_and_cdrom_drives_proc(HWND hdlg, UINT message, WPARAM wParam
lv2_current_sel = get_selected_drive(hdlg, IDC_LIST_CDROM_DRIVES);
if (lv2_current_sel == old_sel)
return FALSE;
else if (lv2_current_sel == -1) {
ignore_change = 1;
lv2_current_sel = old_sel;
settings_listview_select(hdlg, IDC_LIST_CDROM_DRIVES, lv2_current_sel);
ignore_change = 0;
return FALSE;
}
ignore_change = 1;
switch (temp_cdrom[lv2_current_sel].bus_type) {
@@ -4616,6 +4655,8 @@ win_settings_other_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam
settings_set_cur_sel(hdlg, IDC_COMBO_MO_BUS, b);
mo_recalc_location_controls(hdlg, 0);
settings_listview_enable_styles(hdlg, IDC_LIST_MO_DRIVES);
lv2_current_sel = 0;
win_settings_zip_drives_init_columns(hdlg);
image_list_init(hdlg, IDC_LIST_ZIP_DRIVES, (const uint8_t *) zip_icons);
@@ -4638,6 +4679,8 @@ win_settings_other_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam
settings_set_cur_sel(hdlg, IDC_COMBO_ZIP_BUS, b);
zip_recalc_location_controls(hdlg, 0);
settings_listview_enable_styles(hdlg, IDC_LIST_ZIP_DRIVES);
ignore_change = 0;
return TRUE;
@@ -4650,13 +4693,6 @@ win_settings_other_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam
lv1_current_sel = get_selected_drive(hdlg, IDC_LIST_MO_DRIVES);
if (lv1_current_sel == old_sel)
return FALSE;
else if (lv1_current_sel == -1) {
ignore_change = 1;
lv1_current_sel = old_sel;
settings_listview_select(hdlg, IDC_LIST_MO_DRIVES, lv1_current_sel);
ignore_change = 0;
return FALSE;
}
ignore_change = 1;
switch (temp_mo_drives[lv1_current_sel].bus_type) {
@@ -4680,13 +4716,6 @@ win_settings_other_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam
lv2_current_sel = get_selected_drive(hdlg, IDC_LIST_ZIP_DRIVES);
if (lv2_current_sel == old_sel)
return FALSE;
else if (lv2_current_sel == -1) {
ignore_change = 1;
lv2_current_sel = old_sel;
settings_listview_select(hdlg, IDC_LIST_ZIP_DRIVES, lv2_current_sel);
ignore_change = 0;
return FALSE;
}
ignore_change = 1;
switch (temp_zip_drives[lv2_current_sel].bus_type) {
@@ -4900,7 +4929,7 @@ win_settings_confirm(HWND hdlg, int button)
int i;
SendMessage(hwndChildDialog, WM_SAVESETTINGS, 0, 0);
i = settings_msgbox_reset();
i = settings_msgbox_reset(button);
if (i > 0) {
if (i == 2)
win_settings_save();
@@ -4937,6 +4966,7 @@ win_settings_main_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
image_list_init(hdlg, IDC_SETTINGSCATLIST, (const uint8_t *) cat_icons);
win_settings_main_insert_categories(h);
settings_listview_select(hdlg, IDC_SETTINGSCATLIST, first_cat);
settings_listview_enable_styles(hdlg, IDC_SETTINGSCATLIST);
return TRUE;
case WM_NOTIFY:
if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_SETTINGSCATLIST)) {

View File

@@ -34,6 +34,8 @@
#include <86box/device.h>
#include <86box/keyboard.h>
#include <86box/mouse.h>
#include <86box/timer.h>
#include <86box/nvr.h>
#include <86box/video.h>
#include <86box/vid_ega.h> // for update_overscan
#include <86box/plat.h>
@@ -350,6 +352,7 @@ void
plat_power_off(void)
{
confirm_exit = 0;
nvr_save();
config_save();
/* Deduct a sufficiently large number of cycles that no instructions will
@@ -360,6 +363,12 @@ plat_power_off(void)
KillTimer(hwndMain, TIMER_1SEC);
PostQuitMessage(0);
/* Cleanly terminate all of the emulator's components so as
to avoid things like threads getting stuck. */
do_stop();
exit(-1);
}
@@ -401,6 +410,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
pc_reset_hard();
if (i == 10) {
confirm_reset = 0;
nvr_save();
config_save();
}
}
@@ -421,6 +431,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
if ((i % 10) == 0) {
if (i == 10) {
confirm_exit = 0;
nvr_save();
config_save();
}
#ifndef NO_KEYBOARD_HOOK
@@ -801,6 +812,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
if ((i % 10) == 0) {
if (i == 10) {
confirm_exit = 0;
nvr_save();
config_save();
}
#ifndef NO_KEYBOARD_HOOK
@@ -849,6 +861,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
pc_reset_hard();
if (i == 10) {
confirm_reset = 0;
nvr_save();
config_save();
}
}
@@ -866,6 +879,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
if ((i % 10) == 0) {
if (i == 10) {
confirm_exit = 0;
nvr_save();
config_save();
}
#ifndef NO_KEYBOARD_HOOK