Merge remote-tracking branch 'upstream/master' into version/4.1

This commit is contained in:
Jasmine Iwanek
2023-08-21 23:04:03 -04:00
76 changed files with 821 additions and 468 deletions

View File

@@ -247,17 +247,28 @@ viso_convert_utf8(wchar_t *dest, const char *src, ssize_t buf_size)
c -= 'a' - 'A'; \
break; \
\
case ' ': \
case '!': \
case '"': \
case '#': \
case '$': \
case '%': \
case '&': \
case '\'': \
case '(': \
case ')': \
case '-': \
case '@': \
case '^': \
case '`': \
case '{': \
case '}': \
case '~': \
/* Valid on all sets (non-complying DOS characters). */ \
break; \
\
case ' ': \
case '"': \
case '+': \
case ',': \
case '-': \
case '.': \
case '<': \
case '=': \

View File

@@ -9,6 +9,8 @@
#include "x86.h"
#include "x86_ops.h"
#include "x86_flags.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "x87.h"
#include "386_common.h"
#include "cpu.h"

View File

@@ -11,6 +11,8 @@
# include "x86.h"
# include "x86_flags.h"
# include "x86_ops.h"
# include "x86seg_common.h"
# include "x86seg.h"
# include "x87.h"
# include <86box/mem.h>

View File

@@ -49,6 +49,8 @@
# include "x86.h"
# include "x86_flags.h"
# include "x86_ops.h"
# include "x86seg_common.h"
# include "x86seg.h"
# include "x87.h"
/*ex*/
# include <86box/nmi.h>

View File

@@ -6,6 +6,8 @@
#include "x86_ops.h"
#include "codegen.h"
#include "x86.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"

View File

@@ -13,6 +13,8 @@
# include "codegen_backend_arm_ops.h"
# include "codegen_reg.h"
# include "x86.h"
# include "x86seg_common.h"
# include "x86seg.h"
# include "x87.h"
# if defined(__linux__) || defined(__APPLE__)

View File

@@ -13,6 +13,8 @@
# include "codegen_backend_arm64_ops.h"
# include "codegen_reg.h"
# include "x86.h"
# include "x86seg_common.h"
# include "x86seg.h"
# include "x87.h"
# if defined(__linux__) || defined(__APPLE__)

View File

@@ -6,6 +6,8 @@
# include <86box/mem.h>
# include "x86.h"
# include "x86seg_common.h"
# include "x86seg.h"
# include "x87.h"
# include "386_common.h"
# include "codegen.h"

View File

@@ -7,6 +7,8 @@
# include <86box/mem.h>
# include "x86.h"
# include "x86seg_common.h"
# include "x86seg.h"
# include "x87.h"
# include "386_common.h"
# include "codegen.h"

View File

@@ -14,6 +14,8 @@
# include "codegen_backend_x86-64_ops_sse.h"
# include "codegen_reg.h"
# include "x86.h"
# include "x86seg_common.h"
# include "x86seg.h"
# if defined(__linux__) || defined(__APPLE__)
# include <sys/mman.h>

View File

@@ -6,6 +6,8 @@
# include <86box/mem.h>
# include "x86.h"
# include "x86seg_common.h"
# include "x86seg.h"
# include "x87.h"
# include "386_common.h"
# include "codegen.h"

View File

@@ -15,6 +15,8 @@
# include "codegen_backend_x86_ops_sse.h"
# include "codegen_reg.h"
# include "x86.h"
# include "x86seg_common.h"
# include "x86seg.h"
# if defined(__linux__) || defined(__APPLE__)
# include <sys/mman.h>

View File

@@ -7,6 +7,8 @@
# include "x86.h"
# include "x86_ops.h"
# include "x86seg_common.h"
# include "x86seg.h"
# include "386_common.h"
# include "codegen.h"
# include "codegen_allocator.h"

View File

@@ -9,6 +9,8 @@
#include "x86.h"
#include "x86_flags.h"
#include "x86_ops.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "x87.h"
#include "386_common.h"

View File

@@ -5,6 +5,8 @@
#include "x86.h"
#include "x86_flags.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"
#include "codegen.h"
#include "codegen_accumulate.h"

View File

@@ -5,6 +5,8 @@
#include "x86.h"
#include "x86_flags.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"
#include "codegen.h"
#include "codegen_ir.h"

View File

@@ -4,6 +4,8 @@
#include <86box/mem.h>
#include "x86.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"
#include "x86_flags.h"
#include "codegen.h"

View File

@@ -5,6 +5,8 @@
#include "x86.h"
#include "x86_flags.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"
#include "x87.h"
#include "codegen.h"

View File

@@ -5,6 +5,8 @@
#include "x86.h"
#include "x86_flags.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"
#include "x87.h"
#include "codegen.h"

View File

@@ -5,6 +5,8 @@
#include "x86.h"
#include "x86_flags.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"
#include "x87.h"
#include "codegen.h"

View File

@@ -5,6 +5,8 @@
#include "x86.h"
#include "x86_flags.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"
#include "x87.h"
#include "codegen.h"

View File

@@ -4,6 +4,8 @@
#include <86box/mem.h>
#include "x86.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"
#include "codegen.h"
#include "codegen_ir.h"

View File

@@ -4,6 +4,8 @@
#include <86box/mem.h>
#include "x86.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"
#include "codegen.h"
#include "codegen_ir.h"

View File

@@ -5,6 +5,8 @@
#include "x86.h"
#include "x86_flags.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"
#include "codegen.h"
#include "codegen_ir.h"

View File

@@ -5,6 +5,8 @@
#include "x86.h"
#include "x86_flags.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"
#include "codegen.h"
#include "codegen_ir.h"

View File

@@ -5,6 +5,8 @@
#include "x86.h"
#include "x86_flags.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"
#include "codegen.h"
#include "codegen_accumulate.h"

View File

@@ -5,6 +5,8 @@
#include "x86.h"
#include "x86_flags.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"
#include "codegen.h"
#include "codegen_accumulate.h"

View File

@@ -5,6 +5,8 @@
#include "x86.h"
#include "x86_flags.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"
#include "codegen.h"
#include "codegen_accumulate.h"

View File

@@ -5,6 +5,8 @@
#include "x86.h"
#include "x86_flags.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"
#include "codegen.h"
#include "codegen_accumulate.h"

View File

@@ -5,6 +5,8 @@
#include "x86.h"
#include "x86_flags.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"
#include "codegen.h"
#include "codegen_accumulate.h"

View File

@@ -5,6 +5,8 @@
#include "x86.h"
#include "x86_flags.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"
#include "codegen.h"
#include "codegen_accumulate.h"

View File

@@ -4,6 +4,8 @@
#include <86box/mem.h>
#include "x86.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"
#include "codegen.h"
#include "codegen_ir.h"

View File

@@ -4,6 +4,8 @@
#include <86box/mem.h>
#include "x86.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "x86_flags.h"
#include "386_common.h"
#include "codegen.h"

View File

@@ -4,6 +4,8 @@
#include <86box/mem.h>
#include "x86.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "x86_flags.h"
#include "386_common.h"
#include "codegen.h"

View File

@@ -14,6 +14,7 @@
#include "cpu.h"
#include "x86.h"
#include "x86_ops.h"
#include "x86seg_common.h"
#include "x87.h"
#include <86box/io.h>
#include <86box/nmi.h>
@@ -28,6 +29,7 @@
#ifndef OPS_286_386
# define OPS_286_386
#endif
#include "x86seg.h"
#include "386_common.h"
#ifdef USE_NEW_DYNAREC
# include "codegen.h"
@@ -291,7 +293,7 @@ exec386_2386(int cycs)
flags_rebuild();
tempi = cpu_state.abrt & ABRT_MASK;
cpu_state.abrt = 0;
x86_doabrt(tempi);
x86_doabrt_2386(tempi);
if (cpu_state.abrt) {
cpu_state.abrt = 0;
#ifndef USE_NEW_DYNAREC
@@ -299,7 +301,7 @@ exec386_2386(int cycs)
#endif
cpu_state.pc = cpu_state.oldpc;
x386_log("Double fault\n");
pmodeint(8, 0);
pmodeint_2386(8, 0);
if (cpu_state.abrt) {
cpu_state.abrt = 0;
softresetx86();
@@ -342,7 +344,7 @@ exec386_2386(int cycs)
if (vector != -1) {
flags_rebuild();
if (msw & 1)
pmodeint(vector, 0);
pmodeint_2386(vector, 0);
else {
writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags);
writememw(ss, (SP - 4) & 0xFFFF, CS);
@@ -352,7 +354,7 @@ exec386_2386(int cycs)
cpu_state.flags &= ~I_FLAG;
cpu_state.flags &= ~T_FLAG;
cpu_state.pc = readmemw(0, addr);
loadcs(readmemw(0, addr + 2));
loadcs_2386(readmemw(0, addr + 2));
}
}
}

View File

@@ -13,6 +13,7 @@
#include "cpu.h"
#include <86box/timer.h>
#include "x86.h"
#include "x86seg_common.h"
#include "x87.h"
#include <86box/nmi.h>
#include <86box/mem.h>
@@ -23,9 +24,10 @@
#include <86box/fdc.h>
#include <86box/keyboard.h>
#include <86box/timer.h>
#include "x86seg.h"
#include "386_common.h"
#include "x86_flags.h"
#include "x86seg.h"
#include <86box/plat_unused.h>
#ifdef USE_DYNAREC
@@ -1184,7 +1186,10 @@ enter_smm(int in_hlt)
if (is_cxsmm) {
cpu_state.pc = 0x0000;
cpl_override = 1;
cyrix_write_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs);
if (is486)
cyrix_write_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs);
else
cyrix_write_seg_descriptor_2386(smram_state - 0x20, &cpu_state.seg_cs);
cpl_override = 0;
cpu_state.seg_cs.seg = (cyrix.arr[3].base >> 4);
cpu_state.seg_cs.base = cyrix.arr[3].base;
@@ -1317,7 +1322,10 @@ leave_smm(void)
saved_state[3] = readmeml(0, smram_state - 0x10);
saved_state[4] = readmeml(0, smram_state - 0x14);
saved_state[5] = readmeml(0, smram_state - 0x18);
cyrix_load_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs);
if (is486)
cyrix_load_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs);
else
cyrix_load_seg_descriptor_2386(smram_state - 0x20, &cpu_state.seg_cs);
saved_state[6] = readmeml(0, smram_state - 0x24);
} else {
for (uint8_t n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) {
@@ -1403,7 +1411,7 @@ x86_int(int num)
cpu_state.pc = cpu_state.oldpc;
if (msw & 1)
pmodeint(num, 0);
is486 ? pmodeint(num, 0) : pmodeint_2386(num, 0);
else {
addr = (num << 2) + idt.base;
@@ -1436,7 +1444,7 @@ x86_int(int num)
oxpc = cpu_state.pc;
#endif
cpu_state.pc = readmemw(0, addr);
loadcs(readmemw(0, addr + 2));
is486 ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2));
}
}
@@ -1453,7 +1461,7 @@ x86_int_sw(int num)
cycles -= timing_int;
if (msw & 1)
pmodeint(num, 1);
is486 ? pmodeint(num, 1) : pmodeint_2386(num, 1);
else {
addr = (num << 2) + idt.base;
@@ -1478,7 +1486,7 @@ x86_int_sw(int num)
oxpc = cpu_state.pc;
#endif
cpu_state.pc = readmemw(0, addr);
loadcs(readmemw(0, addr + 2));
is486 ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2));
cycles -= timing_int_rm;
}
}
@@ -1520,7 +1528,7 @@ x86_int_sw_rm(int num)
cpu_state.eflags &= ~VIF_FLAG;
cpu_state.flags &= ~T_FLAG;
cpu_state.pc = new_pc;
loadcs(new_cs);
is486 ? loadcs(new_cs) : loadcs_2386(new_cs);
#ifndef USE_NEW_DYNAREC
oxpc = cpu_state.pc;
#endif

View File

@@ -17,6 +17,8 @@
#include "cpu.h"
#include "x86.h"
#include "x86_ops.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "x87.h"
#include <86box/io.h>
#include <86box/mem.h>

View File

@@ -13,6 +13,8 @@
#include <86box/timer.h>
#include "x86.h"
#include "x86_ops.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "x87.h"
#include "x86_flags.h"
#include <86box/io.h>

View File

@@ -173,7 +173,6 @@ extern void x386_dynarec_log(const char *fmt, ...);
# endif
#endif
#include "x86seg.h"
#include "x86_ops_arith.h"
#include "x86_ops_atomic.h"
#include "x86_ops_bcd.h"

View File

@@ -14,7 +14,8 @@
#
add_library(cpu OBJECT cpu.c cpu_table.c fpu.c x86.c 808x.c 386.c 386_common.c
386_dynarec.c x86_ops_mmx.c x86seg.c x87.c x87_timings.c 8080.c)
386_dynarec.c x86_ops_mmx.c x86seg_common.c x86seg.c x86seg_2386.c x87.c
x87_timings.c 8080.c)
if(AMD_K5)
target_compile_definitions(cpu PRIVATE USE_AMD_K5)

View File

@@ -11,6 +11,7 @@
#include "x86.h"
#include "x86_ops.h"
#include "x86seg_common.h"
#include "x87.h"
#include "386_common.h"
#include "codegen.h"

View File

@@ -12,6 +12,7 @@
#include "x86.h"
#include "x86_ops.h"
#include "x86seg_common.h"
#include "x87.h"
#include "386_common.h"
#include "codegen.h"

View File

@@ -33,6 +33,7 @@
#include <86box/machine.h>
#include <86box/io.h>
#include "x86_ops.h"
#include "x86seg_common.h"
#include <86box/mem.h>
#include <86box/nmi.h>
#include <86box/pic.h>

View File

@@ -590,7 +590,6 @@ extern uint64_t cpu_CR4_mask;
extern uint64_t tsc;
extern msr_t msr;
extern uint8_t opcode;
extern int cgate16;
extern int cpl_override;
extern int CPUID;
extern uint64_t xt_cpu_multi;
@@ -721,15 +720,6 @@ extern uint32_t cpu_fast_off_flags;
/* Functions. */
extern int cpu_has_feature(int feature);
#ifdef USE_NEW_DYNAREC
extern void loadseg_dynarec(uint16_t seg, x86seg *s);
extern int loadseg(uint16_t seg, x86seg *s);
extern void loadcs(uint16_t seg);
#else
extern void loadseg(uint16_t seg, x86seg *s);
extern void loadcs(uint16_t seg);
#endif
extern char *cpu_current_pc(char *bufp);
extern void cpu_update_waitstates(void);
@@ -757,19 +747,6 @@ extern void exec386_2386(int cycs);
extern void exec386(int cycs);
extern void exec386_dynarec(int cycs);
extern int idivl(int32_t val);
#ifdef USE_NEW_DYNAREC
extern void loadcscall(uint16_t seg, uint32_t old_pc);
extern void loadcsjmp(uint16_t seg, uint32_t old_pc);
extern void pmodeint(int num, int soft);
extern void pmoderetf(int is32, uint16_t off);
extern void pmodeiret(int is32);
#else
extern void loadcscall(uint16_t seg);
extern void loadcsjmp(uint16_t seg, uint32_t old_pc);
extern void pmodeint(int num, int soft);
extern void pmoderetf(int is32, uint16_t off);
extern void pmodeiret(int is32);
#endif
extern void resetmcr(void);
extern void resetx86(void);
extern void refreshread(void);
@@ -779,11 +756,6 @@ extern void hardresetx86(void);
extern void x86_int(int num);
extern void x86_int_sw(int num);
extern int x86_int_sw_rm(int num);
extern void x86de(char *s, uint16_t error);
extern void x86gpf(char *s, uint16_t error);
extern void x86np(char *s, uint16_t error);
extern void x86ss(char *s, uint16_t error);
extern void x86ts(char *s, uint16_t error);
#ifdef ENABLE_808X_LOG
extern void dumpregs(int __force);

View File

@@ -378,7 +378,7 @@ const cpu_family_t cpu_families[] = {
}, {
.package = CPU_PKG_SOCKET1,
.manufacturer = "Intel",
.name = "i486SX (SL-Enhanced)",
.name = "i486SX-S",
.internal_name = "i486sx_slenh",
.cpus = (const CPU[]) {
{"25", CPU_i486SX_SLENH, fpus_486sx, 25000000, 1, 5000, 0x423, 0x423, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
@@ -409,7 +409,7 @@ const cpu_family_t cpu_families[] = {
}, {
.package = CPU_PKG_SOCKET1,
.manufacturer = "Intel",
.name = "i486DX (SL-Enhanced)",
.name = "i486DX-S",
.internal_name = "i486dx_slenh",
.cpus = (const CPU[]) {
{"33", CPU_i486DX_SLENH, fpus_internal, 33333333, 1, 5000, 0x414, 0x414, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4},
@@ -430,7 +430,7 @@ const cpu_family_t cpu_families[] = {
}, {
.package = CPU_PKG_SOCKET1,
.manufacturer = "Intel",
.name = "i486DX2 (SL-Enhanced)",
.name = "i486DX2-S",
.internal_name = "i486dx2_slenh",
.cpus = (const CPU[]) {
{"40", CPU_i486DX_SLENH, fpus_internal, 40000000, 2, 5000, 0x435, 0x435, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5},

View File

@@ -25,6 +25,8 @@
#include <86box/86box.h>
#include "cpu.h"
#include "x86.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include <86box/machine.h>
#include <86box/device.h>
#include <86box/dma.h>
@@ -270,7 +272,10 @@ reset_common(int hard)
cpu_state.eflags = 0;
cgate32 = 0;
if (is286) {
loadcs(0xF000);
if (is486)
loadcs(0xF000);
else
loadcs_2386(0xF000);
cpu_state.pc = 0xFFF0;
if (hard) {
rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF;

View File

@@ -1,3 +1,26 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Second CPU header.
*
*
*
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
* leilei,
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2020 Sarah Walker.
* Copyright 2016-2018 leilei.
* Copyright 2016-2020 Miran Grca.
*/
#ifndef EMU_X86_H
#define EMU_X86_H
#define ABRT_MASK 0x3f
/*An 'expected' exception is one that would be expected to occur on every execution
of this code path; eg a GPF due to being in v86 mode. An 'unexpected' exception is
@@ -10,7 +33,7 @@
#define ABRT_EXPECTED 0x80
extern uint8_t opcode;
extern uint8_t opcode2;
extern uint8_t flags_p;
extern uint8_t znptable8[256];
@@ -31,7 +54,6 @@ extern int trap;
extern int optype;
extern int stack32;
extern int oldcpl;
extern int cgate32;
extern int cpl_override;
extern int nmi_enable;
extern int oddeven;
@@ -75,24 +97,6 @@ extern uint32_t *eal_w;
fetcheal(); \
}
#define JMP 1
#define CALL 2
#define IRET 3
#define OPTYPE_INT 4
enum {
ABRT_NONE = 0,
ABRT_GEN = 1,
ABRT_TS = 0xA,
ABRT_NP = 0xB,
ABRT_SS = 0xC,
ABRT_GPF = 0xD,
ABRT_PF = 0xE,
ABRT_DE = 0x40 /* INT 0, but we have to distinguish it from ABRT_NONE. */
};
extern void x86_doabrt(int x86_abrt);
extern void x86illegal(void);
extern void x86seg_reset(void);
extern void x86gpf(char *s, uint16_t error);
extern void x86gpf_expected(char *s, uint16_t error);
#endif /*EMU_X86_H*/

View File

@@ -6,9 +6,9 @@
optype = CALL; \
cgate16 = cgate32 = 0; \
if (msw & 1) \
loadcscall(new_seg, old_pc); \
op_loadcscall(new_seg, old_pc); \
else { \
loadcs(new_seg); \
op_loadcs(new_seg); \
cycles -= timing_call_rm; \
} \
optype = 0; \
@@ -54,9 +54,9 @@
optype = CALL; \
cgate16 = cgate32 = 0; \
if (msw & 1) \
loadcscall(new_seg, old_pc); \
op_loadcscall(new_seg, old_pc); \
else { \
loadcs(new_seg); \
op_loadcs(new_seg); \
cycles -= timing_call_rm; \
} \
optype = 0; \
@@ -103,9 +103,9 @@
optype = CALL; \
cgate16 = cgate32 = 0; \
if (msw & 1) \
loadcscall(new_seg); \
op_loadcscall(new_seg); \
else { \
loadcs(new_seg); \
op_loadcs(new_seg); \
cycles -= timing_call_rm; \
} \
optype = 0; \
@@ -148,9 +148,9 @@
optype = CALL; \
cgate16 = cgate32 = 0; \
if (msw & 1) \
loadcscall(new_seg); \
op_loadcscall(new_seg); \
else { \
loadcs(new_seg); \
op_loadcs(new_seg); \
cycles -= timing_call_rm; \
} \
optype = 0; \
@@ -362,14 +362,12 @@ opFF_w_a16(uint32_t fetchdat)
return 1;
cpu_state.pc = new_pc;
#ifdef USE_NEW_DYNAREC
loadcsjmp(new_cs, old_pc);
if (cpu_state.abrt)
return 1;
op_loadcsjmp(new_cs, old_pc);
#else
loadcsjmp(new_cs, oxpc);
op_loadcsjmp(new_cs, oxpc);
#endif
if (cpu_state.abrt)
return 1;
#endif
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 2, 0, 0, 0, 0);
PREFETCH_FLUSH();
@@ -526,14 +524,12 @@ opFF_w_a32(uint32_t fetchdat)
return 1;
cpu_state.pc = new_pc;
#ifdef USE_NEW_DYNAREC
loadcsjmp(new_cs, old_pc);
if (cpu_state.abrt)
return 1;
op_loadcsjmp(new_cs, old_pc);
#else
loadcsjmp(new_cs, oxpc);
op_loadcsjmp(new_cs, oxpc);
#endif
if (cpu_state.abrt)
return 1;
#endif
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 2, 0, 0, 0, 1);
PREFETCH_FLUSH();
@@ -691,14 +687,12 @@ opFF_l_a16(uint32_t fetchdat)
return 1;
cpu_state.pc = new_pc;
#ifdef USE_NEW_DYNAREC
loadcsjmp(new_cs, old_pc);
if (cpu_state.abrt)
return 1;
op_loadcsjmp(new_cs, old_pc);
#else
loadcsjmp(new_cs, oxpc);
op_loadcsjmp(new_cs, oxpc);
#endif
if (cpu_state.abrt)
return 1;
#endif
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 1, 0, 0, 0);
PREFETCH_FLUSH();
@@ -857,14 +851,12 @@ opFF_l_a32(uint32_t fetchdat)
return 1;
cpu_state.pc = new_pc;
#ifdef USE_NEW_DYNAREC
loadcsjmp(new_cs, old_pc);
if (cpu_state.abrt)
return 1;
op_loadcsjmp(new_cs, old_pc);
#else
loadcsjmp(new_cs, oxpc);
op_loadcsjmp(new_cs, oxpc);
#endif
if (cpu_state.abrt)
return 1;
#endif
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 1, 0, 0, 1);
PREFETCH_FLUSH();

View File

@@ -282,7 +282,7 @@ opJMP_far_a16(uint32_t fetchdat)
return 1;
old_pc = cpu_state.pc;
cpu_state.pc = addr;
loadcsjmp(seg, old_pc);
op_loadcsjmp(seg, old_pc);
CPU_BLOCK_END();
PREFETCH_RUN(11, 5, -1, 0, 0, 0, 0, 0);
PREFETCH_FLUSH();
@@ -301,7 +301,7 @@ opJMP_far_a32(uint32_t fetchdat)
return 1;
old_pc = cpu_state.pc;
cpu_state.pc = addr;
loadcsjmp(seg, old_pc);
op_loadcsjmp(seg, old_pc);
CPU_BLOCK_END();
PREFETCH_RUN(11, 7, -1, 0, 0, 0, 0, 0);
PREFETCH_FLUSH();

View File

@@ -23,9 +23,10 @@
#include <86box/fdc.h>
#include <86box/keyboard.h>
#include <86box/timer.h>
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"
#include "x86_flags.h"
#include "x86seg.h"
MMX_REG *MMP[8];
uint16_t *MMEP[8];

View File

@@ -178,13 +178,13 @@ opMOV_seg_w_a16(uint32_t fetchdat)
switch (rmdat & 0x38) {
case 0x00: /*ES*/
loadseg(new_seg, &cpu_state.seg_es);
op_loadseg(new_seg, &cpu_state.seg_es);
break;
case 0x18: /*DS*/
loadseg(new_seg, &cpu_state.seg_ds);
op_loadseg(new_seg, &cpu_state.seg_ds);
break;
case 0x10: /*SS*/
loadseg(new_seg, &cpu_state.seg_ss);
op_loadseg(new_seg, &cpu_state.seg_ss);
if (cpu_state.abrt)
return 1;
cpu_state.oldpc = cpu_state.pc;
@@ -198,10 +198,10 @@ opMOV_seg_w_a16(uint32_t fetchdat)
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return 1;
case 0x20: /*FS*/
loadseg(new_seg, &cpu_state.seg_fs);
op_loadseg(new_seg, &cpu_state.seg_fs);
break;
case 0x28: /*GS*/
loadseg(new_seg, &cpu_state.seg_gs);
op_loadseg(new_seg, &cpu_state.seg_gs);
break;
}
@@ -223,13 +223,13 @@ opMOV_seg_w_a32(uint32_t fetchdat)
switch (rmdat & 0x38) {
case 0x00: /*ES*/
loadseg(new_seg, &cpu_state.seg_es);
op_loadseg(new_seg, &cpu_state.seg_es);
break;
case 0x18: /*DS*/
loadseg(new_seg, &cpu_state.seg_ds);
op_loadseg(new_seg, &cpu_state.seg_ds);
break;
case 0x10: /*SS*/
loadseg(new_seg, &cpu_state.seg_ss);
op_loadseg(new_seg, &cpu_state.seg_ss);
if (cpu_state.abrt)
return 1;
cpu_state.oldpc = cpu_state.pc;
@@ -243,10 +243,10 @@ opMOV_seg_w_a32(uint32_t fetchdat)
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
return 1;
case 0x20: /*FS*/
loadseg(new_seg, &cpu_state.seg_fs);
op_loadseg(new_seg, &cpu_state.seg_fs);
break;
case 0x28: /*GS*/
loadseg(new_seg, &cpu_state.seg_gs);
op_loadseg(new_seg, &cpu_state.seg_gs);
break;
}
@@ -269,7 +269,7 @@ opLDS_w_a16(uint32_t fetchdat)
seg = readmemw(easeg, cpu_state.eaaddr + 2);
if (cpu_state.abrt)
return 1;
loadseg(seg, &cpu_state.seg_ds);
op_loadseg(seg, &cpu_state.seg_ds);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = addr;
@@ -292,7 +292,7 @@ opLDS_w_a32(uint32_t fetchdat)
seg = readmemw(easeg, cpu_state.eaaddr + 2);
if (cpu_state.abrt)
return 1;
loadseg(seg, &cpu_state.seg_ds);
op_loadseg(seg, &cpu_state.seg_ds);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = addr;
@@ -315,7 +315,7 @@ opLDS_l_a16(uint32_t fetchdat)
seg = readmemw(easeg, cpu_state.eaaddr + 4);
if (cpu_state.abrt)
return 1;
loadseg(seg, &cpu_state.seg_ds);
op_loadseg(seg, &cpu_state.seg_ds);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = addr;
@@ -338,7 +338,7 @@ opLDS_l_a32(uint32_t fetchdat)
seg = readmemw(easeg, cpu_state.eaaddr + 4);
if (cpu_state.abrt)
return 1;
loadseg(seg, &cpu_state.seg_ds);
op_loadseg(seg, &cpu_state.seg_ds);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = addr;
@@ -362,7 +362,7 @@ opLSS_w_a16(uint32_t fetchdat)
seg = readmemw(easeg, cpu_state.eaaddr + 2);
if (cpu_state.abrt)
return 1;
loadseg(seg, &cpu_state.seg_ss);
op_loadseg(seg, &cpu_state.seg_ss);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = addr;
@@ -385,7 +385,7 @@ opLSS_w_a32(uint32_t fetchdat)
seg = readmemw(easeg, cpu_state.eaaddr + 2);
if (cpu_state.abrt)
return 1;
loadseg(seg, &cpu_state.seg_ss);
op_loadseg(seg, &cpu_state.seg_ss);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].w = addr;
@@ -408,7 +408,7 @@ opLSS_l_a16(uint32_t fetchdat)
seg = readmemw(easeg, cpu_state.eaaddr + 4);
if (cpu_state.abrt)
return 1;
loadseg(seg, &cpu_state.seg_ss);
op_loadseg(seg, &cpu_state.seg_ss);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = addr;
@@ -431,7 +431,7 @@ opLSS_l_a32(uint32_t fetchdat)
seg = readmemw(easeg, cpu_state.eaaddr + 4);
if (cpu_state.abrt)
return 1;
loadseg(seg, &cpu_state.seg_ss);
op_loadseg(seg, &cpu_state.seg_ss);
if (cpu_state.abrt)
return 1;
cpu_state.regs[cpu_reg].l = addr;
@@ -454,7 +454,7 @@ opLSS_l_a32(uint32_t fetchdat)
seg = readmemw(easeg, cpu_state.eaaddr + 2); \
if (cpu_state.abrt) \
return 1; \
loadseg(seg, &sel); \
op_loadseg(seg, &sel); \
if (cpu_state.abrt) \
return 1; \
cpu_state.regs[cpu_reg].w = addr; \
@@ -476,7 +476,7 @@ opLSS_l_a32(uint32_t fetchdat)
seg = readmemw(easeg, cpu_state.eaaddr + 2); \
if (cpu_state.abrt) \
return 1; \
loadseg(seg, &sel); \
op_loadseg(seg, &sel); \
if (cpu_state.abrt) \
return 1; \
cpu_state.regs[cpu_reg].w = addr; \
@@ -499,7 +499,7 @@ opLSS_l_a32(uint32_t fetchdat)
seg = readmemw(easeg, cpu_state.eaaddr + 4); \
if (cpu_state.abrt) \
return 1; \
loadseg(seg, &sel); \
op_loadseg(seg, &sel); \
if (cpu_state.abrt) \
return 1; \
cpu_state.regs[cpu_reg].l = addr; \
@@ -522,7 +522,7 @@ opLSS_l_a32(uint32_t fetchdat)
seg = readmemw(easeg, cpu_state.eaaddr + 4); \
if (cpu_state.abrt) \
return 1; \
loadseg(seg, &sel); \
op_loadseg(seg, &sel); \
if (cpu_state.abrt) \
return 1; \
cpu_state.regs[cpu_reg].l = addr; \

View File

@@ -6,16 +6,16 @@
#define RETF_a16(stack_offset) \
if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \
pmoderetf(0, stack_offset); \
op_pmoderetf(0, stack_offset); \
return 1; \
} \
CPU_SET_OXPC \
if (stack32) { \
cpu_state.pc = readmemw(ss, ESP); \
loadcs(readmemw(ss, ESP + 2)); \
op_loadcs(readmemw(ss, ESP + 2)); \
} else { \
cpu_state.pc = readmemw(ss, SP); \
loadcs(readmemw(ss, SP + 2)); \
op_loadcs(readmemw(ss, SP + 2)); \
} \
if (cpu_state.abrt) \
return 1; \
@@ -27,16 +27,16 @@
#define RETF_a32(stack_offset) \
if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \
pmoderetf(1, stack_offset); \
op_pmoderetf(1, stack_offset); \
return 1; \
} \
CPU_SET_OXPC \
if (stack32) { \
cpu_state.pc = readmeml(ss, ESP); \
loadcs(readmeml(ss, ESP + 4) & 0xffff); \
op_loadcs(readmeml(ss, ESP + 4) & 0xffff); \
} else { \
cpu_state.pc = readmeml(ss, SP); \
loadcs(readmeml(ss, SP + 4) & 0xffff); \
op_loadcs(readmeml(ss, SP + 4) & 0xffff); \
} \
if (cpu_state.abrt) \
return 1; \
@@ -114,7 +114,7 @@ opIRET_186(uint32_t fetchdat)
}
if (msw & 1) {
optype = IRET;
pmodeiret(0);
op_pmodeiret(0);
optype = 0;
} else {
uint16_t new_cs;
@@ -130,7 +130,7 @@ opIRET_186(uint32_t fetchdat)
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2;
SP += 6;
}
loadcs(new_cs);
op_loadcs(new_cs);
cycles -= timing_iret_rm;
}
flags_extract();
@@ -154,7 +154,7 @@ opIRET_286(uint32_t fetchdat)
}
if (msw & 1) {
optype = IRET;
pmodeiret(0);
op_pmodeiret(0);
optype = 0;
} else {
uint16_t new_cs;
@@ -170,7 +170,7 @@ opIRET_286(uint32_t fetchdat)
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2;
SP += 6;
}
loadcs(new_cs);
op_loadcs(new_cs);
cycles -= timing_iret_rm;
}
flags_extract();
@@ -210,7 +210,7 @@ opIRET(uint32_t fetchdat)
else
cpu_state.eflags &= ~VIF_FLAG;
cpu_state.flags = (cpu_state.flags & 0x3300) | (new_flags & 0x4cd5) | 2;
loadcs(new_cs);
op_loadcs(new_cs);
cpu_state.pc = new_pc;
cycles -= timing_iret_rm;
@@ -221,7 +221,7 @@ opIRET(uint32_t fetchdat)
} else {
if (msw & 1) {
optype = IRET;
pmodeiret(0);
op_pmodeiret(0);
optype = 0;
} else {
uint16_t new_cs;
@@ -237,7 +237,7 @@ opIRET(uint32_t fetchdat)
cpu_state.flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2;
SP += 6;
}
loadcs(new_cs);
op_loadcs(new_cs);
cycles -= timing_iret_rm;
}
}
@@ -262,7 +262,7 @@ opIRETD(uint32_t fetchdat)
}
if (msw & 1) {
optype = IRET;
pmodeiret(1);
op_pmodeiret(1);
optype = 0;
} else {
uint16_t new_cs;
@@ -280,7 +280,7 @@ opIRETD(uint32_t fetchdat)
cpu_state.eflags = readmemw(ss, (SP + 10) & 0xffff);
SP += 12;
}
loadcs(new_cs);
op_loadcs(new_cs);
cycles -= timing_iret_rm;
}
flags_extract();

View File

@@ -610,7 +610,7 @@ opLEAVE_l(uint32_t fetchdat)
temp_seg = POP_W(); \
if (cpu_state.abrt) \
return 1; \
loadseg(temp_seg, realseg); \
op_loadseg(temp_seg, realseg); \
if (cpu_state.abrt) \
ESP = temp_esp; \
CLOCK_CYCLES(is486 ? 3 : 7); \
@@ -624,7 +624,7 @@ opLEAVE_l(uint32_t fetchdat)
temp_seg = POP_L(); \
if (cpu_state.abrt) \
return 1; \
loadseg(temp_seg & 0xffff, realseg); \
op_loadseg(temp_seg & 0xffff, realseg); \
if (cpu_state.abrt) \
ESP = temp_esp; \
CLOCK_CYCLES(is486 ? 3 : 7); \
@@ -651,7 +651,7 @@ opPOP_SS_w(uint32_t fetchdat)
temp_seg = POP_W();
if (cpu_state.abrt)
return 1;
loadseg(temp_seg, &cpu_state.seg_ss);
op_loadseg(temp_seg, &cpu_state.seg_ss);
if (cpu_state.abrt) {
ESP = temp_esp;
return 1;
@@ -679,7 +679,7 @@ opPOP_SS_l(uint32_t fetchdat)
temp_seg = POP_L();
if (cpu_state.abrt)
return 1;
loadseg(temp_seg & 0xffff, &cpu_state.seg_ss);
op_loadseg(temp_seg & 0xffff, &cpu_state.seg_ss);
if (cpu_state.abrt) {
ESP = temp_esp;
return 1;

View File

@@ -36,17 +36,25 @@
#include "x86.h"
#include "x86_flags.h"
#include "x86seg.h"
#include "x86seg_common.h"
#include "386_common.h"
uint8_t opcode2;
int cgate16;
int cgate32;
int intgatesize;
void taskswitch286(uint16_t seg, uint16_t *segdat, int is32);
void pmodeint(int num, int soft);
#ifdef OPS_286_386
#define seg_readmembl readmembl_2386
#define seg_readmemwl readmemwl_2386
#define seg_readmemll readmemll_2386
#define seg_writemembl writemembl_2386
#define seg_writememwl writememwl_2386
#define seg_writememll writememll_2386
#else
#define seg_readmembl readmembl_2386
#define seg_readmemwl readmemwl_2386
#define seg_readmemll readmemll_2386
#define seg_writemembl writemembl_2386
#define seg_writememwl writememwl_2386
#define seg_writememll writememll_2386
#endif
#define DPL ((segdat[2] >> 13) & 3)
#define DPL2 ((segdat2[2] >> 13) & 3)
@@ -70,41 +78,12 @@ x86seg_log(const char *fmt, ...)
# define x86seg_log(fmt, ...)
#endif
static void
seg_reset(x86seg *s)
{
s->access = 0x82;
s->ar_high = 0x10;
s->limit = 0xffff;
s->limit_low = 0;
s->limit_high = 0xffff;
if (s == &cpu_state.seg_cs) {
if (!cpu_inited)
fatal("seg_reset(&cpu_state.seg.cs) without an initialized CPU\n");
if (is6117)
s->base = 0x03ff0000;
else
s->base = is286 ? (cpu_16bitbus ? 0x00ff0000 : 0xffff0000) : 0x000ffff0;
s->seg = is286 ? 0xf000 : 0xffff;
} else {
s->base = 0;
s->seg = 0;
}
}
void
x86seg_reset(void)
{
seg_reset(&cpu_state.seg_cs);
seg_reset(&cpu_state.seg_ds);
seg_reset(&cpu_state.seg_es);
seg_reset(&cpu_state.seg_fs);
seg_reset(&cpu_state.seg_gs);
seg_reset(&cpu_state.seg_ss);
}
void
#ifdef OPS_286_386
x86_doabrt_2386(int x86_abrt)
#else
x86_doabrt(int x86_abrt)
#endif
{
#ifndef USE_NEW_DYNAREC
CS = oldcs;
@@ -114,7 +93,7 @@ x86_doabrt(int x86_abrt)
cpu_state.seg_cs.ar_high = 0x10;
if (msw & 1)
pmodeint(x86_abrt, 0);
op_pmodeint(x86_abrt, 0);
else {
uint32_t addr = (x86_abrt << 2) + idt.base;
if (stack32) {
@@ -134,7 +113,7 @@ x86_doabrt(int x86_abrt)
oxpc = cpu_state.pc;
#endif
cpu_state.pc = readmemw(0, addr);
loadcs(readmemw(0, addr + 2));
op_loadcs(readmemw(0, addr + 2));
return;
}
@@ -160,52 +139,6 @@ x86_doabrt(int x86_abrt)
}
}
void
x86de(UNUSED(char *s), UNUSED(uint16_t error))
{
#ifdef BAD_CODE
cpu_state.abrt = ABRT_DE;
abrt_error = error;
#else
x86_int(0);
#endif
}
void
x86gpf(UNUSED(char *s), uint16_t error)
{
cpu_state.abrt = ABRT_GPF;
abrt_error = error;
}
void
x86gpf_expected(UNUSED(char *s), uint16_t error)
{
cpu_state.abrt = ABRT_GPF | ABRT_EXPECTED;
abrt_error = error;
}
void
x86ss(UNUSED(char *s), uint16_t error)
{
cpu_state.abrt = ABRT_SS;
abrt_error = error;
}
void
x86ts(UNUSED(char *s), uint16_t error)
{
cpu_state.abrt = ABRT_TS;
abrt_error = error;
}
void
x86np(UNUSED(char *s), uint16_t error)
{
cpu_state.abrt = ABRT_NP;
abrt_error = error;
}
static void
set_stack32(int s)
{
@@ -228,6 +161,7 @@ set_use32(int u)
cpu_cur_status &= ~CPU_STATUS_USE32;
}
#ifndef OPS_286_386
void
do_seg_load(x86seg *s, uint16_t *segdat)
{
@@ -262,6 +196,7 @@ do_seg_load(x86seg *s, uint16_t *segdat)
cpu_cur_status |= CPU_STATUS_NOTFLATSS;
}
}
#endif
static void
do_seg_v86_init(x86seg *s)
@@ -310,7 +245,7 @@ check_seg_valid(x86seg *s)
}
if (!valid)
loadseg(0, s);
op_loadseg(0, s);
}
static void
@@ -336,7 +271,11 @@ int
#else
void
#endif
#ifdef OPS_286_386
loadseg_2386(uint16_t seg, x86seg *s)
#else
loadseg(uint16_t seg, x86seg *s)
#endif
{
uint16_t segdat[4];
uint32_t addr;
@@ -534,7 +473,11 @@ loadseg(uint16_t seg, x86seg *s)
}
void
#ifdef OPS_286_386
loadcs_2386(uint16_t seg)
#else
loadcs(uint16_t seg)
#endif
{
uint16_t segdat[4];
uint32_t addr;
@@ -623,7 +566,11 @@ loadcs(uint16_t seg)
}
void
#ifdef OPS_286_386
loadcsjmp_2386(uint16_t seg, uint32_t old_pc)
#else
loadcsjmp(uint16_t seg, uint32_t old_pc)
#endif
{
uint16_t type;
uint16_t seg2;
@@ -783,7 +730,7 @@ loadcsjmp(uint16_t seg, uint32_t old_pc)
cpu_state.pc = old_pc;
optype = JMP;
cpl_override = 1;
taskswitch286(seg, segdat, segdat[2] & 0x800);
op_taskswitch286(seg, segdat, segdat[2] & 0x800);
cpu_state.flags &= ~NT_FLAG;
cpl_override = 0;
return;
@@ -810,7 +757,7 @@ loadcsjmp(uint16_t seg, uint32_t old_pc)
}
}
void
static void
PUSHW(uint16_t v)
{
if (stack32) {
@@ -826,7 +773,7 @@ PUSHW(uint16_t v)
}
}
void
static void
PUSHL(uint32_t v)
{
if (cpu_16bitbus) {
@@ -847,7 +794,7 @@ PUSHL(uint32_t v)
}
}
uint16_t
static uint16_t
POPW(void)
{
uint16_t tempw;
@@ -865,7 +812,7 @@ POPW(void)
return tempw;
}
uint32_t
static uint32_t
POPL(void)
{
uint32_t templ;
@@ -890,6 +837,15 @@ POPL(void)
return templ;
}
#ifdef OPS_286_386
#ifdef USE_NEW_DYNAREC
void
loadcscall_2386(uint16_t seg, uint32_t old_pc)
#else
void
loadcscall_2386(uint16_t seg)
#endif
#else
#ifdef USE_NEW_DYNAREC
void
loadcscall(uint16_t seg, uint32_t old_pc)
@@ -897,6 +853,7 @@ loadcscall(uint16_t seg, uint32_t old_pc)
void
loadcscall(uint16_t seg)
#endif
#endif
{
uint16_t seg2;
uint16_t newss;
@@ -1225,7 +1182,7 @@ loadcscall(uint16_t seg)
cpu_state.pc = oxpc;
#endif
cpl_override = 1;
taskswitch286(seg, segdat, segdat[2] & 0x0800);
op_taskswitch286(seg, segdat, segdat[2] & 0x0800);
cpl_override = 0;
break;
@@ -1251,7 +1208,11 @@ loadcscall(uint16_t seg)
}
void
#ifdef OPS_286_386
pmoderetf_2386(int is32, uint16_t off)
#else
pmoderetf(int is32, uint16_t off)
#endif
{
uint16_t segdat[4];
uint16_t segdat2[4];
@@ -1487,7 +1448,11 @@ pmoderetf(int is32, uint16_t off)
}
void
#ifdef OPS_286_386
pmodeint_2386(int num, int soft)
#else
pmodeint(int num, int soft)
#endif
{
uint16_t segdat[4];
uint16_t segdat2[4];
@@ -1518,7 +1483,7 @@ pmodeint(int num, int soft)
softresetx86();
cpu_set_edx();
} else if (num == 0x0d)
pmodeint(8, 0);
op_pmodeint(8, 0);
else
x86gpf("pmodeint(): Vector > IDT limit", (num << 3) + 2 + !soft);
x86seg_log("addr >= IDT.limit\n");
@@ -1659,10 +1624,10 @@ pmodeint(int num, int soft)
PUSHL(ES);
if (cpu_state.abrt)
return;
loadseg(0, &cpu_state.seg_ds);
loadseg(0, &cpu_state.seg_es);
loadseg(0, &cpu_state.seg_fs);
loadseg(0, &cpu_state.seg_gs);
op_loadseg(0, &cpu_state.seg_ds);
op_loadseg(0, &cpu_state.seg_es);
op_loadseg(0, &cpu_state.seg_fs);
op_loadseg(0, &cpu_state.seg_gs);
}
PUSHL(oldss);
PUSHL(oldsp);
@@ -1764,7 +1729,7 @@ pmodeint(int num, int soft)
}
optype = OPTYPE_INT;
cpl_override = 1;
taskswitch286(seg, segdat2, segdat2[2] & 0x0800);
op_taskswitch286(seg, segdat2, segdat2[2] & 0x0800);
cpl_override = 0;
break;
@@ -1775,7 +1740,11 @@ pmodeint(int num, int soft)
}
void
#ifdef OPS_286_386
pmodeiret_2386(int is32)
#else
pmodeiret(int is32)
#endif
{
uint16_t newss;
uint16_t seg = 0;
@@ -1842,7 +1811,7 @@ pmodeiret(int is32)
}
cpl_override = 1;
read_descriptor(addr, segdat, segdat32, 1);
taskswitch286(seg, segdat, segdat[2] & 0x0800);
op_taskswitch286(seg, segdat, segdat[2] & 0x0800);
cpl_override = 0;
return;
}
@@ -1876,14 +1845,14 @@ pmodeiret(int is32)
}
cpu_state.eflags = tempflags >> 16;
cpu_cur_status |= CPU_STATUS_V86;
loadseg(segs[0], &cpu_state.seg_es);
op_loadseg(segs[0], &cpu_state.seg_es);
do_seg_v86_init(&cpu_state.seg_es);
loadseg(segs[1], &cpu_state.seg_ds);
op_loadseg(segs[1], &cpu_state.seg_ds);
do_seg_v86_init(&cpu_state.seg_ds);
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
loadseg(segs[2], &cpu_state.seg_fs);
op_loadseg(segs[2], &cpu_state.seg_fs);
do_seg_v86_init(&cpu_state.seg_fs);
loadseg(segs[3], &cpu_state.seg_gs);
op_loadseg(segs[3], &cpu_state.seg_gs);
do_seg_v86_init(&cpu_state.seg_gs);
cpu_state.pc = newpc & 0xffff;
@@ -1901,7 +1870,7 @@ pmodeiret(int is32)
#endif
ESP = newsp;
loadseg(newss, &cpu_state.seg_ss);
op_loadseg(newss, &cpu_state.seg_ss);
do_seg_v86_init(&cpu_state.seg_ss);
cpu_cur_status |= CPU_STATUS_NOTFLATSS;
use32 = 0;
@@ -2088,7 +2057,11 @@ pmodeiret(int is32)
}
void
#ifdef OPS_286_386
taskswitch286_2386(uint16_t seg, uint16_t *segdat, int is32)
#else
taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
#endif
{
uint16_t tempw;
uint16_t new_ldt;
@@ -2235,7 +2208,7 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
ldt.base = (readmemw(0, templ + 2)) | (readmemb(0, templ + 4) << 16) | (readmemb(0, templ + 7) << 24);
if (cpu_state.eflags & VM_FLAG) {
loadcs(new_cs);
op_loadcs(new_cs);
set_use32(0);
cpu_cur_status |= CPU_STATUS_V86;
} else {
@@ -2299,11 +2272,11 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
ESI = new_esi;
EDI = new_edi;
loadseg(new_es, &cpu_state.seg_es);
loadseg(new_ss, &cpu_state.seg_ss);
loadseg(new_ds, &cpu_state.seg_ds);
loadseg(new_fs, &cpu_state.seg_fs);
loadseg(new_gs, &cpu_state.seg_gs);
op_loadseg(new_es, &cpu_state.seg_es);
op_loadseg(new_ss, &cpu_state.seg_ss);
op_loadseg(new_ds, &cpu_state.seg_ds);
op_loadseg(new_fs, &cpu_state.seg_fs);
op_loadseg(new_gs, &cpu_state.seg_gs);
} else {
if (limit < 43) {
x86ts(NULL, seg);
@@ -2465,12 +2438,12 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
ESI = new_esi | 0xffff0000;
EDI = new_edi | 0xffff0000;
loadseg(new_es, &cpu_state.seg_es);
loadseg(new_ss, &cpu_state.seg_ss);
loadseg(new_ds, &cpu_state.seg_ds);
op_loadseg(new_es, &cpu_state.seg_es);
op_loadseg(new_ss, &cpu_state.seg_ss);
op_loadseg(new_ds, &cpu_state.seg_ds);
if (is386) {
loadseg(0, &cpu_state.seg_fs);
loadseg(0, &cpu_state.seg_gs);
op_loadseg(0, &cpu_state.seg_fs);
op_loadseg(0, &cpu_state.seg_gs);
}
}
@@ -2482,7 +2455,11 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
}
void
#ifdef OPS_286_386
cyrix_write_seg_descriptor_2386(uint32_t addr, x86seg *seg)
#else
cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg)
#endif
{
uint32_t limit_raw = seg->limit;
@@ -2494,7 +2471,11 @@ cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg)
}
void
#ifdef OPS_286_386
cyrix_load_seg_descriptor_2386(uint32_t addr, x86seg *seg)
#else
cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg)
#endif
{
uint16_t segdat[4];
uint16_t selector;

View File

@@ -6,7 +6,7 @@
*
* This file is part of the 86Box distribution.
*
* x86 CPU segment emulation.
* x86 CPU segment emulation header.
*
*
*
@@ -14,8 +14,82 @@
*
* Copyright 2016-2017 Miran Grca.
*/
#ifndef EMU_X86SEG_H
#define EMU_X86SEG_H
extern void do_seg_load(x86seg *s, uint16_t *segdat);
#ifdef OPS_286_386
extern void x86_doabrt_2386(int x86_abrt);
#ifdef USE_NEW_DYNAREC
extern int loadseg_2386(uint16_t seg, x86seg *s);
#else
extern void loadseg_2386(uint16_t seg, x86seg *s);
#endif
extern void loadcs_2386(uint16_t seg);
extern void loadcsjmp_2386(uint16_t seg, uint32_t old_pc);
#ifdef USE_NEW_DYNAREC
extern void loadcscall_2386(uint16_t seg, uint32_t old_pc);
#else
extern void loadcscall_2386(uint16_t seg);
#endif
extern void pmoderetf_2386(int is32, uint16_t off);
extern void pmodeint_2386(int num, int soft);
extern void pmodeiret_2386(int is32);
extern void taskswitch286_2386(uint16_t seg, uint16_t *segdat, int is32);
/* #define's to avoid long #ifdef blocks in x86_ops_*.h. */
#define op_doabrt x86_doabrt_2386
#define op_loadseg loadseg_2386
#define op_loadcs loadcs_2386
#define op_loadcsjmp loadcsjmp_2386
#define op_loadcscall loadcscall_2386
#define op_pmoderetf pmoderetf_2386
#define op_pmodeint pmodeint_2386
#define op_pmodeiret pmodeiret_2386
#define op_taskswitch taskswitch_2386
#define op_taskswitch286 taskswitch286_2386
#else
extern void x86_doabrt(int x86_abrt);
#ifdef USE_NEW_DYNAREC
extern int loadseg(uint16_t seg, x86seg *s);
#else
extern void loadseg(uint16_t seg, x86seg *s);
#endif
/* The prototype of loadcs_2386() is needed here for reset. */
extern void loadcs_2386(uint16_t seg);
extern void loadcs(uint16_t seg);
extern void loadcsjmp(uint16_t seg, uint32_t old_pc);
#ifdef USE_NEW_DYNAREC
extern void loadcscall(uint16_t seg, uint32_t old_pc);
#else
extern void loadcscall(uint16_t seg);
#endif
extern void pmoderetf(int is32, uint16_t off);
/* The prototype of pmodeint_2386() is needed here for 386_common.c interrupts. */
extern void pmodeint_2386(int num, int soft);
extern void pmodeint(int num, int soft);
extern void pmodeiret(int is32);
extern void taskswitch286(uint16_t seg, uint16_t *segdat, int is32);
/* #define's to avoid long #ifdef blocks in x86_ops_*.h. */
#define op_doabrt x86_doabrt
#define op_loadseg loadseg
#define op_loadcs loadcs
#define op_loadcsjmp loadcsjmp
#define op_loadcscall loadcscall
#define op_pmoderetf pmoderetf
#define op_pmodeint pmodeint
#define op_pmodeiret pmodeiret
#define op_taskswitch286 taskswitch286
#endif
extern void cyrix_write_seg_descriptor_2386(uint32_t addr, x86seg *seg);
extern void cyrix_load_seg_descriptor_2386(uint32_t addr, x86seg *seg);
extern void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg);
extern void cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg);
#endif /*EMU_X86SEG_H*/

22
src/cpu/x86seg_2386.c Normal file
View File

@@ -0,0 +1,22 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* x86 CPU segment emulation for the 286/386 interpreter.
*
*
*
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
#ifndef OPS_286_386
# define OPS_286_386
#endif
#include "x86seg.c"

123
src/cpu/x86seg_common.c Normal file
View File

@@ -0,0 +1,123 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* x86 CPU segment emulation commmon parts.
*
*
*
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include "cpu.h"
#include "x86.h"
#include "x86seg_common.h"
#include <86box/device.h>
#include <86box/timer.h>
#include <86box/machine.h>
#include <86box/mem.h>
#include <86box/nvr.h>
#include <86box/plat_fallthrough.h>
#include <86box/plat_unused.h>
uint8_t opcode2;
int cgate16;
int cgate32;
int intgatesize;
static void
seg_reset(x86seg *s)
{
s->access = 0x82;
s->ar_high = 0x10;
s->limit = 0xffff;
s->limit_low = 0;
s->limit_high = 0xffff;
if (s == &cpu_state.seg_cs) {
if (!cpu_inited)
fatal("seg_reset(&cpu_state.seg.cs) without an initialized CPU\n");
if (is6117)
s->base = 0x03ff0000;
else
s->base = is286 ? (cpu_16bitbus ? 0x00ff0000 : 0xffff0000) : 0x000ffff0;
s->seg = is286 ? 0xf000 : 0xffff;
} else {
s->base = 0;
s->seg = 0;
}
}
void
x86seg_reset(void)
{
seg_reset(&cpu_state.seg_cs);
seg_reset(&cpu_state.seg_ds);
seg_reset(&cpu_state.seg_es);
seg_reset(&cpu_state.seg_fs);
seg_reset(&cpu_state.seg_gs);
seg_reset(&cpu_state.seg_ss);
}
void
x86de(UNUSED(char *s), UNUSED(uint16_t error))
{
#ifdef BAD_CODE
cpu_state.abrt = ABRT_DE;
abrt_error = error;
#else
x86_int(0);
#endif
}
void
x86gpf(UNUSED(char *s), uint16_t error)
{
cpu_state.abrt = ABRT_GPF;
abrt_error = error;
}
void
x86gpf_expected(UNUSED(char *s), uint16_t error)
{
cpu_state.abrt = ABRT_GPF | ABRT_EXPECTED;
abrt_error = error;
}
void
x86ss(UNUSED(char *s), uint16_t error)
{
cpu_state.abrt = ABRT_SS;
abrt_error = error;
}
void
x86ts(UNUSED(char *s), uint16_t error)
{
cpu_state.abrt = ABRT_TS;
abrt_error = error;
}
void
x86np(UNUSED(char *s), uint16_t error)
{
cpu_state.abrt = ABRT_NP;
abrt_error = error;
}

52
src/cpu/x86seg_common.h Normal file
View File

@@ -0,0 +1,52 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* x86 CPU segment emulation common parts header.
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2016-2017 Miran Grca.
*/
#ifndef EMU_X86SEG_COMMON_H
#define EMU_X86SEG_COMMON_H
#define JMP 1
#define CALL 2
#define IRET 3
#define OPTYPE_INT 4
enum {
ABRT_NONE = 0,
ABRT_GEN = 1,
ABRT_TS = 0xA,
ABRT_NP = 0xB,
ABRT_SS = 0xC,
ABRT_GPF = 0xD,
ABRT_PF = 0xE,
ABRT_DE = 0x40 /* INT 0, but we have to distinguish it from ABRT_NONE. */
};
extern uint8_t opcode2;
extern int cgate16;
extern int cgate32;
extern int intgatesize;
extern void x86seg_reset(void);
extern void x86de(char *s, uint16_t error);
extern void x86gpf(char *s, uint16_t error);
extern void x86gpf_expected(char *s, uint16_t error);
extern void x86np(char *s, uint16_t error);
extern void x86ss(char *s, uint16_t error);
extern void x86ts(char *s, uint16_t error);
extern void do_seg_load(x86seg *s, uint16_t *segdat);
#endif /*EMU_X86SEG_COMMON_H*/

View File

@@ -13,6 +13,7 @@
#include "x86.h"
#include "x86_flags.h"
#include "x86_ops.h"
#include "x86seg_common.h"
#include "x87.h"
#include "386_common.h"
#include "softfloat/softfloat-specialize.h"

22
src/cpu/x886seg_2386.c Normal file
View File

@@ -0,0 +1,22 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* x86 CPU segment emulation for the 286/386 interpreter.
*
*
*
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
#ifndef OPS_286_386
# define OPS_286_386
#endif
#include "x86seg.c"

View File

@@ -25,6 +25,7 @@
#include <wchar.h>
#include <86box/86box.h>
#include "cpu.h"
#include "x86seg.h"
#include <86box/timer.h>
#include <86box/io.h>
#include <86box/pic.h>
@@ -759,7 +760,7 @@ write_p2(atkbc_t *dev, uint8_t val)
correctly despite A20 being gated when the CPU is reset, this will
have to do. */
else if (kbc_ven == KBC_VEN_SIEMENS)
loadcs(0xF000);
is486 ? loadcs(0xf000) : loadcs_2386(0xf000);
}
}
}

View File

@@ -662,7 +662,7 @@ kbd_read(uint16_t port, void *priv)
/* LaserXT = Always 512k RAM;
LaserXT/3 = Bit 0: set = 512k, clear = 256k. */
#if defined(DEV_BRANCH) && defined(USE_LASERXT)
if (kbd->type == KBD_TYPE_TOSHIBA)
if (kbd->type == KBD_TYPE_VTECH)
ret = ((mem_size == 512) ? 0x0d : 0x0c) | (hasfpu ? 0x02 : 0x00);
else
#endif

View File

@@ -102,7 +102,7 @@
#include <86box/hdc.h>
#include <86box/hdd.h>
#define HDC_TIME (50 * TIMER_USEC)
#define HDC_TIME (250 * TIMER_USEC)
#define WD_REV_1_BIOS_FILE "roms/hdd/xta/idexywd2.bin"
#define WD_REV_2_BIOS_FILE "roms/hdd/xta/infowdbios.rom"
@@ -248,7 +248,6 @@ typedef struct hdc_t {
uint8_t sense; /* current SENSE ERROR value */
uint8_t status; /* current operational status */
uint8_t intr;
uint64_t callback;
pc_timer_t timer;
/* Data transfer. */
@@ -343,22 +342,6 @@ next_sector(hdc_t *dev, drive_t *drive)
}
}
static void
xta_set_callback(hdc_t *dev, uint64_t callback)
{
if (!dev) {
return;
}
if (callback) {
dev->callback = callback;
timer_set_delay_u64(&dev->timer, dev->callback);
} else {
dev->callback = 0;
timer_disable(&dev->timer);
}
}
/* Perform the seek operation. */
static void
do_seek(hdc_t *dev, drive_t *drive, int cyl)
@@ -457,9 +440,6 @@ hdc_callback(void *priv)
int no_data = 0;
int val;
/* Cancel timer. */
xta_set_callback(dev, 0);
drive = &dev->drives[dcb->drvsel];
dev->comp = (dcb->drvsel) ? COMP_DRIVE : 0x00;
dev->status |= STAT_DCB;
@@ -558,12 +538,12 @@ do_send:
dev->buf_idx = 0;
if (no_data) {
/* Delay a bit, no actual transfer. */
xta_set_callback(dev, HDC_TIME);
timer_advance_u64(&dev->timer, HDC_TIME);
} else {
if (dev->intr & DMA_ENA) {
/* DMA enabled. */
dev->buf_ptr = dev->sector_buf;
xta_set_callback(dev, HDC_TIME);
timer_advance_u64(&dev->timer, HDC_TIME);
} else {
/* Copy from sector to data. */
memcpy(dev->data,
@@ -586,14 +566,14 @@ do_send:
xta_log("%s: CMD_READ_SECTORS out of data (idx=%d, len=%d)!\n", dev->name, dev->buf_idx, dev->buf_len);
dev->status |= (STAT_CD | STAT_IO | STAT_REQ);
xta_set_callback(dev, HDC_TIME);
timer_advance_u64(&dev->timer, HDC_TIME);
return;
}
dev->buf_ptr++;
dev->buf_idx++;
}
}
xta_set_callback(dev, HDC_TIME);
timer_advance_u64(&dev->timer, HDC_TIME);
dev->state = STATE_SDONE;
break;
@@ -654,7 +634,7 @@ do_recv:
if (dev->intr & DMA_ENA) {
/* DMA enabled. */
dev->buf_ptr = dev->sector_buf;
xta_set_callback(dev, HDC_TIME);
timer_advance_u64(&dev->timer, HDC_TIME);
} else {
/* No DMA, do PIO. */
dev->buf_ptr = dev->data;
@@ -673,7 +653,7 @@ do_recv:
xta_log("%s: CMD_WRITE_SECTORS out of data!\n", dev->name);
dev->status |= (STAT_CD | STAT_IO | STAT_REQ);
xta_set_callback(dev, HDC_TIME);
timer_advance_u64(&dev->timer, HDC_TIME);
return;
}
@@ -681,7 +661,7 @@ do_recv:
dev->buf_idx++;
}
dev->state = STATE_RDONE;
xta_set_callback(dev, HDC_TIME);
timer_advance_u64(&dev->timer, HDC_TIME);
}
break;
@@ -785,7 +765,7 @@ do_recv:
dev->state = STATE_RDATA;
if (dev->intr & DMA_ENA) {
dev->buf_ptr = dev->sector_buf;
xta_set_callback(dev, HDC_TIME);
timer_advance_u64(&dev->timer, HDC_TIME);
} else {
dev->buf_ptr = dev->data;
dev->status |= STAT_REQ;
@@ -800,7 +780,7 @@ do_recv:
if (val == DMA_NODATA) {
xta_log("%s: CMD_WRITE_BUFFER out of data!\n", dev->name);
dev->status |= (STAT_CD | STAT_IO | STAT_REQ);
xta_set_callback(dev, HDC_TIME);
timer_advance_u64(&dev->timer, HDC_TIME);
return;
}
@@ -808,7 +788,7 @@ do_recv:
dev->buf_idx++;
}
dev->state = STATE_RDONE;
xta_set_callback(dev, HDC_TIME);
timer_advance_u64(&dev->timer, HDC_TIME);
}
break;
@@ -828,7 +808,7 @@ do_recv:
switch (dev->state) {
case STATE_IDLE:
dev->state = STATE_RDONE;
xta_set_callback(dev, 5 * HDC_TIME);
timer_advance_u64(&dev->timer, 5 * HDC_TIME);
break;
case STATE_RDONE:
@@ -845,7 +825,7 @@ do_recv:
case STATE_IDLE:
if (drive->present) {
dev->state = STATE_RDONE;
xta_set_callback(dev, 5 * HDC_TIME);
timer_advance_u64(&dev->timer, 5 * HDC_TIME);
} else {
dev->comp |= COMP_ERR;
dev->sense = ERR_NOTRDY;
@@ -866,7 +846,7 @@ do_recv:
switch (dev->state) {
case STATE_IDLE:
dev->state = STATE_RDONE;
xta_set_callback(dev, 10 * HDC_TIME);
timer_advance_u64(&dev->timer, 10 * HDC_TIME);
break;
case STATE_RDONE:
@@ -911,7 +891,7 @@ hdc_read(uint16_t port, void *priv)
/* All data sent. */
dev->status &= ~STAT_REQ;
dev->state = STATE_SDONE;
xta_set_callback(dev, HDC_TIME);
timer_set_delay_u64(&dev->timer, HDC_TIME);
}
} else if (dev->state == STATE_COMPL) {
xta_log("DCB=%02X status=%02X comp=%02X\n", dev->dcb.cmd, dev->status, dev->comp);
@@ -969,7 +949,7 @@ hdc_write(uint16_t port, uint8_t val, void *priv)
else
dev->state = STATE_IDLE;
dev->status &= ~STAT_CD;
xta_set_callback(dev, HDC_TIME);
timer_set_delay_u64(&dev->timer, HDC_TIME);
}
}
break;

View File

@@ -560,7 +560,7 @@ extern int machine_at_portableii_init(const machine_t *);
extern int machine_at_portableiii_init(const machine_t *);
extern int machine_at_portableiii386_init(const machine_t *);
extern int machine_at_deskpro386_init(const machine_t *);
extern int machine_at_deskpro386_01_1988_init(const machine_t *);
extern int machine_at_deskpro386_05_1988_init(const machine_t *);
/* m_at_socket4.c */
extern void machine_at_premiere_common_init(const machine_t *, int);

View File

@@ -2598,10 +2598,10 @@ machine_amstrad_init(const machine_t *model, int type)
io_sethandler(0x0060, 7,
kbd_read, NULL, NULL, kbd_write, NULL, NULL, ams);
timer_add(&ams->send_delay_timer, kbd_poll, ams, 1);
if (type == AMS_PC200)
keyboard_set_table(scancode_pc200);
else
if (type == AMS_PC1512)
keyboard_set_table(scancode_xt);
else
keyboard_set_table(scancode_pc200);
keyboard_send = kbd_adddata_ex;
keyboard_scan = 1;
keyboard_set_is_amstrad(((type == AMS_PC1512) || (type == AMS_PC1640)) ? 0 : 1);

View File

@@ -52,7 +52,7 @@ enum {
COMPAQ_PORTABLEIII,
COMPAQ_PORTABLEIII386,
COMPAQ_DESKPRO386,
COMPAQ_DESKPRO386_01_1988
COMPAQ_DESKPRO386_05_1988
};
#define CGA_RGB 0
@@ -829,7 +829,7 @@ machine_at_compaq_init(const machine_t *model, int type)
break;
case COMPAQ_DESKPRO386:
case COMPAQ_DESKPRO386_01_1988:
case COMPAQ_DESKPRO386_05_1988:
if (hdc_current == 1)
device_add(&ide_isa_device);
device_add(&compaq_386_device);
@@ -909,17 +909,17 @@ machine_at_deskpro386_init(const machine_t *model)
}
int
machine_at_deskpro386_01_1988_init(const machine_t *model)
machine_at_deskpro386_05_1988_init(const machine_t *model)
{
int ret;
ret = bios_load_linearr("roms/machines/deskpro386/1988-01-28.json.bin",
ret = bios_load_linearr("roms/machines/deskpro386/1988-05-10.json.bin",
0x000f8000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_compaq_init(model, COMPAQ_DESKPRO386_01_1988);
machine_at_compaq_init(model, COMPAQ_DESKPRO386_05_1988);
return ret;
}

View File

@@ -99,7 +99,7 @@
#include <86box/ui.h>
#include <86box/machine.h>
#define HDC_TIME (50 * TIMER_USEC)
#define HDC_TIME (250 * TIMER_USEC)
#define HDC_TYPE_USER 47 /* user drive type */
enum {
@@ -380,7 +380,6 @@ typedef struct hdc_t {
uint8_t *reg_91; /* handle to system board's register 0x91 */
/* Controller state. */
uint64_t callback;
pc_timer_t timer;
int8_t state; /* controller state */
int8_t reset; /* reset state counter */
@@ -463,6 +462,7 @@ static const geom_t ibm_type_table[] = {
// clang-format on
};
#define ENABLE_PS1_HDC_LOG 1
#ifdef ENABLE_PS1_HDC_LOG
int ps1_hdc_do_log = ENABLE_PS1_HDC_LOG;
@@ -481,22 +481,6 @@ ps1_hdc_log(const char *fmt, ...)
# define ps1_hdc_log(fmt, ...)
#endif
static void
hdc_set_callback(hdc_t *dev, uint64_t callback)
{
if (!dev) {
return;
}
if (callback) {
dev->callback = callback;
timer_set_delay_u64(&dev->timer, dev->callback);
} else {
dev->callback = 0;
timer_disable(&dev->timer);
}
}
/* FIXME: we should use the disk/hdd_table.c code with custom tables! */
static int
ibm_drive_type(drive_t *drive)
@@ -633,7 +617,7 @@ do_format(hdc_t *dev, drive_t *drive, ccb_t *ccb)
/* Enable for PIO or DMA, as needed. */
#if NOT_USED
if (dev->ctrl & ACR_DMA_EN)
hdc_set_callback(dev, HDC_TIME);
timer_advance_u64(&dev->timer, HDC_TIME);
else
#endif
dev->status |= ASR_DATA_REQ;
@@ -653,7 +637,7 @@ do_format(hdc_t *dev, drive_t *drive, ccb_t *ccb)
dev->buf_idx++;
}
dev->state = STATE_RDONE;
hdc_set_callback(dev, HDC_TIME);
timer_advance_u64(&dev->timer, HDC_TIME);
break;
case STATE_RDONE:
@@ -737,9 +721,7 @@ hdc_callback(void *priv)
off64_t addr;
int no_data = 0;
int val;
/* Cancel timer. */
dev->callback = 0;
uint8_t cmd = ccb->cmd & 0x0f;
/* Clear the SSB error bits. */
dev->ssb.track_0 = 0;
@@ -758,6 +740,8 @@ hdc_callback(void *priv)
/* We really only support one drive, but ohwell. */
drive = &dev->drives[0];
ps1_hdc_log("hdc_callback(): %02X\n", cmd);
switch (ccb->cmd) {
case CMD_READ_VERIFY:
no_data = 1;
@@ -812,12 +796,12 @@ do_send:
dev->buf_idx = 0;
if (no_data) {
/* Delay a bit, no actual transfer. */
hdc_set_callback(dev, HDC_TIME);
timer_advance_u64(&dev->timer, HDC_TIME);
} else {
if (dev->ctrl & ACR_DMA_EN) {
/* DMA enabled. */
dev->buf_ptr = dev->sector_buf;
hdc_set_callback(dev, HDC_TIME);
timer_advance_u64(&dev->timer, HDC_TIME);
} else {
/* No DMA, do PIO. */
dev->status |= (ASR_DATA_REQ | ASR_DIR);
@@ -852,7 +836,7 @@ do_send:
}
}
dev->state = STATE_SDONE;
hdc_set_callback(dev, HDC_TIME);
timer_advance_u64(&dev->timer, HDC_TIME);
break;
case STATE_SDONE:
@@ -880,7 +864,6 @@ do_send:
}
break;
case CMD_READ_EXT: /* READ_EXT */
case CMD_READ_ID: /* READ_ID */
if (!drive->present) {
dev->ssb.not_ready = 1;
@@ -888,6 +871,56 @@ do_send:
return;
}
switch (dev->state) {
case STATE_IDLE:
/* Seek to cylinder if requested. */
if (ccb->auto_seek) {
if (do_seek(dev, drive,
(ccb->cyl_low | (ccb->cyl_high << 8)))) {
do_finish(dev);
return;
}
}
dev->head = ccb->head;
/* Get sector count and size. */
dev->count = (int) ccb->count;
dev->buf_len = (128 << dev->ssb.sect_size);
/* Activate the status icon. */
ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 1);
/* Ready to transfer the data out. */
dev->state = STATE_SDONE;
dev->buf_idx = 0;
/* Delay a bit, no actual transfer. */
timer_advance_u64(&dev->timer, HDC_TIME);
break;
case STATE_SDONE:
dev->buf_idx = 0;
/* De-activate the status icon. */
ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 0);
if (!(dev->ctrl & ACR_DMA_EN))
dev->status &= ~(ASR_DATA_REQ | ASR_DIR);
dev->ssb.cmd_syndrome = 0x14;
do_finish(dev);
break;
default:
break;
}
break;
case CMD_READ_EXT: /* READ_EXT */
if (!drive->present) {
dev->ssb.not_ready = 1;
do_finish(dev);
return;
}
dev->intstat |= ISR_INVALID_CMD;
do_finish(dev);
break;
@@ -943,12 +976,12 @@ do_recv:
dev->buf_idx = 0;
if (no_data) {
/* Delay a bit, no actual transfer. */
hdc_set_callback(dev, HDC_TIME);
timer_advance_u64(&dev->timer, HDC_TIME);
} else {
if (dev->ctrl & ACR_DMA_EN) {
/* DMA enabled. */
dev->buf_ptr = dev->sector_buf;
hdc_set_callback(dev, HDC_TIME);
timer_advance_u64(&dev->timer, HDC_TIME);
} else {
/* No DMA, do PIO. */
dev->buf_ptr = dev->data;
@@ -978,7 +1011,7 @@ do_recv:
}
}
dev->state = STATE_RDONE;
hdc_set_callback(dev, HDC_TIME);
timer_advance_u64(&dev->timer, HDC_TIME);
break;
case STATE_RDONE:
@@ -1140,6 +1173,8 @@ hdc_read(uint16_t port, void *priv)
break;
}
ps1_hdc_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, port, ret);
return ret;
}
@@ -1148,6 +1183,8 @@ hdc_write(uint16_t port, uint8_t val, void *priv)
{
hdc_t *dev = (hdc_t *) priv;
ps1_hdc_log("[%04X:%08X] [W] %04X = %02X\n", CS, cpu_state.pc, port, val);
/* TRM: tell system board we are alive. */
*dev->reg_91 |= 0x01;
@@ -1164,6 +1201,7 @@ hdc_write(uint16_t port, uint8_t val, void *priv)
/* Store the data into the buffer. */
dev->buf_ptr[dev->buf_idx] = val;
ps1_hdc_log("dev->buf_ptr[%02X] = %02X\n", dev->buf_idx, val);
if (++dev->buf_idx == dev->buf_len) {
/* We got all the data we need. */
dev->status &= ~ASR_DATA_REQ;
@@ -1182,7 +1220,7 @@ hdc_write(uint16_t port, uint8_t val, void *priv)
dev->status |= ASR_BUSY;
/* Schedule command execution. */
hdc_set_callback(dev, HDC_TIME);
timer_set_delay_u64(&dev->timer, HDC_TIME);
}
}
}

View File

@@ -128,6 +128,7 @@ typedef struct tandy_t {
int rom_offset; /* SL2 */
uint32_t base;
uint32_t mask;
int is_sl2;
t1kvid_t *vid;
@@ -1319,8 +1320,19 @@ tandy_write(uint16_t addr, uint8_t val, void *priv)
switch (addr) {
case 0x00a0:
mem_mapping_set_addr(&dev->ram_mapping,
((val >> 1) & 7) * 128 * 1024, 0x20000);
if (val & 0x10) {
dev->base = (mem_size - 256) * 1024;
dev->mask = 0x3ffff;
mem_mapping_set_addr(&ram_low_mapping, 0, dev->base);
mem_mapping_set_addr(&dev->ram_mapping,
((val >> 1) & 7) * 128 * 1024, 0x40000);
} else {
dev->base = (mem_size - 128) * 1024;
dev->mask = 0x1ffff;
mem_mapping_set_addr(&ram_low_mapping, 0, dev->base);
mem_mapping_set_addr(&dev->ram_mapping,
((val >> 1) & 7) * 128 * 1024, 0x20000);
}
dev->ram_bank = val;
break;
@@ -1378,7 +1390,7 @@ write_ram(uint32_t addr, uint8_t val, void *priv)
{
const tandy_t *dev = (tandy_t *) priv;
ram[dev->base + (addr & 0x1ffff)] = val;
ram[dev->base + (addr & dev->mask)] = val;
}
static uint8_t
@@ -1386,7 +1398,7 @@ read_ram(uint32_t addr, void *priv)
{
const tandy_t *dev = (tandy_t *) priv;
return (ram[dev->base + (addr & 0x1ffff)]);
return (ram[dev->base + (addr & dev->mask)]);
}
static uint8_t
@@ -1462,8 +1474,10 @@ machine_tandy1k_init(const machine_t *model, int type)
* 0xFFE8 (SL2), so we remove it from the main mapping.
*/
dev->base = (mem_size - 128) * 1024;
mem_mapping_add(&dev->ram_mapping, 0x80000, 0x20000,
read_ram, NULL, NULL, write_ram, NULL, NULL, NULL, 0, dev);
dev->mask = 0x1ffff;
mem_mapping_add(&dev->ram_mapping, 0x60000, 0x20000,
read_ram, NULL, NULL, write_ram, NULL, NULL, NULL,
MEM_MAPPING_INTERNAL, dev);
mem_mapping_set_addr(&ram_low_mapping, 0, dev->base);
device_add(&keyboard_tandy_device);

View File

@@ -310,7 +310,9 @@ machine_xt_pxxt_init(const machine_t *model)
if (bios_only || !ret)
return ret;
machine_xt_clone_init(model);
device_add(&keyboard_xt_device);
machine_xt_common_init(model);
return ret;
}

View File

@@ -1892,7 +1892,7 @@ const machine_t machines[] = {
.package = CPU_PKG_8086,
.block = CPU_BLOCK_NONE,
.min_bus = 0,
.max_bus = 0,
.max_bus = 10000000,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
@@ -1930,7 +1930,7 @@ const machine_t machines[] = {
.package = CPU_PKG_8086,
.block = CPU_BLOCK_NONE,
.min_bus = 0,
.max_bus = 0,
.max_bus = 10000000,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
@@ -1968,7 +1968,7 @@ const machine_t machines[] = {
.package = CPU_PKG_8086,
.block = CPU_BLOCK_NONE,
.min_bus = 0,
.max_bus = 0,
.max_bus = 10000000,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
@@ -2006,7 +2006,7 @@ const machine_t machines[] = {
.package = CPU_PKG_8086,
.block = CPU_BLOCK_NONE,
.min_bus = 0,
.max_bus = 0,
.max_bus = 10000000,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
@@ -2044,7 +2044,7 @@ const machine_t machines[] = {
.package = CPU_PKG_8086,
.block = CPU_BLOCK_NONE,
.min_bus = 0,
.max_bus = 0,
.max_bus = 10000000,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
@@ -4708,11 +4708,11 @@ const machine_t machines[] = {
.net_device = NULL
},
{
.name = "[ISA] Compaq Deskpro 386 (January 1988)",
.internal_name = "deskpro386_01_1988",
.name = "[ISA] Compaq Deskpro 386 (May 1988)",
.internal_name = "deskpro386_05_1988",
.type = MACHINE_TYPE_386DX,
.chipset = MACHINE_CHIPSET_DISCRETE,
.init = machine_at_deskpro386_01_1988_init,
.init = machine_at_deskpro386_05_1988_init,
.pad = 0,
.pad0 = 0,
.pad1 = MACHINE_AVAILABLE,

View File

@@ -29,6 +29,7 @@
#include "cpu.h"
#include "x86_ops.h"
#include "x86.h"
#include "x86seg_common.h"
#include <86box/machine.h>
#include <86box/m_xt_xi8088.h>
#include <86box/config.h>

View File

@@ -29,6 +29,7 @@
#include "cpu.h"
#include "x86_ops.h"
#include "x86.h"
#include "x86seg_common.h"
#include <86box/machine.h>
#include <86box/m_xt_xi8088.h>
#include <86box/config.h>

View File

@@ -442,6 +442,10 @@ pic_read(uint16_t addr, void *priv)
}
} else {
/* Standard 8259 PIC read */
#ifndef UNDEFINED_READ
/* Put the IRR on to the data bus by default until the real PIC is probed. */
dev->data_bus = dev->irr;
#endif
if (dev->ocw3 & 0x04) {
if (dev->int_pending) {
dev->data_bus = 0x80 | (dev->interrupt & 7);

View File

@@ -15,7 +15,7 @@ pc_timer_t *timer_head = NULL;
/* Are we initialized? */
int timer_inited = 0;
static void timer_advance_ex(pc_timer_t *timer);
static void timer_advance_ex(pc_timer_t *timer, int start);
void
timer_enable(pc_timer_t *timer)
@@ -127,15 +127,13 @@ timer_process(void)
timer->next = timer->prev = NULL;
timer->flags &= ~TIMER_ENABLED;
timer->flags |= TIMER_PROCESS;
if (timer->flags & TIMER_SPLIT)
timer_advance_ex(timer); /* We're splitting a > 1 s period into
timer_advance_ex(timer, 0); /* We're splitting a > 1 s period into
multiple <= 1 s periods. */
else if (timer->callback != NULL) /* Make sure it's not NULL, so that we can
have a NULL callback when no operation
is needed. */
timer->callback(timer->priv);
timer->flags &= ~TIMER_PROCESS;
}
timer_target = timer_head->ts.ts32.integer;
@@ -191,47 +189,62 @@ timer_stop(pc_timer_t *timer)
return;
timer->period = 0.0;
if (timer_is_enabled(timer))
timer_disable(timer);
timer_disable(timer);
timer->flags &= ~TIMER_SPLIT;
}
static void
timer_do_period(pc_timer_t *timer, uint64_t period)
timer_do_period(pc_timer_t *timer, uint64_t period, int start)
{
if (timer->flags & TIMER_PROCESS)
timer_advance_u64(timer, period);
else
if (!timer_inited || (timer == NULL))
return;
if (start)
timer_set_delay_u64(timer, period);
else
timer_advance_u64(timer, period);
}
static void
timer_advance_ex(pc_timer_t *timer)
timer_advance_ex(pc_timer_t *timer, int start)
{
double dusec = ((double) TIMER_USEC);
double period;
if (!timer_inited || (timer == NULL))
return;
period = (timer->period > MAX_USEC) ? MAX_USEC64 : timer->period;
if (timer->period > 0.0) {
timer_do_period(timer, (uint64_t) (period * dusec));
timer->period -= period;
timer->flags = (timer->flags & ~TIMER_SPLIT) | ((timer->period > MAX_USEC) ? TIMER_SPLIT : 0);
} else if (timer_is_enabled(timer)) {
timer_disable(timer);
if (timer->period > MAX_USEC) {
timer_do_period(timer, MAX_USEC64 * TIMER_USEC, start);
timer->period -= MAX_USEC;
timer->flags |= TIMER_SPLIT;
} else {
if (timer->period > 0.0)
timer_do_period(timer, (uint64_t) (timer->period * ((double) TIMER_USEC)), start);
else
timer_disable(timer);
timer->period = 0.0;
timer->flags &= ~TIMER_SPLIT;
}
}
static void
timer_on(pc_timer_t *timer, double period, int start)
{
if (!timer_inited || (timer == NULL))
return;
timer->period = period;
timer_advance_ex(timer, start);
}
void
timer_on_auto(pc_timer_t *timer, double period)
{
uint32_t *p = NULL;
if (!timer_inited || (timer == NULL))
return;
if (period > 0.0) {
timer->period = period;
timer_advance_ex(timer);
} else if (timer_is_on(timer))
if (period > 0.0)
timer_on(timer, period, timer->period <= 0.0);
else
timer_stop(timer);
}

View File

@@ -231,9 +231,10 @@ draw_char_rom(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr)
int elg;
int blk;
int cw = HERCULESPLUS_CW;
int blink = dev->ctrl & HERCULESPLUS_CTRL_BLINK;
blk = 0;
if (dev->ctrl & HERCULESPLUS_CTRL_BLINK) {
if (blink) {
if (attr & 0x80)
blk = (dev->blink & 16);
attr &= 0x7f;
@@ -318,35 +319,22 @@ draw_char_ram4(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr)
elg = 0;
else
elg = ((chr >= 0xc0) && (chr <= 0xdf));
fnt = dev->vram + 0x4000 + 16 * chr + dev->sc;
if (blk) {
/* Blinking, draw all background */
val = 0x000;
val = 0x000; /* Blinking, draw all background */
} else if (dev->sc == ull) {
/* Underscore, draw all foreground */
val = 0x1ff;
val = 0x1ff; /* Underscore, draw all foreground */
} else {
val = fnt[0x00000] << 1;
val = fnt[0] << 1;
if (elg)
val |= (val >> 1) & 1;
}
for (int i = 0; i < cw; i++) {
/* Generate pixel colour */
cfg = 0;
if (val & 0x100)
cfg = ifg;
else
cfg = ibg;
/* cfg = colour of foreground pixels */
if ((attr & 0x77) == 0)
cfg = ibg; /* 'blank' attribute */
buffer32->line[dev->displine][x * cw + i] = dev->cols[attr][!!blink][cfg];
buffer32->line[dev->displine][x * cw + i] = (val & 0x100) ? ifg : ibg;
val = val << 1;
}
}
@@ -354,98 +342,66 @@ draw_char_ram4(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr)
static void
draw_char_ram48(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr)
{
int elg;
int blk;
int ul;
int ol;
int bld;
unsigned ull;
unsigned oll;
unsigned ulc = 0;
unsigned olc = 0;
unsigned val;
unsigned ibg;
unsigned cfg;
const unsigned char *fnt;
int cw = HERCULESPLUS_CW;
int blink = dev->ctrl & HERCULESPLUS_CTRL_BLINK;
int font = (attr & 0x0F);
unsigned ull;
unsigned val;
unsigned ifg;
unsigned ibg;
unsigned cfg;
const uint8_t *fnt;
int elg;
int blk;
int cw = HERCULESPLUS_CW;
int blink = dev->ctrl & HERCULESPLUS_CTRL_BLINK;
int font = (attr & 0x0F);
if (font >= 12)
font &= 7;
attr = (attr >> 4) ^ 0x0f;;
blk = 0;
if (blink) {
if (attr & 0x40)
if (attr & 0x80)
blk = (dev->blink & 16);
attr &= 0x7f;
}
/* MDA-compatible attributes */
if (blink) {
ibg = (attr & 0x80) ? 8 : 0;
bld = 0;
ol = (attr & 0x20) ? 1 : 0;
ul = (attr & 0x10) ? 1 : 0;
} else {
bld = (attr & 0x80) ? 1 : 0;
ibg = (attr & 0x40) ? 0x0F : 0;
ol = (attr & 0x20) ? 1 : 0;
ul = (attr & 0x10) ? 1 : 0;
}
if (ul) {
ull = dev->crtc[HERCULESPLUS_CRTC_UNDER] & 0x0F;
ulc = (dev->crtc[HERCULESPLUS_CRTC_UNDER] >> 4) & 0x0F;
if (ulc == 0)
ulc = 7;
} else {
ull = 0xFFFF;
}
if (ol) {
oll = dev->crtc[HERCULESPLUS_CRTC_OVER] & 0x0F;
olc = (dev->crtc[HERCULESPLUS_CRTC_OVER] >> 4) & 0x0F;
if (olc == 0)
olc = 7;
} else {
oll = 0xFFFF;
ibg = 0;
ifg = 7;
if ((attr & 0x77) == 0x70) { /* Invert */
ifg = 0;
ibg = 7;
}
if (attr & 8)
ifg |= 8; /* High intensity FG */
if (attr & 0x80)
ibg |= 8; /* High intensity BG */
if ((attr & 0x77) == 0) /* Blank */
ifg = ibg;
ull = ((attr & 0x07) == 1) ? 13 : 0xffff;
if (dev->crtc[HERCULESPLUS_CRTC_XMODE] & HERCULESPLUS_XMODE_90COL)
elg = 0;
else
elg = ((chr >= 0xc0) && (chr <= 0xdf));
fnt = dev->vram + 0x4000 + 16 * chr + 4096 * font + dev->sc;
if (blk) { /* Blinking, draw all background */
val = 0x000;
if (blk) {
val = 0x000; /* Blinking, draw all background */
} else if (dev->sc == ull) {
/* Underscore, draw all foreground */
val = 0x1ff;
val = 0x1ff; /* Underscore, draw all foreground */
} else {
val = fnt[0x00000] << 1;
val = fnt[0] << 1;
if (elg)
val |= (val >> 1) & 1;
if (bld)
val |= (val >> 1);
}
for (int i = 0; i < cw; i++) {
/* Generate pixel colour */
cfg = val & 0x100;
if (dev->sc == oll)
cfg = olc ^ ibg; /* Strikethrough */
else if (dev->sc == ull)
cfg = ulc ^ ibg; /* Underline */
else if (val & 0x100)
cfg |= ~ibg;
else
cfg |= ibg;
buffer32->line[dev->displine][(x * cw) + i] = dev->cols[attr][!!blink][cfg];
val = val << 1;
buffer32->line[dev->displine][x * cw + i] = (val & 0x100) ? ifg : ibg;
val = val << 1;
}
}

View File

@@ -577,7 +577,7 @@ CPUOBJ := $(DYNARECOBJ) \
$(CGTOBJ) \
cpu.o cpu_table.o fpu.o x86.o \
8080.o 808x.o 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o \
x86_ops_mmx.o x86seg.o x87.o x87_timings.o \
x86_ops_mmx.o x86seg_common.o x86seg_2386.o x86seg.o x87.o x87_timings.o \
f2xm1.o fpatan.o fprem.o fsincos.o fyl2x.o softfloat_poly.o softfloat.o softfloat16.o \
softfloat-muladd.o softfloat-round-pack.o softfloat-specialize.o softfloatx80.o