diff --git a/src/cdrom/cdrom_image_viso.c b/src/cdrom/cdrom_image_viso.c index 94b4e44ca..c0c3bbf51 100644 --- a/src/cdrom/cdrom_image_viso.c +++ b/src/cdrom/cdrom_image_viso.c @@ -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 '=': \ diff --git a/src/codegen/codegen_ops.c b/src/codegen/codegen_ops.c index 894ebb100..801f83d7f 100644 --- a/src/codegen/codegen_ops.c +++ b/src/codegen/codegen_ops.c @@ -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" diff --git a/src/codegen/codegen_x86-64.c b/src/codegen/codegen_x86-64.c index 3934b4ac5..38a353f55 100644 --- a/src/codegen/codegen_x86-64.c +++ b/src/codegen/codegen_x86-64.c @@ -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> diff --git a/src/codegen/codegen_x86.c b/src/codegen/codegen_x86.c index 712fbe087..68fc40f17 100644 --- a/src/codegen/codegen_x86.c +++ b/src/codegen/codegen_x86.c @@ -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> diff --git a/src/codegen_new/codegen.c b/src/codegen_new/codegen.c index b0250fb7d..66d232357 100644 --- a/src/codegen_new/codegen.c +++ b/src/codegen_new/codegen.c @@ -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" diff --git a/src/codegen_new/codegen_backend_arm.c b/src/codegen_new/codegen_backend_arm.c index a389f239f..50d1c6bf9 100644 --- a/src/codegen_new/codegen_backend_arm.c +++ b/src/codegen_new/codegen_backend_arm.c @@ -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__) diff --git a/src/codegen_new/codegen_backend_arm64.c b/src/codegen_new/codegen_backend_arm64.c index 48d949406..0d7440013 100644 --- a/src/codegen_new/codegen_backend_arm64.c +++ b/src/codegen_new/codegen_backend_arm64.c @@ -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__) diff --git a/src/codegen_new/codegen_backend_arm64_uops.c b/src/codegen_new/codegen_backend_arm64_uops.c index a3a38ab22..c2fa6680b 100644 --- a/src/codegen_new/codegen_backend_arm64_uops.c +++ b/src/codegen_new/codegen_backend_arm64_uops.c @@ -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" diff --git a/src/codegen_new/codegen_backend_arm_uops.c b/src/codegen_new/codegen_backend_arm_uops.c index d0b8b86c1..0213f2e28 100644 --- a/src/codegen_new/codegen_backend_arm_uops.c +++ b/src/codegen_new/codegen_backend_arm_uops.c @@ -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" diff --git a/src/codegen_new/codegen_backend_x86-64.c b/src/codegen_new/codegen_backend_x86-64.c index a57cb4282..67355539b 100644 --- a/src/codegen_new/codegen_backend_x86-64.c +++ b/src/codegen_new/codegen_backend_x86-64.c @@ -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 diff --git a/src/codegen_new/codegen_backend_x86-64_uops.c b/src/codegen_new/codegen_backend_x86-64_uops.c index e9c08cbc8..a5f9259f0 100644 --- a/src/codegen_new/codegen_backend_x86-64_uops.c +++ b/src/codegen_new/codegen_backend_x86-64_uops.c @@ -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" diff --git a/src/codegen_new/codegen_backend_x86.c b/src/codegen_new/codegen_backend_x86.c index f656e708f..18235e2b2 100644 --- a/src/codegen_new/codegen_backend_x86.c +++ b/src/codegen_new/codegen_backend_x86.c @@ -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 diff --git a/src/codegen_new/codegen_backend_x86_uops.c b/src/codegen_new/codegen_backend_x86_uops.c index 00ae453c3..470a6ac54 100644 --- a/src/codegen_new/codegen_backend_x86_uops.c +++ b/src/codegen_new/codegen_backend_x86_uops.c @@ -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" diff --git a/src/codegen_new/codegen_block.c b/src/codegen_new/codegen_block.c index 95e422408..d10f72353 100644 --- a/src/codegen_new/codegen_block.c +++ b/src/codegen_new/codegen_block.c @@ -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" diff --git a/src/codegen_new/codegen_ops_3dnow.c b/src/codegen_new/codegen_ops_3dnow.c index c2b04584c..75059d168 100644 --- a/src/codegen_new/codegen_ops_3dnow.c +++ b/src/codegen_new/codegen_ops_3dnow.c @@ -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" diff --git a/src/codegen_new/codegen_ops_arith.c b/src/codegen_new/codegen_ops_arith.c index 5325b282b..a952811a4 100644 --- a/src/codegen_new/codegen_ops_arith.c +++ b/src/codegen_new/codegen_ops_arith.c @@ -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" diff --git a/src/codegen_new/codegen_ops_branch.c b/src/codegen_new/codegen_ops_branch.c index 9a6722342..b2726b28b 100644 --- a/src/codegen_new/codegen_ops_branch.c +++ b/src/codegen_new/codegen_ops_branch.c @@ -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" diff --git a/src/codegen_new/codegen_ops_fpu_arith.c b/src/codegen_new/codegen_ops_fpu_arith.c index 98d77250c..e31f6281b 100644 --- a/src/codegen_new/codegen_ops_fpu_arith.c +++ b/src/codegen_new/codegen_ops_fpu_arith.c @@ -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" diff --git a/src/codegen_new/codegen_ops_fpu_constant.c b/src/codegen_new/codegen_ops_fpu_constant.c index 89c138637..5ba787e24 100644 --- a/src/codegen_new/codegen_ops_fpu_constant.c +++ b/src/codegen_new/codegen_ops_fpu_constant.c @@ -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" diff --git a/src/codegen_new/codegen_ops_fpu_loadstore.c b/src/codegen_new/codegen_ops_fpu_loadstore.c index 06709913d..ec563cbbf 100644 --- a/src/codegen_new/codegen_ops_fpu_loadstore.c +++ b/src/codegen_new/codegen_ops_fpu_loadstore.c @@ -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" diff --git a/src/codegen_new/codegen_ops_fpu_misc.c b/src/codegen_new/codegen_ops_fpu_misc.c index cca9f4e4f..9524e62c0 100644 --- a/src/codegen_new/codegen_ops_fpu_misc.c +++ b/src/codegen_new/codegen_ops_fpu_misc.c @@ -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" diff --git a/src/codegen_new/codegen_ops_helpers.c b/src/codegen_new/codegen_ops_helpers.c index 242cbb818..891780a90 100644 --- a/src/codegen_new/codegen_ops_helpers.c +++ b/src/codegen_new/codegen_ops_helpers.c @@ -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" diff --git a/src/codegen_new/codegen_ops_jump.c b/src/codegen_new/codegen_ops_jump.c index 0bd4db24a..9118174e5 100644 --- a/src/codegen_new/codegen_ops_jump.c +++ b/src/codegen_new/codegen_ops_jump.c @@ -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" diff --git a/src/codegen_new/codegen_ops_logic.c b/src/codegen_new/codegen_ops_logic.c index 6db452a45..6d79016e3 100644 --- a/src/codegen_new/codegen_ops_logic.c +++ b/src/codegen_new/codegen_ops_logic.c @@ -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" diff --git a/src/codegen_new/codegen_ops_misc.c b/src/codegen_new/codegen_ops_misc.c index 9a23536ed..84958eb82 100644 --- a/src/codegen_new/codegen_ops_misc.c +++ b/src/codegen_new/codegen_ops_misc.c @@ -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" diff --git a/src/codegen_new/codegen_ops_mmx_arith.c b/src/codegen_new/codegen_ops_mmx_arith.c index b352c402a..2a176e374 100644 --- a/src/codegen_new/codegen_ops_mmx_arith.c +++ b/src/codegen_new/codegen_ops_mmx_arith.c @@ -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" diff --git a/src/codegen_new/codegen_ops_mmx_cmp.c b/src/codegen_new/codegen_ops_mmx_cmp.c index c8d4909f9..4973ef486 100644 --- a/src/codegen_new/codegen_ops_mmx_cmp.c +++ b/src/codegen_new/codegen_ops_mmx_cmp.c @@ -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" diff --git a/src/codegen_new/codegen_ops_mmx_loadstore.c b/src/codegen_new/codegen_ops_mmx_loadstore.c index a20e18e68..510956e36 100644 --- a/src/codegen_new/codegen_ops_mmx_loadstore.c +++ b/src/codegen_new/codegen_ops_mmx_loadstore.c @@ -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" diff --git a/src/codegen_new/codegen_ops_mmx_logic.c b/src/codegen_new/codegen_ops_mmx_logic.c index 664bfd14c..a7599334c 100644 --- a/src/codegen_new/codegen_ops_mmx_logic.c +++ b/src/codegen_new/codegen_ops_mmx_logic.c @@ -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" diff --git a/src/codegen_new/codegen_ops_mmx_pack.c b/src/codegen_new/codegen_ops_mmx_pack.c index 99016352e..40691e54c 100644 --- a/src/codegen_new/codegen_ops_mmx_pack.c +++ b/src/codegen_new/codegen_ops_mmx_pack.c @@ -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" diff --git a/src/codegen_new/codegen_ops_mmx_shift.c b/src/codegen_new/codegen_ops_mmx_shift.c index 32449d188..64411ecb5 100644 --- a/src/codegen_new/codegen_ops_mmx_shift.c +++ b/src/codegen_new/codegen_ops_mmx_shift.c @@ -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" diff --git a/src/codegen_new/codegen_ops_mov.c b/src/codegen_new/codegen_ops_mov.c index 68e8fb011..1d1b7df99 100644 --- a/src/codegen_new/codegen_ops_mov.c +++ b/src/codegen_new/codegen_ops_mov.c @@ -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" diff --git a/src/codegen_new/codegen_ops_shift.c b/src/codegen_new/codegen_ops_shift.c index 8ccf7d9e7..a2444e541 100644 --- a/src/codegen_new/codegen_ops_shift.c +++ b/src/codegen_new/codegen_ops_shift.c @@ -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" diff --git a/src/codegen_new/codegen_ops_stack.c b/src/codegen_new/codegen_ops_stack.c index b7afdce25..3ad7219aa 100644 --- a/src/codegen_new/codegen_ops_stack.c +++ b/src/codegen_new/codegen_ops_stack.c @@ -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" diff --git a/src/cpu/386.c b/src/cpu/386.c index 20b67ff89..1b255fe5f 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -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)); } } } diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 5c6b43980..60ecd8954 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -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 diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index ab01d28b8..f53b216de 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -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> diff --git a/src/cpu/386_dynarec_ops.c b/src/cpu/386_dynarec_ops.c index f46062bcc..77b72ef59 100644 --- a/src/cpu/386_dynarec_ops.c +++ b/src/cpu/386_dynarec_ops.c @@ -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> diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h index dc5eea606..8a0f4cd5a 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.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" diff --git a/src/cpu/CMakeLists.txt b/src/cpu/CMakeLists.txt index e4d8e71b2..27e89c523 100644 --- a/src/cpu/CMakeLists.txt +++ b/src/cpu/CMakeLists.txt @@ -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) diff --git a/src/cpu/codegen_timing_k6.c b/src/cpu/codegen_timing_k6.c index 88215bb17..4a9f23cd8 100644 --- a/src/cpu/codegen_timing_k6.c +++ b/src/cpu/codegen_timing_k6.c @@ -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" diff --git a/src/cpu/codegen_timing_p6.c b/src/cpu/codegen_timing_p6.c index 008e36594..2c087ae86 100644 --- a/src/cpu/codegen_timing_p6.c +++ b/src/cpu/codegen_timing_p6.c @@ -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" diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 42ad8aa70..0f12cf773 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -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> diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 7fdfcb3d4..66ccc05c9 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.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); diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 3afaf055e..cec3c4874 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -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}, diff --git a/src/cpu/x86.c b/src/cpu/x86.c index f994e1946..328ab8887 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -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; diff --git a/src/cpu/x86.h b/src/cpu/x86.h index 77d9329fe..5736dc665 100644 --- a/src/cpu/x86.h +++ b/src/cpu/x86.h @@ -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, + * leilei, + * Miran Grca, + * + * 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*/ diff --git a/src/cpu/x86_ops_call.h b/src/cpu/x86_ops_call.h index 731f58ec8..9d52a2764 100644 --- a/src/cpu/x86_ops_call.h +++ b/src/cpu/x86_ops_call.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(); diff --git a/src/cpu/x86_ops_jump.h b/src/cpu/x86_ops_jump.h index 091e0da35..97ca673d7 100644 --- a/src/cpu/x86_ops_jump.h +++ b/src/cpu/x86_ops_jump.h @@ -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(); diff --git a/src/cpu/x86_ops_mmx.c b/src/cpu/x86_ops_mmx.c index 6d4dd5557..f26c903f9 100644 --- a/src/cpu/x86_ops_mmx.c +++ b/src/cpu/x86_ops_mmx.c @@ -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]; diff --git a/src/cpu/x86_ops_mov_seg.h b/src/cpu/x86_ops_mov_seg.h index 2498a7d90..2a798db5c 100644 --- a/src/cpu/x86_ops_mov_seg.h +++ b/src/cpu/x86_ops_mov_seg.h @@ -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; \ diff --git a/src/cpu/x86_ops_ret.h b/src/cpu/x86_ops_ret.h index 64da566d3..0d9a6370b 100644 --- a/src/cpu/x86_ops_ret.h +++ b/src/cpu/x86_ops_ret.h @@ -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(); diff --git a/src/cpu/x86_ops_stack.h b/src/cpu/x86_ops_stack.h index 8fa66e082..13eb883d3 100644 --- a/src/cpu/x86_ops_stack.h +++ b/src/cpu/x86_ops_stack.h @@ -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; diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 3c4847a36..eaa63f846 100644 --- a/src/cpu/x86seg.c +++ b/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; diff --git a/src/cpu/x86seg.h b/src/cpu/x86seg.h index 715251f2d..dcc8c9ef8 100644 --- a/src/cpu/x86seg.h +++ b/src/cpu/x86seg.h @@ -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*/ diff --git a/src/cpu/x86seg_2386.c b/src/cpu/x86seg_2386.c new file mode 100644 index 000000000..335c757e4 --- /dev/null +++ b/src/cpu/x86seg_2386.c @@ -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, + * Miran Grca, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + */ +#ifndef OPS_286_386 +# define OPS_286_386 +#endif +#include "x86seg.c" diff --git a/src/cpu/x86seg_common.c b/src/cpu/x86seg_common.c new file mode 100644 index 000000000..8926af0d7 --- /dev/null +++ b/src/cpu/x86seg_common.c @@ -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, + * Miran Grca, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#include +#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; +} diff --git a/src/cpu/x86seg_common.h b/src/cpu/x86seg_common.h new file mode 100644 index 000000000..f4bffed40 --- /dev/null +++ b/src/cpu/x86seg_common.h @@ -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, + * + * 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*/ diff --git a/src/cpu/x87.c b/src/cpu/x87.c index c75dac569..1f7643453 100644 --- a/src/cpu/x87.c +++ b/src/cpu/x87.c @@ -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" diff --git a/src/cpu/x886seg_2386.c b/src/cpu/x886seg_2386.c new file mode 100644 index 000000000..335c757e4 --- /dev/null +++ b/src/cpu/x886seg_2386.c @@ -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, + * Miran Grca, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + */ +#ifndef OPS_286_386 +# define OPS_286_386 +#endif +#include "x86seg.c" diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index f40c032c7..4a5911caf 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -25,6 +25,7 @@ #include #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); } } } diff --git a/src/device/keyboard_xt.c b/src/device/keyboard_xt.c index a5b5579a6..0f573ea5a 100644 --- a/src/device/keyboard_xt.c +++ b/src/device/keyboard_xt.c @@ -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 diff --git a/src/disk/hdc_xta.c b/src/disk/hdc_xta.c index 9325c8f91..95eb517df 100644 --- a/src/disk/hdc_xta.c +++ b/src/disk/hdc_xta.c @@ -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; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index fd1fc6826..14974293e 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -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); diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index 091642287..826474c16 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -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); diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index fe1236ed8..1d208dea2 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -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; } diff --git a/src/machine/m_ps1_hdc.c b/src/machine/m_ps1_hdc.c index 2636812d4..116acbf11 100644 --- a/src/machine/m_ps1_hdc.c +++ b/src/machine/m_ps1_hdc.c @@ -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); } } } diff --git a/src/machine/m_tandy.c b/src/machine/m_tandy.c index 5784eb4df..6cd1afde9 100644 --- a/src/machine/m_tandy.c +++ b/src/machine/m_tandy.c @@ -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); diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 84eb517c8..fe519c65b 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -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; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 98b657178..1012a1260 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -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, diff --git a/src/mem/mem.c b/src/mem/mem.c index af80365e8..0b002b302 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -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> diff --git a/src/mem/mmu_2386.c b/src/mem/mmu_2386.c index d4fe49742..735c15592 100644 --- a/src/mem/mmu_2386.c +++ b/src/mem/mmu_2386.c @@ -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> diff --git a/src/pic.c b/src/pic.c index 56a6a927f..3db41b4c2 100644 --- a/src/pic.c +++ b/src/pic.c @@ -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); diff --git a/src/timer.c b/src/timer.c index e45fc4398..9a3ed805f 100644 --- a/src/timer.c +++ b/src/timer.c @@ -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); } diff --git a/src/video/vid_herculesplus.c b/src/video/vid_herculesplus.c index 0c2c0270c..a3e3b832e 100644 --- a/src/video/vid_herculesplus.c +++ b/src/video/vid_herculesplus.c @@ -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; } } diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 3349ff895..d98ea151f 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -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