Merge branch '86Box:master' into master

This commit is contained in:
starfrost
2025-03-19 15:27:47 +00:00
committed by GitHub
33 changed files with 1126 additions and 437 deletions

View File

@@ -499,14 +499,14 @@ static int opcode_modrm[256] = {
int opcode_0f_modrm[256] = {
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, /*00*/
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/
1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /*30*/
0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, /*30*/
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/
1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, /*50*/
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, /*60*/
0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, /*70*/
0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*70*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/

View File

@@ -1643,14 +1643,14 @@ static int opcode_modrm[256] = {
int opcode_0f_modrm[256] = {
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, /*00*/
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/
1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /*30*/
0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, /*30*/
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/
1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, /*50*/
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, /*60*/
0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, /*70*/
0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*70*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/

View File

@@ -359,14 +359,14 @@ static uint8_t opcode_modrm[256] = {
static uint8_t opcode_0f_modrm[256] = {
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, /*00*/
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/
1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /*30*/
0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, /*30*/
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/
1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, /*50*/
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, /*60*/
0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, /*70*/
0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*70*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/

View File

@@ -533,7 +533,7 @@ host_x86_MOV16_ABS_IMM(codeblock_t *block, void *p, uint16_t imm_data)
codegen_addbyte4(block, 0x66, 0xc7, 0x45, offset); /*MOV offset[RBP], imm_data*/
codegen_addword(block, imm_data);
} else if (offset < (1ULL << 32)) {
codegen_alloc_bytes(block, 8);
codegen_alloc_bytes(block, 9);
codegen_addbyte3(block, 0x66, 0xc7, 0x85); /*MOV offset[RBP], imm_data*/
codegen_addlong(block, offset);
codegen_addword(block, imm_data);

View File

@@ -107,6 +107,12 @@ uint32_t backupregs[16];
x86seg _oldds;
uint8_t rep_op = 0x00;
uint8_t is_smint = 0;
uint16_t io_port = 0x0000;
uint32_t io_val = 0x00000000;
int opcode_has_modrm[256] = {
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/
@@ -1215,7 +1221,7 @@ smram_restore_state_amd_k(uint32_t *saved_state)
}
static void
smram_save_state_cyrix(uint32_t *saved_state, UNUSED(int in_hlt))
smram_save_state_cyrix(uint32_t *saved_state, int in_hlt)
{
saved_state[0] = dr[7];
saved_state[1] = cpu_state.flags | (cpu_state.eflags << 16);
@@ -1224,6 +1230,35 @@ smram_save_state_cyrix(uint32_t *saved_state, UNUSED(int in_hlt))
saved_state[4] = cpu_state.pc;
saved_state[5] = CS | (CPL << 21);
saved_state[6] = 0x00000000;
saved_state[7] = 0x00010000;
if (((opcode >= 0x6e) && (opcode <= 0x6f)) || ((opcode >= 0xe6) && (opcode <= 0xe7)) ||
((opcode >= 0xee) && (opcode <= 0xef))) {
saved_state[6] |= 0x00000002;
saved_state[7] = (opcode & 0x01) ? (cpu_state.op32 ? 0x000f0000 : 0x00030000) : 0x00010000;
} else if (((opcode == 0xf2) || (opcode == 0xf3)) && (rep_op >= 0x6e) && (rep_op <= 0x6f)) {
saved_state[6] |= 0x00000006;
saved_state[7] = (rep_op & 0x01) ? (cpu_state.op32 ? 0x000f0000 : 0x00030000) : 0x00010000;
} else if (((opcode == 0xf2) || (opcode == 0xf3)) && (rep_op >= 0x6e) && (rep_op <= 0x6f)) {
saved_state[6] |= 0x00000004;
saved_state[7] = (rep_op & 0x01) ? (cpu_state.op32 ? 0x000f0000 : 0x00030000) : 0x00010000;
}
if (is_smint) {
saved_state[6] |= 0x00000008;
is_smint = 0;
}
if (in_hlt)
saved_state[6] |= 0x00000010;
saved_state[7] |= io_port;
saved_state[8] = io_val;
if (saved_state[6] & 0x00000002)
saved_state[9] = ESI;
else
saved_state[9] = EDI;
}
static void
@@ -1234,6 +1269,13 @@ smram_restore_state_cyrix(uint32_t *saved_state)
cpu_state.eflags = saved_state[1] >> 16;
cr0 = saved_state[2];
cpu_state.pc = saved_state[4];
/* Restore CPL. */
cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x9f) | (((saved_state[5] >> 21) & 0x03) << 5);
if (saved_state[6] & 0x00000002)
ESI = saved_state[9];
else
EDI = saved_state[9];
}
void
@@ -1368,6 +1410,9 @@ enter_smm(int in_hlt)
writememl(0, smram_state - 0x14, saved_state[4]);
writememl(0, smram_state - 0x18, saved_state[5]);
writememl(0, smram_state - 0x24, saved_state[6]);
writememl(0, smram_state - 0x28, saved_state[7]);
writememl(0, smram_state - 0x2c, saved_state[8]);
writememl(0, smram_state - 0x30, saved_state[9]);
} else {
for (uint8_t n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) {
smram_state -= 4;
@@ -1404,26 +1449,44 @@ enter_smm(int in_hlt)
void
enter_smm_check(int in_hlt)
{
if ((in_smm == 0) && smi_line) {
#ifdef ENABLE_386_COMMON_LOG
x386_common_log("SMI while not in SMM\n");
#endif
enter_smm(in_hlt);
} else if ((in_smm == 1) && smi_line) {
/* Mark this so that we don't latch more than one SMI. */
#ifdef ENABLE_386_COMMON_LOG
x386_common_log("SMI while in unlatched SMM\n");
#endif
smi_latched = 1;
} else if ((in_smm == 2) && smi_line) {
/* Mark this so that we don't latch more than one SMI. */
#ifdef ENABLE_386_COMMON_LOG
x386_common_log("SMI while in latched SMM\n");
#endif
}
uint8_t ccr1_check = ((ccr1 & (CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)) ==
(CCR1_USE_SMI | CCR1_SM3)) && (cyrix.arr[3].size > 0);
if (smi_line) {
if (!is_cxsmm || ccr1_check) switch (in_smm) {
default:
#ifdef ENABLE_386_COMMON_LOG
fatal("SMI while in_smm = %i\n", in_smm);
break;
#endif
case 0:
#ifdef ENABLE_386_COMMON_LOG
x386_common_log("SMI while not in SMM\n");
#endif
enter_smm(in_hlt);
break;
case 1:
/* Mark this so that we don't latch more than one SMI. */
#ifdef ENABLE_386_COMMON_LOG
x386_common_log("SMI while in unlatched SMM\n");
#endif
smi_latched = 1;
break;
case 2:
#ifdef ENABLE_386_COMMON_LOG
x386_common_log("SMI while in latched SMM\n");
#endif
break;
}
#ifdef ENABLE_386_COMMON_LOG
else {
x386_common_log("SMI while in Cyrix disabled mode\n");
x386_common_log("lol\n");
}
#endif
if (smi_line)
smi_line = 0;
}
}
void
@@ -1452,6 +1515,9 @@ leave_smm(void)
else
cyrix_load_seg_descriptor_2386(smram_state - 0x20, &cpu_state.seg_cs);
saved_state[6] = readmeml(0, smram_state - 0x24);
saved_state[7] = readmeml(0, smram_state - 0x28);
saved_state[8] = readmeml(0, smram_state - 0x2c);
saved_state[9] = readmeml(0, smram_state - 0x30);
} else {
for (uint8_t n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) {
smram_state -= 4;
@@ -2138,6 +2204,12 @@ cpu_fast_off_reset(void)
void
smi_raise(void)
{
uint8_t ccr1_check = ((ccr1 & (CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)) ==
(CCR1_USE_SMI | CCR1_SM3)) && (cyrix.arr[3].size > 0);
if (is_cxsmm && !ccr1_check)
return;
if (is486 && (cpu_fast_off_flags & 0x80000000))
cpu_fast_off_advance();

View File

@@ -40,6 +40,7 @@
#include <86box/nmi.h>
#include <86box/pic.h>
#include <86box/pci.h>
#include <86box/smram.h>
#include <86box/timer.h>
#include <86box/gdbstub.h>
#include <86box/plat_fallthrough.h>
@@ -50,13 +51,6 @@
#endif /* USE_DYNAREC */
#include "x87_timings.h"
#define CCR1_USE_SMI (1 << 1)
#define CCR1_SMAC (1 << 2)
#define CCR1_SM3 (1 << 7)
#define CCR3_SMI_LOCK (1 << 0)
#define CCR3_NMI_EN (1 << 1)
enum {
CPUID_FPU = (1 << 0), /* On-chip Floating Point Unit */
CPUID_VME = (1 << 1), /* Virtual 8086 mode extensions */
@@ -289,6 +283,10 @@ uint8_t ccr5;
uint8_t ccr6;
uint8_t ccr7;
uint8_t reg_30 = 0x00;
uint8_t arr[24] = { 0 };
uint8_t rcr[8] = { 0 };
static int cyrix_addr;
static void cpu_write(uint16_t addr, uint8_t val, void *priv);
@@ -384,6 +382,14 @@ cpu_is_eligible(const cpu_family_t *cpu_family, int cpu, int machine)
if (cpu_override)
return 1;
/* Cyrix 6x86MX on the NuPRO 592. */
if (((cpu_s->cyrix_id & 0xff00) == 0x0400) && (strstr(machine_s->internal_name, "nupro") != NULL))
return 0;
/* Cyrix 6x86MX or MII on the P5MMS98. */
if ((cpu_s->cpu_type == CPU_Cx6x86MX) && (strstr(machine_s->internal_name, "p5mms98") != NULL))
return 0;
/* Check CPU blocklist. */
if (machine_s->cpu.block) {
i = 0;
@@ -2619,6 +2625,23 @@ cpu_ven_reset(void)
msr.amd_efer = (cpu_s->cpu_type >= CPU_K6_2C) ? 2ULL : 0ULL;
break;
case CPU_Cx6x86MX:
ccr0 = 0x00;
ccr1 = 0x00;
ccr2 = 0x00;
ccr3 = 0x00;
ccr4 = 0x80;
ccr5 = 0x00;
ccr6 = 0x00;
memset(arr, 0x00, 24);
memset(rcr, 0x00, 3);
cyrix.arr[3].base = 0x00;
cyrix.arr[3].size = 0; /* Disabled */
cyrix.smhr &= ~SMHR_VALID;
CPUID = cpu_s->cpuid_model;
reg_30 = 0xff;
break;
case CPU_PENTIUMPRO:
case CPU_PENTIUM2:
case CPU_PENTIUM2D:
@@ -4229,78 +4252,105 @@ cpu_write(uint16_t addr, uint8_t val, UNUSED(void *priv))
picintc(1 << 13);
else
nmi = 0;
return;
} else if (addr >= 0xf1)
return; /* FPU stuff */
if (!(addr & 1))
} else if ((addr < 0xf1) && !(addr & 1))
cyrix_addr = val;
else
switch (cyrix_addr) {
case 0xc0: /* CCR0 */
ccr0 = val;
break;
case 0xc1: /* CCR1 */
if ((ccr3 & CCR3_SMI_LOCK) && !in_smm)
val = (val & ~(CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)) | (ccr1 & (CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3));
ccr1 = val;
break;
case 0xc2: /* CCR2 */
ccr2 = val;
break;
case 0xc3: /* CCR3 */
if ((ccr3 & CCR3_SMI_LOCK) && !in_smm)
val = (val & ~(CCR3_NMI_EN)) | (ccr3 & CCR3_NMI_EN) | CCR3_SMI_LOCK;
ccr3 = val;
break;
case 0xcd:
if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) {
cyrix.arr[3].base = (cyrix.arr[3].base & ~0xff000000) | (val << 24);
cyrix.smhr &= ~SMHR_VALID;
}
break;
case 0xce:
if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) {
cyrix.arr[3].base = (cyrix.arr[3].base & ~0x00ff0000) | (val << 16);
cyrix.smhr &= ~SMHR_VALID;
}
break;
case 0xcf:
if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) {
cyrix.arr[3].base = (cyrix.arr[3].base & ~0x0000f000) | ((val & 0xf0) << 8);
if ((val & 0xf) == 0xf)
cyrix.arr[3].size = 1ULL << 32; /* 4 GB */
else if (val & 0xf)
cyrix.arr[3].size = 2048 << (val & 0xf);
else
cyrix.arr[3].size = 0; /* Disabled */
cyrix.smhr &= ~SMHR_VALID;
}
break;
else if (addr < 0xf1) switch (cyrix_addr) {
default:
if (cyrix_addr >= 0xc0)
fatal("Writing unimplemented Cyrix register %02X\n", cyrix_addr);
break;
case 0xe8: /* CCR4 */
if ((ccr3 & 0xf0) == 0x10) {
ccr4 = val;
if (cpu_s->cpu_type >= CPU_Cx6x86) {
if (val & 0x80)
CPUID = cpu_s->cpuid_model;
else
CPUID = 0;
}
case 0x30: /* ???? */
reg_30 = val;
break;
case 0xc0: /* CCR0 */
ccr0 = val;
break;
case 0xc1: { /* CCR1 */
uint8_t old = ccr1;
if ((ccr3 & CCR3_SMI_LOCK) && !in_smm)
val = (val & ~(CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)) | (ccr1 & (CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3));
ccr1 = val;
if ((old ^ ccr1) & (CCR1_SMAC)) {
if (ccr1 & CCR1_SMAC)
smram_backup_all();
smram_recalc_all(!(ccr1 & CCR1_SMAC));
}
break;
} case 0xc2: /* CCR2 */
ccr2 = val;
break;
case 0xc3: /* CCR3 */
if ((ccr3 & CCR3_SMI_LOCK) && !in_smm)
val = (val & ~(CCR3_NMI_EN)) | (ccr3 & CCR3_NMI_EN) | CCR3_SMI_LOCK;
ccr3 = val;
break;
case 0xc4 ... 0xcc:
if (ccr5 & 0x20)
arr[cyrix_addr - 0xc4] = val;
break;
case 0xcd:
if ((ccr5 & 0x20) || (!(ccr3 & CCR3_SMI_LOCK) || in_smm)) {
arr[cyrix_addr - 0xc4] = val;
cyrix.arr[3].base = (cyrix.arr[3].base & ~0xff000000) | (val << 24);
cyrix.smhr &= ~SMHR_VALID;
}
break;
case 0xce:
if ((ccr5 & 0x20) || (!(ccr3 & CCR3_SMI_LOCK) || in_smm)) {
arr[cyrix_addr - 0xc4] = val;
cyrix.arr[3].base = (cyrix.arr[3].base & ~0x00ff0000) | (val << 16);
cyrix.smhr &= ~SMHR_VALID;
}
break;
case 0xcf:
if ((ccr5 & 0x20) || (!(ccr3 & CCR3_SMI_LOCK) || in_smm)) {
arr[cyrix_addr - 0xc4] = val;
cyrix.arr[3].base = (cyrix.arr[3].base & ~0x0000f000) | ((val & 0xf0) << 8);
if ((val & 0xf) == 0xf)
cyrix.arr[3].size = 1ULL << 32; /* 4 GB */
else if (val & 0xf)
cyrix.arr[3].size = 2048 << (val & 0xf);
else
cyrix.arr[3].size = 0; /* Disabled */
cyrix.smhr &= ~SMHR_VALID;
}
break;
case 0xd0 ... 0xdb:
if (((ccr3 & 0xf0) == 0x10) && (ccr5 & 0x20))
arr[cyrix_addr - 0xc4] = val;
break;
case 0xdc ... 0xe3:
if ((ccr3 & 0xf0) == 0x10)
rcr[cyrix_addr - 0xdc] = val;
break;
case 0xe8: /* CCR4 */
if ((ccr3 & 0xf0) == 0x10) {
ccr4 = val;
if (cpu_s->cpu_type >= CPU_Cx6x86) {
if (val & 0x80)
CPUID = cpu_s->cpuid_model;
else
CPUID = 0;
}
break;
case 0xe9: /* CCR5 */
if ((ccr3 & 0xf0) == 0x10)
ccr5 = val;
break;
case 0xea: /* CCR6 */
if ((ccr3 & 0xf0) == 0x10)
ccr6 = val;
break;
case 0xeb: /* CCR7 */
ccr7 = val & 5;
break;
}
}
break;
case 0xe9: /* CCR5 */
if ((ccr3 & 0xf0) == 0x10)
ccr5 = val;
break;
case 0xea: /* CCR6 */
if ((ccr3 & 0xf0) == 0x10)
ccr6 = val;
break;
case 0xeb: /* CCR7 */
ccr7 = val & 5;
break;
}
}
static uint8_t
@@ -4311,6 +4361,15 @@ cpu_read(uint16_t addr, UNUSED(void *priv))
if (addr == 0xf007)
ret = 0x7f;
else if ((addr < 0xf0) && (addr & 1)) switch (cyrix_addr) {
default:
if (cyrix_addr >= 0xc0)
fatal("Reading unimplemented Cyrix register %02X\n", cyrix_addr);
break;
case 0x30: /* ???? */
ret = reg_30;
break;
case 0xc0:
ret = ccr0;
break;
@@ -4323,14 +4382,36 @@ cpu_read(uint16_t addr, UNUSED(void *priv))
case 0xc3:
ret = ccr3;
break;
case 0xc4 ... 0xcc:
if (ccr5 & 0x20)
ret = arr[cyrix_addr - 0xc4];
break;
case 0xcd ... 0xcf:
if ((ccr5 & 0x20) || (!(ccr3 & CCR3_SMI_LOCK) || in_smm))
ret = arr[cyrix_addr - 0xc4];
break;
case 0xd0 ... 0xdb:
if (((ccr3 & 0xf0) == 0x10) && (ccr5 & 0x20))
ret = arr[cyrix_addr - 0xc4];
break;
case 0xdc ... 0xe3:
if ((ccr3 & 0xf0) == 0x10)
ret = rcr[cyrix_addr - 0xdc];
break;
case 0xe8:
ret = ((ccr3 & 0xf0) == 0x10) ? ccr4 : 0xff;
if ((ccr3 & 0xf0) == 0x10)
ret = ccr4;
break;
case 0xe9:
ret = ((ccr3 & 0xf0) == 0x10) ? ccr5 : 0xff;
if ((ccr3 & 0xf0) == 0x10)
ret = ccr5;
break;
case 0xea:
ret = ((ccr3 & 0xf0) == 0x10) ? ccr6 : 0xff;
if ((ccr3 & 0xf0) == 0x10)
ret = ccr6;
break;
case 0xeb:
ret = ccr7;
@@ -4341,11 +4422,8 @@ cpu_read(uint16_t addr, UNUSED(void *priv))
case 0xff:
ret = cpu_s->cyrix_id >> 8;
break;
default:
break;
}
return ret;
}

View File

@@ -120,6 +120,13 @@ enum {
#define CPU_ALTERNATE_XTAL 4
#define CPU_FIXED_MULTIPLIER 8
#define CCR1_USE_SMI (1 << 1)
#define CCR1_SMAC (1 << 2)
#define CCR1_SM3 (1 << 7)
#define CCR3_SMI_LOCK (1 << 0)
#define CCR3_NMI_EN (1 << 1)
#if (defined __amd64__ || defined _M_X64)
# define LOOKUP_INV -1LL
#else

View File

@@ -6366,6 +6366,74 @@ const cpu_family_t cpu_families[] = {
.name = "MII",
.internal_name = "mii",
.cpus = (const CPU[]) {
{
.name = "IBM 133 (PR166)",
.cpu_type = CPU_Cx6x86MX,
.fpus = fpus_internal,
.rspeed = 133333333,
.multi = 2.0,
.voltage = 2900,
.edx_reset = 0x601,
.cpuid_model = 0x601,
.cyrix_id = 0x0851,
.cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
.mem_read_cycles = 12,
.mem_write_cycles = 12,
.cache_read_cycles = 6,
.cache_write_cycles = 6,
.atclk_div = 16
},
{
.name = "166 (PR200)",
.cpu_type = CPU_Cx6x86MX,
.fpus = fpus_internal,
.rspeed = 166666666,
.multi = 2.5,
.voltage = 2900,
.edx_reset = 0x601,
.cpuid_model = 0x601,
.cyrix_id = 0x0852,
.cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
.mem_read_cycles = 15,
.mem_write_cycles = 15,
.cache_read_cycles = 7,
.cache_write_cycles = 7,
.atclk_div = 20
},
{
.name = "187.5 (PR233)",
.cpu_type = CPU_Cx6x86MX,
.fpus = fpus_internal,
.rspeed = 187500000,
.multi = 2.5,
.voltage = 2900,
.edx_reset = 0x601,
.cpuid_model = 0x601,
.cyrix_id = 0x0852,
.cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
.mem_read_cycles = 15,
.mem_write_cycles = 15,
.cache_read_cycles = 7,
.cache_write_cycles = 7,
.atclk_div = 45/2
},
{
.name = "208.3 (PR266)",
.cpu_type = CPU_Cx6x86MX,
.fpus = fpus_internal,
.rspeed = 208333333,
.multi = 2.5,
.voltage = 2700,
.edx_reset = 0x601,
.cpuid_model = 0x601,
.cyrix_id = 0x0852,
.cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
.mem_read_cycles = 17,
.mem_write_cycles = 17,
.cache_read_cycles = 7,
.cache_write_cycles = 7,
.atclk_div = 25
},
{
.name = "233 (PR300)",
.cpu_type = CPU_Cx6x86MX,
@@ -6375,7 +6443,7 @@ const cpu_family_t cpu_families[] = {
.voltage = 2900,
.edx_reset = 0x601,
.cpuid_model = 0x601,
.cyrix_id = 0x0852,
.cyrix_id = 0x0854,
.cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
.mem_read_cycles = 21,
.mem_write_cycles = 21,
@@ -6409,7 +6477,7 @@ const cpu_family_t cpu_families[] = {
.voltage = 2900,
.edx_reset = 0x601,
.cpuid_model = 0x601,
.cyrix_id = 0x0853,
.cyrix_id = 0x0852,
.cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
.mem_read_cycles = 23,
.mem_write_cycles = 23,
@@ -6417,6 +6485,23 @@ const cpu_family_t cpu_families[] = {
.cache_write_cycles = 7,
.atclk_div = 30
},
{
.name = "270 (PR350)",
.cpu_type = CPU_Cx6x86MX,
.fpus = fpus_internal,
.rspeed = 270000000,
.multi = 3.0,
.voltage = 2900,
.edx_reset = 0x601,
.cpuid_model = 0x601,
.cyrix_id = 0x0853,
.cpu_flags = CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC,
.mem_read_cycles = 25,
.mem_write_cycles = 25,
.cache_read_cycles = 8,
.cache_write_cycles = 8,
.atclk_div = 32
},
{
.name = "285 (PR400)",
.cpu_type = CPU_Cx6x86MX,

View File

@@ -103,4 +103,10 @@ extern int fpu_cycles;
extern void x86illegal(void);
extern uint8_t rep_op;
extern uint8_t is_smint;
extern uint16_t io_port;
extern uint32_t io_val;
#endif /*EMU_X86_H*/

View File

@@ -35,7 +35,13 @@ opSVDC_common(uint32_t fetchdat)
static int
opSVDC_a16(uint32_t fetchdat)
{
if (in_smm) {
uint8_t ins_check = ((ccr1 & (CCR1_USE_SMI | CCR1_SM3)) ==
(CCR1_USE_SMI | CCR1_SM3)) &&
((ccr1 & CCR1_SMAC) || in_smm) &&
(cyrix.arr[3].size > 0) &&
(CPL == 0);
if (ins_check) {
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
opSVDC_common(fetchdat);
@@ -47,7 +53,13 @@ opSVDC_a16(uint32_t fetchdat)
static int
opSVDC_a32(uint32_t fetchdat)
{
if (in_smm) {
uint8_t ins_check = ((ccr1 & (CCR1_USE_SMI | CCR1_SM3)) ==
(CCR1_USE_SMI | CCR1_SM3)) &&
((ccr1 & CCR1_SMAC) || in_smm) &&
(cyrix.arr[3].size > 0) &&
(CPL == 0);
if (ins_check) {
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
opSVDC_common(fetchdat);
@@ -63,18 +75,23 @@ opRSDC_common(uint32_t fetchdat)
switch (rmdat & 0x38) {
case 0x00: /*ES*/
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_es);
ES = readmemw(0, easeg + cpu_state.eaaddr + 8);
break;
case 0x18: /*DS*/
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ds);
DS = readmemw(0, easeg + cpu_state.eaaddr + 8);
break;
case 0x10: /*SS*/
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ss);
SS = readmemw(0, easeg + cpu_state.eaaddr + 8);
break;
case 0x20: /*FS*/
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_fs);
FS = readmemw(0, easeg + cpu_state.eaaddr + 8);
break;
case 0x28: /*GS*/
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_gs);
GS = readmemw(0, easeg + cpu_state.eaaddr + 8);
break;
default:
x86illegal();
@@ -83,7 +100,13 @@ opRSDC_common(uint32_t fetchdat)
static int
opRSDC_a16(uint32_t fetchdat)
{
if (in_smm) {
uint8_t ins_check = ((ccr1 & (CCR1_USE_SMI | CCR1_SM3)) ==
(CCR1_USE_SMI | CCR1_SM3)) &&
((ccr1 & CCR1_SMAC) || in_smm) &&
(cyrix.arr[3].size > 0) &&
(CPL == 0);
if (ins_check) {
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
opRSDC_common(fetchdat);
@@ -95,7 +118,13 @@ opRSDC_a16(uint32_t fetchdat)
static int
opRSDC_a32(uint32_t fetchdat)
{
if (in_smm) {
uint8_t ins_check = ((ccr1 & (CCR1_USE_SMI | CCR1_SM3)) ==
(CCR1_USE_SMI | CCR1_SM3)) &&
((ccr1 & CCR1_SMAC) || in_smm) &&
(cyrix.arr[3].size > 0) &&
(CPL == 0);
if (ins_check) {
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
opRSDC_common(fetchdat);
@@ -108,7 +137,13 @@ opRSDC_a32(uint32_t fetchdat)
static int
opSVLDT_a16(uint32_t fetchdat)
{
if (in_smm) {
uint8_t ins_check = ((ccr1 & (CCR1_USE_SMI | CCR1_SM3)) ==
(CCR1_USE_SMI | CCR1_SM3)) &&
((ccr1 & CCR1_SMAC) || in_smm) &&
(cyrix.arr[3].size > 0) &&
(CPL == 0);
if (ins_check) {
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &ldt);
@@ -121,7 +156,13 @@ opSVLDT_a16(uint32_t fetchdat)
static int
opSVLDT_a32(uint32_t fetchdat)
{
if (in_smm) {
uint8_t ins_check = ((ccr1 & (CCR1_USE_SMI | CCR1_SM3)) ==
(CCR1_USE_SMI | CCR1_SM3)) &&
((ccr1 & CCR1_SMAC) || in_smm) &&
(cyrix.arr[3].size > 0) &&
(CPL == 0);
if (ins_check) {
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &ldt);
@@ -135,7 +176,13 @@ opSVLDT_a32(uint32_t fetchdat)
static int
opRSLDT_a16(uint32_t fetchdat)
{
if (in_smm) {
uint8_t ins_check = ((ccr1 & (CCR1_USE_SMI | CCR1_SM3)) ==
(CCR1_USE_SMI | CCR1_SM3)) &&
((ccr1 & CCR1_SMAC) || in_smm) &&
(cyrix.arr[3].size > 0) &&
(CPL == 0);
if (ins_check) {
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &ldt);
@@ -147,7 +194,13 @@ opRSLDT_a16(uint32_t fetchdat)
static int
opRSLDT_a32(uint32_t fetchdat)
{
if (in_smm) {
uint8_t ins_check = ((ccr1 & (CCR1_USE_SMI | CCR1_SM3)) ==
(CCR1_USE_SMI | CCR1_SM3)) &&
((ccr1 & CCR1_SMAC) || in_smm) &&
(cyrix.arr[3].size > 0) &&
(CPL == 0);
if (ins_check) {
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &ldt);
@@ -160,7 +213,13 @@ opRSLDT_a32(uint32_t fetchdat)
static int
opSVTS_a16(uint32_t fetchdat)
{
if (in_smm) {
uint8_t ins_check = ((ccr1 & (CCR1_USE_SMI | CCR1_SM3)) ==
(CCR1_USE_SMI | CCR1_SM3)) &&
((ccr1 & CCR1_SMAC) || in_smm) &&
(cyrix.arr[3].size > 0) &&
(CPL == 0);
if (ins_check) {
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr);
@@ -173,7 +232,13 @@ opSVTS_a16(uint32_t fetchdat)
static int
opSVTS_a32(uint32_t fetchdat)
{
if (in_smm) {
uint8_t ins_check = ((ccr1 & (CCR1_USE_SMI | CCR1_SM3)) ==
(CCR1_USE_SMI | CCR1_SM3)) &&
((ccr1 & CCR1_SMAC) || in_smm) &&
(cyrix.arr[3].size > 0) &&
(CPL == 0);
if (ins_check) {
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr);
@@ -187,7 +252,13 @@ opSVTS_a32(uint32_t fetchdat)
static int
opRSTS_a16(uint32_t fetchdat)
{
if (in_smm) {
uint8_t ins_check = ((ccr1 & (CCR1_USE_SMI | CCR1_SM3)) ==
(CCR1_USE_SMI | CCR1_SM3)) &&
((ccr1 & CCR1_SMAC) || in_smm) &&
(cyrix.arr[3].size > 0) &&
(CPL == 0);
if (ins_check) {
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr);
@@ -200,7 +271,13 @@ opRSTS_a16(uint32_t fetchdat)
static int
opRSTS_a32(uint32_t fetchdat)
{
if (in_smm) {
uint8_t ins_check = ((ccr1 & (CCR1_USE_SMI | CCR1_SM3)) ==
(CCR1_USE_SMI | CCR1_SM3)) &&
((ccr1 & CCR1_SMAC) || in_smm) &&
(cyrix.arr[3].size > 0) &&
(CPL == 0);
if (ins_check) {
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr);
@@ -214,10 +291,16 @@ opRSTS_a32(uint32_t fetchdat)
static int
opSMINT(UNUSED(uint32_t fetchdat))
{
uint8_t ccr1_check = ((ccr1 & (CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)) ==
(CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)) &&
(cyrix.arr[3].size > 0);
if (in_smm)
fatal("opSMINT\n");
else
x86illegal();
else if (ccr1_check) {
is_smint = 1;
enter_smm(0);
}
return 1;
}
@@ -225,9 +308,26 @@ opSMINT(UNUSED(uint32_t fetchdat))
static int
opRDSHR_a16(UNUSED(uint32_t fetchdat))
{
if (in_smm)
fatal("opRDSHR_a16\n");
else
uint8_t ins_check = ((ccr1 & (CCR1_USE_SMI | CCR1_SM3)) ==
(CCR1_USE_SMI | CCR1_SM3)) &&
((ccr1 & CCR1_SMAC) || in_smm) &&
(cyrix.arr[3].size > 0) &&
(CPL == 0);
if (ins_check) {
fetch_ea_16(fetchdat);
if (cpu_mod == 3) {
cpu_state.regs[cpu_rm].l = cyrix.smhr;
CLOCK_CYCLES(timing_rr);
PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0);
} else {
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteal(cyrix.smhr);
CLOCK_CYCLES(is486 ? 1 : 2);
PREFETCH_RUN(2, 2, rmdat, 0, 0, 0, 1, 0);
}
return cpu_state.abrt;
} else
x86illegal();
return 1;
@@ -235,30 +335,91 @@ opRDSHR_a16(UNUSED(uint32_t fetchdat))
static int
opRDSHR_a32(UNUSED(uint32_t fetchdat))
{
if (in_smm)
fatal("opRDSHR_a32\n");
else
uint8_t ins_check = ((ccr1 & (CCR1_USE_SMI | CCR1_SM3)) ==
(CCR1_USE_SMI | CCR1_SM3)) &&
((ccr1 & CCR1_SMAC) || in_smm) &&
(cyrix.arr[3].size > 0) &&
(CPL == 0);
if (ins_check) {
fetch_ea_32(fetchdat);
if (cpu_mod == 3) {
cpu_state.regs[cpu_rm].l = cyrix.smhr;
CLOCK_CYCLES(timing_rr);
PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1);
} else {
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteal(cyrix.smhr);
CLOCK_CYCLES(is486 ? 1 : 2);
PREFETCH_RUN(2, 2, rmdat, 0, 0, 0, 1, 1);
}
return cpu_state.abrt;
} else
x86illegal();
return 1;
}
static int
opWRSHR_a16(UNUSED(uint32_t fetchdat))
opWRSHR_a16(uint32_t fetchdat)
{
if (in_smm)
fatal("opWRSHR_a16\n");
else
uint8_t ins_check = ((ccr1 & (CCR1_USE_SMI | CCR1_SM3)) ==
(CCR1_USE_SMI | CCR1_SM3)) &&
((ccr1 & CCR1_SMAC) || in_smm) &&
(cyrix.arr[3].size > 0) &&
(CPL == 0);
if (ins_check) {
fetch_ea_16(fetchdat);
if (cpu_mod == 3) {
cyrix.smhr = cpu_state.regs[cpu_rm].l;
CLOCK_CYCLES(timing_rr);
PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0);
} else {
uint32_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
temp = geteal();
if (cpu_state.abrt)
return 1;
cyrix.smhr = temp;
CLOCK_CYCLES(is486 ? 1 : 4);
PREFETCH_RUN(4, 2, rmdat, 0, 1, 0, 0, 0);
}
return 0;
} else
x86illegal();
return 1;
}
static int
opWRSHR_a32(UNUSED(uint32_t fetchdat))
opWRSHR_a32(uint32_t fetchdat)
{
if (in_smm)
fatal("opWRSHR_a32\n");
else
uint8_t ins_check = ((ccr1 & (CCR1_USE_SMI | CCR1_SM3)) ==
(CCR1_USE_SMI | CCR1_SM3)) &&
((ccr1 & CCR1_SMAC) || in_smm) &&
(cyrix.arr[3].size > 0) &&
(CPL == 0);
if (ins_check) {
fetch_ea_32(fetchdat);
if (cpu_mod == 3) {
cyrix.smhr = cpu_state.regs[cpu_rm].l;
CLOCK_CYCLES(timing_rr);
PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1);
} else {
uint32_t temp;
SEG_CHECK_READ(cpu_state.ea_seg);
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
temp = geteal();
if (cpu_state.abrt)
return 1;
cyrix.smhr = temp;
CLOCK_CYCLES(is486 ? 1 : 4);
PREFETCH_RUN(4, 2, rmdat, 0, 1, 0, 0, 1);
}
return 0;
} else
x86illegal();
return 1;

View File

@@ -855,6 +855,7 @@ opREPNE(uint32_t fetchdat)
CLOCK_CYCLES(2);
PREFETCH_PREFIX();
rep_op = fetchdat & 0xff;
if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32])
return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
@@ -869,6 +870,7 @@ opREPE(uint32_t fetchdat)
CLOCK_CYCLES(2);
PREFETCH_PREFIX();
rep_op = fetchdat & 0xff;
if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32])
return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);

View File

@@ -843,6 +843,7 @@ opREPNE(uint32_t fetchdat)
CLOCK_CYCLES(2);
PREFETCH_PREFIX();
rep_op = fetchdat & 0xff;
if (x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32])
return x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
@@ -857,6 +858,7 @@ opREPE(uint32_t fetchdat)
CLOCK_CYCLES(2);
PREFETCH_PREFIX();
rep_op = fetchdat & 0xff;
if (x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32])
return x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);

View File

@@ -761,6 +761,7 @@ opREPNE(uint32_t fetchdat)
cpu_state.pc++;
CLOCK_CYCLES(2);
rep_op = fetchdat & 0xff;
if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32])
return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
@@ -774,6 +775,7 @@ opREPE(uint32_t fetchdat)
cpu_state.pc++;
CLOCK_CYCLES(2);
rep_op = fetchdat & 0xff;
if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32])
return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);

View File

@@ -1334,6 +1334,12 @@ pmoderetf(int is32, uint16_t off)
if (CPL == (seg & 0x0003)) {
x86seg_log("RETF CPL = RPL %04X\n", segdat[2]);
switch (segdat[2] & 0x1f00) {
case 0x1000:
case 0x1100:
case 0x1200:
case 0x1300:
/* Data segment, apparently valid when CPL is the same, used by MS LINK for DOS. */
fallthrough;
case 0x1800:
case 0x1900:
case 0x1a00:
@@ -1384,6 +1390,12 @@ pmoderetf(int is32, uint16_t off)
cycles -= timing_retf_pm;
} else {
switch (segdat[2] & 0x1f00) {
case 0x1000:
case 0x1100:
case 0x1200:
case 0x1300:
/* Data segment, apparently valid when CPL is the same, used by MS LINK for DOS. */
fallthrough;
case 0x1800:
case 0x1900:
case 0x1a00:
@@ -1605,6 +1617,12 @@ pmodeint(int num, int soft)
return;
}
switch (segdat2[2] & 0x1f00) {
case 0x1000:
case 0x1100:
case 0x1200:
case 0x1300:
/* Data segment, apparently valid when CPL is the same, used by MS CodeView for DOS. */
fallthrough;
case 0x1800:
case 0x1900:
case 0x1a00:
@@ -1983,6 +2001,12 @@ pmodeiret(int is32)
}
switch (segdat[2] & 0x1f00) {
case 0x1000:
case 0x1100:
case 0x1200:
case 0x1300:
/* Data segment, apparently valid when CPL is the same, used by MS CodeView for DOS. */
fallthrough;
case 0x1800:
case 0x1900:
case 0x1a00:
@@ -2581,19 +2605,17 @@ cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg)
cpu_cur_status &= ~CPU_STATUS_NOTFLATDS;
else
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
#ifdef USE_DYNAREC
codegen_flat_ds = 0;
#endif
}
if (seg == &cpu_state.seg_cs)
set_use32(segdat[3] & 0x40);
if (seg == &cpu_state.seg_ss) {
if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff)
cpu_cur_status &= ~CPU_STATUS_NOTFLATSS;
else
cpu_cur_status |= CPU_STATUS_NOTFLATSS;
set_stack32((segdat[3] & 0x40) ? 1 : 0);
#ifdef USE_DYNAREC
codegen_flat_ss = 0;
#endif
}
}
}

View File

@@ -84,6 +84,7 @@ typedef struct xtkbd_t {
uint8_t key_waiting;
uint8_t type;
uint8_t pravetz_flags;
uint8_t cpu_speed;
pc_timer_t send_delay_timer;
} xtkbd_t;
@@ -799,6 +800,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
kbd_adddata(0xaa);
}
}
kbd->pb = val;
if (!(kbd->pb & 0x80) || (kbd->type == KBD_TYPE_HYUNDAI))
kbd->clock = !!(kbd->pb & 0x40);
@@ -846,6 +848,14 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
}
break;
case 0x1f0:
kbd_log("XTkbd: Port %04X out: %02X\n", port, val);
if (kbd->type == KBD_TYPE_VTECH) {
kbd->cpu_speed = val;
cpu_dynamic_switch(kbd->cpu_speed >> 7);
}
break;
default:
break;
}
@@ -863,12 +873,14 @@ kbd_read(uint16_t port, void *priv)
(kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ) ||
(kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_XT86) ||
(kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) ||
(kbd->type == KBD_TYPE_ZENITH) || (kbd->type == KBD_TYPE_HYUNDAI))) {
(kbd->type == KBD_TYPE_ZENITH) || (kbd->type == KBD_TYPE_HYUNDAI) ||
(kbd->type == KBD_TYPE_VTECH))) {
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) ||
(kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) ||
(kbd->type == KBD_TYPE_PRAVETZ) || (kbd->type == KBD_TYPE_HYUNDAI))
ret = (kbd->pd & ~0x02) | (hasfpu ? 0x02 : 0x00);
else if ((kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_XT86))
else if ((kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_XT86) ||
(kbd->type == KBD_TYPE_VTECH))
/* According to Ruud on the PCem forum, this is supposed to
return 0xFF on the XT. */
ret = 0xff;
@@ -926,16 +938,8 @@ kbd_read(uint16_t port, void *priv)
} else {
if (kbd->pb & 0x08) /* PB3 */
ret = kbd->pd >> 4;
else {
/* LaserXT = Always 512k RAM;
LaserXT/3 = Bit 0: set = 512k, clear = 256k. */
#ifdef USE_LASERXT
if (kbd->type == KBD_TYPE_VTECH)
ret = ((mem_size == 512) ? 0x0d : 0x0c) | (hasfpu ? 0x02 : 0x00);
else
#endif /* USE_LASERXT */
ret = (kbd->pd & 0x0d) | (hasfpu ? 0x02 : 0x00);
}
else
ret = (kbd->pd & 0x0d) | (hasfpu ? 0x02 : 0x00);
}
ret |= (ppispeakon ? 0x20 : 0);
@@ -956,7 +960,8 @@ kbd_read(uint16_t port, void *priv)
case 0x63: /* Keyboard Configuration Register (aka Port D) */
if ((kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_XT86) ||
(kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) ||
(kbd->type == KBD_TYPE_TOSHIBA) || (kbd->type == KBD_TYPE_HYUNDAI))
(kbd->type == KBD_TYPE_TOSHIBA) || (kbd->type == KBD_TYPE_HYUNDAI) ||
(kbd->type == KBD_TYPE_VTECH))
ret = kbd->pd;
break;
@@ -966,6 +971,12 @@ kbd_read(uint16_t port, void *priv)
kbd_log("XTkbd: Port %02X in : %02X\n", port, ret);
break;
case 0x1f0:
if (kbd->type == KBD_TYPE_VTECH)
ret = kbd->cpu_speed;
kbd_log("XTkbd: Port %04X in : %02X\n", port, ret);
break;
default:
break;
}
@@ -984,7 +995,7 @@ kbd_reset(void *priv)
kbd->pb = 0x00;
kbd->pravetz_flags = 0x00;
keyboard_scan = 1;
keyboard_scan = 1;
key_queue_start = 0;
key_queue_end = 0;
@@ -1006,12 +1017,16 @@ kbd_init(const device_t *info)
io_sethandler(0x0060, 4,
kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd);
keyboard_send = kbd_adddata_ex;
kbd_reset(kbd);
kbd->type = info->local;
if (kbd->type == KBD_TYPE_PRAVETZ) {
if (kbd->type == KBD_TYPE_VTECH)
kbd->cpu_speed = (!!cpu) << 2;
kbd_reset(kbd);
if (kbd->type == KBD_TYPE_PRAVETZ)
io_sethandler(0x00c0, 16,
kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd);
}
if (kbd->type == KBD_TYPE_VTECH)
io_sethandler(0x01f0, 1,
kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd);
key_queue_start = key_queue_end = 0;
@@ -1021,7 +1036,8 @@ kbd_init(const device_t *info)
(kbd->type == KBD_TYPE_PRAVETZ) || (kbd->type == KBD_TYPE_XT82) ||
(kbd->type <= KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_XTCLONE) ||
(kbd->type == KBD_TYPE_COMPAQ) || (kbd->type == KBD_TYPE_TOSHIBA) ||
(kbd->type == KBD_TYPE_OLIVETTI) || (kbd->type == KBD_TYPE_HYUNDAI)) {
(kbd->type == KBD_TYPE_OLIVETTI) || (kbd->type == KBD_TYPE_HYUNDAI) ||
(kbd->type == KBD_TYPE_VTECH)) {
/* DIP switch readout: bit set = OFF, clear = ON. */
if (kbd->type == KBD_TYPE_OLIVETTI)
/* Olivetti M19
@@ -1035,7 +1051,7 @@ kbd_init(const device_t *info)
/* Switches 7, 8 - floppy drives. */
kbd->pd = get_fdd_switch_settings();
/* Siitches 5, 6 - video card type */
/* Switches 5, 6 - video card type */
kbd->pd |= get_videomode_switch_settings();
/* Switches 3, 4 - memory size. */
@@ -1057,7 +1073,7 @@ kbd_init(const device_t *info)
kbd->pd |= 0x0c;
break;
}
} else if (kbd->type == KBD_TYPE_XT82) {
} else if ((kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_VTECH)) {
switch (mem_size) {
case 64: /* 1x64k */
kbd->pd |= 0x00;
@@ -1075,9 +1091,13 @@ kbd_init(const device_t *info)
}
} else if (kbd->type == KBD_TYPE_PC82) {
switch (mem_size) {
#ifdef PC82_192K_3BANK
case 192: /* 3x64k, not supported by stock BIOS due to bugs */
kbd->pd |= 0x08;
break;
#else
case 192: /* 2x64k + 2x32k */
#endif
case 64: /* 4x16k */
case 96: /* 2x32k + 2x16k */
case 128: /* 4x32k */
@@ -1294,8 +1314,8 @@ const device_t keyboard_xt_t1x00_device = {
#ifdef USE_LASERXT
const device_t keyboard_xt_lxt3_device = {
.name = "VTech Laser XT3 Keyboard",
.internal_name = "keyboard_xt_lxt3",
.name = "VTech Laser Turbo XT Keyboard",
.internal_name = "keyboard_xt_lxt",
.flags = 0,
.local = KBD_TYPE_VTECH,
.init = kbd_init,

View File

@@ -117,7 +117,7 @@
#define ROM_PATH_MCIDE "roms/hdd/xtide/ide_ps2 R1.1.bin"
typedef struct ide_bm_t {
int (*dma)(uint8_t *data, int transfer_length, int out, void *priv);
int (*dma)(uint8_t *data, int transfer_length, int total_length, int out, void *priv);
void (*set_irq)(uint8_t status, void *priv);
void *priv;
} ide_bm_t;
@@ -1094,7 +1094,7 @@ ide_atapi_callback(ide_t *ide)
if (!IDE_ATAPI_IS_EARLY && !ide_boards[ide->board]->force_ata3 &&
(bm != NULL) && bm->dma) {
if (ide->sc->block_len == 0) {
ret = bm->dma(ide->sc->temp_buffer, ide->sc->packet_len, 0, bm->priv);
ret = bm->dma(ide->sc->temp_buffer, ide->sc->packet_len, 0, 0, bm->priv);
/* Underrun. */
if (ret == 1)
@@ -1102,6 +1102,7 @@ ide_atapi_callback(ide_t *ide)
} else {
ret = bm->dma(ide->sc->temp_buffer + ide->sc->buffer_pos -
ide->sc->block_len, ide->sc->block_len,
ide->sc->sector_len * ide->sc->block_len,
0, bm->priv);
if (ret == 1) {
@@ -1144,14 +1145,16 @@ ide_atapi_callback(ide_t *ide)
if (!IDE_ATAPI_IS_EARLY && !ide_boards[ide->board]->force_ata3 &&
(bm != NULL) && bm->dma) {
if (ide->sc->block_len == 0) {
ret = bm->dma(ide->sc->temp_buffer, ide->sc->packet_len, 1, bm->priv);
ret = bm->dma(ide->sc->temp_buffer, ide->sc->packet_len, 0, 1, bm->priv);
/* Underrun. */
if (ret == 1)
ret = 3;
} else {
ret = bm->dma(ide->sc->temp_buffer + ide->sc->buffer_pos,
ide->sc->block_len, 1, bm->priv);
ide->sc->block_len,
ide->sc->sector_len * ide->sc->block_len,
1, bm->priv);
if (ret & 1) {
if (ide->write != NULL)
@@ -1197,7 +1200,8 @@ ide_atapi_callback(ide_t *ide)
static void
ide_atapi_pio_request(ide_t *ide, uint8_t out)
{
scsi_common_t *dev = ide->sc;
scsi_common_t *dev = ide->sc;
int left = 0;
ide_irq_lower(ide);
@@ -1221,6 +1225,8 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out)
ide_log("%i bytes %s, %i bytes are still left\n", ide->tf->pos,
out ? "written" : "read", dev->packet_len - ide->tf->pos);
left = 1;
/*
If less than (packet length) bytes are remaining, update packet length
accordingly.
@@ -1252,23 +1258,33 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out)
ide->write(dev);
if (dev->sector_len == 0) {
ide->sc->packet_status = PHASE_COMPLETE;
ide->sc->callback = 0.0;
if (left) {
ide_atapi_callback(ide);
ide_set_callback(ide, 0.0);
} else {
ide->sc->packet_status = PHASE_COMPLETE;
ide->sc->callback = 0.0;
if (ide->phase_data_out != NULL)
(void) ide->phase_data_out(dev);
if (ide->phase_data_out != NULL)
(void) ide->phase_data_out(dev);
ide_atapi_callback(ide);
ide_atapi_callback(ide);
}
}
} else {
if (dev->sector_len == 0) {
if (ide->command_stop != NULL)
ide->command_stop(dev);
if (left) {
ide_atapi_callback(ide);
ide_set_callback(ide, 0.0);
} else {
if (ide->command_stop != NULL)
ide->command_stop(dev);
ide->sc->packet_status = PHASE_COMPLETE;
ide->sc->callback = 0.0;
ide->sc->packet_status = PHASE_COMPLETE;
ide->sc->callback = 0.0;
ide_atapi_callback(ide);
ide_atapi_callback(ide);
}
} else if (ide->read != NULL)
ide->read(dev);
}
@@ -2379,7 +2395,7 @@ ide_callback(void *priv)
err = UNC_ERR;
} else if (!ide_boards[ide->board]->force_ata3 && bm->dma) {
/* We should not abort - we should simply wait for the host to start DMA. */
ret = bm->dma(ide->sector_buffer, ide->sector_pos * 512, 0, bm->priv);
ret = bm->dma(ide->sector_buffer, ide->sector_pos * 512, 0, 0, bm->priv);
if (ret == 2) {
/* Bus master DMA disabled, simply wait for the host to enable DMA. */
ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT;
@@ -2487,7 +2503,7 @@ ide_callback(void *priv)
else
ide->sector_pos = 256;
ret = bm->dma(ide->sector_buffer, ide->sector_pos * 512, 1, bm->priv);
ret = bm->dma(ide->sector_buffer, ide->sector_pos * 512, 0, 1, bm->priv);
if (ret == 2) {
/* Bus master DMA disabled, simply wait for the host to enable DMA. */
@@ -3114,7 +3130,7 @@ ide_xtide_close(void)
void
ide_set_bus_master(int board,
int (*dma)(uint8_t *data, int transfer_length, int out, void *priv),
int (*dma)(uint8_t *data, int transfer_length, int total_length, int out, void *priv),
void (*set_irq)(uint8_t status, void *priv), void *priv)
{
ide_bm_t *bm;

View File

@@ -95,19 +95,19 @@ cmd646_set_irq_1(uint8_t status, void *priv)
}
static int
cmd646_bus_master_dma_0(uint8_t *data, int transfer_length, int out, void *priv)
cmd646_bus_master_dma_0(uint8_t *data, int transfer_length, int total_length, int out, void *priv)
{
const cmd646_t *dev = (cmd646_t *) priv;
return sff_bus_master_dma(data, transfer_length, out, dev->bm[0]);
return sff_bus_master_dma(data, transfer_length, total_length, out, dev->bm[0]);
}
static int
cmd646_bus_master_dma_1(uint8_t *data, int transfer_length, int out, void *priv)
cmd646_bus_master_dma_1(uint8_t *data, int transfer_length, int total_length, int out, void *priv)
{
const cmd646_t *dev = (cmd646_t *) priv;
return sff_bus_master_dma(data, transfer_length, out, dev->bm[1]);
return sff_bus_master_dma(data, transfer_length, total_length, out, dev->bm[1]);
}
static void

View File

@@ -316,14 +316,14 @@ sff_bus_master_readl(uint16_t port, void *priv)
}
int
sff_bus_master_dma(uint8_t *data, int transfer_length, int out, void *priv)
sff_bus_master_dma(uint8_t *data, int transfer_length, int total_length, int out, void *priv)
{
sff8038i_t *dev = (sff8038i_t *) priv;
#ifdef ENABLE_SFF_LOG
char *sop;
#endif
int force_end = 0;
int force_end = 0;
int buffer_pos = 0;
#ifdef ENABLE_SFF_LOG
@@ -365,9 +365,15 @@ sff_bus_master_dma(uint8_t *data, int transfer_length, int out, void *priv)
return 1; /* This block has exhausted the data to transfer and it was smaller than the count, break. */
} else {
if (!transfer_length && !dev->eot) {
sff_log("Total transfer length smaller than sum of all blocks, full block\n");
dev->status &= ~2;
return 1; /* We have exhausted the data to transfer but there's more blocks left, break. */
if (total_length) {
sff_log("Total transfer length smaller than sum of all blocks, partial transfer\n");
sff_bus_master_next_addr(dev);
return 1; /* We have exhausted the data to transfer but there's more blocks left, break. */
} else {
sff_log("Total transfer length smaller than sum of all blocks, full block\n");
dev->status &= ~2;
return 1; /* We have exhausted the data to transfer but there's more blocks left, break. */
}
} else if (transfer_length && dev->eot) {
sff_log("Total transfer length greater than sum of all blocks\n");
dev->status |= 2;

View File

@@ -17,6 +17,8 @@
* Copyright 2020-2025 Miran Grca.
* Copyright 2020-2025 Fred N. van Kempen
*/
#define _GNU_SOURCE
#include <inttypes.h>
#ifdef ENABLE_MO_LOG
#include <stdarg.h>
#endif
@@ -63,7 +65,7 @@ const uint8_t mo_command_flags[0x100] = {
[0x0a] = IMPLEMENTED | CHECK_READY,
[0x0b] = IMPLEMENTED | CHECK_READY,
[0x12] = IMPLEMENTED | ALLOW_UA,
[0x13] = IMPLEMENTED | CHECK_READY | SCSI_ONLY,
[0x13] = IMPLEMENTED | CHECK_READY,
[0x15] = IMPLEMENTED,
[0x16] = IMPLEMENTED | SCSI_ONLY,
[0x17] = IMPLEMENTED | SCSI_ONLY,
@@ -74,8 +76,7 @@ const uint8_t mo_command_flags[0x100] = {
[0x25] = IMPLEMENTED | CHECK_READY,
[0x28] = IMPLEMENTED | CHECK_READY,
[0x2a ... 0x2c] = IMPLEMENTED | CHECK_READY,
[0x2e] = IMPLEMENTED | CHECK_READY,
[0x2f] = IMPLEMENTED | CHECK_READY | SCSI_ONLY,
[0x2e ... 0x2f] = IMPLEMENTED | CHECK_READY,
[0x41] = IMPLEMENTED | CHECK_READY,
[0x55] = IMPLEMENTED,
[0x5a] = IMPLEMENTED,
@@ -172,9 +173,9 @@ mo_load(const mo_t *dev, const char *fn, const int skip_insert)
}
if (ret) {
fseek(dev->drv->fp, 0, SEEK_END);
fseeko64(dev->drv->fp, 0, SEEK_END);
uint32_t size = (uint32_t) ftell(dev->drv->fp);
uint64_t size = (uint64_t) ftello64(dev->drv->fp);
unsigned int found = 0;
if (is_mdi) {
@@ -184,17 +185,20 @@ mo_load(const mo_t *dev, const char *fn, const int skip_insert)
} else
dev->drv->base = 0;
dev->drv->supported = 0;
for (uint8_t i = 0; i < KNOWN_MO_TYPES; i++) {
if (size == (mo_types[i].sectors * mo_types[i].bytes_per_sector)) {
if (size == ((uint64_t) mo_types[i].sectors * mo_types[i].bytes_per_sector)) {
found = 1;
dev->drv->medium_size = mo_types[i].sectors;
dev->drv->sector_size = mo_types[i].bytes_per_sector;
dev->drv->supported = mo_drive_types[dev->drv->type].supported_media[i];
break;
}
}
if (found) {
if (fseek(dev->drv->fp, dev->drv->base, SEEK_SET) == -1)
if (fseeko64(dev->drv->fp, (uint64_t) dev->drv->base, SEEK_SET) == -1)
log_fatal(dev->log, "mo_load(): Error seeking to the beginning of "
"the file\n");
@@ -433,7 +437,8 @@ mo_update_request_length(mo_t *dev, int len, int block_len)
case 0xa8:
case 0xaa:
/* Round it to the nearest 2048 bytes. */
dev->max_transfer_len = (dev->max_transfer_len >> 9) << 9;
dev->max_transfer_len = (dev->max_transfer_len / dev->drv->sector_size) *
dev->drv->sector_size;
/*
Make sure total length is not bigger than sum of the lengths of
@@ -793,52 +798,54 @@ mo_invalid_field_pl(mo_t *dev, const uint32_t field)
}
static int
mo_blocks(mo_t *dev, int32_t *len, int out)
mo_blocks(mo_t *dev, int32_t *len, const int out)
{
int ret = 0;
int ret = 1;
*len = 0;
if (!dev->sector_len)
mo_command_complete(dev);
else {
if (dev->sector_len > 0) {
mo_log(dev->log, "%sing %i blocks starting from %i...\n", out ? "Writ" : "Read",
dev->requested_blocks, dev->sector_pos);
if (dev->sector_pos >= dev->drv->medium_size) {
mo_log(dev->log, "Trying to %s beyond the end of disk\n", out ? "write" : "read");
if (!dev->drv->supported) {
mo_log(dev->log, "Trying to %s an unsupported medium\n",
out ? "write" : "read");
out ? mo_write_error(dev) : mo_read_error(dev);
ret = 0;
} else if (dev->sector_pos >= dev->drv->medium_size) {
mo_log(dev->log, "Trying to %s beyond the end of disk\n",
out ? "write" : "read");
mo_lba_out_of_range(dev);
ret = 0;
} else {
*len = dev->requested_blocks * dev->drv->sector_size;
ret = 1;
*len = dev->requested_blocks * dev->drv->sector_size;
for (int i = 0; i < dev->requested_blocks; i++) {
if (fseek(dev->drv->fp, dev->drv->base + (dev->sector_pos * dev->drv->sector_size) + (i * dev->drv->sector_size), SEEK_SET) == -1) {
if (fseeko64(dev->drv->fp, (uint64_t) dev->drv->base +
(uint64_t) (dev->sector_pos * dev->drv->sector_size),
SEEK_SET) == -1) {
if (out)
mo_write_error(dev);
else
mo_read_error(dev);
ret = -1;
} else {
if (!feof(dev->drv->fp))
if (feof(dev->drv->fp))
break;
if (out) {
if (fwrite(dev->buffer + (i * dev->drv->sector_size), 1,
dev->drv->sector_size, dev->drv->fp) != dev->drv->sector_size) {
dev->drv->sector_size, dev->drv->fp) != dev->drv->sector_size) {
mo_log(dev->log, "mo_blocks(): Error writing data\n");
mo_write_error(dev);
ret = -1;
} else
fflush(dev->drv->fp);
} else {
if (fread(dev->buffer + (i * dev->drv->sector_size), 1,
dev->drv->sector_size, dev->drv->fp) != dev->drv->sector_size) {
mo_log(dev->log, "mo_blocks(): Error reading data\n");
mo_read_error(dev);
ret = -1;
}
} else if (fread(dev->buffer + (i * dev->drv->sector_size), 1,
dev->drv->sector_size, dev->drv->fp) != dev->drv->sector_size) {
mo_log(dev->log, "mo_blocks(): Error reading data\n");
mo_read_error(dev);
ret = -1;
}
}
@@ -849,11 +856,15 @@ mo_blocks(mo_t *dev, int32_t *len, int out)
}
if (ret == 1) {
mo_log(dev->log, "%s %i bytes of blocks...\n", out ? "Written" : "Read", *len);
mo_log(dev->log, "%s %i bytes of blocks...\n", out ? "Written" :
"Read", *len);
dev->sector_len -= dev->requested_blocks;
}
}
} else {
mo_command_complete(dev);
ret = 0;
}
return ret;
@@ -888,8 +899,8 @@ mo_format(mo_t *dev)
mo_log(dev->log, "Formatting media...\n");
fseek(dev->drv->fp, 0, SEEK_END);
long size = ftell(dev->drv->fp);
fseeko64(dev->drv->fp, 0, SEEK_END);
int64_t size = ftello64(dev->drv->fp);
#ifdef _WIN32
LARGE_INTEGER liSize;
@@ -953,7 +964,11 @@ mo_erase(mo_t *dev)
mo_log(dev->log, "Erasing %i blocks starting from %i...\n",
dev->sector_len, dev->sector_pos);
if (dev->sector_pos >= dev->drv->medium_size) {
if (!dev->drv->supported) {
mo_log(dev->log, "Trying to erase an unsupported medium\n");
mo_write_error(dev);
return 0;
} else if (dev->sector_pos >= dev->drv->medium_size) {
mo_log(dev->log, "Trying to erase beyond the end of disk\n");
mo_lba_out_of_range(dev);
return 0;
@@ -962,8 +977,9 @@ mo_erase(mo_t *dev)
mo_buf_alloc(dev, dev->drv->sector_size);
memset(dev->buffer, 0, dev->drv->sector_size);
fseek(dev->drv->fp, dev->drv->base + (dev->sector_pos * dev->drv->sector_size),
SEEK_SET);
fseeko64(dev->drv->fp, dev->drv->base +
((uint64_t) dev->sector_pos * dev->drv->sector_size),
SEEK_SET);
for (i = 0; i < dev->requested_blocks; i++) {
if (feof(dev->drv->fp))
@@ -1383,6 +1399,9 @@ mo_command(scsi_common_t *sc, const uint8_t *cdb)
mo_set_phase(dev, SCSI_PHASE_STATUS);
mo_command_complete(dev);
break;
} else if (!dev->drv->supported) {
mo_read_error(dev);
break;
}
fallthrough;
case GPCMD_WRITE_6:
@@ -1391,7 +1410,7 @@ mo_command(scsi_common_t *sc, const uint8_t *cdb)
case GPCMD_WRITE_12:
case GPCMD_WRITE_AND_VERIFY_12:
mo_set_phase(dev, SCSI_PHASE_DATA_OUT);
alloc_length = 512;
alloc_length = dev->drv->sector_size;
switch (cdb[0]) {
case GPCMD_VERIFY_6:
@@ -1430,7 +1449,9 @@ mo_command(scsi_common_t *sc, const uint8_t *cdb)
break;
}
if (dev->sector_pos > (mo_types[dev->drv->type].sectors - 1))
if (!dev->drv->supported)
mo_write_error(dev);
else if (dev->sector_pos >= dev->drv->medium_size)
mo_lba_out_of_range(dev);
else {
if (dev->sector_len) {
@@ -1441,11 +1462,11 @@ mo_command(scsi_common_t *sc, const uint8_t *cdb)
mo_buf_alloc(dev, dev->packet_len);
dev->requested_blocks = max_len;
dev->packet_len = max_len << 9;
dev->packet_len = max_len * dev->drv->sector_size;
mo_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len);
mo_data_command_finish(dev, dev->packet_len, 512,
mo_data_command_finish(dev, dev->packet_len, dev->drv->sector_size,
dev->packet_len, 1);
ui_sb_update_icon(SB_MO | dev->id,
@@ -1462,7 +1483,7 @@ mo_command(scsi_common_t *sc, const uint8_t *cdb)
case GPCMD_WRITE_SAME_10:
mo_set_phase(dev, SCSI_PHASE_DATA_OUT);
alloc_length = 512;
alloc_length = dev->drv->sector_size;
if ((cdb[1] & 6) == 6)
mo_invalid_field(dev, cdb[1]);
@@ -1470,7 +1491,9 @@ mo_command(scsi_common_t *sc, const uint8_t *cdb)
dev->sector_len = (cdb[7] << 8) | cdb[8];
dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5];
if (dev->sector_pos > (mo_types[dev->drv->type].sectors - 1))
if (!dev->drv->supported)
mo_write_error(dev);
else if (dev->sector_pos >= dev->drv->medium_size)
mo_lba_out_of_range(dev);
else if (dev->sector_len) {
mo_buf_alloc(dev, alloc_length);
@@ -1481,7 +1504,8 @@ mo_command(scsi_common_t *sc, const uint8_t *cdb)
mo_set_phase(dev, SCSI_PHASE_DATA_OUT);
mo_data_command_finish(dev, 512, 512,
mo_data_command_finish(dev, dev->drv->sector_size,
dev->drv->sector_size,
alloc_length, 1);
ui_sb_update_icon(SB_MO | dev->id,
@@ -1830,7 +1854,7 @@ static uint8_t
mo_phase_data_out(scsi_common_t *sc)
{
mo_t * dev = (mo_t *) sc;
const uint32_t last_sector = mo_types[dev->drv->type].sectors - 1;
const uint32_t last_sector = dev->drv->medium_size - 1;
int len = 0;
uint8_t error = 0;
uint32_t last_to_write;
@@ -1878,7 +1902,8 @@ mo_phase_data_out(scsi_common_t *sc)
dev->buffer[6] = (s >> 8) & 0xff;
dev->buffer[7] = s & 0xff;
}
if (fseek(dev->drv->fp, (i * dev->drv->sector_size), SEEK_SET) == -1)
if (fseeko64(dev->drv->fp,
((uint64_t) i * dev->drv->sector_size), SEEK_SET) == -1)
mo_write_error(dev);
if (feof(dev->drv->fp))
break;
@@ -1912,6 +1937,9 @@ mo_phase_data_out(scsi_common_t *sc)
block_desc_len = 0;
pos = hdr_len + block_desc_len;
mo_log(dev->log, "Block descriptor: %08X %08X %08X %08X %08X %08X %08X %08X\n",
dev->buffer[hdr_len], dev->buffer[hdr_len + 1], dev->buffer[hdr_len + 2], dev->buffer[hdr_len + 3],
dev->buffer[hdr_len + 4], dev->buffer[hdr_len + 5], dev->buffer[hdr_len + 6], dev->buffer[hdr_len + 7]);
while (1) {
if (pos >= param_list_len) {

View File

@@ -53,7 +53,7 @@ const uint8_t zip_command_flags[0x100] = {
[0x0c] = IMPLEMENTED,
[0x0d] = IMPLEMENTED | ATAPI_ONLY,
[0x12] = IMPLEMENTED | ALLOW_UA,
[0x13] = IMPLEMENTED | CHECK_READY | SCSI_ONLY,
[0x13] = IMPLEMENTED | CHECK_READY,
[0x15] = IMPLEMENTED,
[0x16 ... 0x17] = IMPLEMENTED | SCSI_ONLY,
[0x1a] = IMPLEMENTED,
@@ -64,8 +64,7 @@ const uint8_t zip_command_flags[0x100] = {
[0x25] = IMPLEMENTED | CHECK_READY,
[0x28] = IMPLEMENTED | CHECK_READY,
[0x2a ... 0x2b] = IMPLEMENTED | CHECK_READY,
[0x2e] = IMPLEMENTED | CHECK_READY,
[0x2f] = IMPLEMENTED | CHECK_READY | SCSI_ONLY,
[0x2e ... 0x2f] = IMPLEMENTED | CHECK_READY,
[0x41] = IMPLEMENTED | CHECK_READY,
[0x55] = IMPLEMENTED,
[0x5a] = IMPLEMENTED,
@@ -898,9 +897,7 @@ zip_blocks(zip_t *dev, int32_t *len, const int out)
int ret = 1;
*len = 0;
if (!dev->sector_len)
zip_command_complete(dev);
else {
if (dev->sector_len > 0) {
zip_log(dev->log, "%sing %i blocks starting from %i...\n", out ? "Writ" : "Read",
dev->requested_blocks, dev->sector_pos);
@@ -908,12 +905,13 @@ zip_blocks(zip_t *dev, int32_t *len, const int out)
zip_log(dev->log, "Trying to %s beyond the end of disk\n",
out ? "write" : "read");
zip_lba_out_of_range(dev);
ret = 0;
} else {
*len = dev->requested_blocks << 9;
for (int i = 0; i < dev->requested_blocks; i++) {
if (fseek(dev->drv->fp, dev->drv->base + (dev->sector_pos << 9) +
(i << 9), SEEK_SET) == -1) {
if (fseek(dev->drv->fp, dev->drv->base + (dev->sector_pos << 9),
SEEK_SET) == -1) {
if (out)
zip_write_error(dev);
else
@@ -952,6 +950,9 @@ zip_blocks(zip_t *dev, int32_t *len, const int out)
dev->sector_len -= dev->requested_blocks;
}
}
} else {
zip_command_complete(dev);
ret = 0;
}
return ret;

View File

@@ -201,7 +201,7 @@ extern uint8_t ide_read_alt_status(uint16_t addr, void *priv);
extern uint16_t ide_readw(uint16_t addr, void *priv);
extern void ide_set_bus_master(int board,
int (*dma)(uint8_t *data, int transfer_length, int out, void *priv),
int (*dma)(uint8_t *data, int transfer_length, int total_length, int out, void *priv),
void (*set_irq)(uint8_t status, void *priv), void *priv);
extern void win_cdrom_eject(uint8_t id);

View File

@@ -63,7 +63,7 @@ extern const device_t sff8038i_device;
extern void sff_bus_master_handler(sff8038i_t *dev, int enabled, uint16_t base);
extern void sff_bus_master_set_irq(uint8_t status, void *priv);
extern int sff_bus_master_dma(uint8_t *data, int transfer_length, int out, void *priv);
extern int sff_bus_master_dma(uint8_t *data, int transfer_length, int total_length, int out, void *priv);
extern void sff_bus_master_write(uint16_t port, uint8_t val, void *priv);
extern uint8_t sff_bus_master_read(uint16_t port, void *priv);

View File

@@ -855,6 +855,7 @@ extern int machine_at_s1857_init(const machine_t *);
extern int machine_at_p6bap_init(const machine_t *);
extern int machine_at_p6bat_init(const machine_t *);
extern int machine_at_prosignias31x_bx_init(const machine_t *);
extern int machine_at_7sbb_init(const machine_t *);
/* m_at_misc.c */
extern int machine_at_vpc2007_init(const machine_t *);

View File

@@ -122,6 +122,8 @@ typedef struct mo_drive_t {
uint32_t medium_size;
uint32_t base;
uint16_t sector_size;
int supported;
} mo_drive_t;
typedef struct mo_t {

View File

@@ -28,6 +28,7 @@
#include <86box/io.h>
#include <86box/timer.h>
#include "cpu.h"
#include "x86.h"
#include <86box/m_amstrad.h>
#include <86box/pci.h>
@@ -344,6 +345,8 @@ inb(uint16_t port)
int qfound = 0;
#endif
io_port = port;
#ifdef USE_DEBUG_REGS_486
io_debug_check_addr(port);
#endif
@@ -408,6 +411,9 @@ outb(uint16_t port, uint8_t val)
int qfound = 0;
#endif
io_port = port;
io_val = val;
#ifdef USE_DEBUG_REGS_486
io_debug_check_addr(port);
#endif
@@ -464,6 +470,8 @@ inw(uint16_t port)
#endif
uint8_t ret8[2];
io_port = port;
#ifdef USE_DEBUG_REGS_486
io_debug_check_addr(port);
#endif
@@ -540,6 +548,9 @@ outw(uint16_t port, uint16_t val)
int qfound = 0;
#endif
io_port = port;
io_val = val;
#ifdef USE_DEBUG_REGS_486
io_debug_check_addr(port);
#endif
@@ -612,6 +623,8 @@ inl(uint16_t port)
int qfound = 0;
#endif
io_port = port;
#ifdef USE_DEBUG_REGS_486
io_debug_check_addr(port);
#endif
@@ -720,6 +733,9 @@ outl(uint16_t port, uint32_t val)
#endif
int i = 0;
io_port = port;
io_val = val;
#ifdef USE_DEBUG_REGS_486
io_debug_check_addr(port);
#endif

View File

@@ -750,9 +750,6 @@ machine_at_acer100t_init(const machine_t *model)
machine_at_ps2_ide_init(model);
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&ali1409_device);
if (gfxcard[0] == VID_INTERNAL)
device_add(&oti077_acer100t_device);

View File

@@ -541,3 +541,31 @@ machine_at_6via90ap_init(const machine_t *model)
return ret;
}
int
machine_at_7sbb_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/7sbb/sbb12aa2.bin",
0x000c0000, 262144, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init_ex(model, 2);
pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0);
device_add(&sis_5600_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&it8661f_device);
device_add(&sst_flash_29ee020_device); /* assumed */
return ret;
}

View File

@@ -16227,6 +16227,48 @@ const machine_t machines[] = {
.snd_device = &cmi8738_onboard_device,
.net_device = NULL
},
/* SiS (5)600 */
/* Has the SiS 600 chipset, which is a re-brand of the 5600, with
on-chip KBC. */
{
.name = "[SiS 600] Soyo SY-7SBB",
.internal_name = "7sbb",
.type = MACHINE_TYPE_SOCKET370,
.chipset = MACHINE_CHIPSET_SIS_5600,
.init = machine_at_7sbb_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_SOCKET370,
.block = CPU_BLOCK(CPU_CYRIX3S),
.min_bus = 60000000,
.max_bus = 100000000,
.min_voltage = 1800,
.max_voltage = 3500,
.min_multi = 1.5,
.max_multi = 8.0
},
.bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB,
.flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB,
.ram = {
.min = 8192,
.max = 1572864,
.step = 1024
},
.nvrmask = 255,
.kbc_device = NULL,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
},
/* Miscellaneous/Fake/Hypervisor machines */
/* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC

View File

@@ -367,7 +367,7 @@ NewFloppyDialog::create86f(const QString &filename, const disk_size_t &disk_size
bool
NewFloppyDialog::createSectorImage(const QString &filename, const disk_size_t &disk_size, FileType type)
{
uint32_t total_size = 0;
uint64_t total_size = 0;
uint32_t total_sectors = 0;
uint32_t sector_bytes = 0;
uint32_t root_dir_bytes = 0;
@@ -388,7 +388,7 @@ NewFloppyDialog::createSectorImage(const QString &filename, const disk_size_t &d
total_sectors = disk_size.sides * disk_size.tracks * disk_size.sectors;
if (total_sectors > ZIP_SECTORS)
total_sectors = ZIP_250_SECTORS;
total_size = total_sectors * sector_bytes;
total_size = (uint64_t) total_sectors * sector_bytes;
root_dir_bytes = (disk_size.root_dir_entries << 5);
fat_size = (disk_size.spfat * sector_bytes);
fat1_offs = sector_bytes;
@@ -465,11 +465,11 @@ NewFloppyDialog::createSectorImage(const QString &filename, const disk_size_t &d
bool
NewFloppyDialog::createZipSectorImage(const QString &filename, const disk_size_t &disk_size, FileType type, QProgressDialog &pbar)
{
uint32_t total_size = 0;
uint64_t total_size = 0;
uint32_t total_sectors = 0;
uint32_t sector_bytes = 0;
uint16_t base = 0x1000;
uint32_t pbar_max = 0;
uint64_t pbar_max = 0;
QFile file(filename);
if (!file.open(QIODevice::WriteOnly)) {
@@ -482,7 +482,7 @@ NewFloppyDialog::createZipSectorImage(const QString &filename, const disk_size_t
total_sectors = disk_size.sides * disk_size.tracks * disk_size.sectors;
if (total_sectors > ZIP_SECTORS)
total_sectors = ZIP_250_SECTORS;
total_size = total_sectors * sector_bytes;
total_size = (uint64_t) total_sectors * sector_bytes;
pbar_max = total_size;
if (type == FileType::Zdi) {
@@ -649,12 +649,12 @@ bool
NewFloppyDialog::createMoSectorImage(const QString &filename, int8_t disk_size, FileType type, QProgressDialog &pbar)
{
const mo_type_t *dp = &mo_types[disk_size];
uint32_t total_size = 0;
uint32_t total_size2;
uint64_t total_size = 0;
uint64_t total_size2;
uint32_t total_sectors = 0;
uint32_t sector_bytes = 0;
uint16_t base = 0x1000;
uint32_t pbar_max = 0;
uint64_t pbar_max = 0;
uint32_t blocks_num;
QFile file(filename);
@@ -666,7 +666,7 @@ NewFloppyDialog::createMoSectorImage(const QString &filename, int8_t disk_size,
sector_bytes = dp->bytes_per_sector;
total_sectors = dp->sectors;
total_size = total_sectors * sector_bytes;
total_size = (uint64_t) total_sectors * sector_bytes;
total_size2 = (total_size >> 20) << 20;
total_size2 = total_size - total_size2;

View File

@@ -144,6 +144,10 @@ RendererCommon::eventDelegate(QEvent *event, bool &result)
case QEvent::MouseButtonPress:
case QEvent::MouseMove:
case QEvent::MouseButtonRelease:
case QEvent::TouchBegin:
case QEvent::TouchEnd:
case QEvent::TouchCancel:
case QEvent::TouchUpdate:
case QEvent::Wheel:
case QEvent::Enter:
case QEvent::Leave:

View File

@@ -38,6 +38,7 @@
#include <QScreen>
#include <QMessageBox>
#include <QTouchEvent>
#ifdef __APPLE__
# include <CoreGraphics/CoreGraphics.h>
@@ -63,6 +64,7 @@ RendererStack::RendererStack(QWidget *parent, int monitor_index)
: QStackedWidget(parent)
, ui(new Ui::RendererStack)
{
setAttribute(Qt::WA_AcceptTouchEvents, true);
rendererTakesScreenshots = false;
#ifdef Q_OS_WINDOWS
int raw = 1;
@@ -206,9 +208,11 @@ RendererStack::wheelEvent(QWheelEvent *event)
return;
}
#if !defined(Q_OS_WINDOWS) && !defined(__APPLE__)
double numSteps = (double) event->angleDelta().y() / 120.0;
mouse_set_z((int) numSteps);
#endif
event->accept();
}
@@ -477,8 +481,8 @@ RendererStack::event(QEvent* event)
if (m_monitor_index >= 1) {
if (mouse_input_mode >= 1) {
mouse_x_abs = (mouse_event->localPos().x()) / (long double)width();
mouse_y_abs = (mouse_event->localPos().y()) / (long double)height();
mouse_x_abs = (mouse_event->localPos().x()) / (double)width();
mouse_y_abs = (mouse_event->localPos().y()) / (double)height();
if (!mouse_tablet_in_proximity)
mouse_tablet_in_proximity = mousedata.mouse_tablet_in_proximity;
}
@@ -487,15 +491,69 @@ RendererStack::event(QEvent* event)
#ifdef Q_OS_WINDOWS
if (mouse_input_mode == 0) {
mouse_x_abs = (mouse_event->localPos().x()) / (long double)width();
mouse_y_abs = (mouse_event->localPos().y()) / (long double)height();
mouse_x_abs = (mouse_event->localPos().x()) / (double)width();
mouse_y_abs = (mouse_event->localPos().y()) / (double)height();
return QStackedWidget::event(event);
}
#endif
mouse_x_abs = (mouse_event->localPos().x()) / (long double)width();
mouse_y_abs = (mouse_event->localPos().y()) / (long double)height();
mouse_x_abs = (mouse_event->localPos().x()) / (double)width();
mouse_y_abs = (mouse_event->localPos().y()) / (double)height();
mouse_tablet_in_proximity = mousedata.mouse_tablet_in_proximity;
} else switch (event->type()) {
case QEvent::TouchBegin:
case QEvent::TouchUpdate:
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QTouchEvent* touchevent = (QTouchEvent*)event;
if (mouse_input_mode == 0) break;
if (touchevent->touchPoints().count()) {
mouse_x_abs = (touchevent->touchPoints()[0].pos().x()) / (double)width();
mouse_y_abs = (touchevent->touchPoints()[0].pos().y()) / (double)height();
}
mouse_set_buttons_ex(mouse_get_buttons_ex() | 1);
touchevent->accept();
return true;
#else
QTouchEvent* touchevent = (QTouchEvent*)event;
if (mouse_input_mode == 0) break;
if (touchevent->pointCount()) {
mouse_x_abs = (touchevent->point(0).position().x()) / (double)width();
mouse_y_abs = (touchevent->point(0).position().y()) / (double)height();
}
mouse_set_buttons_ex(mouse_get_buttons_ex() | 1);
touchevent->accept();
return true;
#endif
}
case QEvent::TouchEnd:
case QEvent::TouchCancel:
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QTouchEvent* touchevent = (QTouchEvent*)event;
if (mouse_input_mode == 0) break;
if (touchevent->touchPoints().count()) {
mouse_x_abs = (touchevent->touchPoints()[0].pos().x()) / (double)width();
mouse_y_abs = (touchevent->touchPoints()[0].pos().y()) / (double)height();
}
mouse_set_buttons_ex(mouse_get_buttons_ex() & ~1);
touchevent->accept();
return true;
#else
QTouchEvent* touchevent = (QTouchEvent*)event;
if (mouse_input_mode == 0) break;
if (touchevent->pointCount()) {
mouse_x_abs = (touchevent->point(0).position().x()) / (double)width();
mouse_y_abs = (touchevent->point(0).position().y()) / (double)height();
}
mouse_set_buttons_ex(mouse_get_buttons_ex() & ~1);
touchevent->accept();
return true;
#endif
}
default:
return QStackedWidget::event(event);
}
return QStackedWidget::event(event);

View File

@@ -1096,6 +1096,10 @@ scsi_cdrom_read_blocks(scsi_cdrom_t *dev)
int msf = 0;
int type = dev->sector_type;
int flags = dev->sector_flags;
#ifdef ENABLE_SCSI_CDROM_LOG
int num = (dev->drv->bus_type == CDROM_BUS_SCSI) ?
dev->requested_blocks : 1;
#endif
switch (dev->current_cdb[0]) {
case GPCMD_READ_CD_MSF_OLD:
@@ -1128,7 +1132,7 @@ scsi_cdrom_read_blocks(scsi_cdrom_t *dev)
}
scsi_cdrom_log(dev->log, "Reading %i blocks starting from %i...\n",
dev->requested_blocks, dev->sector_pos);
num, dev->sector_pos);
ret = scsi_cdrom_read_data(dev, msf, type, flags, dev->vendor_type);

View File

@@ -107,6 +107,7 @@ typedef struct chips_69000_t {
uint8_t mm_regs[256], mm_index;
uint8_t flat_panel_regs[256], flat_panel_index;
uint8_t ext_regs[256], ext_index;
uint8_t pci_regs[256];
union {
uint32_t mem_regs[4];
@@ -239,7 +240,7 @@ chips_69000_write_flat_panel(chips_69000_t* chips, uint8_t val)
void
chips_69000_interrupt(chips_69000_t* chips)
{
pci_irq(chips->slot, PCI_INTA, 0, !!((chips->mem_regs[0] & chips->mem_regs[1]) & 0x80004040), &chips->irq_state);
pci_irq(chips->slot, PCI_INTA, 0, !!(chips->mem_regs[0] & chips->mem_regs[1] & 0x80004040), &chips->irq_state);
}
void
@@ -1041,7 +1042,9 @@ void
chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t pattern, uint32_t src, uint8_t rop)
{
uint32_t orig_dst = *dst & 0xFF000000;
ROPMIX(rop, *dst, pattern, src, *dst);
*dst &= 0xFFFFFF;
*dst |= orig_dst;
}
@@ -1206,22 +1209,20 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel)
switch (chips->bitblt_running.bytes_per_pixel) {
case 1: /* 8 bits-per-pixel. */
{
//dest_pixel = chips_69000_readb_linear(dest_addr, chips);
dest_pixel = chips->svga.vram[dest_addr & chips->svga.vram_mask];
dest_pixel = chips_69000_readb_linear(dest_addr, chips);
break;
}
case 2: /* 16 bits-per-pixel. */
{
//dest_pixel = *(uint16_t*)&chips->svga.vram[dest_addr & chips->svga.vram_mask];
dest_pixel = chips->svga.vram[dest_addr & chips->svga.vram_mask];
dest_pixel |= chips->svga.vram[(dest_addr + 1) & chips->svga.vram_mask] << 8;
dest_pixel = chips_69000_readb_linear(dest_addr, chips);
dest_pixel |= chips_69000_readb_linear(dest_addr + 1, chips) << 8;
break;
}
case 3: /* 24 bits-per-pixel. */
{
dest_pixel = chips->svga.vram[dest_addr & chips->svga.vram_mask];
dest_pixel |= chips->svga.vram[(dest_addr + 1) & chips->svga.vram_mask] << 8;
dest_pixel |= chips->svga.vram[(dest_addr + 2) & chips->svga.vram_mask] << 16;
dest_pixel = chips_69000_readb_linear(dest_addr, chips);
dest_pixel |= chips_69000_readb_linear(dest_addr + 1, chips) << 8;
dest_pixel |= chips_69000_readb_linear(dest_addr + 2, chips) << 16;
break;
}
}
@@ -1234,7 +1235,7 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel)
if (chips->bitblt_running.bitblt.bitblt_control & (1 << 19))
pattern_data = 0;
else
pattern_data = chips->svga.vram[(chips->bitblt_running.bitblt.pat_addr + ((vert_pat_alignment + (chips->bitblt_running.y & 7)) & 7)) & chips->svga.vram_mask]; //chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + ((vert_pat_alignment + (chips->bitblt_running.y & 7)) & 7), chips);
pattern_data = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + ((vert_pat_alignment + (chips->bitblt_running.y & 7)) & 7), chips);
is_true = !!(pattern_data & (1 << (7 - ((chips->bitblt_running.bitblt.destination_addr + chips->bitblt_running.x) & 7))));
@@ -1250,30 +1251,32 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel)
pattern_pixel &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1;
} else {
uint32_t pattern_pixel_addr = 0;
if (chips->bitblt_running.bytes_per_pixel == 1) {
pattern_pixel_addr = chips->bitblt_running.bitblt.pat_addr
+ 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)
+ (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7);
pattern_pixel = chips->svga.vram[pattern_pixel_addr & chips->svga.vram_mask];
pattern_pixel = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr
+ 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)
+ (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7), chips);
}
if (chips->bitblt_running.bytes_per_pixel == 2) {
pattern_pixel_addr = chips->bitblt_running.bitblt.pat_addr
+ (2 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7))
+ (2 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7));
pattern_pixel = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr
+ (2 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7))
+ (2 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)), chips);
pattern_pixel = chips->svga.vram[pattern_pixel_addr & chips->svga.vram_mask];
pattern_pixel |= chips->svga.vram[(pattern_pixel_addr + 1) & chips->svga.vram_mask] << 8;
pattern_pixel |= chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr
+ (2 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7))
+ (2 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)) + 1, chips) << 8;
}
if (chips->bitblt_running.bytes_per_pixel == 3) {
pattern_pixel_addr = chips->bitblt_running.bitblt.pat_addr
+ (4 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7))
+ (3 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7));
pattern_pixel = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr
+ (4 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7))
+ (3 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)), chips);
pattern_pixel = chips->svga.vram[pattern_pixel_addr & chips->svga.vram_mask];
pattern_pixel |= chips->svga.vram[(pattern_pixel_addr + 1) & chips->svga.vram_mask] << 8;
pattern_pixel |= chips->svga.vram[(pattern_pixel_addr + 2) & chips->svga.vram_mask] << 16;
pattern_pixel |= chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr
+ (4 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7))
+ (3 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)) + 1, chips) << 8;
pattern_pixel |= chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr
+ (4 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7))
+ (3 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)) + 2, chips) << 16;
}
}
if (chips->bitblt_running.bytes_per_pixel == 2) {
@@ -1341,21 +1344,20 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel)
switch (chips->bitblt_running.bytes_per_pixel) {
case 1: /* 8 bits-per-pixel. */
{
chips->svga.vram[dest_addr & chips->svga.vram_mask] = dest_pixel & 0xFF;
//chips_69000_writeb_linear(dest_addr, dest_pixel & 0xFF, chips);
chips_69000_writeb_linear(dest_addr, dest_pixel & 0xFF, chips);
break;
}
case 2: /* 16 bits-per-pixel. */
{
chips->svga.vram[dest_addr & chips->svga.vram_mask] = dest_pixel & 0xFF;
chips->svga.vram[(dest_addr + 1) & chips->svga.vram_mask] = (dest_pixel >> 8) & 0xFF;
chips_69000_writeb_linear(dest_addr, dest_pixel & 0xFF, chips);
chips_69000_writeb_linear(dest_addr + 1, (dest_pixel >> 8) & 0xFF, chips);
break;
}
case 3: /* 24 bits-per-pixel. */
{
chips->svga.vram[dest_addr & chips->svga.vram_mask] = dest_pixel & 0xFF;
chips->svga.vram[(dest_addr + 1) & chips->svga.vram_mask] = (dest_pixel >> 8) & 0xFF;
chips->svga.vram[(dest_addr + 2) & chips->svga.vram_mask] = (dest_pixel >> 16) & 0xFF;
chips_69000_writeb_linear(dest_addr, dest_pixel & 0xFF, chips);
chips_69000_writeb_linear(dest_addr + 1, (dest_pixel >> 8) & 0xFF, chips);
chips_69000_writeb_linear(dest_addr + 2, (dest_pixel >> 16) & 0xFF, chips);
break;
}
}
@@ -1523,8 +1525,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips)
uint32_t orig_source_addr = chips->bitblt_running.bitblt.source_addr;
while (orig_count_y == chips->bitblt_running.count_y) {
int i = 0;
//uint8_t data = chips_69000_readb_linear(orig_source_addr, chips);
uint8_t data = chips->svga.vram[orig_source_addr & chips->svga.vram_mask];
uint8_t data = chips_69000_readb_linear(orig_source_addr, chips);
orig_source_addr++;
for (i = 0; i < 8; i++) {
chips_69000_process_mono_bit(chips, !!(data & (1 << (7 - i))));
@@ -1543,15 +1544,14 @@ chips_69000_setup_bitblt(chips_69000_t* chips)
case 1: /* Bit-aligned */
case 2: /* Byte-aligned */
{
//uint32_t data = chips_69000_readb_linear(source_addr, chips);
uint32_t data = chips->svga.vram[source_addr & chips->svga.vram_mask];
uint32_t data = chips_69000_readb_linear(source_addr, chips);
chips_69000_bitblt_write(chips, data & 0xFF);
source_addr += 1;
break;
}
case 3: /* Word-aligned*/
{
uint32_t data = chips->svga.vram[source_addr & chips->svga.vram_mask] | (chips->svga.vram[(source_addr + 1) & chips->svga.vram_mask] << 8);
uint32_t data = chips_69000_readw_linear(source_addr, chips);
chips_69000_bitblt_write(chips, data & 0xFF);
chips_69000_bitblt_write(chips, (data >> 8) & 0xFF);
source_addr += 2;
@@ -1559,8 +1559,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips)
}
case 4: /* Doubleword-aligned*/
{
uint32_t data = chips->svga.vram[source_addr & chips->svga.vram_mask] | (chips->svga.vram[(source_addr + 1) & chips->svga.vram_mask] << 8)
| (chips->svga.vram[(source_addr + 2) & chips->svga.vram_mask] << 16) | (chips->svga.vram[(source_addr + 3) & chips->svga.vram_mask] << 24);
uint32_t data = chips_69000_readl_linear(source_addr, chips);
chips_69000_bitblt_write(chips, data & 0xFF);
chips_69000_bitblt_write(chips, (data >> 8) & 0xFF);
chips_69000_bitblt_write(chips, (data >> 16) & 0xFF);
@@ -1570,15 +1569,7 @@ chips_69000_setup_bitblt(chips_69000_t* chips)
}
case 5: /* Quadword-aligned*/
{
uint64_t data = chips->svga.vram[source_addr & chips->svga.vram_mask]
| (chips->svga.vram[(source_addr + 1) & chips->svga.vram_mask] << 8)
| (chips->svga.vram[(source_addr + 2) & chips->svga.vram_mask] << 16)
| (chips->svga.vram[(source_addr + 3) & chips->svga.vram_mask] << 24)
| ((uint64_t)chips->svga.vram[(source_addr + 4) & chips->svga.vram_mask] << 32ULL)
| ((uint64_t)chips->svga.vram[(source_addr + 5) & chips->svga.vram_mask] << 40ULL)
| ((uint64_t)chips->svga.vram[(source_addr + 6) & chips->svga.vram_mask] << 48ULL)
| ((uint64_t)chips->svga.vram[(source_addr + 7) & chips->svga.vram_mask] << 56ULL);
//uint64_t data = (uint64_t)chips_69000_readl_linear(source_addr, chips) | ((uint64_t)chips_69000_readl_linear(source_addr + 4, chips) << 32ull);
uint64_t data = (uint64_t)chips_69000_readl_linear(source_addr, chips) | ((uint64_t)chips_69000_readl_linear(source_addr + 4, chips) << 32ull);
chips_69000_bitblt_write(chips, data & 0xFF);
chips_69000_bitblt_write(chips, (data >> 8) & 0xFF);
chips_69000_bitblt_write(chips, (data >> 16) & 0xFF);
@@ -1603,21 +1594,20 @@ chips_69000_setup_bitblt(chips_69000_t* chips)
switch (chips->bitblt_running.bytes_per_pixel) {
case 1: /* 8 bits-per-pixel. */
{
//pixel = chips_69000_readb_linear(source_addr, chips);
pixel = chips->svga.vram[source_addr & chips->svga.vram_mask];
pixel = chips_69000_readb_linear(source_addr, chips);
break;
}
case 2: /* 16 bits-per-pixel. */
{
pixel = chips->svga.vram[source_addr & chips->svga.vram_mask];
pixel |= chips->svga.vram[(source_addr + 1) & chips->svga.vram_mask] << 8;
pixel = chips_69000_readb_linear(source_addr, chips);
pixel |= chips_69000_readb_linear(source_addr + 1, chips) << 8;
break;
}
case 3: /* 24 bits-per-pixel. */
{
pixel = chips->svga.vram[source_addr & chips->svga.vram_mask];
pixel |= chips->svga.vram[(source_addr + 1) & chips->svga.vram_mask] << 8;
pixel |= chips->svga.vram[(source_addr + 2) & chips->svga.vram_mask] << 16;
pixel = chips_69000_readb_linear(source_addr, chips);
pixel |= chips_69000_readb_linear(source_addr + 1, chips) << 8;
pixel |= chips_69000_readb_linear(source_addr + 2, chips) << 16;
break;
}
}
@@ -2156,57 +2146,74 @@ static uint8_t
chips_69000_pci_read(UNUSED(int func), int addr, void *priv)
{
chips_69000_t *chips = (chips_69000_t *) priv;
uint8_t ret = 0x00;
{
switch (addr) {
case 0x00:
return 0x2C;
case 0x01:
return 0x10;
case 0x02:
return 0xC0;
case 0x03:
return 0x00;
case 0x04:
return (chips->pci_conf_status & 0b11100011) | 0x80;
case 0x06:
return 0x80;
case 0x07:
return 0x02;
case 0x08:
case 0x09:
case 0x0a:
return 0x00;
case 0x0b:
return 0x03;
case 0x13:
return chips->linear_mapping.base >> 24;
case 0x30:
return chips->pci_rom_enable & 0x1;
case 0x31:
return 0x0;
case 0x32:
return chips->rom_addr & 0xFF;
case 0x33:
return (chips->rom_addr & 0xFF00) >> 8;
case 0x3c:
return chips->pci_line_interrupt;
case 0x3d:
return 0x01;
case 0x2C:
case 0x2D:
case 0x6C:
case 0x6D:
return (chips->subsys_vid >> ((addr & 1) * 8)) & 0xFF;
case 0x2E:
case 0x2F:
case 0x6E:
case 0x6F:
return (chips->subsys_pid >> ((addr & 1) * 8)) & 0xFF;
default:
return 0x00;
}
switch (addr) {
case 0x00:
ret = 0x2c;
break;
case 0x01:
ret = 0x10;
break;
case 0x02:
ret = 0xc0;
break;
case 0x03:
ret = 0x00;
break;
case 0x04:
ret = (chips->pci_conf_status & 0x73) | 0x80;
break;
case 0x05:
ret = chips->pci_regs[addr] & 0x01;
break;
case 0x06:
ret = 0x80;
break;
case 0x07:
ret = chips->pci_regs[addr] | 0x02;
break;
case 0x0b:
ret = 0x03;
break;
case 0x13:
ret = chips->linear_mapping.base >> 24;
break;
case 0x2c ... 0x2d:
case 0x6c ... 0x6d:
ret = chips->subsys_vid_b[addr & 1];
break;
case 0x2e ... 0x2f:
case 0x6e ... 0x6f:
ret = chips->subsys_pid_b[addr & 1];
break;
case 0x30:
ret = chips->pci_rom_enable & 0x1;
break;
case 0x32:
ret = chips->rom_addr & 0xff;
break;
case 0x33:
ret = (chips->rom_addr & 0xff00) >> 8;
break;
case 0x3c:
ret = chips->pci_line_interrupt;
break;
case 0x3d:
ret = 0x01;
break;
default:
break;
}
return ret;
}
static void
@@ -2214,67 +2221,77 @@ chips_69000_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
{
chips_69000_t *chips = (chips_69000_t *) priv;
{
switch (addr) {
case 0x04:
{
chips->pci_conf_status = val;
io_removehandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips);
mem_mapping_disable(&chips->linear_mapping);
mem_mapping_disable(&chips->svga.mapping);
if (chips->pci_conf_status & PCI_COMMAND_IO) {
io_sethandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips);
}
if (chips->pci_conf_status & PCI_COMMAND_MEM) {
mem_mapping_enable(&chips->svga.mapping);
if (chips->linear_mapping.base)
mem_mapping_set_addr(&chips->linear_mapping, chips->linear_mapping.base, (1 << 24));
}
break;
}
case 0x13:
{
chips->linear_mapping.base = val << 24;
if (chips->linear_mapping.base)
mem_mapping_set_addr(&chips->linear_mapping, chips->linear_mapping.base, (1 << 24));
break;
}
case 0x3c:
chips->pci_line_interrupt = val;
break;
case 0x30:
if (chips->on_board) break;
switch (addr) {
case 0x04:
chips->pci_conf_status = val;
io_removehandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips);
mem_mapping_disable(&chips->linear_mapping);
mem_mapping_disable(&chips->svga.mapping);
if (!chips->on_board)
mem_mapping_disable(&chips->bios_rom.mapping);
if (val & PCI_COMMAND_IO)
io_sethandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips);
if (val & PCI_COMMAND_MEM) {
if (!chips->on_board && (chips->pci_rom_enable & 1))
mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x10000);
mem_mapping_enable(&chips->svga.mapping);
if (chips->linear_mapping.base > 0x00000000)
mem_mapping_set_addr(&chips->linear_mapping, chips->linear_mapping.base, (1 << 24));
}
break;
case 0x05:
chips->pci_regs[addr] = val & 0x01;
break;
case 0x07:
chips->pci_regs[addr] &= ~(val & 0xc8);
break;
case 0x13:
chips->linear_mapping.base = val << 24;
mem_mapping_disable(&chips->linear_mapping);
if ((chips->pci_conf_status & PCI_COMMAND_MEM) &&
(chips->linear_mapping.base > 0x00000000))
mem_mapping_set_addr(&chips->linear_mapping, chips->linear_mapping.base, (1 << 24));
break;
case 0x30:
if (!chips->on_board) {
chips->pci_rom_enable = val & 0x1;
mem_mapping_disable(&chips->bios_rom.mapping);
if (chips->pci_rom_enable & 1) {
if ((chips->pci_conf_status & PCI_COMMAND_MEM) &&
(chips->pci_rom_enable & 1))
mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x10000);
}
break;
case 0x32:
if (chips->on_board) break;
chips->rom_addr &= ~0xFF;
chips->rom_addr |= val & 0xFC;
if (chips->pci_rom_enable & 1) {
}
break;
case 0x32:
if (!chips->on_board) {
chips->rom_addr &= ~0xff;
chips->rom_addr |= val & 0xfc;
if ((chips->pci_conf_status & PCI_COMMAND_MEM) &&
(chips->pci_rom_enable & 1))
mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x10000);
}
break;
case 0x33:
if (chips->on_board) break;
chips->rom_addr &= ~0xFF00;
}
break;
case 0x33:
if (!chips->on_board) {
chips->rom_addr &= ~0xff00;
chips->rom_addr |= (val << 8);
if (chips->pci_rom_enable & 1) {
if ((chips->pci_conf_status & PCI_COMMAND_MEM) &&
(chips->pci_rom_enable & 1))
mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x10000);
}
break;
case 0x6C:
case 0x6D:
chips->subsys_vid_b[addr & 1] = val;
break;
case 0x6E:
case 0x6F:
chips->subsys_pid_b[addr & 1] = val;
break;
}
}
break;
case 0x3c:
chips->pci_line_interrupt = val;
break;
case 0x6c ... 0x6d:
chips->subsys_vid_b[addr & 1] = val;
break;
case 0x6e ... 0x6f:
chips->subsys_pid_b[addr & 1] = val;
break;
}
}
@@ -2399,7 +2416,7 @@ chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips)
{
chips->mem_regs_b[addr & 0xF] = val;
chips->mem_regs[(addr >> 2) & 0x3] &= 0x80004040;
if (addr == 0x605 || addr == 0x607)
if (addr == 0x601 || addr == 0x603)
chips_69000_interrupt(chips);
break;
}
@@ -2718,7 +2735,7 @@ chips_69000_getclock(int clock, void *priv)
int pl = ((chips->ext_regs[0xcb] >> 4) & 7);
float fvco = 14318181.0 * ((float)(m + 2) / (float)(n + 2));
if (chips->ext_regs[0xcb] & 4)
if (!(chips->ext_regs[0xcb] & 4))
fvco *= 4.0;
float fo = fvco / (float)(1 << pl);
@@ -2818,7 +2835,7 @@ chips_69000_init(const device_t *info)
chips->svga.bpp = 8;
chips->svga.miscout = 1;
chips->svga.vblank_start = chips_69000_vblank_start;
chips->svga.vsync_callback = chips_69000_vblank_start;
chips->svga.getclock = chips_69000_getclock;
chips->svga.conv_16to32 = chips_69000_conv_16to32;
chips->svga.line_compare = chips_69000_line_compare;
@@ -2839,6 +2856,18 @@ chips_69000_init(const device_t *info)
chips->flat_panel_regs[0x01] = 1;
chips->pci_conf_status = 0x00;
chips->pci_rom_enable = 0x00;
chips->rom_addr = 0x0000;
chips->subsys_vid = 0x102c;
chips->subsys_pid = 0x00c0;
io_removehandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips);
mem_mapping_disable(&chips->linear_mapping);
mem_mapping_disable(&chips->svga.mapping);
if (!chips->on_board)
mem_mapping_disable(&chips->bios_rom.mapping);
*reset_state = *chips;
return chips;