mirror of
https://github.com/86Box/86Box.git
synced 2026-02-22 09:35:32 -07:00
The 286/386 interpreter now has its own variant of x86seg.c.
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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__)
|
||||
|
||||
@@ -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__)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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*/
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
221
src/cpu/x86seg.c
221
src/cpu/x86seg.c
@@ -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;
|
||||
|
||||
@@ -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
22
src/cpu/x86seg_2386.c
Normal 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"
|
||||
124
src/cpu/x86seg_common.c
Normal file
124
src/cpu/x86seg_common.c
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
pclog("GPF %04X: %s\n", error, s);
|
||||
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
52
src/cpu/x86seg_common.h
Normal 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*/
|
||||
@@ -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
22
src/cpu/x886seg_2386.c
Normal 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"
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user