mirror of
https://github.com/86Box/86Box.git
synced 2026-02-28 01:44:22 -07:00
Merge branch '86Box:master' into master
This commit is contained in:
@@ -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*/
|
||||
|
||||
@@ -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*/
|
||||
|
||||
@@ -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*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
244
src/cpu/cpu.c
244
src/cpu/cpu.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
116
src/disk/mo.c
116
src/disk/mo.c
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 *);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
16
src/io.c
16
src/io.c
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user