diff --git a/src/cpu/386.c b/src/cpu/386.c index 421a978bd..a5bae7de6 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -209,7 +209,7 @@ exec386(int cycs) enter_smm_check(0); else if (nmi && nmi_enable && nmi_mask) { #ifndef USE_NEW_DYNAREC - oldcs = CS; + oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; x86_int(2); diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 24875ee4e..f8e7c11ce 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -6,7 +6,7 @@ #include #include #ifndef INFINITY -# define INFINITY (__builtin_inff()) +# define INFINITY (__builtin_inff()) #endif #define HAVE_STDARG_H #include <86box/86box.h> @@ -28,20 +28,19 @@ #include "x86seg.h" #ifdef USE_DYNAREC -#include "codegen.h" -#define CPU_BLOCK_END() cpu_block_end = 1 +# include "codegen.h" +# define CPU_BLOCK_END() cpu_block_end = 1 #else -#define CPU_BLOCK_END() +# define CPU_BLOCK_END() #endif - x86seg gdt, ldt, idt, tr; uint32_t cr2, cr3, cr4; uint32_t dr[8]; uint32_t use32; -int stack32; +int stack32; uint32_t *eal_r, *eal_w; @@ -57,11 +56,10 @@ uint32_t cpu_cur_status = 0; extern uint8_t *pccache2; -extern int optype; +extern int optype; extern uint32_t pccache; - -int in_sys = 0, unmask_a20_in_smm = 0; +int in_sys = 0, unmask_a20_in_smm = 0; uint32_t old_rammask = 0xffffffff; int soft_reset_mask = 0; @@ -72,348 +70,339 @@ int smm_in_hlt = 0, smi_block = 0; uint32_t addr64, addr64_2; uint32_t addr64a[8], addr64a_2[8]; -static pc_timer_t *cpu_fast_off_timer = NULL; -static double cpu_fast_off_period = 0.0; - - -#define AMD_SYSCALL_EIP (msr.star & 0xFFFFFFFF) -#define AMD_SYSCALL_SB ((msr.star >> 32) & 0xFFFF) -#define AMD_SYSRET_SB ((msr.star >> 48) & 0xFFFF) +static pc_timer_t *cpu_fast_off_timer = NULL; +static double cpu_fast_off_period = 0.0; +#define AMD_SYSCALL_EIP (msr.star & 0xFFFFFFFF) +#define AMD_SYSCALL_SB ((msr.star >> 32) & 0xFFFF) +#define AMD_SYSRET_SB ((msr.star >> 48) & 0xFFFF) /* These #define's and enum have been borrowed from Bochs. */ /* SMM feature masks */ -#define SMM_IO_INSTRUCTION_RESTART (0x00010000) -#define SMM_SMBASE_RELOCATION (0x00020000) -#define SMM_REVISION (0x20000000) +#define SMM_IO_INSTRUCTION_RESTART (0x00010000) +#define SMM_SMBASE_RELOCATION (0x00020000) +#define SMM_REVISION (0x20000000) /* TODO: Which CPU added SMBASE relocation? */ -#define SMM_REVISION_ID (SMM_SMBASE_RELOCATION | SMM_IO_INSTRUCTION_RESTART | SMM_REVISION) +#define SMM_REVISION_ID (SMM_SMBASE_RELOCATION | SMM_IO_INSTRUCTION_RESTART | SMM_REVISION) #define SMM_SAVE_STATE_MAP_SIZE 128 - enum SMMRAM_Fields_386_To_P5 { - SMRAM_FIELD_P5_CR0 = 0, /* 1FC */ - SMRAM_FIELD_P5_CR3, /* 1F8 */ - SMRAM_FIELD_P5_EFLAGS, /* 1F4 */ - SMRAM_FIELD_P5_EIP, /* 1F0 */ - SMRAM_FIELD_P5_EDI, /* 1EC */ - SMRAM_FIELD_P5_ESI, /* 1E8 */ - SMRAM_FIELD_P5_EBP, /* 1E4 */ - SMRAM_FIELD_P5_ESP, /* 1E0 */ - SMRAM_FIELD_P5_EBX, /* 1DC */ - SMRAM_FIELD_P5_EDX, /* 1D8 */ - SMRAM_FIELD_P5_ECX, /* 1D4 */ - SMRAM_FIELD_P5_EAX, /* 1D0 */ - SMRAM_FIELD_P5_DR6, /* 1CC */ - SMRAM_FIELD_P5_DR7, /* 1C8 */ - SMRAM_FIELD_P5_TR_SELECTOR, /* 1C4 */ - SMRAM_FIELD_P5_LDTR_SELECTOR, /* 1C0 */ - SMRAM_FIELD_P5_GS_SELECTOR, /* 1BC */ - SMRAM_FIELD_P5_FS_SELECTOR, /* 1B8 */ - SMRAM_FIELD_P5_DS_SELECTOR, /* 1B4 */ - SMRAM_FIELD_P5_SS_SELECTOR, /* 1B0 */ - SMRAM_FIELD_P5_CS_SELECTOR, /* 1AC */ - SMRAM_FIELD_P5_ES_SELECTOR, /* 1A8 */ - SMRAM_FIELD_P5_TR_ACCESS, /* 1A4 */ - SMRAM_FIELD_P5_TR_BASE, /* 1A0 */ - SMRAM_FIELD_P5_TR_LIMIT, /* 19C */ - SMRAM_FIELD_P5_IDTR_ACCESS, /* 198 */ - SMRAM_FIELD_P5_IDTR_BASE, /* 194 */ - SMRAM_FIELD_P5_IDTR_LIMIT, /* 190 */ - SMRAM_FIELD_P5_GDTR_ACCESS, /* 18C */ - SMRAM_FIELD_P5_GDTR_BASE, /* 188 */ - SMRAM_FIELD_P5_GDTR_LIMIT, /* 184 */ - SMRAM_FIELD_P5_LDTR_ACCESS, /* 180 */ - SMRAM_FIELD_P5_LDTR_BASE, /* 17C */ - SMRAM_FIELD_P5_LDTR_LIMIT, /* 178 */ - SMRAM_FIELD_P5_GS_ACCESS, /* 174 */ - SMRAM_FIELD_P5_GS_BASE, /* 170 */ - SMRAM_FIELD_P5_GS_LIMIT, /* 16C */ - SMRAM_FIELD_P5_FS_ACCESS, /* 168 */ - SMRAM_FIELD_P5_FS_BASE, /* 164 */ - SMRAM_FIELD_P5_FS_LIMIT, /* 160 */ - SMRAM_FIELD_P5_DS_ACCESS, /* 15C */ - SMRAM_FIELD_P5_DS_BASE, /* 158 */ - SMRAM_FIELD_P5_DS_LIMIT, /* 154 */ - SMRAM_FIELD_P5_SS_ACCESS, /* 150 */ - SMRAM_FIELD_P5_SS_BASE, /* 14C */ - SMRAM_FIELD_P5_SS_LIMIT, /* 148 */ - SMRAM_FIELD_P5_CS_ACCESS, /* 144 */ - SMRAM_FIELD_P5_CS_BASE, /* 140 */ - SMRAM_FIELD_P5_CS_LIMIT, /* 13C */ - SMRAM_FIELD_P5_ES_ACCESS, /* 138 */ - SMRAM_FIELD_P5_ES_BASE, /* 134 */ - SMRAM_FIELD_P5_ES_LIMIT, /* 130 */ - SMRAM_FIELD_P5_UNWRITTEN_1, /* 12C */ - SMRAM_FIELD_P5_CR4, /* 128 */ - SMRAM_FIELD_P5_ALTERNATE_DR6, /* 124 */ - SMRAM_FIELD_P5_RESERVED_1, /* 120 */ - SMRAM_FIELD_P5_RESERVED_2, /* 11C */ - SMRAM_FIELD_P5_RESERVED_3, /* 118 */ - SMRAM_FIELD_P5_RESERVED_4, /* 114 */ - SMRAM_FIELD_P5_IO_RESTART_EIP, /* 110 */ - SMRAM_FIELD_P5_IO_RESTART_ESI, /* 10C */ - SMRAM_FIELD_P5_IO_RESTART_ECX, /* 108 */ - SMRAM_FIELD_P5_IO_RESTART_EDI, /* 104 */ - SMRAM_FIELD_P5_AUTOHALT_RESTART, /* 100 */ - SMRAM_FIELD_P5_SMM_REVISION_ID, /* 0FC */ - SMRAM_FIELD_P5_SMBASE_OFFSET, /* 0F8 */ - SMRAM_FIELD_AM486_CR2, /* 0F4 */ - SMRAM_FIELD_AM486_DR0, /* 0F0 */ - SMRAM_FIELD_AM486_DR1, /* 0EC */ - SMRAM_FIELD_AM486_DR2, /* 0E8 */ - SMRAM_FIELD_AM486_DR3, /* 0E4 */ + SMRAM_FIELD_P5_CR0 = 0, /* 1FC */ + SMRAM_FIELD_P5_CR3, /* 1F8 */ + SMRAM_FIELD_P5_EFLAGS, /* 1F4 */ + SMRAM_FIELD_P5_EIP, /* 1F0 */ + SMRAM_FIELD_P5_EDI, /* 1EC */ + SMRAM_FIELD_P5_ESI, /* 1E8 */ + SMRAM_FIELD_P5_EBP, /* 1E4 */ + SMRAM_FIELD_P5_ESP, /* 1E0 */ + SMRAM_FIELD_P5_EBX, /* 1DC */ + SMRAM_FIELD_P5_EDX, /* 1D8 */ + SMRAM_FIELD_P5_ECX, /* 1D4 */ + SMRAM_FIELD_P5_EAX, /* 1D0 */ + SMRAM_FIELD_P5_DR6, /* 1CC */ + SMRAM_FIELD_P5_DR7, /* 1C8 */ + SMRAM_FIELD_P5_TR_SELECTOR, /* 1C4 */ + SMRAM_FIELD_P5_LDTR_SELECTOR, /* 1C0 */ + SMRAM_FIELD_P5_GS_SELECTOR, /* 1BC */ + SMRAM_FIELD_P5_FS_SELECTOR, /* 1B8 */ + SMRAM_FIELD_P5_DS_SELECTOR, /* 1B4 */ + SMRAM_FIELD_P5_SS_SELECTOR, /* 1B0 */ + SMRAM_FIELD_P5_CS_SELECTOR, /* 1AC */ + SMRAM_FIELD_P5_ES_SELECTOR, /* 1A8 */ + SMRAM_FIELD_P5_TR_ACCESS, /* 1A4 */ + SMRAM_FIELD_P5_TR_BASE, /* 1A0 */ + SMRAM_FIELD_P5_TR_LIMIT, /* 19C */ + SMRAM_FIELD_P5_IDTR_ACCESS, /* 198 */ + SMRAM_FIELD_P5_IDTR_BASE, /* 194 */ + SMRAM_FIELD_P5_IDTR_LIMIT, /* 190 */ + SMRAM_FIELD_P5_GDTR_ACCESS, /* 18C */ + SMRAM_FIELD_P5_GDTR_BASE, /* 188 */ + SMRAM_FIELD_P5_GDTR_LIMIT, /* 184 */ + SMRAM_FIELD_P5_LDTR_ACCESS, /* 180 */ + SMRAM_FIELD_P5_LDTR_BASE, /* 17C */ + SMRAM_FIELD_P5_LDTR_LIMIT, /* 178 */ + SMRAM_FIELD_P5_GS_ACCESS, /* 174 */ + SMRAM_FIELD_P5_GS_BASE, /* 170 */ + SMRAM_FIELD_P5_GS_LIMIT, /* 16C */ + SMRAM_FIELD_P5_FS_ACCESS, /* 168 */ + SMRAM_FIELD_P5_FS_BASE, /* 164 */ + SMRAM_FIELD_P5_FS_LIMIT, /* 160 */ + SMRAM_FIELD_P5_DS_ACCESS, /* 15C */ + SMRAM_FIELD_P5_DS_BASE, /* 158 */ + SMRAM_FIELD_P5_DS_LIMIT, /* 154 */ + SMRAM_FIELD_P5_SS_ACCESS, /* 150 */ + SMRAM_FIELD_P5_SS_BASE, /* 14C */ + SMRAM_FIELD_P5_SS_LIMIT, /* 148 */ + SMRAM_FIELD_P5_CS_ACCESS, /* 144 */ + SMRAM_FIELD_P5_CS_BASE, /* 140 */ + SMRAM_FIELD_P5_CS_LIMIT, /* 13C */ + SMRAM_FIELD_P5_ES_ACCESS, /* 138 */ + SMRAM_FIELD_P5_ES_BASE, /* 134 */ + SMRAM_FIELD_P5_ES_LIMIT, /* 130 */ + SMRAM_FIELD_P5_UNWRITTEN_1, /* 12C */ + SMRAM_FIELD_P5_CR4, /* 128 */ + SMRAM_FIELD_P5_ALTERNATE_DR6, /* 124 */ + SMRAM_FIELD_P5_RESERVED_1, /* 120 */ + SMRAM_FIELD_P5_RESERVED_2, /* 11C */ + SMRAM_FIELD_P5_RESERVED_3, /* 118 */ + SMRAM_FIELD_P5_RESERVED_4, /* 114 */ + SMRAM_FIELD_P5_IO_RESTART_EIP, /* 110 */ + SMRAM_FIELD_P5_IO_RESTART_ESI, /* 10C */ + SMRAM_FIELD_P5_IO_RESTART_ECX, /* 108 */ + SMRAM_FIELD_P5_IO_RESTART_EDI, /* 104 */ + SMRAM_FIELD_P5_AUTOHALT_RESTART, /* 100 */ + SMRAM_FIELD_P5_SMM_REVISION_ID, /* 0FC */ + SMRAM_FIELD_P5_SMBASE_OFFSET, /* 0F8 */ + SMRAM_FIELD_AM486_CR2, /* 0F4 */ + SMRAM_FIELD_AM486_DR0, /* 0F0 */ + SMRAM_FIELD_AM486_DR1, /* 0EC */ + SMRAM_FIELD_AM486_DR2, /* 0E8 */ + SMRAM_FIELD_AM486_DR3, /* 0E4 */ SMRAM_FIELD_P5_LAST }; enum SMMRAM_Fields_P6 { - SMRAM_FIELD_P6_CR0 = 0, /* 1FC */ - SMRAM_FIELD_P6_CR3, /* 1F8 */ - SMRAM_FIELD_P6_EFLAGS, /* 1F4 */ - SMRAM_FIELD_P6_EIP, /* 1F0 */ - SMRAM_FIELD_P6_EDI, /* 1EC */ - SMRAM_FIELD_P6_ESI, /* 1E8 */ - SMRAM_FIELD_P6_EBP, /* 1E4 */ - SMRAM_FIELD_P6_ESP, /* 1E0 */ - SMRAM_FIELD_P6_EBX, /* 1DC */ - SMRAM_FIELD_P6_EDX, /* 1D8 */ - SMRAM_FIELD_P6_ECX, /* 1D4 */ - SMRAM_FIELD_P6_EAX, /* 1D0 */ - SMRAM_FIELD_P6_DR6, /* 1CC */ - SMRAM_FIELD_P6_DR7, /* 1C8 */ - SMRAM_FIELD_P6_TR_SELECTOR, /* 1C4 */ - SMRAM_FIELD_P6_LDTR_SELECTOR, /* 1C0 */ - SMRAM_FIELD_P6_GS_SELECTOR, /* 1BC */ - SMRAM_FIELD_P6_FS_SELECTOR, /* 1B8 */ - SMRAM_FIELD_P6_DS_SELECTOR, /* 1B4 */ - SMRAM_FIELD_P6_SS_SELECTOR, /* 1B0 */ - SMRAM_FIELD_P6_CS_SELECTOR, /* 1AC */ - SMRAM_FIELD_P6_ES_SELECTOR, /* 1A8 */ - SMRAM_FIELD_P6_SS_BASE, /* 1A4 */ - SMRAM_FIELD_P6_SS_LIMIT, /* 1A0 */ - SMRAM_FIELD_P6_SS_SELECTOR_AR, /* 19C */ - SMRAM_FIELD_P6_CS_BASE, /* 198 */ - SMRAM_FIELD_P6_CS_LIMIT, /* 194 */ - SMRAM_FIELD_P6_CS_SELECTOR_AR, /* 190 */ - SMRAM_FIELD_P6_ES_BASE, /* 18C */ - SMRAM_FIELD_P6_ES_LIMIT, /* 188 */ - SMRAM_FIELD_P6_ES_SELECTOR_AR, /* 184 */ - SMRAM_FIELD_P6_LDTR_BASE, /* 180 */ - SMRAM_FIELD_P6_LDTR_LIMIT, /* 17C */ - SMRAM_FIELD_P6_LDTR_SELECTOR_AR, /* 178 */ - SMRAM_FIELD_P6_GDTR_BASE, /* 174 */ - SMRAM_FIELD_P6_GDTR_LIMIT, /* 170 */ - SMRAM_FIELD_P6_GDTR_SELECTOR_AR, /* 16C */ - SMRAM_FIELD_P6_SREG_STATUS1, /* 168 */ - SMRAM_FIELD_P6_TR_BASE, /* 164 */ - SMRAM_FIELD_P6_TR_LIMIT, /* 160 */ - SMRAM_FIELD_P6_TR_SELECTOR_AR, /* 15C */ - SMRAM_FIELD_P6_IDTR_BASE, /* 158 */ - SMRAM_FIELD_P6_IDTR_LIMIT, /* 154 */ - SMRAM_FIELD_P6_IDTR_SELECTOR_AR, /* 150 */ - SMRAM_FIELD_P6_GS_BASE, /* 14C */ - SMRAM_FIELD_P6_GS_LIMIT, /* 148 */ - SMRAM_FIELD_P6_GS_SELECTOR_AR, /* 144 */ - SMRAM_FIELD_P6_FS_BASE, /* 140 */ - SMRAM_FIELD_P6_FS_LIMIT, /* 13C */ - SMRAM_FIELD_P6_FS_SELECTOR_AR, /* 138 */ - SMRAM_FIELD_P6_DS_BASE, /* 134 */ - SMRAM_FIELD_P6_DS_LIMIT, /* 130 */ - SMRAM_FIELD_P6_DS_SELECTOR_AR, /* 12C */ - SMRAM_FIELD_P6_SREG_STATUS0, /* 128 */ - SMRAM_FIELD_P6_ALTERNATIVE_DR6, /* 124 */ - SMRAM_FIELD_P6_CPL, /* 120 */ - SMRAM_FIELD_P6_SMM_STATUS, /* 11C */ - SMRAM_FIELD_P6_A20M, /* 118 */ - SMRAM_FIELD_P6_CR4, /* 114 */ - SMRAM_FIELD_P6_IO_RESTART_EIP, /* 110 */ - SMRAM_FIELD_P6_IO_RESTART_ESI, /* 10C */ - SMRAM_FIELD_P6_IO_RESTART_ECX, /* 108 */ - SMRAM_FIELD_P6_IO_RESTART_EDI, /* 104 */ - SMRAM_FIELD_P6_AUTOHALT_RESTART, /* 100 */ - SMRAM_FIELD_P6_SMM_REVISION_ID, /* 0FC */ - SMRAM_FIELD_P6_SMBASE_OFFSET, /* 0F8 */ + SMRAM_FIELD_P6_CR0 = 0, /* 1FC */ + SMRAM_FIELD_P6_CR3, /* 1F8 */ + SMRAM_FIELD_P6_EFLAGS, /* 1F4 */ + SMRAM_FIELD_P6_EIP, /* 1F0 */ + SMRAM_FIELD_P6_EDI, /* 1EC */ + SMRAM_FIELD_P6_ESI, /* 1E8 */ + SMRAM_FIELD_P6_EBP, /* 1E4 */ + SMRAM_FIELD_P6_ESP, /* 1E0 */ + SMRAM_FIELD_P6_EBX, /* 1DC */ + SMRAM_FIELD_P6_EDX, /* 1D8 */ + SMRAM_FIELD_P6_ECX, /* 1D4 */ + SMRAM_FIELD_P6_EAX, /* 1D0 */ + SMRAM_FIELD_P6_DR6, /* 1CC */ + SMRAM_FIELD_P6_DR7, /* 1C8 */ + SMRAM_FIELD_P6_TR_SELECTOR, /* 1C4 */ + SMRAM_FIELD_P6_LDTR_SELECTOR, /* 1C0 */ + SMRAM_FIELD_P6_GS_SELECTOR, /* 1BC */ + SMRAM_FIELD_P6_FS_SELECTOR, /* 1B8 */ + SMRAM_FIELD_P6_DS_SELECTOR, /* 1B4 */ + SMRAM_FIELD_P6_SS_SELECTOR, /* 1B0 */ + SMRAM_FIELD_P6_CS_SELECTOR, /* 1AC */ + SMRAM_FIELD_P6_ES_SELECTOR, /* 1A8 */ + SMRAM_FIELD_P6_SS_BASE, /* 1A4 */ + SMRAM_FIELD_P6_SS_LIMIT, /* 1A0 */ + SMRAM_FIELD_P6_SS_SELECTOR_AR, /* 19C */ + SMRAM_FIELD_P6_CS_BASE, /* 198 */ + SMRAM_FIELD_P6_CS_LIMIT, /* 194 */ + SMRAM_FIELD_P6_CS_SELECTOR_AR, /* 190 */ + SMRAM_FIELD_P6_ES_BASE, /* 18C */ + SMRAM_FIELD_P6_ES_LIMIT, /* 188 */ + SMRAM_FIELD_P6_ES_SELECTOR_AR, /* 184 */ + SMRAM_FIELD_P6_LDTR_BASE, /* 180 */ + SMRAM_FIELD_P6_LDTR_LIMIT, /* 17C */ + SMRAM_FIELD_P6_LDTR_SELECTOR_AR, /* 178 */ + SMRAM_FIELD_P6_GDTR_BASE, /* 174 */ + SMRAM_FIELD_P6_GDTR_LIMIT, /* 170 */ + SMRAM_FIELD_P6_GDTR_SELECTOR_AR, /* 16C */ + SMRAM_FIELD_P6_SREG_STATUS1, /* 168 */ + SMRAM_FIELD_P6_TR_BASE, /* 164 */ + SMRAM_FIELD_P6_TR_LIMIT, /* 160 */ + SMRAM_FIELD_P6_TR_SELECTOR_AR, /* 15C */ + SMRAM_FIELD_P6_IDTR_BASE, /* 158 */ + SMRAM_FIELD_P6_IDTR_LIMIT, /* 154 */ + SMRAM_FIELD_P6_IDTR_SELECTOR_AR, /* 150 */ + SMRAM_FIELD_P6_GS_BASE, /* 14C */ + SMRAM_FIELD_P6_GS_LIMIT, /* 148 */ + SMRAM_FIELD_P6_GS_SELECTOR_AR, /* 144 */ + SMRAM_FIELD_P6_FS_BASE, /* 140 */ + SMRAM_FIELD_P6_FS_LIMIT, /* 13C */ + SMRAM_FIELD_P6_FS_SELECTOR_AR, /* 138 */ + SMRAM_FIELD_P6_DS_BASE, /* 134 */ + SMRAM_FIELD_P6_DS_LIMIT, /* 130 */ + SMRAM_FIELD_P6_DS_SELECTOR_AR, /* 12C */ + SMRAM_FIELD_P6_SREG_STATUS0, /* 128 */ + SMRAM_FIELD_P6_ALTERNATIVE_DR6, /* 124 */ + SMRAM_FIELD_P6_CPL, /* 120 */ + SMRAM_FIELD_P6_SMM_STATUS, /* 11C */ + SMRAM_FIELD_P6_A20M, /* 118 */ + SMRAM_FIELD_P6_CR4, /* 114 */ + SMRAM_FIELD_P6_IO_RESTART_EIP, /* 110 */ + SMRAM_FIELD_P6_IO_RESTART_ESI, /* 10C */ + SMRAM_FIELD_P6_IO_RESTART_ECX, /* 108 */ + SMRAM_FIELD_P6_IO_RESTART_EDI, /* 104 */ + SMRAM_FIELD_P6_AUTOHALT_RESTART, /* 100 */ + SMRAM_FIELD_P6_SMM_REVISION_ID, /* 0FC */ + SMRAM_FIELD_P6_SMBASE_OFFSET, /* 0F8 */ SMRAM_FIELD_P6_LAST }; enum SMMRAM_Fields_AMD_K { - SMRAM_FIELD_AMD_K_CR0 = 0, /* 1FC */ - SMRAM_FIELD_AMD_K_CR3, /* 1F8 */ - SMRAM_FIELD_AMD_K_EFLAGS, /* 1F4 */ - SMRAM_FIELD_AMD_K_EIP, /* 1F0 */ - SMRAM_FIELD_AMD_K_EDI, /* 1EC */ - SMRAM_FIELD_AMD_K_ESI, /* 1E8 */ - SMRAM_FIELD_AMD_K_EBP, /* 1E4 */ - SMRAM_FIELD_AMD_K_ESP, /* 1E0 */ - SMRAM_FIELD_AMD_K_EBX, /* 1DC */ - SMRAM_FIELD_AMD_K_EDX, /* 1D8 */ - SMRAM_FIELD_AMD_K_ECX, /* 1D4 */ - SMRAM_FIELD_AMD_K_EAX, /* 1D0 */ - SMRAM_FIELD_AMD_K_DR6, /* 1CC */ - SMRAM_FIELD_AMD_K_DR7, /* 1C8 */ - SMRAM_FIELD_AMD_K_TR_SELECTOR, /* 1C4 */ - SMRAM_FIELD_AMD_K_LDTR_SELECTOR, /* 1C0 */ - SMRAM_FIELD_AMD_K_GS_SELECTOR, /* 1BC */ - SMRAM_FIELD_AMD_K_FS_SELECTOR, /* 1B8 */ - SMRAM_FIELD_AMD_K_DS_SELECTOR, /* 1B4 */ - SMRAM_FIELD_AMD_K_SS_SELECTOR, /* 1B0 */ - SMRAM_FIELD_AMD_K_CS_SELECTOR, /* 1AC */ - SMRAM_FIELD_AMD_K_ES_SELECTOR, /* 1A8 */ - SMRAM_FIELD_AMD_K_IO_RESTART_DWORD, /* 1A4 */ - SMRAM_FIELD_AMD_K_RESERVED_1, /* 1A0 */ - SMRAM_FIELD_AMD_K_IO_RESTART_EIP, /* 19C */ - SMRAM_FIELD_AMD_K_RESERVED_2, /* 198 */ - SMRAM_FIELD_AMD_K_RESERVED_3, /* 194 */ - SMRAM_FIELD_AMD_K_IDTR_BASE, /* 190 */ - SMRAM_FIELD_AMD_K_IDTR_LIMIT, /* 18C */ - SMRAM_FIELD_AMD_K_GDTR_BASE, /* 188 */ - SMRAM_FIELD_AMD_K_GDTR_LIMIT, /* 184 */ - SMRAM_FIELD_AMD_K_TR_ACCESS, /* 180 */ - SMRAM_FIELD_AMD_K_TR_BASE, /* 17C */ - SMRAM_FIELD_AMD_K_TR_LIMIT, /* 178 */ - SMRAM_FIELD_AMD_K_LDTR_ACCESS, /* 174 - reserved on K6 */ - SMRAM_FIELD_AMD_K_LDTR_BASE, /* 170 */ - SMRAM_FIELD_AMD_K_LDTR_LIMIT, /* 16C */ - SMRAM_FIELD_AMD_K_GS_ACCESS, /* 168 */ - SMRAM_FIELD_AMD_K_GS_BASE, /* 164 */ - SMRAM_FIELD_AMD_K_GS_LIMIT, /* 160 */ - SMRAM_FIELD_AMD_K_FS_ACCESS, /* 15C */ - SMRAM_FIELD_AMD_K_FS_BASE, /* 158 */ - SMRAM_FIELD_AMD_K_FS_LIMIT, /* 154 */ - SMRAM_FIELD_AMD_K_DS_ACCESS, /* 150 */ - SMRAM_FIELD_AMD_K_DS_BASE, /* 14C */ - SMRAM_FIELD_AMD_K_DS_LIMIT, /* 148 */ - SMRAM_FIELD_AMD_K_SS_ACCESS, /* 144 */ - SMRAM_FIELD_AMD_K_SS_BASE, /* 140 */ - SMRAM_FIELD_AMD_K_SS_LIMIT, /* 13C */ - SMRAM_FIELD_AMD_K_CS_ACCESS, /* 138 */ - SMRAM_FIELD_AMD_K_CS_BASE, /* 134 */ - SMRAM_FIELD_AMD_K_CS_LIMIT, /* 130 */ - SMRAM_FIELD_AMD_K_ES_ACCESS, /* 12C */ - SMRAM_FIELD_AMD_K_ES_BASE, /* 128 */ - SMRAM_FIELD_AMD_K_ES_LIMIT, /* 124 */ - SMRAM_FIELD_AMD_K_RESERVED_4, /* 120 */ - SMRAM_FIELD_AMD_K_RESERVED_5, /* 11C */ - SMRAM_FIELD_AMD_K_RESERVED_6, /* 118 */ - SMRAM_FIELD_AMD_K_CR2, /* 114 */ - SMRAM_FIELD_AMD_K_CR4, /* 110 */ - SMRAM_FIELD_AMD_K_IO_RESTART_ESI, /* 10C */ - SMRAM_FIELD_AMD_K_IO_RESTART_ECX, /* 108 */ - SMRAM_FIELD_AMD_K_IO_RESTART_EDI, /* 104 */ - SMRAM_FIELD_AMD_K_AUTOHALT_RESTART, /* 100 */ - SMRAM_FIELD_AMD_K_SMM_REVISION_ID, /* 0FC */ - SMRAM_FIELD_AMD_K_SMBASE_OFFSET, /* 0F8 */ + SMRAM_FIELD_AMD_K_CR0 = 0, /* 1FC */ + SMRAM_FIELD_AMD_K_CR3, /* 1F8 */ + SMRAM_FIELD_AMD_K_EFLAGS, /* 1F4 */ + SMRAM_FIELD_AMD_K_EIP, /* 1F0 */ + SMRAM_FIELD_AMD_K_EDI, /* 1EC */ + SMRAM_FIELD_AMD_K_ESI, /* 1E8 */ + SMRAM_FIELD_AMD_K_EBP, /* 1E4 */ + SMRAM_FIELD_AMD_K_ESP, /* 1E0 */ + SMRAM_FIELD_AMD_K_EBX, /* 1DC */ + SMRAM_FIELD_AMD_K_EDX, /* 1D8 */ + SMRAM_FIELD_AMD_K_ECX, /* 1D4 */ + SMRAM_FIELD_AMD_K_EAX, /* 1D0 */ + SMRAM_FIELD_AMD_K_DR6, /* 1CC */ + SMRAM_FIELD_AMD_K_DR7, /* 1C8 */ + SMRAM_FIELD_AMD_K_TR_SELECTOR, /* 1C4 */ + SMRAM_FIELD_AMD_K_LDTR_SELECTOR, /* 1C0 */ + SMRAM_FIELD_AMD_K_GS_SELECTOR, /* 1BC */ + SMRAM_FIELD_AMD_K_FS_SELECTOR, /* 1B8 */ + SMRAM_FIELD_AMD_K_DS_SELECTOR, /* 1B4 */ + SMRAM_FIELD_AMD_K_SS_SELECTOR, /* 1B0 */ + SMRAM_FIELD_AMD_K_CS_SELECTOR, /* 1AC */ + SMRAM_FIELD_AMD_K_ES_SELECTOR, /* 1A8 */ + SMRAM_FIELD_AMD_K_IO_RESTART_DWORD, /* 1A4 */ + SMRAM_FIELD_AMD_K_RESERVED_1, /* 1A0 */ + SMRAM_FIELD_AMD_K_IO_RESTART_EIP, /* 19C */ + SMRAM_FIELD_AMD_K_RESERVED_2, /* 198 */ + SMRAM_FIELD_AMD_K_RESERVED_3, /* 194 */ + SMRAM_FIELD_AMD_K_IDTR_BASE, /* 190 */ + SMRAM_FIELD_AMD_K_IDTR_LIMIT, /* 18C */ + SMRAM_FIELD_AMD_K_GDTR_BASE, /* 188 */ + SMRAM_FIELD_AMD_K_GDTR_LIMIT, /* 184 */ + SMRAM_FIELD_AMD_K_TR_ACCESS, /* 180 */ + SMRAM_FIELD_AMD_K_TR_BASE, /* 17C */ + SMRAM_FIELD_AMD_K_TR_LIMIT, /* 178 */ + SMRAM_FIELD_AMD_K_LDTR_ACCESS, /* 174 - reserved on K6 */ + SMRAM_FIELD_AMD_K_LDTR_BASE, /* 170 */ + SMRAM_FIELD_AMD_K_LDTR_LIMIT, /* 16C */ + SMRAM_FIELD_AMD_K_GS_ACCESS, /* 168 */ + SMRAM_FIELD_AMD_K_GS_BASE, /* 164 */ + SMRAM_FIELD_AMD_K_GS_LIMIT, /* 160 */ + SMRAM_FIELD_AMD_K_FS_ACCESS, /* 15C */ + SMRAM_FIELD_AMD_K_FS_BASE, /* 158 */ + SMRAM_FIELD_AMD_K_FS_LIMIT, /* 154 */ + SMRAM_FIELD_AMD_K_DS_ACCESS, /* 150 */ + SMRAM_FIELD_AMD_K_DS_BASE, /* 14C */ + SMRAM_FIELD_AMD_K_DS_LIMIT, /* 148 */ + SMRAM_FIELD_AMD_K_SS_ACCESS, /* 144 */ + SMRAM_FIELD_AMD_K_SS_BASE, /* 140 */ + SMRAM_FIELD_AMD_K_SS_LIMIT, /* 13C */ + SMRAM_FIELD_AMD_K_CS_ACCESS, /* 138 */ + SMRAM_FIELD_AMD_K_CS_BASE, /* 134 */ + SMRAM_FIELD_AMD_K_CS_LIMIT, /* 130 */ + SMRAM_FIELD_AMD_K_ES_ACCESS, /* 12C */ + SMRAM_FIELD_AMD_K_ES_BASE, /* 128 */ + SMRAM_FIELD_AMD_K_ES_LIMIT, /* 124 */ + SMRAM_FIELD_AMD_K_RESERVED_4, /* 120 */ + SMRAM_FIELD_AMD_K_RESERVED_5, /* 11C */ + SMRAM_FIELD_AMD_K_RESERVED_6, /* 118 */ + SMRAM_FIELD_AMD_K_CR2, /* 114 */ + SMRAM_FIELD_AMD_K_CR4, /* 110 */ + SMRAM_FIELD_AMD_K_IO_RESTART_ESI, /* 10C */ + SMRAM_FIELD_AMD_K_IO_RESTART_ECX, /* 108 */ + SMRAM_FIELD_AMD_K_IO_RESTART_EDI, /* 104 */ + SMRAM_FIELD_AMD_K_AUTOHALT_RESTART, /* 100 */ + SMRAM_FIELD_AMD_K_SMM_REVISION_ID, /* 0FC */ + SMRAM_FIELD_AMD_K_SMBASE_OFFSET, /* 0F8 */ SMRAM_FIELD_AMD_K_LAST }; - #ifdef ENABLE_386_COMMON_LOG int x386_common_do_log = ENABLE_386_COMMON_LOG; - void x386_common_log(const char *fmt, ...) { va_list ap; if (x386_common_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define x386_common_log(fmt, ...) +# define x386_common_log(fmt, ...) #endif - static __inline void set_stack32(int s) { - if ((cr0 & 1) && ! (cpu_state.eflags & VM_FLAG)) - stack32 = s; + if ((cr0 & 1) && !(cpu_state.eflags & VM_FLAG)) + stack32 = s; else - stack32 = 0; + stack32 = 0; if (stack32) - cpu_cur_status |= CPU_STATUS_STACK32; + cpu_cur_status |= CPU_STATUS_STACK32; else - cpu_cur_status &= ~CPU_STATUS_STACK32; + cpu_cur_status &= ~CPU_STATUS_STACK32; } - static __inline void set_use32(int u) { - if ((cr0 & 1) && ! (cpu_state.eflags & VM_FLAG)) - use32 = u ? 0x300 : 0; + if ((cr0 & 1) && !(cpu_state.eflags & VM_FLAG)) + use32 = u ? 0x300 : 0; else - use32 = 0; + use32 = 0; if (use32) - cpu_cur_status |= CPU_STATUS_USE32; + cpu_cur_status |= CPU_STATUS_USE32; else - cpu_cur_status &= ~CPU_STATUS_USE32; + cpu_cur_status &= ~CPU_STATUS_USE32; } - static void smm_seg_load(x86seg *s) { if (!is386) - s->base &= 0x00ffffff; + s->base &= 0x00ffffff; if ((s->access & 0x18) != 0x10 || !(s->access & (1 << 2))) { - /* Expand down. */ - s->limit_high = s->limit; - s->limit_low = 0; + /* Expand down. */ + s->limit_high = s->limit; + s->limit_low = 0; } else { - s->limit_high = (s->ar_high & 0x40) ? 0xffffffff : 0xffff; - s->limit_low = s->limit + 1; + s->limit_high = (s->ar_high & 0x40) ? 0xffffffff : 0xffff; + s->limit_low = s->limit + 1; } if ((cr0 & 1) && !(cpu_state.eflags & VM_FLAG)) - s->checked = s->seg ? 1 : 0; + s->checked = s->seg ? 1 : 0; else - s->checked = 1; + s->checked = 1; if (s == &cpu_state.seg_cs) - set_use32(s->ar_high & 0x40); + set_use32(s->ar_high & 0x40); if (s == &cpu_state.seg_ds) { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATDS; } if (s == &cpu_state.seg_ss) { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - set_stack32((s->ar_high & 0x40) ? 1 : 0); + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATSS; + set_stack32((s->ar_high & 0x40) ? 1 : 0); } } - static void smram_save_state_p5(uint32_t *saved_state, int in_hlt) { int n = 0; saved_state[SMRAM_FIELD_P5_SMM_REVISION_ID] = SMM_REVISION_ID; - saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET] = smbase; + saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET] = smbase; for (n = 0; n < 8; n++) - saved_state[SMRAM_FIELD_P5_EAX - n] = cpu_state.regs[n].l; + saved_state[SMRAM_FIELD_P5_EAX - n] = cpu_state.regs[n].l; if (in_hlt) - saved_state[SMRAM_FIELD_P5_AUTOHALT_RESTART] = 1; + saved_state[SMRAM_FIELD_P5_AUTOHALT_RESTART] = 1; else - saved_state[SMRAM_FIELD_P5_AUTOHALT_RESTART] = 0; + saved_state[SMRAM_FIELD_P5_AUTOHALT_RESTART] = 0; saved_state[SMRAM_FIELD_P5_EIP] = cpu_state.pc; @@ -427,376 +416,367 @@ smram_save_state_p5(uint32_t *saved_state, int in_hlt) /* TR */ saved_state[SMRAM_FIELD_P5_TR_SELECTOR] = tr.seg; - saved_state[SMRAM_FIELD_P5_TR_BASE] = tr.base; - saved_state[SMRAM_FIELD_P5_TR_LIMIT] = tr.limit; - saved_state[SMRAM_FIELD_P5_TR_ACCESS] = (tr.ar_high << 16) | (tr.access << 8); + saved_state[SMRAM_FIELD_P5_TR_BASE] = tr.base; + saved_state[SMRAM_FIELD_P5_TR_LIMIT] = tr.limit; + saved_state[SMRAM_FIELD_P5_TR_ACCESS] = (tr.ar_high << 16) | (tr.access << 8); /* LDTR */ saved_state[SMRAM_FIELD_P5_LDTR_SELECTOR] = ldt.seg; - saved_state[SMRAM_FIELD_P5_LDTR_BASE] = ldt.base; - saved_state[SMRAM_FIELD_P5_LDTR_LIMIT] = ldt.limit; - saved_state[SMRAM_FIELD_P5_LDTR_ACCESS] = (ldt.ar_high << 16) | (ldt.access << 8); + saved_state[SMRAM_FIELD_P5_LDTR_BASE] = ldt.base; + saved_state[SMRAM_FIELD_P5_LDTR_LIMIT] = ldt.limit; + saved_state[SMRAM_FIELD_P5_LDTR_ACCESS] = (ldt.ar_high << 16) | (ldt.access << 8); /* IDTR */ - saved_state[SMRAM_FIELD_P5_IDTR_BASE] = idt.base; - saved_state[SMRAM_FIELD_P5_IDTR_LIMIT] = idt.limit; + saved_state[SMRAM_FIELD_P5_IDTR_BASE] = idt.base; + saved_state[SMRAM_FIELD_P5_IDTR_LIMIT] = idt.limit; saved_state[SMRAM_FIELD_P5_IDTR_ACCESS] = (idt.ar_high << 16) | (idt.access << 8); /* GDTR */ - saved_state[SMRAM_FIELD_P5_GDTR_BASE] = gdt.base; - saved_state[SMRAM_FIELD_P5_GDTR_LIMIT] = gdt.limit; + saved_state[SMRAM_FIELD_P5_GDTR_BASE] = gdt.base; + saved_state[SMRAM_FIELD_P5_GDTR_LIMIT] = gdt.limit; saved_state[SMRAM_FIELD_P5_GDTR_ACCESS] = (gdt.ar_high << 16) | (gdt.access << 8); /* ES */ saved_state[SMRAM_FIELD_P5_ES_SELECTOR] = cpu_state.seg_es.seg; - saved_state[SMRAM_FIELD_P5_ES_BASE] = cpu_state.seg_es.base; - saved_state[SMRAM_FIELD_P5_ES_LIMIT] = cpu_state.seg_es.limit; - saved_state[SMRAM_FIELD_P5_ES_ACCESS] = (cpu_state.seg_es.ar_high << 16) | (cpu_state.seg_es.access << 8); + saved_state[SMRAM_FIELD_P5_ES_BASE] = cpu_state.seg_es.base; + saved_state[SMRAM_FIELD_P5_ES_LIMIT] = cpu_state.seg_es.limit; + saved_state[SMRAM_FIELD_P5_ES_ACCESS] = (cpu_state.seg_es.ar_high << 16) | (cpu_state.seg_es.access << 8); /* CS */ saved_state[SMRAM_FIELD_P5_CS_SELECTOR] = cpu_state.seg_cs.seg; - saved_state[SMRAM_FIELD_P5_CS_BASE] = cpu_state.seg_cs.base; - saved_state[SMRAM_FIELD_P5_CS_LIMIT] = cpu_state.seg_cs.limit; - saved_state[SMRAM_FIELD_P5_CS_ACCESS] = (cpu_state.seg_cs.ar_high << 16) | (cpu_state.seg_cs.access << 8); + saved_state[SMRAM_FIELD_P5_CS_BASE] = cpu_state.seg_cs.base; + saved_state[SMRAM_FIELD_P5_CS_LIMIT] = cpu_state.seg_cs.limit; + saved_state[SMRAM_FIELD_P5_CS_ACCESS] = (cpu_state.seg_cs.ar_high << 16) | (cpu_state.seg_cs.access << 8); /* DS */ saved_state[SMRAM_FIELD_P5_DS_SELECTOR] = cpu_state.seg_ds.seg; - saved_state[SMRAM_FIELD_P5_DS_BASE] = cpu_state.seg_ds.base; - saved_state[SMRAM_FIELD_P5_DS_LIMIT] = cpu_state.seg_ds.limit; - saved_state[SMRAM_FIELD_P5_DS_ACCESS] = (cpu_state.seg_ds.ar_high << 16) | (cpu_state.seg_ds.access << 8); + saved_state[SMRAM_FIELD_P5_DS_BASE] = cpu_state.seg_ds.base; + saved_state[SMRAM_FIELD_P5_DS_LIMIT] = cpu_state.seg_ds.limit; + saved_state[SMRAM_FIELD_P5_DS_ACCESS] = (cpu_state.seg_ds.ar_high << 16) | (cpu_state.seg_ds.access << 8); /* SS */ saved_state[SMRAM_FIELD_P5_SS_SELECTOR] = cpu_state.seg_ss.seg; - saved_state[SMRAM_FIELD_P5_SS_BASE] = cpu_state.seg_ss.base; - saved_state[SMRAM_FIELD_P5_SS_LIMIT] = cpu_state.seg_ss.limit; - saved_state[SMRAM_FIELD_P5_SS_ACCESS] = (cpu_state.seg_ss.ar_high << 16) | (cpu_state.seg_ss.access << 8); + saved_state[SMRAM_FIELD_P5_SS_BASE] = cpu_state.seg_ss.base; + saved_state[SMRAM_FIELD_P5_SS_LIMIT] = cpu_state.seg_ss.limit; + saved_state[SMRAM_FIELD_P5_SS_ACCESS] = (cpu_state.seg_ss.ar_high << 16) | (cpu_state.seg_ss.access << 8); /* FS */ saved_state[SMRAM_FIELD_P5_FS_SELECTOR] = cpu_state.seg_fs.seg; - saved_state[SMRAM_FIELD_P5_FS_BASE] = cpu_state.seg_fs.base; - saved_state[SMRAM_FIELD_P5_FS_LIMIT] = cpu_state.seg_fs.limit; - saved_state[SMRAM_FIELD_P5_FS_ACCESS] = (cpu_state.seg_fs.ar_high << 16) | (cpu_state.seg_fs.access << 8); + saved_state[SMRAM_FIELD_P5_FS_BASE] = cpu_state.seg_fs.base; + saved_state[SMRAM_FIELD_P5_FS_LIMIT] = cpu_state.seg_fs.limit; + saved_state[SMRAM_FIELD_P5_FS_ACCESS] = (cpu_state.seg_fs.ar_high << 16) | (cpu_state.seg_fs.access << 8); /* GS */ saved_state[SMRAM_FIELD_P5_GS_SELECTOR] = cpu_state.seg_gs.seg; - saved_state[SMRAM_FIELD_P5_GS_BASE] = cpu_state.seg_gs.base; - saved_state[SMRAM_FIELD_P5_GS_LIMIT] = cpu_state.seg_gs.limit; - saved_state[SMRAM_FIELD_P5_GS_ACCESS] = (cpu_state.seg_gs.ar_high << 16) | (cpu_state.seg_gs.access << 8); + saved_state[SMRAM_FIELD_P5_GS_BASE] = cpu_state.seg_gs.base; + saved_state[SMRAM_FIELD_P5_GS_LIMIT] = cpu_state.seg_gs.limit; + saved_state[SMRAM_FIELD_P5_GS_ACCESS] = (cpu_state.seg_gs.ar_high << 16) | (cpu_state.seg_gs.access << 8); /* Am486/5x86 stuff */ if (!is_pentium) { - saved_state[SMRAM_FIELD_AM486_CR2] = cr2; - saved_state[SMRAM_FIELD_AM486_DR0] = dr[0]; - saved_state[SMRAM_FIELD_AM486_DR1] = dr[1]; - saved_state[SMRAM_FIELD_AM486_DR2] = dr[2]; - saved_state[SMRAM_FIELD_AM486_DR3] = dr[3]; + saved_state[SMRAM_FIELD_AM486_CR2] = cr2; + saved_state[SMRAM_FIELD_AM486_DR0] = dr[0]; + saved_state[SMRAM_FIELD_AM486_DR1] = dr[1]; + saved_state[SMRAM_FIELD_AM486_DR2] = dr[2]; + saved_state[SMRAM_FIELD_AM486_DR3] = dr[3]; } } - static void smram_restore_state_p5(uint32_t *saved_state) { int n = 0; for (n = 0; n < 8; n++) - cpu_state.regs[n].l = saved_state[SMRAM_FIELD_P5_EAX - n]; + cpu_state.regs[n].l = saved_state[SMRAM_FIELD_P5_EAX - n]; if (saved_state[SMRAM_FIELD_P5_AUTOHALT_RESTART] & 0xffff) - cpu_state.pc = saved_state[SMRAM_FIELD_P5_EIP] - 1; + cpu_state.pc = saved_state[SMRAM_FIELD_P5_EIP] - 1; else - cpu_state.pc = saved_state[SMRAM_FIELD_P5_EIP]; + cpu_state.pc = saved_state[SMRAM_FIELD_P5_EIP]; cpu_state.eflags = saved_state[SMRAM_FIELD_P5_EFLAGS] >> 16; - cpu_state.flags = saved_state[SMRAM_FIELD_P5_EFLAGS] & 0xffff; + cpu_state.flags = saved_state[SMRAM_FIELD_P5_EFLAGS] & 0xffff; - cr0 = saved_state[SMRAM_FIELD_P5_CR0]; - cr3 = saved_state[SMRAM_FIELD_P5_CR3]; - cr4 = saved_state[SMRAM_FIELD_P5_CR4]; + cr0 = saved_state[SMRAM_FIELD_P5_CR0]; + cr3 = saved_state[SMRAM_FIELD_P5_CR3]; + cr4 = saved_state[SMRAM_FIELD_P5_CR4]; dr[6] = saved_state[SMRAM_FIELD_P5_DR6]; dr[7] = saved_state[SMRAM_FIELD_P5_DR7]; /* TR */ - tr.seg = saved_state[SMRAM_FIELD_P5_TR_SELECTOR]; - tr.base = saved_state[SMRAM_FIELD_P5_TR_BASE]; - tr.limit = saved_state[SMRAM_FIELD_P5_TR_LIMIT]; - tr.access = (saved_state[SMRAM_FIELD_P5_TR_ACCESS] >> 8) & 0xff; + tr.seg = saved_state[SMRAM_FIELD_P5_TR_SELECTOR]; + tr.base = saved_state[SMRAM_FIELD_P5_TR_BASE]; + tr.limit = saved_state[SMRAM_FIELD_P5_TR_LIMIT]; + tr.access = (saved_state[SMRAM_FIELD_P5_TR_ACCESS] >> 8) & 0xff; tr.ar_high = (saved_state[SMRAM_FIELD_P5_TR_ACCESS] >> 16) & 0xff; smm_seg_load(&tr); /* LDTR */ - ldt.seg = saved_state[SMRAM_FIELD_P5_LDTR_SELECTOR]; - ldt.base = saved_state[SMRAM_FIELD_P5_LDTR_BASE]; - ldt.limit = saved_state[SMRAM_FIELD_P5_LDTR_LIMIT]; - ldt.access = (saved_state[SMRAM_FIELD_P5_LDTR_ACCESS] >> 8) & 0xff; + ldt.seg = saved_state[SMRAM_FIELD_P5_LDTR_SELECTOR]; + ldt.base = saved_state[SMRAM_FIELD_P5_LDTR_BASE]; + ldt.limit = saved_state[SMRAM_FIELD_P5_LDTR_LIMIT]; + ldt.access = (saved_state[SMRAM_FIELD_P5_LDTR_ACCESS] >> 8) & 0xff; ldt.ar_high = (saved_state[SMRAM_FIELD_P5_LDTR_ACCESS] >> 16) & 0xff; smm_seg_load(&ldt); /* IDTR */ - idt.base = saved_state[SMRAM_FIELD_P5_IDTR_BASE]; - idt.limit = saved_state[SMRAM_FIELD_P5_IDTR_LIMIT]; - idt.access = (saved_state[SMRAM_FIELD_P5_IDTR_ACCESS] >> 8) & 0xff; + idt.base = saved_state[SMRAM_FIELD_P5_IDTR_BASE]; + idt.limit = saved_state[SMRAM_FIELD_P5_IDTR_LIMIT]; + idt.access = (saved_state[SMRAM_FIELD_P5_IDTR_ACCESS] >> 8) & 0xff; idt.ar_high = (saved_state[SMRAM_FIELD_P5_IDTR_ACCESS] >> 16) & 0xff; /* GDTR */ - gdt.base = saved_state[SMRAM_FIELD_P5_GDTR_BASE]; - gdt.limit = saved_state[SMRAM_FIELD_P5_GDTR_LIMIT]; - gdt.access = (saved_state[SMRAM_FIELD_P5_GDTR_ACCESS] >> 8) & 0xff; + gdt.base = saved_state[SMRAM_FIELD_P5_GDTR_BASE]; + gdt.limit = saved_state[SMRAM_FIELD_P5_GDTR_LIMIT]; + gdt.access = (saved_state[SMRAM_FIELD_P5_GDTR_ACCESS] >> 8) & 0xff; gdt.ar_high = (saved_state[SMRAM_FIELD_P5_GDTR_ACCESS] >> 16) & 0xff; /* ES */ - cpu_state.seg_es.seg = saved_state[SMRAM_FIELD_P5_ES_SELECTOR]; - cpu_state.seg_es.base = saved_state[SMRAM_FIELD_P5_ES_BASE]; - cpu_state.seg_es.limit = saved_state[SMRAM_FIELD_P5_ES_LIMIT]; - cpu_state.seg_es.access = (saved_state[SMRAM_FIELD_P5_ES_ACCESS] >> 8) & 0xff; + cpu_state.seg_es.seg = saved_state[SMRAM_FIELD_P5_ES_SELECTOR]; + cpu_state.seg_es.base = saved_state[SMRAM_FIELD_P5_ES_BASE]; + cpu_state.seg_es.limit = saved_state[SMRAM_FIELD_P5_ES_LIMIT]; + cpu_state.seg_es.access = (saved_state[SMRAM_FIELD_P5_ES_ACCESS] >> 8) & 0xff; cpu_state.seg_es.ar_high = (saved_state[SMRAM_FIELD_P5_ES_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_es); /* CS */ - cpu_state.seg_cs.seg = saved_state[SMRAM_FIELD_P5_CS_SELECTOR]; - cpu_state.seg_cs.base = saved_state[SMRAM_FIELD_P5_CS_BASE]; - cpu_state.seg_cs.limit = saved_state[SMRAM_FIELD_P5_CS_LIMIT]; - cpu_state.seg_cs.access = (saved_state[SMRAM_FIELD_P5_CS_ACCESS] >> 8) & 0xff; + cpu_state.seg_cs.seg = saved_state[SMRAM_FIELD_P5_CS_SELECTOR]; + cpu_state.seg_cs.base = saved_state[SMRAM_FIELD_P5_CS_BASE]; + cpu_state.seg_cs.limit = saved_state[SMRAM_FIELD_P5_CS_LIMIT]; + cpu_state.seg_cs.access = (saved_state[SMRAM_FIELD_P5_CS_ACCESS] >> 8) & 0xff; cpu_state.seg_cs.ar_high = (saved_state[SMRAM_FIELD_P5_CS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_cs); /* DS */ - cpu_state.seg_ds.seg = saved_state[SMRAM_FIELD_P5_DS_SELECTOR]; - cpu_state.seg_ds.base = saved_state[SMRAM_FIELD_P5_DS_BASE]; - cpu_state.seg_ds.limit = saved_state[SMRAM_FIELD_P5_DS_LIMIT]; - cpu_state.seg_ds.access = (saved_state[SMRAM_FIELD_P5_DS_ACCESS] >> 8) & 0xff; + cpu_state.seg_ds.seg = saved_state[SMRAM_FIELD_P5_DS_SELECTOR]; + cpu_state.seg_ds.base = saved_state[SMRAM_FIELD_P5_DS_BASE]; + cpu_state.seg_ds.limit = saved_state[SMRAM_FIELD_P5_DS_LIMIT]; + cpu_state.seg_ds.access = (saved_state[SMRAM_FIELD_P5_DS_ACCESS] >> 8) & 0xff; cpu_state.seg_ds.ar_high = (saved_state[SMRAM_FIELD_P5_DS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_ds); /* SS */ - cpu_state.seg_ss.seg = saved_state[SMRAM_FIELD_P5_SS_SELECTOR]; - cpu_state.seg_ss.base = saved_state[SMRAM_FIELD_P5_SS_BASE]; - cpu_state.seg_ss.limit = saved_state[SMRAM_FIELD_P5_SS_LIMIT]; + cpu_state.seg_ss.seg = saved_state[SMRAM_FIELD_P5_SS_SELECTOR]; + cpu_state.seg_ss.base = saved_state[SMRAM_FIELD_P5_SS_BASE]; + cpu_state.seg_ss.limit = saved_state[SMRAM_FIELD_P5_SS_LIMIT]; cpu_state.seg_ss.access = (saved_state[SMRAM_FIELD_P5_SS_ACCESS] >> 8) & 0xff; /* The actual CPL (DPL of CS) is overwritten with DPL of SS. */ - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | (cpu_state.seg_ss.access & 0x60); + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | (cpu_state.seg_ss.access & 0x60); cpu_state.seg_ss.ar_high = (saved_state[SMRAM_FIELD_P5_SS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_ss); /* FS */ - cpu_state.seg_fs.seg = saved_state[SMRAM_FIELD_P5_FS_SELECTOR]; - cpu_state.seg_fs.base = saved_state[SMRAM_FIELD_P5_FS_BASE]; - cpu_state.seg_fs.limit = saved_state[SMRAM_FIELD_P5_FS_LIMIT]; - cpu_state.seg_fs.access = (saved_state[SMRAM_FIELD_P5_FS_ACCESS] >> 8) & 0xff; + cpu_state.seg_fs.seg = saved_state[SMRAM_FIELD_P5_FS_SELECTOR]; + cpu_state.seg_fs.base = saved_state[SMRAM_FIELD_P5_FS_BASE]; + cpu_state.seg_fs.limit = saved_state[SMRAM_FIELD_P5_FS_LIMIT]; + cpu_state.seg_fs.access = (saved_state[SMRAM_FIELD_P5_FS_ACCESS] >> 8) & 0xff; cpu_state.seg_fs.ar_high = (saved_state[SMRAM_FIELD_P5_FS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_fs); /* GS */ - cpu_state.seg_gs.seg = saved_state[SMRAM_FIELD_P5_GS_SELECTOR]; - cpu_state.seg_gs.base = saved_state[SMRAM_FIELD_P5_GS_BASE]; - cpu_state.seg_gs.limit = saved_state[SMRAM_FIELD_P5_GS_LIMIT]; - cpu_state.seg_gs.access = (saved_state[SMRAM_FIELD_P5_GS_ACCESS] >> 8) & 0xff; + cpu_state.seg_gs.seg = saved_state[SMRAM_FIELD_P5_GS_SELECTOR]; + cpu_state.seg_gs.base = saved_state[SMRAM_FIELD_P5_GS_BASE]; + cpu_state.seg_gs.limit = saved_state[SMRAM_FIELD_P5_GS_LIMIT]; + cpu_state.seg_gs.access = (saved_state[SMRAM_FIELD_P5_GS_ACCESS] >> 8) & 0xff; cpu_state.seg_gs.ar_high = (saved_state[SMRAM_FIELD_P5_GS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_gs); if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION) - smbase = saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET]; + smbase = saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET]; /* Am486/5x86 stuff */ if (!is_pentium) { - cr2 = saved_state[SMRAM_FIELD_AM486_CR2]; - dr[0] = saved_state[SMRAM_FIELD_AM486_DR0]; - dr[1] = saved_state[SMRAM_FIELD_AM486_DR1]; - dr[2] = saved_state[SMRAM_FIELD_AM486_DR2]; - dr[3] = saved_state[SMRAM_FIELD_AM486_DR3]; + cr2 = saved_state[SMRAM_FIELD_AM486_CR2]; + dr[0] = saved_state[SMRAM_FIELD_AM486_DR0]; + dr[1] = saved_state[SMRAM_FIELD_AM486_DR1]; + dr[2] = saved_state[SMRAM_FIELD_AM486_DR2]; + dr[3] = saved_state[SMRAM_FIELD_AM486_DR3]; } } - static void smram_save_state_p6(uint32_t *saved_state, int in_hlt) { int n = 0; saved_state[SMRAM_FIELD_P6_SMM_REVISION_ID] = SMM_REVISION_ID; - saved_state[SMRAM_FIELD_P6_SMBASE_OFFSET] = smbase; + saved_state[SMRAM_FIELD_P6_SMBASE_OFFSET] = smbase; for (n = 0; n < 8; n++) - saved_state[SMRAM_FIELD_P6_EAX - n] = cpu_state.regs[n].l; + saved_state[SMRAM_FIELD_P6_EAX - n] = cpu_state.regs[n].l; if (in_hlt) - saved_state[SMRAM_FIELD_P6_AUTOHALT_RESTART] = 1; + saved_state[SMRAM_FIELD_P6_AUTOHALT_RESTART] = 1; else - saved_state[SMRAM_FIELD_P6_AUTOHALT_RESTART] = 0; + saved_state[SMRAM_FIELD_P6_AUTOHALT_RESTART] = 0; saved_state[SMRAM_FIELD_P6_EIP] = cpu_state.pc; saved_state[SMRAM_FIELD_P6_EFLAGS] = (cpu_state.eflags << 16) | (cpu_state.flags); - saved_state[SMRAM_FIELD_P6_CR0] = cr0; - saved_state[SMRAM_FIELD_P6_CR3] = cr3; - saved_state[SMRAM_FIELD_P6_CR4] = cr4; - saved_state[SMRAM_FIELD_P6_DR6] = dr[6]; - saved_state[SMRAM_FIELD_P6_DR7] = dr[7]; - saved_state[SMRAM_FIELD_P6_CPL] = CPL; + saved_state[SMRAM_FIELD_P6_CR0] = cr0; + saved_state[SMRAM_FIELD_P6_CR3] = cr3; + saved_state[SMRAM_FIELD_P6_CR4] = cr4; + saved_state[SMRAM_FIELD_P6_DR6] = dr[6]; + saved_state[SMRAM_FIELD_P6_DR7] = dr[7]; + saved_state[SMRAM_FIELD_P6_CPL] = CPL; saved_state[SMRAM_FIELD_P6_A20M] = !mem_a20_state; /* TR */ - saved_state[SMRAM_FIELD_P6_TR_SELECTOR] = tr.seg; - saved_state[SMRAM_FIELD_P6_TR_BASE] = tr.base; - saved_state[SMRAM_FIELD_P6_TR_LIMIT] = tr.limit; + saved_state[SMRAM_FIELD_P6_TR_SELECTOR] = tr.seg; + saved_state[SMRAM_FIELD_P6_TR_BASE] = tr.base; + saved_state[SMRAM_FIELD_P6_TR_LIMIT] = tr.limit; saved_state[SMRAM_FIELD_P6_TR_SELECTOR_AR] = (tr.ar_high << 24) | (tr.access << 16) | tr.seg; /* LDTR */ - saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR] = ldt.seg; - saved_state[SMRAM_FIELD_P6_LDTR_BASE] = ldt.base; - saved_state[SMRAM_FIELD_P6_LDTR_LIMIT] = ldt.limit; + saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR] = ldt.seg; + saved_state[SMRAM_FIELD_P6_LDTR_BASE] = ldt.base; + saved_state[SMRAM_FIELD_P6_LDTR_LIMIT] = ldt.limit; saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR_AR] = (ldt.ar_high << 24) | (ldt.access << 16) | ldt.seg; /* IDTR */ - saved_state[SMRAM_FIELD_P6_IDTR_BASE] = idt.base; - saved_state[SMRAM_FIELD_P6_IDTR_LIMIT] = idt.limit; + saved_state[SMRAM_FIELD_P6_IDTR_BASE] = idt.base; + saved_state[SMRAM_FIELD_P6_IDTR_LIMIT] = idt.limit; saved_state[SMRAM_FIELD_P6_IDTR_SELECTOR_AR] = (idt.ar_high << 24) | (idt.access << 16) | idt.seg; /* GDTR */ - saved_state[SMRAM_FIELD_P6_GDTR_BASE] = gdt.base; - saved_state[SMRAM_FIELD_P6_GDTR_LIMIT] = gdt.limit; + saved_state[SMRAM_FIELD_P6_GDTR_BASE] = gdt.base; + saved_state[SMRAM_FIELD_P6_GDTR_LIMIT] = gdt.limit; saved_state[SMRAM_FIELD_P6_GDTR_SELECTOR_AR] = (gdt.ar_high << 24) | (gdt.access << 16) | gdt.seg; /* ES */ - saved_state[SMRAM_FIELD_P6_ES_SELECTOR] = cpu_state.seg_es.seg; - saved_state[SMRAM_FIELD_P6_ES_BASE] = cpu_state.seg_es.base; - saved_state[SMRAM_FIELD_P6_ES_LIMIT] = cpu_state.seg_es.limit; - saved_state[SMRAM_FIELD_P6_ES_SELECTOR_AR] = - (cpu_state.seg_es.ar_high << 24) | (cpu_state.seg_es.access << 16) | cpu_state.seg_es.seg; + saved_state[SMRAM_FIELD_P6_ES_SELECTOR] = cpu_state.seg_es.seg; + saved_state[SMRAM_FIELD_P6_ES_BASE] = cpu_state.seg_es.base; + saved_state[SMRAM_FIELD_P6_ES_LIMIT] = cpu_state.seg_es.limit; + saved_state[SMRAM_FIELD_P6_ES_SELECTOR_AR] = (cpu_state.seg_es.ar_high << 24) | (cpu_state.seg_es.access << 16) | cpu_state.seg_es.seg; /* CS */ - saved_state[SMRAM_FIELD_P6_CS_SELECTOR] = cpu_state.seg_cs.seg; - saved_state[SMRAM_FIELD_P6_CS_BASE] = cpu_state.seg_cs.base; - saved_state[SMRAM_FIELD_P6_CS_LIMIT] = cpu_state.seg_cs.limit; - saved_state[SMRAM_FIELD_P6_CS_SELECTOR_AR] = - (cpu_state.seg_cs.ar_high << 24) | (cpu_state.seg_cs.access << 16) | cpu_state.seg_cs.seg; + saved_state[SMRAM_FIELD_P6_CS_SELECTOR] = cpu_state.seg_cs.seg; + saved_state[SMRAM_FIELD_P6_CS_BASE] = cpu_state.seg_cs.base; + saved_state[SMRAM_FIELD_P6_CS_LIMIT] = cpu_state.seg_cs.limit; + saved_state[SMRAM_FIELD_P6_CS_SELECTOR_AR] = (cpu_state.seg_cs.ar_high << 24) | (cpu_state.seg_cs.access << 16) | cpu_state.seg_cs.seg; /* DS */ - saved_state[SMRAM_FIELD_P6_DS_SELECTOR] = cpu_state.seg_ds.seg; - saved_state[SMRAM_FIELD_P6_DS_BASE] = cpu_state.seg_ds.base; - saved_state[SMRAM_FIELD_P6_DS_LIMIT] = cpu_state.seg_ds.limit; - saved_state[SMRAM_FIELD_P6_DS_SELECTOR_AR] = - (cpu_state.seg_ds.ar_high << 24) | (cpu_state.seg_ds.access << 16) | cpu_state.seg_ds.seg; + saved_state[SMRAM_FIELD_P6_DS_SELECTOR] = cpu_state.seg_ds.seg; + saved_state[SMRAM_FIELD_P6_DS_BASE] = cpu_state.seg_ds.base; + saved_state[SMRAM_FIELD_P6_DS_LIMIT] = cpu_state.seg_ds.limit; + saved_state[SMRAM_FIELD_P6_DS_SELECTOR_AR] = (cpu_state.seg_ds.ar_high << 24) | (cpu_state.seg_ds.access << 16) | cpu_state.seg_ds.seg; /* SS */ - saved_state[SMRAM_FIELD_P6_SS_SELECTOR] = cpu_state.seg_ss.seg; - saved_state[SMRAM_FIELD_P6_SS_BASE] = cpu_state.seg_ss.base; - saved_state[SMRAM_FIELD_P6_SS_LIMIT] = cpu_state.seg_ss.limit; - saved_state[SMRAM_FIELD_P6_SS_SELECTOR_AR] = - (cpu_state.seg_ss.ar_high << 24) | (cpu_state.seg_ss.access << 16) | cpu_state.seg_ss.seg; + saved_state[SMRAM_FIELD_P6_SS_SELECTOR] = cpu_state.seg_ss.seg; + saved_state[SMRAM_FIELD_P6_SS_BASE] = cpu_state.seg_ss.base; + saved_state[SMRAM_FIELD_P6_SS_LIMIT] = cpu_state.seg_ss.limit; + saved_state[SMRAM_FIELD_P6_SS_SELECTOR_AR] = (cpu_state.seg_ss.ar_high << 24) | (cpu_state.seg_ss.access << 16) | cpu_state.seg_ss.seg; /* FS */ - saved_state[SMRAM_FIELD_P6_FS_SELECTOR] = cpu_state.seg_fs.seg; - saved_state[SMRAM_FIELD_P6_FS_BASE] = cpu_state.seg_fs.base; - saved_state[SMRAM_FIELD_P6_FS_LIMIT] = cpu_state.seg_fs.limit; - saved_state[SMRAM_FIELD_P6_FS_SELECTOR_AR] = - (cpu_state.seg_fs.ar_high << 24) | (cpu_state.seg_fs.access << 16) | cpu_state.seg_fs.seg; + saved_state[SMRAM_FIELD_P6_FS_SELECTOR] = cpu_state.seg_fs.seg; + saved_state[SMRAM_FIELD_P6_FS_BASE] = cpu_state.seg_fs.base; + saved_state[SMRAM_FIELD_P6_FS_LIMIT] = cpu_state.seg_fs.limit; + saved_state[SMRAM_FIELD_P6_FS_SELECTOR_AR] = (cpu_state.seg_fs.ar_high << 24) | (cpu_state.seg_fs.access << 16) | cpu_state.seg_fs.seg; /* GS */ - saved_state[SMRAM_FIELD_P6_GS_SELECTOR] = cpu_state.seg_gs.seg; - saved_state[SMRAM_FIELD_P6_GS_BASE] = cpu_state.seg_gs.base; - saved_state[SMRAM_FIELD_P6_GS_LIMIT] = cpu_state.seg_gs.limit; - saved_state[SMRAM_FIELD_P6_GS_SELECTOR_AR] = - (cpu_state.seg_gs.ar_high << 24) | (cpu_state.seg_gs.access << 16) | cpu_state.seg_gs.seg; + saved_state[SMRAM_FIELD_P6_GS_SELECTOR] = cpu_state.seg_gs.seg; + saved_state[SMRAM_FIELD_P6_GS_BASE] = cpu_state.seg_gs.base; + saved_state[SMRAM_FIELD_P6_GS_LIMIT] = cpu_state.seg_gs.limit; + saved_state[SMRAM_FIELD_P6_GS_SELECTOR_AR] = (cpu_state.seg_gs.ar_high << 24) | (cpu_state.seg_gs.access << 16) | cpu_state.seg_gs.seg; } - static void smram_restore_state_p6(uint32_t *saved_state) { int n = 0; for (n = 0; n < 8; n++) - cpu_state.regs[n].l = saved_state[SMRAM_FIELD_P6_EAX - n]; + cpu_state.regs[n].l = saved_state[SMRAM_FIELD_P6_EAX - n]; if (saved_state[SMRAM_FIELD_P6_AUTOHALT_RESTART] & 0xffff) - cpu_state.pc = saved_state[SMRAM_FIELD_P6_EIP] - 1; + cpu_state.pc = saved_state[SMRAM_FIELD_P6_EIP] - 1; else - cpu_state.pc = saved_state[SMRAM_FIELD_P6_EIP]; + cpu_state.pc = saved_state[SMRAM_FIELD_P6_EIP]; cpu_state.eflags = saved_state[SMRAM_FIELD_P6_EFLAGS] >> 16; - cpu_state.flags = saved_state[SMRAM_FIELD_P6_EFLAGS] & 0xffff; + cpu_state.flags = saved_state[SMRAM_FIELD_P6_EFLAGS] & 0xffff; - cr0 = saved_state[SMRAM_FIELD_P6_CR0]; - cr3 = saved_state[SMRAM_FIELD_P6_CR3]; - cr4 = saved_state[SMRAM_FIELD_P6_CR4]; + cr0 = saved_state[SMRAM_FIELD_P6_CR0]; + cr3 = saved_state[SMRAM_FIELD_P6_CR3]; + cr4 = saved_state[SMRAM_FIELD_P6_CR4]; dr[6] = saved_state[SMRAM_FIELD_P6_DR6]; dr[7] = saved_state[SMRAM_FIELD_P6_DR7]; /* TR */ - tr.seg = saved_state[SMRAM_FIELD_P6_TR_SELECTOR]; - tr.base = saved_state[SMRAM_FIELD_P6_TR_BASE]; - tr.limit = saved_state[SMRAM_FIELD_P6_TR_LIMIT]; - tr.access = (saved_state[SMRAM_FIELD_P6_TR_SELECTOR_AR] >> 16) & 0xff; + tr.seg = saved_state[SMRAM_FIELD_P6_TR_SELECTOR]; + tr.base = saved_state[SMRAM_FIELD_P6_TR_BASE]; + tr.limit = saved_state[SMRAM_FIELD_P6_TR_LIMIT]; + tr.access = (saved_state[SMRAM_FIELD_P6_TR_SELECTOR_AR] >> 16) & 0xff; tr.ar_high = (saved_state[SMRAM_FIELD_P6_TR_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&tr); /* LDTR */ - ldt.seg = saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR]; - ldt.base = saved_state[SMRAM_FIELD_P6_LDTR_BASE]; - ldt.limit = saved_state[SMRAM_FIELD_P6_LDTR_LIMIT]; - ldt.access = (saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR_AR] >> 16) & 0xff; + ldt.seg = saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR]; + ldt.base = saved_state[SMRAM_FIELD_P6_LDTR_BASE]; + ldt.limit = saved_state[SMRAM_FIELD_P6_LDTR_LIMIT]; + ldt.access = (saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR_AR] >> 16) & 0xff; ldt.ar_high = (saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&ldt); /* IDTR */ - idt.base = saved_state[SMRAM_FIELD_P6_IDTR_BASE]; - idt.limit = saved_state[SMRAM_FIELD_P6_IDTR_LIMIT]; - idt.access = (saved_state[SMRAM_FIELD_P6_IDTR_SELECTOR_AR] >> 16) & 0xff; + idt.base = saved_state[SMRAM_FIELD_P6_IDTR_BASE]; + idt.limit = saved_state[SMRAM_FIELD_P6_IDTR_LIMIT]; + idt.access = (saved_state[SMRAM_FIELD_P6_IDTR_SELECTOR_AR] >> 16) & 0xff; idt.ar_high = (saved_state[SMRAM_FIELD_P6_IDTR_SELECTOR_AR] >> 24) & 0xff; /* GDTR */ - gdt.base = saved_state[SMRAM_FIELD_P6_GDTR_BASE]; - gdt.limit = saved_state[SMRAM_FIELD_P6_GDTR_LIMIT]; - gdt.access = (saved_state[SMRAM_FIELD_P6_GDTR_SELECTOR_AR] >> 16) & 0xff; + gdt.base = saved_state[SMRAM_FIELD_P6_GDTR_BASE]; + gdt.limit = saved_state[SMRAM_FIELD_P6_GDTR_LIMIT]; + gdt.access = (saved_state[SMRAM_FIELD_P6_GDTR_SELECTOR_AR] >> 16) & 0xff; gdt.ar_high = (saved_state[SMRAM_FIELD_P6_GDTR_SELECTOR_AR] >> 24) & 0xff; /* ES */ - cpu_state.seg_es.seg = saved_state[SMRAM_FIELD_P6_ES_SELECTOR]; - cpu_state.seg_es.base = saved_state[SMRAM_FIELD_P6_ES_BASE]; - cpu_state.seg_es.limit = saved_state[SMRAM_FIELD_P6_ES_LIMIT]; - cpu_state.seg_es.access = (saved_state[SMRAM_FIELD_P6_ES_SELECTOR_AR] >> 16) & 0xff; + cpu_state.seg_es.seg = saved_state[SMRAM_FIELD_P6_ES_SELECTOR]; + cpu_state.seg_es.base = saved_state[SMRAM_FIELD_P6_ES_BASE]; + cpu_state.seg_es.limit = saved_state[SMRAM_FIELD_P6_ES_LIMIT]; + cpu_state.seg_es.access = (saved_state[SMRAM_FIELD_P6_ES_SELECTOR_AR] >> 16) & 0xff; cpu_state.seg_es.ar_high = (saved_state[SMRAM_FIELD_P6_ES_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&cpu_state.seg_es); /* CS */ - cpu_state.seg_cs.seg = saved_state[SMRAM_FIELD_P6_CS_SELECTOR]; - cpu_state.seg_cs.base = saved_state[SMRAM_FIELD_P6_CS_BASE]; - cpu_state.seg_cs.limit = saved_state[SMRAM_FIELD_P6_CS_LIMIT]; - cpu_state.seg_cs.access = (saved_state[SMRAM_FIELD_P6_CS_SELECTOR_AR] >> 16) & 0xff; + cpu_state.seg_cs.seg = saved_state[SMRAM_FIELD_P6_CS_SELECTOR]; + cpu_state.seg_cs.base = saved_state[SMRAM_FIELD_P6_CS_BASE]; + cpu_state.seg_cs.limit = saved_state[SMRAM_FIELD_P6_CS_LIMIT]; + cpu_state.seg_cs.access = (saved_state[SMRAM_FIELD_P6_CS_SELECTOR_AR] >> 16) & 0xff; cpu_state.seg_cs.ar_high = (saved_state[SMRAM_FIELD_P6_CS_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&cpu_state.seg_cs); cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | ((saved_state[SMRAM_FIELD_P6_CPL] & 0x03) << 5); /* DS */ - cpu_state.seg_ds.seg = saved_state[SMRAM_FIELD_P6_DS_SELECTOR]; - cpu_state.seg_ds.base = saved_state[SMRAM_FIELD_P6_DS_BASE]; - cpu_state.seg_ds.limit = saved_state[SMRAM_FIELD_P6_DS_LIMIT]; - cpu_state.seg_ds.access = (saved_state[SMRAM_FIELD_P6_DS_SELECTOR_AR] >> 16) & 0xff; + cpu_state.seg_ds.seg = saved_state[SMRAM_FIELD_P6_DS_SELECTOR]; + cpu_state.seg_ds.base = saved_state[SMRAM_FIELD_P6_DS_BASE]; + cpu_state.seg_ds.limit = saved_state[SMRAM_FIELD_P6_DS_LIMIT]; + cpu_state.seg_ds.access = (saved_state[SMRAM_FIELD_P6_DS_SELECTOR_AR] >> 16) & 0xff; cpu_state.seg_ds.ar_high = (saved_state[SMRAM_FIELD_P6_DS_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&cpu_state.seg_ds); /* SS */ - cpu_state.seg_ss.seg = saved_state[SMRAM_FIELD_P6_SS_SELECTOR]; - cpu_state.seg_ss.base = saved_state[SMRAM_FIELD_P6_SS_BASE]; - cpu_state.seg_ss.limit = saved_state[SMRAM_FIELD_P6_SS_LIMIT]; - cpu_state.seg_ss.access = (saved_state[SMRAM_FIELD_P6_SS_SELECTOR_AR] >> 16) & 0xff; + cpu_state.seg_ss.seg = saved_state[SMRAM_FIELD_P6_SS_SELECTOR]; + cpu_state.seg_ss.base = saved_state[SMRAM_FIELD_P6_SS_BASE]; + cpu_state.seg_ss.limit = saved_state[SMRAM_FIELD_P6_SS_LIMIT]; + cpu_state.seg_ss.access = (saved_state[SMRAM_FIELD_P6_SS_SELECTOR_AR] >> 16) & 0xff; cpu_state.seg_ss.ar_high = (saved_state[SMRAM_FIELD_P6_SS_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&cpu_state.seg_ss); /* FS */ - cpu_state.seg_fs.seg = saved_state[SMRAM_FIELD_P6_FS_SELECTOR]; - cpu_state.seg_fs.base = saved_state[SMRAM_FIELD_P6_FS_BASE]; - cpu_state.seg_fs.limit = saved_state[SMRAM_FIELD_P6_FS_LIMIT]; - cpu_state.seg_fs.access = (saved_state[SMRAM_FIELD_P6_FS_SELECTOR_AR] >> 16) & 0xff; + cpu_state.seg_fs.seg = saved_state[SMRAM_FIELD_P6_FS_SELECTOR]; + cpu_state.seg_fs.base = saved_state[SMRAM_FIELD_P6_FS_BASE]; + cpu_state.seg_fs.limit = saved_state[SMRAM_FIELD_P6_FS_LIMIT]; + cpu_state.seg_fs.access = (saved_state[SMRAM_FIELD_P6_FS_SELECTOR_AR] >> 16) & 0xff; cpu_state.seg_fs.ar_high = (saved_state[SMRAM_FIELD_P6_FS_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&cpu_state.seg_fs); /* GS */ - cpu_state.seg_gs.seg = saved_state[SMRAM_FIELD_P6_GS_SELECTOR]; - cpu_state.seg_gs.base = saved_state[SMRAM_FIELD_P6_GS_BASE]; - cpu_state.seg_gs.limit = saved_state[SMRAM_FIELD_P6_GS_LIMIT]; - cpu_state.seg_gs.access = (saved_state[SMRAM_FIELD_P6_GS_SELECTOR_AR] >> 16) & 0xff; + cpu_state.seg_gs.seg = saved_state[SMRAM_FIELD_P6_GS_SELECTOR]; + cpu_state.seg_gs.base = saved_state[SMRAM_FIELD_P6_GS_BASE]; + cpu_state.seg_gs.limit = saved_state[SMRAM_FIELD_P6_GS_LIMIT]; + cpu_state.seg_gs.access = (saved_state[SMRAM_FIELD_P6_GS_SELECTOR_AR] >> 16) & 0xff; cpu_state.seg_gs.ar_high = (saved_state[SMRAM_FIELD_P6_GS_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&cpu_state.seg_gs); @@ -805,25 +785,24 @@ smram_restore_state_p6(uint32_t *saved_state) mem_a20_recalc(); if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION) - smbase = saved_state[SMRAM_FIELD_P6_SMBASE_OFFSET]; + smbase = saved_state[SMRAM_FIELD_P6_SMBASE_OFFSET]; } - static void smram_save_state_amd_k(uint32_t *saved_state, int in_hlt) { int n = 0; saved_state[SMRAM_FIELD_AMD_K_SMM_REVISION_ID] = SMM_REVISION_ID; - saved_state[SMRAM_FIELD_AMD_K_SMBASE_OFFSET] = smbase; + saved_state[SMRAM_FIELD_AMD_K_SMBASE_OFFSET] = smbase; for (n = 0; n < 8; n++) - saved_state[SMRAM_FIELD_AMD_K_EAX - n] = cpu_state.regs[n].l; + saved_state[SMRAM_FIELD_AMD_K_EAX - n] = cpu_state.regs[n].l; if (in_hlt) - saved_state[SMRAM_FIELD_AMD_K_AUTOHALT_RESTART] = 1; + saved_state[SMRAM_FIELD_AMD_K_AUTOHALT_RESTART] = 1; else - saved_state[SMRAM_FIELD_AMD_K_AUTOHALT_RESTART] = 0; + saved_state[SMRAM_FIELD_AMD_K_AUTOHALT_RESTART] = 0; saved_state[SMRAM_FIELD_AMD_K_EIP] = cpu_state.pc; @@ -838,167 +817,165 @@ smram_save_state_amd_k(uint32_t *saved_state, int in_hlt) /* TR */ saved_state[SMRAM_FIELD_AMD_K_TR_SELECTOR] = tr.seg; - saved_state[SMRAM_FIELD_AMD_K_TR_BASE] = tr.base; - saved_state[SMRAM_FIELD_AMD_K_TR_LIMIT] = tr.limit; - saved_state[SMRAM_FIELD_AMD_K_TR_ACCESS] = (tr.ar_high << 16) | (tr.access << 8); + saved_state[SMRAM_FIELD_AMD_K_TR_BASE] = tr.base; + saved_state[SMRAM_FIELD_AMD_K_TR_LIMIT] = tr.limit; + saved_state[SMRAM_FIELD_AMD_K_TR_ACCESS] = (tr.ar_high << 16) | (tr.access << 8); /* LDTR */ saved_state[SMRAM_FIELD_AMD_K_LDTR_SELECTOR] = ldt.seg; - saved_state[SMRAM_FIELD_AMD_K_LDTR_BASE] = ldt.base; - saved_state[SMRAM_FIELD_AMD_K_LDTR_LIMIT] = ldt.limit; + saved_state[SMRAM_FIELD_AMD_K_LDTR_BASE] = ldt.base; + saved_state[SMRAM_FIELD_AMD_K_LDTR_LIMIT] = ldt.limit; if (!is_k6) - saved_state[SMRAM_FIELD_AMD_K_LDTR_ACCESS] = (ldt.ar_high << 16) | (ldt.access << 8); + saved_state[SMRAM_FIELD_AMD_K_LDTR_ACCESS] = (ldt.ar_high << 16) | (ldt.access << 8); /* IDTR */ - saved_state[SMRAM_FIELD_AMD_K_IDTR_BASE] = idt.base; + saved_state[SMRAM_FIELD_AMD_K_IDTR_BASE] = idt.base; saved_state[SMRAM_FIELD_AMD_K_IDTR_LIMIT] = idt.limit; /* GDTR */ - saved_state[SMRAM_FIELD_AMD_K_GDTR_BASE] = gdt.base; + saved_state[SMRAM_FIELD_AMD_K_GDTR_BASE] = gdt.base; saved_state[SMRAM_FIELD_AMD_K_GDTR_LIMIT] = gdt.limit; /* ES */ saved_state[SMRAM_FIELD_AMD_K_ES_SELECTOR] = cpu_state.seg_es.seg; - saved_state[SMRAM_FIELD_AMD_K_ES_BASE] = cpu_state.seg_es.base; - saved_state[SMRAM_FIELD_AMD_K_ES_LIMIT] = cpu_state.seg_es.limit; - saved_state[SMRAM_FIELD_AMD_K_ES_ACCESS] = (cpu_state.seg_es.ar_high << 16) | (cpu_state.seg_es.access << 8); + saved_state[SMRAM_FIELD_AMD_K_ES_BASE] = cpu_state.seg_es.base; + saved_state[SMRAM_FIELD_AMD_K_ES_LIMIT] = cpu_state.seg_es.limit; + saved_state[SMRAM_FIELD_AMD_K_ES_ACCESS] = (cpu_state.seg_es.ar_high << 16) | (cpu_state.seg_es.access << 8); /* CS */ saved_state[SMRAM_FIELD_AMD_K_CS_SELECTOR] = cpu_state.seg_cs.seg; - saved_state[SMRAM_FIELD_AMD_K_CS_BASE] = cpu_state.seg_cs.base; - saved_state[SMRAM_FIELD_AMD_K_CS_LIMIT] = cpu_state.seg_cs.limit; - saved_state[SMRAM_FIELD_AMD_K_CS_ACCESS] = (cpu_state.seg_cs.ar_high << 16) | (cpu_state.seg_cs.access << 8); + saved_state[SMRAM_FIELD_AMD_K_CS_BASE] = cpu_state.seg_cs.base; + saved_state[SMRAM_FIELD_AMD_K_CS_LIMIT] = cpu_state.seg_cs.limit; + saved_state[SMRAM_FIELD_AMD_K_CS_ACCESS] = (cpu_state.seg_cs.ar_high << 16) | (cpu_state.seg_cs.access << 8); /* DS */ saved_state[SMRAM_FIELD_AMD_K_DS_SELECTOR] = cpu_state.seg_ds.seg; - saved_state[SMRAM_FIELD_AMD_K_DS_BASE] = cpu_state.seg_ds.base; - saved_state[SMRAM_FIELD_AMD_K_DS_LIMIT] = cpu_state.seg_ds.limit; - saved_state[SMRAM_FIELD_AMD_K_DS_ACCESS] = (cpu_state.seg_ds.ar_high << 16) | (cpu_state.seg_ds.access << 8); + saved_state[SMRAM_FIELD_AMD_K_DS_BASE] = cpu_state.seg_ds.base; + saved_state[SMRAM_FIELD_AMD_K_DS_LIMIT] = cpu_state.seg_ds.limit; + saved_state[SMRAM_FIELD_AMD_K_DS_ACCESS] = (cpu_state.seg_ds.ar_high << 16) | (cpu_state.seg_ds.access << 8); /* SS */ saved_state[SMRAM_FIELD_AMD_K_SS_SELECTOR] = cpu_state.seg_ss.seg; - saved_state[SMRAM_FIELD_AMD_K_SS_BASE] = cpu_state.seg_ss.base; - saved_state[SMRAM_FIELD_AMD_K_SS_LIMIT] = cpu_state.seg_ss.limit; - saved_state[SMRAM_FIELD_AMD_K_SS_ACCESS] = (cpu_state.seg_ss.ar_high << 16) | (cpu_state.seg_ss.access << 8); + saved_state[SMRAM_FIELD_AMD_K_SS_BASE] = cpu_state.seg_ss.base; + saved_state[SMRAM_FIELD_AMD_K_SS_LIMIT] = cpu_state.seg_ss.limit; + saved_state[SMRAM_FIELD_AMD_K_SS_ACCESS] = (cpu_state.seg_ss.ar_high << 16) | (cpu_state.seg_ss.access << 8); /* FS */ saved_state[SMRAM_FIELD_AMD_K_FS_SELECTOR] = cpu_state.seg_fs.seg; - saved_state[SMRAM_FIELD_AMD_K_FS_BASE] = cpu_state.seg_fs.base; - saved_state[SMRAM_FIELD_AMD_K_FS_LIMIT] = cpu_state.seg_fs.limit; - saved_state[SMRAM_FIELD_AMD_K_FS_ACCESS] = (cpu_state.seg_fs.ar_high << 16) | (cpu_state.seg_fs.access << 8); + saved_state[SMRAM_FIELD_AMD_K_FS_BASE] = cpu_state.seg_fs.base; + saved_state[SMRAM_FIELD_AMD_K_FS_LIMIT] = cpu_state.seg_fs.limit; + saved_state[SMRAM_FIELD_AMD_K_FS_ACCESS] = (cpu_state.seg_fs.ar_high << 16) | (cpu_state.seg_fs.access << 8); /* GS */ saved_state[SMRAM_FIELD_AMD_K_GS_SELECTOR] = cpu_state.seg_gs.seg; - saved_state[SMRAM_FIELD_AMD_K_GS_BASE] = cpu_state.seg_gs.base; - saved_state[SMRAM_FIELD_AMD_K_GS_LIMIT] = cpu_state.seg_gs.limit; - saved_state[SMRAM_FIELD_AMD_K_GS_ACCESS] = (cpu_state.seg_gs.ar_high << 16) | (cpu_state.seg_gs.access << 8); + saved_state[SMRAM_FIELD_AMD_K_GS_BASE] = cpu_state.seg_gs.base; + saved_state[SMRAM_FIELD_AMD_K_GS_LIMIT] = cpu_state.seg_gs.limit; + saved_state[SMRAM_FIELD_AMD_K_GS_ACCESS] = (cpu_state.seg_gs.ar_high << 16) | (cpu_state.seg_gs.access << 8); } - static void smram_restore_state_amd_k(uint32_t *saved_state) { int n = 0; for (n = 0; n < 8; n++) - cpu_state.regs[n].l = saved_state[SMRAM_FIELD_AMD_K_EAX - n]; + cpu_state.regs[n].l = saved_state[SMRAM_FIELD_AMD_K_EAX - n]; if (saved_state[SMRAM_FIELD_AMD_K_AUTOHALT_RESTART] & 0xffff) - cpu_state.pc = saved_state[SMRAM_FIELD_AMD_K_EIP] - 1; + cpu_state.pc = saved_state[SMRAM_FIELD_AMD_K_EIP] - 1; else - cpu_state.pc = saved_state[SMRAM_FIELD_AMD_K_EIP]; + cpu_state.pc = saved_state[SMRAM_FIELD_AMD_K_EIP]; cpu_state.eflags = saved_state[SMRAM_FIELD_AMD_K_EFLAGS] >> 16; - cpu_state.flags = saved_state[SMRAM_FIELD_AMD_K_EFLAGS] & 0xffff; + cpu_state.flags = saved_state[SMRAM_FIELD_AMD_K_EFLAGS] & 0xffff; - cr0 = saved_state[SMRAM_FIELD_AMD_K_CR0]; - cr2 = saved_state[SMRAM_FIELD_AMD_K_CR2]; - cr3 = saved_state[SMRAM_FIELD_AMD_K_CR3]; - cr4 = saved_state[SMRAM_FIELD_AMD_K_CR4]; + cr0 = saved_state[SMRAM_FIELD_AMD_K_CR0]; + cr2 = saved_state[SMRAM_FIELD_AMD_K_CR2]; + cr3 = saved_state[SMRAM_FIELD_AMD_K_CR3]; + cr4 = saved_state[SMRAM_FIELD_AMD_K_CR4]; dr[6] = saved_state[SMRAM_FIELD_AMD_K_DR6]; dr[7] = saved_state[SMRAM_FIELD_AMD_K_DR7]; /* TR */ - tr.seg = saved_state[SMRAM_FIELD_AMD_K_TR_SELECTOR]; - tr.base = saved_state[SMRAM_FIELD_AMD_K_TR_BASE]; - tr.limit = saved_state[SMRAM_FIELD_AMD_K_TR_LIMIT]; - tr.access = (saved_state[SMRAM_FIELD_AMD_K_TR_ACCESS] >> 8) & 0xff; + tr.seg = saved_state[SMRAM_FIELD_AMD_K_TR_SELECTOR]; + tr.base = saved_state[SMRAM_FIELD_AMD_K_TR_BASE]; + tr.limit = saved_state[SMRAM_FIELD_AMD_K_TR_LIMIT]; + tr.access = (saved_state[SMRAM_FIELD_AMD_K_TR_ACCESS] >> 8) & 0xff; tr.ar_high = (saved_state[SMRAM_FIELD_AMD_K_TR_ACCESS] >> 16) & 0xff; smm_seg_load(&tr); /* LDTR */ - ldt.seg = saved_state[SMRAM_FIELD_AMD_K_LDTR_SELECTOR]; - ldt.base = saved_state[SMRAM_FIELD_AMD_K_LDTR_BASE]; + ldt.seg = saved_state[SMRAM_FIELD_AMD_K_LDTR_SELECTOR]; + ldt.base = saved_state[SMRAM_FIELD_AMD_K_LDTR_BASE]; ldt.limit = saved_state[SMRAM_FIELD_AMD_K_LDTR_LIMIT]; if (!is_k6) { - ldt.access = (saved_state[SMRAM_FIELD_AMD_K_LDTR_ACCESS] >> 8) & 0xff; - ldt.ar_high = (saved_state[SMRAM_FIELD_AMD_K_LDTR_ACCESS] >> 16) & 0xff; + ldt.access = (saved_state[SMRAM_FIELD_AMD_K_LDTR_ACCESS] >> 8) & 0xff; + ldt.ar_high = (saved_state[SMRAM_FIELD_AMD_K_LDTR_ACCESS] >> 16) & 0xff; } smm_seg_load(&ldt); /* IDTR */ - idt.base = saved_state[SMRAM_FIELD_AMD_K_IDTR_BASE]; + idt.base = saved_state[SMRAM_FIELD_AMD_K_IDTR_BASE]; idt.limit = saved_state[SMRAM_FIELD_AMD_K_IDTR_LIMIT]; /* GDTR */ - gdt.base = saved_state[SMRAM_FIELD_AMD_K_GDTR_BASE]; + gdt.base = saved_state[SMRAM_FIELD_AMD_K_GDTR_BASE]; gdt.limit = saved_state[SMRAM_FIELD_AMD_K_GDTR_LIMIT]; /* ES */ - cpu_state.seg_es.seg = saved_state[SMRAM_FIELD_AMD_K_ES_SELECTOR]; - cpu_state.seg_es.base = saved_state[SMRAM_FIELD_AMD_K_ES_BASE]; - cpu_state.seg_es.limit = saved_state[SMRAM_FIELD_AMD_K_ES_LIMIT]; - cpu_state.seg_es.access = (saved_state[SMRAM_FIELD_AMD_K_ES_ACCESS] >> 8) & 0xff; + cpu_state.seg_es.seg = saved_state[SMRAM_FIELD_AMD_K_ES_SELECTOR]; + cpu_state.seg_es.base = saved_state[SMRAM_FIELD_AMD_K_ES_BASE]; + cpu_state.seg_es.limit = saved_state[SMRAM_FIELD_AMD_K_ES_LIMIT]; + cpu_state.seg_es.access = (saved_state[SMRAM_FIELD_AMD_K_ES_ACCESS] >> 8) & 0xff; cpu_state.seg_es.ar_high = (saved_state[SMRAM_FIELD_AMD_K_ES_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_es); /* CS */ - cpu_state.seg_cs.seg = saved_state[SMRAM_FIELD_AMD_K_CS_SELECTOR]; - cpu_state.seg_cs.base = saved_state[SMRAM_FIELD_AMD_K_CS_BASE]; - cpu_state.seg_cs.limit = saved_state[SMRAM_FIELD_AMD_K_CS_LIMIT]; - cpu_state.seg_cs.access = (saved_state[SMRAM_FIELD_AMD_K_CS_ACCESS] >> 8) & 0xff; + cpu_state.seg_cs.seg = saved_state[SMRAM_FIELD_AMD_K_CS_SELECTOR]; + cpu_state.seg_cs.base = saved_state[SMRAM_FIELD_AMD_K_CS_BASE]; + cpu_state.seg_cs.limit = saved_state[SMRAM_FIELD_AMD_K_CS_LIMIT]; + cpu_state.seg_cs.access = (saved_state[SMRAM_FIELD_AMD_K_CS_ACCESS] >> 8) & 0xff; cpu_state.seg_cs.ar_high = (saved_state[SMRAM_FIELD_AMD_K_CS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_cs); /* DS */ - cpu_state.seg_ds.seg = saved_state[SMRAM_FIELD_AMD_K_DS_SELECTOR]; - cpu_state.seg_ds.base = saved_state[SMRAM_FIELD_AMD_K_DS_BASE]; - cpu_state.seg_ds.limit = saved_state[SMRAM_FIELD_AMD_K_DS_LIMIT]; - cpu_state.seg_ds.access = (saved_state[SMRAM_FIELD_AMD_K_DS_ACCESS] >> 8) & 0xff; + cpu_state.seg_ds.seg = saved_state[SMRAM_FIELD_AMD_K_DS_SELECTOR]; + cpu_state.seg_ds.base = saved_state[SMRAM_FIELD_AMD_K_DS_BASE]; + cpu_state.seg_ds.limit = saved_state[SMRAM_FIELD_AMD_K_DS_LIMIT]; + cpu_state.seg_ds.access = (saved_state[SMRAM_FIELD_AMD_K_DS_ACCESS] >> 8) & 0xff; cpu_state.seg_ds.ar_high = (saved_state[SMRAM_FIELD_AMD_K_DS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_ds); /* SS */ - cpu_state.seg_ss.seg = saved_state[SMRAM_FIELD_AMD_K_SS_SELECTOR]; - cpu_state.seg_ss.base = saved_state[SMRAM_FIELD_AMD_K_SS_BASE]; - cpu_state.seg_ss.limit = saved_state[SMRAM_FIELD_AMD_K_SS_LIMIT]; + cpu_state.seg_ss.seg = saved_state[SMRAM_FIELD_AMD_K_SS_SELECTOR]; + cpu_state.seg_ss.base = saved_state[SMRAM_FIELD_AMD_K_SS_BASE]; + cpu_state.seg_ss.limit = saved_state[SMRAM_FIELD_AMD_K_SS_LIMIT]; cpu_state.seg_ss.access = (saved_state[SMRAM_FIELD_AMD_K_SS_ACCESS] >> 8) & 0xff; /* The actual CPL (DPL of CS) is overwritten with DPL of SS. */ - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | (cpu_state.seg_ss.access & 0x60); + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | (cpu_state.seg_ss.access & 0x60); cpu_state.seg_ss.ar_high = (saved_state[SMRAM_FIELD_AMD_K_SS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_ss); /* FS */ - cpu_state.seg_fs.seg = saved_state[SMRAM_FIELD_AMD_K_FS_SELECTOR]; - cpu_state.seg_fs.base = saved_state[SMRAM_FIELD_AMD_K_FS_BASE]; - cpu_state.seg_fs.limit = saved_state[SMRAM_FIELD_AMD_K_FS_LIMIT]; - cpu_state.seg_fs.access = (saved_state[SMRAM_FIELD_AMD_K_FS_ACCESS] >> 8) & 0xff; + cpu_state.seg_fs.seg = saved_state[SMRAM_FIELD_AMD_K_FS_SELECTOR]; + cpu_state.seg_fs.base = saved_state[SMRAM_FIELD_AMD_K_FS_BASE]; + cpu_state.seg_fs.limit = saved_state[SMRAM_FIELD_AMD_K_FS_LIMIT]; + cpu_state.seg_fs.access = (saved_state[SMRAM_FIELD_AMD_K_FS_ACCESS] >> 8) & 0xff; cpu_state.seg_fs.ar_high = (saved_state[SMRAM_FIELD_AMD_K_FS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_fs); /* GS */ - cpu_state.seg_gs.seg = saved_state[SMRAM_FIELD_AMD_K_GS_SELECTOR]; - cpu_state.seg_gs.base = saved_state[SMRAM_FIELD_AMD_K_GS_BASE]; - cpu_state.seg_gs.limit = saved_state[SMRAM_FIELD_AMD_K_GS_LIMIT]; - cpu_state.seg_gs.access = (saved_state[SMRAM_FIELD_AMD_K_GS_ACCESS] >> 8) & 0xff; + cpu_state.seg_gs.seg = saved_state[SMRAM_FIELD_AMD_K_GS_SELECTOR]; + cpu_state.seg_gs.base = saved_state[SMRAM_FIELD_AMD_K_GS_BASE]; + cpu_state.seg_gs.limit = saved_state[SMRAM_FIELD_AMD_K_GS_LIMIT]; + cpu_state.seg_gs.access = (saved_state[SMRAM_FIELD_AMD_K_GS_ACCESS] >> 8) & 0xff; cpu_state.seg_gs.ar_high = (saved_state[SMRAM_FIELD_AMD_K_GS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_gs); if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION) - smbase = saved_state[SMRAM_FIELD_AMD_K_SMBASE_OFFSET]; + smbase = saved_state[SMRAM_FIELD_AMD_K_SMBASE_OFFSET]; } - static void smram_save_state_cyrix(uint32_t *saved_state, int in_hlt) { @@ -1011,18 +988,16 @@ smram_save_state_cyrix(uint32_t *saved_state, int in_hlt) saved_state[6] = 0x00000000; } - static void smram_restore_state_cyrix(uint32_t *saved_state) { - dr[7] = saved_state[0]; - cpu_state.flags = saved_state[1] & 0xffff; + dr[7] = saved_state[0]; + cpu_state.flags = saved_state[1] & 0xffff; cpu_state.eflags = saved_state[1] >> 16; - cr0 = saved_state[2]; - cpu_state.pc = saved_state[4]; + cr0 = saved_state[2]; + cpu_state.pc = saved_state[4]; } - void enter_smm(int in_hlt) { @@ -1031,39 +1006,39 @@ enter_smm(int in_hlt) /* If it's a CPU on which SMM is not supported, do nothing. */ if (!is_am486 && !is_pentium && !is_k5 && !is_k6 && !is_p6 && !is_cxsmm) - return; + return; x386_common_log("enter_smm(): smbase = %08X\n", smbase); x386_common_log("CS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_cs.seg, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.limit_low, - cpu_state.seg_cs.limit_high, cpu_state.seg_cs.access, cpu_state.seg_cs.ar_high); + cpu_state.seg_cs.seg, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.limit_low, + cpu_state.seg_cs.limit_high, cpu_state.seg_cs.access, cpu_state.seg_cs.ar_high); x386_common_log("DS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_ds.seg, cpu_state.seg_ds.base, cpu_state.seg_ds.limit, cpu_state.seg_ds.limit_low, - cpu_state.seg_ds.limit_high, cpu_state.seg_ds.access, cpu_state.seg_ds.ar_high); + cpu_state.seg_ds.seg, cpu_state.seg_ds.base, cpu_state.seg_ds.limit, cpu_state.seg_ds.limit_low, + cpu_state.seg_ds.limit_high, cpu_state.seg_ds.access, cpu_state.seg_ds.ar_high); x386_common_log("ES : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_es.seg, cpu_state.seg_es.base, cpu_state.seg_es.limit, cpu_state.seg_es.limit_low, - cpu_state.seg_es.limit_high, cpu_state.seg_es.access, cpu_state.seg_es.ar_high); + cpu_state.seg_es.seg, cpu_state.seg_es.base, cpu_state.seg_es.limit, cpu_state.seg_es.limit_low, + cpu_state.seg_es.limit_high, cpu_state.seg_es.access, cpu_state.seg_es.ar_high); x386_common_log("FS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_fs.seg, cpu_state.seg_fs.base, cpu_state.seg_fs.limit, cpu_state.seg_fs.limit_low, - cpu_state.seg_fs.limit_high, cpu_state.seg_fs.access, cpu_state.seg_fs.ar_high); + cpu_state.seg_fs.seg, cpu_state.seg_fs.base, cpu_state.seg_fs.limit, cpu_state.seg_fs.limit_low, + cpu_state.seg_fs.limit_high, cpu_state.seg_fs.access, cpu_state.seg_fs.ar_high); x386_common_log("GS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_gs.seg, cpu_state.seg_gs.base, cpu_state.seg_gs.limit, cpu_state.seg_gs.limit_low, - cpu_state.seg_gs.limit_high, cpu_state.seg_gs.access, cpu_state.seg_gs.ar_high); + cpu_state.seg_gs.seg, cpu_state.seg_gs.base, cpu_state.seg_gs.limit, cpu_state.seg_gs.limit_low, + cpu_state.seg_gs.limit_high, cpu_state.seg_gs.access, cpu_state.seg_gs.ar_high); x386_common_log("SS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_ss.seg, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.limit_low, - cpu_state.seg_ss.limit_high, cpu_state.seg_ss.access, cpu_state.seg_ss.ar_high); + cpu_state.seg_ss.seg, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.limit_low, + cpu_state.seg_ss.limit_high, cpu_state.seg_ss.access, cpu_state.seg_ss.ar_high); x386_common_log("TR : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - tr.seg, tr.base, tr.limit, tr.limit_low, tr.limit_high, tr.access, tr.ar_high); + tr.seg, tr.base, tr.limit, tr.limit_low, tr.limit_high, tr.access, tr.ar_high); x386_common_log("LDT: seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - ldt.seg, ldt.base, ldt.limit, ldt.limit_low, ldt.limit_high, ldt.access, ldt.ar_high); + ldt.seg, ldt.base, ldt.limit, ldt.limit_low, ldt.limit_high, ldt.access, ldt.ar_high); x386_common_log("GDT: seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - gdt.seg, gdt.base, gdt.limit, gdt.limit_low, gdt.limit_high, gdt.access, gdt.ar_high); + gdt.seg, gdt.base, gdt.limit, gdt.limit_low, gdt.limit_high, gdt.access, gdt.ar_high); x386_common_log("IDT: seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - idt.seg, idt.base, idt.limit, idt.limit_low, idt.limit_high, idt.access, idt.ar_high); + idt.seg, idt.base, idt.limit, idt.limit_low, idt.limit_high, idt.access, idt.ar_high); x386_common_log("CR0 = %08X, CR3 = %08X, CR4 = %08X, DR6 = %08X, DR7 = %08X\n", cr0, cr3, cr4, dr[6], dr[7]); x386_common_log("EIP = %08X, EFLAGS = %04X%04X\n", cpu_state.pc, cpu_state.eflags, cpu_state.flags); x386_common_log("EAX = %08X, EBX = %08X, ECX = %08X, EDX = %08X, ESI = %08X, EDI = %08X, ESP = %08X, EBP = %08X\n", - EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP); + EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP); flags_rebuild(); in_smm = 1; @@ -1071,24 +1046,24 @@ enter_smm(int in_hlt) smram_recalc_all(0); if (is_cxsmm) { - if (!(cyrix.smhr & SMHR_VALID)) - cyrix.smhr = (cyrix.arr[3].base + cyrix.arr[3].size) | SMHR_VALID; - smram_state = cyrix.smhr & SMHR_ADDR_MASK; + if (!(cyrix.smhr & SMHR_VALID)) + cyrix.smhr = (cyrix.arr[3].base + cyrix.arr[3].size) | SMHR_VALID; + smram_state = cyrix.smhr & SMHR_ADDR_MASK; } memset(saved_state, 0x00, SMM_SAVE_STATE_MAP_SIZE * sizeof(uint32_t)); - if (is_cxsmm) /* Cx6x86 */ - smram_save_state_cyrix(saved_state, in_hlt); - else if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */ - smram_save_state_p5(saved_state, in_hlt); - else if (is_k5 || is_k6) /* AMD K5 and K6 */ - smram_save_state_amd_k(saved_state, in_hlt); - else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ - smram_save_state_p6(saved_state, in_hlt); + if (is_cxsmm) /* Cx6x86 */ + smram_save_state_cyrix(saved_state, in_hlt); + else if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */ + smram_save_state_p5(saved_state, in_hlt); + else if (is_k5 || is_k6) /* AMD K5 and K6 */ + smram_save_state_amd_k(saved_state, in_hlt); + else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ + smram_save_state_p6(saved_state, in_hlt); cr0 &= ~0x8000000d; - cpu_state.flags = 2; + cpu_state.flags = 2; cpu_state.eflags = 0; cr4 = 0; @@ -1096,87 +1071,87 @@ enter_smm(int in_hlt) dr[7] = 0x400; if (is_cxsmm) { - cpu_state.pc = 0x0000; - cpl_override = 1; - cyrix_write_seg_descriptor(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; - cpu_state.seg_cs.limit = 0xffffffff; - cpu_state.seg_cs.access = 0x93; - cpu_state.seg_cs.ar_high = 0x80; - cpu_state.seg_cs.checked = 1; + cpu_state.pc = 0x0000; + cpl_override = 1; + cyrix_write_seg_descriptor(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; + cpu_state.seg_cs.limit = 0xffffffff; + cpu_state.seg_cs.access = 0x93; + cpu_state.seg_cs.ar_high = 0x80; + cpu_state.seg_cs.checked = 1; - smm_seg_load(&cpu_state.seg_cs); + smm_seg_load(&cpu_state.seg_cs); } else { - cpu_state.pc = 0x8000; - cpu_state.seg_ds.seg = 0x00000000; - cpu_state.seg_ds.base = 0x00000000; - cpu_state.seg_ds.limit = 0xffffffff; - cpu_state.seg_ds.access = 0x93; - cpu_state.seg_ds.ar_high = 0x80; + cpu_state.pc = 0x8000; + cpu_state.seg_ds.seg = 0x00000000; + cpu_state.seg_ds.base = 0x00000000; + cpu_state.seg_ds.limit = 0xffffffff; + cpu_state.seg_ds.access = 0x93; + cpu_state.seg_ds.ar_high = 0x80; - memcpy(&cpu_state.seg_es, &cpu_state.seg_ds, sizeof(x86seg)); - memcpy(&cpu_state.seg_ss, &cpu_state.seg_ds, sizeof(x86seg)); - memcpy(&cpu_state.seg_fs, &cpu_state.seg_ds, sizeof(x86seg)); - memcpy(&cpu_state.seg_gs, &cpu_state.seg_ds, sizeof(x86seg)); + memcpy(&cpu_state.seg_es, &cpu_state.seg_ds, sizeof(x86seg)); + memcpy(&cpu_state.seg_ss, &cpu_state.seg_ds, sizeof(x86seg)); + memcpy(&cpu_state.seg_fs, &cpu_state.seg_ds, sizeof(x86seg)); + memcpy(&cpu_state.seg_gs, &cpu_state.seg_ds, sizeof(x86seg)); - if (is_p6) - cpu_state.seg_cs.seg = (smbase >> 4); - else - cpu_state.seg_cs.seg = 0x3000; + if (is_p6) + cpu_state.seg_cs.seg = (smbase >> 4); + else + cpu_state.seg_cs.seg = 0x3000; - /* On Pentium, CS selector in SMM is always 3000, regardless of SMBASE. */ - cpu_state.seg_cs.base = smbase; - cpu_state.seg_cs.limit = 0xffffffff; - cpu_state.seg_cs.access = 0x93; - cpu_state.seg_cs.ar_high = 0x80; - cpu_state.seg_cs.checked = 1; + /* On Pentium, CS selector in SMM is always 3000, regardless of SMBASE. */ + cpu_state.seg_cs.base = smbase; + cpu_state.seg_cs.limit = 0xffffffff; + cpu_state.seg_cs.access = 0x93; + cpu_state.seg_cs.ar_high = 0x80; + cpu_state.seg_cs.checked = 1; - smm_seg_load(&cpu_state.seg_es); - smm_seg_load(&cpu_state.seg_cs); - smm_seg_load(&cpu_state.seg_ds); - smm_seg_load(&cpu_state.seg_ss); - smm_seg_load(&cpu_state.seg_fs); - smm_seg_load(&cpu_state.seg_gs); + smm_seg_load(&cpu_state.seg_es); + smm_seg_load(&cpu_state.seg_cs); + smm_seg_load(&cpu_state.seg_ds); + smm_seg_load(&cpu_state.seg_ss); + smm_seg_load(&cpu_state.seg_fs); + smm_seg_load(&cpu_state.seg_gs); } cpu_state.op32 = use32; cpl_override = 1; if (is_cxsmm) { - writememl(0, smram_state - 0x04, saved_state[0]); - writememl(0, smram_state - 0x08, saved_state[1]); - writememl(0, smram_state - 0x0c, saved_state[2]); - writememl(0, smram_state - 0x10, saved_state[3]); - writememl(0, smram_state - 0x14, saved_state[4]); - writememl(0, smram_state - 0x18, saved_state[5]); - writememl(0, smram_state - 0x24, saved_state[6]); + writememl(0, smram_state - 0x04, saved_state[0]); + writememl(0, smram_state - 0x08, saved_state[1]); + writememl(0, smram_state - 0x0c, saved_state[2]); + writememl(0, smram_state - 0x10, saved_state[3]); + writememl(0, smram_state - 0x14, saved_state[4]); + writememl(0, smram_state - 0x18, saved_state[5]); + writememl(0, smram_state - 0x24, saved_state[6]); } else { - for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) { - smram_state -= 4; - writememl(0, smram_state, saved_state[n]); - } + for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) { + smram_state -= 4; + writememl(0, smram_state, saved_state[n]); + } } cpl_override = 0; nmi_mask = 0; if (smi_latched) { - in_smm = 2; - smi_latched = 0; + in_smm = 2; + smi_latched = 0; } else - in_smm = 1; + in_smm = 1; smm_in_hlt = in_hlt; if (unmask_a20_in_smm) { - old_rammask = rammask; - rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; - if (is6117) - rammask |= 0x3000000; + old_rammask = rammask; + rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; + if (is6117) + rammask |= 0x3000000; - flushmmucache(); + flushmmucache(); } oldcpl = 0; @@ -1185,33 +1160,31 @@ enter_smm(int in_hlt) CPU_BLOCK_END(); } - void enter_smm_check(int in_hlt) { if ((in_smm == 0) && smi_line) { #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SMI while not in SMM\n"); + x386_common_log("SMI while not in SMM\n"); #endif - enter_smm(in_hlt); + enter_smm(in_hlt); } else if ((in_smm == 1) && smi_line) { - /* Mark this so that we don't latch more than one SMI. */ + /* Mark this so that we don't latch more than one SMI. */ #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SMI while in unlatched SMM\n"); + x386_common_log("SMI while in unlatched SMM\n"); #endif - smi_latched = 1; + smi_latched = 1; } else if ((in_smm == 2) && smi_line) { - /* Mark this so that we don't latch more than one SMI. */ + /* Mark this so that we don't latch more than one SMI. */ #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SMI while in latched SMM\n"); + x386_common_log("SMI while in latched SMM\n"); #endif } if (smi_line) - smi_line = 0; + smi_line = 0; } - void leave_smm(void) { @@ -1220,45 +1193,45 @@ leave_smm(void) /* If it's a CPU on which SMM is not supported (or not implemented in 86Box), do nothing. */ if (!is_am486 && !is_pentium && !is_k5 && !is_k6 && !is_p6 && !is_cxsmm) - return; + return; memset(saved_state, 0x00, SMM_SAVE_STATE_MAP_SIZE * sizeof(uint32_t)); cpl_override = 1; if (is_cxsmm) { - smram_state = cyrix.smhr & SMHR_ADDR_MASK; - saved_state[0] = readmeml(0, smram_state - 0x04); - saved_state[1] = readmeml(0, smram_state - 0x08); - saved_state[2] = readmeml(0, smram_state - 0x0c); - 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); - saved_state[6] = readmeml(0, smram_state - 0x24); + smram_state = cyrix.smhr & SMHR_ADDR_MASK; + saved_state[0] = readmeml(0, smram_state - 0x04); + saved_state[1] = readmeml(0, smram_state - 0x08); + saved_state[2] = readmeml(0, smram_state - 0x0c); + 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); + saved_state[6] = readmeml(0, smram_state - 0x24); } else { - for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) { - smram_state -= 4; - saved_state[n] = readmeml(0, smram_state); - x386_common_log("Reading %08X from memory at %08X to array element %i\n", saved_state[n], smram_state, n); - } + for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) { + smram_state -= 4; + saved_state[n] = readmeml(0, smram_state); + x386_common_log("Reading %08X from memory at %08X to array element %i\n", saved_state[n], smram_state, n); + } } cpl_override = 0; if (unmask_a20_in_smm) { - rammask = old_rammask; + rammask = old_rammask; - flushmmucache(); + flushmmucache(); } x386_common_log("New SMBASE: %08X (%08X)\n", saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET], saved_state[66]); - if (is_cxsmm) /* Cx6x86 */ - smram_restore_state_cyrix(saved_state); - else if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */ - smram_restore_state_p5(saved_state); - else if (is_k5 || is_k6) /* AMD K5 and K6 */ - smram_restore_state_amd_k(saved_state); - else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ - smram_restore_state_p6(saved_state); + if (is_cxsmm) /* Cx6x86 */ + smram_restore_state_cyrix(saved_state); + else if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */ + smram_restore_state_p5(saved_state); + else if (is_k5 || is_k6) /* AMD K5 and K6 */ + smram_restore_state_amd_k(saved_state); + else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ + smram_restore_state_p6(saved_state); in_smm = 0; smram_recalc_all(1); @@ -1266,9 +1239,9 @@ leave_smm(void) cpu_386_flags_extract(); cpu_cur_status &= ~(CPU_STATUS_PMODE | CPU_STATUS_V86); if (cr0 & 1) { - cpu_cur_status |= CPU_STATUS_PMODE; - if (cpu_state.eflags & VM_FLAG) - cpu_cur_status |= CPU_STATUS_V86; + cpu_cur_status |= CPU_STATUS_PMODE; + if (cpu_state.eflags & VM_FLAG) + cpu_cur_status |= CPU_STATUS_V86; } nmi_mask = 1; @@ -1278,90 +1251,88 @@ leave_smm(void) CPU_BLOCK_END(); x386_common_log("CS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_cs.seg, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.limit_low, - cpu_state.seg_cs.limit_high, cpu_state.seg_cs.access, cpu_state.seg_cs.ar_high); + cpu_state.seg_cs.seg, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.limit_low, + cpu_state.seg_cs.limit_high, cpu_state.seg_cs.access, cpu_state.seg_cs.ar_high); x386_common_log("DS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_ds.seg, cpu_state.seg_ds.base, cpu_state.seg_ds.limit, cpu_state.seg_ds.limit_low, - cpu_state.seg_ds.limit_high, cpu_state.seg_ds.access, cpu_state.seg_ds.ar_high); + cpu_state.seg_ds.seg, cpu_state.seg_ds.base, cpu_state.seg_ds.limit, cpu_state.seg_ds.limit_low, + cpu_state.seg_ds.limit_high, cpu_state.seg_ds.access, cpu_state.seg_ds.ar_high); x386_common_log("ES : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_es.seg, cpu_state.seg_es.base, cpu_state.seg_es.limit, cpu_state.seg_es.limit_low, - cpu_state.seg_es.limit_high, cpu_state.seg_es.access, cpu_state.seg_es.ar_high); + cpu_state.seg_es.seg, cpu_state.seg_es.base, cpu_state.seg_es.limit, cpu_state.seg_es.limit_low, + cpu_state.seg_es.limit_high, cpu_state.seg_es.access, cpu_state.seg_es.ar_high); x386_common_log("FS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_fs.seg, cpu_state.seg_fs.base, cpu_state.seg_fs.limit, cpu_state.seg_fs.limit_low, - cpu_state.seg_fs.limit_high, cpu_state.seg_fs.access, cpu_state.seg_fs.ar_high); + cpu_state.seg_fs.seg, cpu_state.seg_fs.base, cpu_state.seg_fs.limit, cpu_state.seg_fs.limit_low, + cpu_state.seg_fs.limit_high, cpu_state.seg_fs.access, cpu_state.seg_fs.ar_high); x386_common_log("GS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_gs.seg, cpu_state.seg_gs.base, cpu_state.seg_gs.limit, cpu_state.seg_gs.limit_low, - cpu_state.seg_gs.limit_high, cpu_state.seg_gs.access, cpu_state.seg_gs.ar_high); + cpu_state.seg_gs.seg, cpu_state.seg_gs.base, cpu_state.seg_gs.limit, cpu_state.seg_gs.limit_low, + cpu_state.seg_gs.limit_high, cpu_state.seg_gs.access, cpu_state.seg_gs.ar_high); x386_common_log("SS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_ss.seg, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.limit_low, - cpu_state.seg_ss.limit_high, cpu_state.seg_ss.access, cpu_state.seg_ss.ar_high); + cpu_state.seg_ss.seg, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.limit_low, + cpu_state.seg_ss.limit_high, cpu_state.seg_ss.access, cpu_state.seg_ss.ar_high); x386_common_log("TR : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - tr.seg, tr.base, tr.limit, tr.limit_low, tr.limit_high, tr.access, tr.ar_high); + tr.seg, tr.base, tr.limit, tr.limit_low, tr.limit_high, tr.access, tr.ar_high); x386_common_log("LDT: seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - ldt.seg, ldt.base, ldt.limit, ldt.limit_low, ldt.limit_high, ldt.access, ldt.ar_high); + ldt.seg, ldt.base, ldt.limit, ldt.limit_low, ldt.limit_high, ldt.access, ldt.ar_high); x386_common_log("GDT: seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - gdt.seg, gdt.base, gdt.limit, gdt.limit_low, gdt.limit_high, gdt.access, gdt.ar_high); + gdt.seg, gdt.base, gdt.limit, gdt.limit_low, gdt.limit_high, gdt.access, gdt.ar_high); x386_common_log("IDT: seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - idt.seg, idt.base, idt.limit, idt.limit_low, idt.limit_high, idt.access, idt.ar_high); + idt.seg, idt.base, idt.limit, idt.limit_low, idt.limit_high, idt.access, idt.ar_high); x386_common_log("CR0 = %08X, CR3 = %08X, CR4 = %08X, DR6 = %08X, DR7 = %08X\n", cr0, cr3, cr4, dr[6], dr[7]); x386_common_log("EIP = %08X, EFLAGS = %04X%04X\n", cpu_state.pc, cpu_state.eflags, cpu_state.flags); x386_common_log("EAX = %08X, EBX = %08X, ECX = %08X, EDX = %08X, ESI = %08X, EDI = %08X, ESP = %08X, EBP = %08X\n", - EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP); + EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP); x386_common_log("leave_smm()\n"); } - void x86_int(int num) { uint32_t addr; flags_rebuild(); - cpu_state.pc=cpu_state.oldpc; + cpu_state.pc = cpu_state.oldpc; - if (msw&1) - pmodeint(num,0); + if (msw & 1) + pmodeint(num, 0); else { - addr = (num << 2) + idt.base; + addr = (num << 2) + idt.base; - if ((num << 2UL) + 3UL > idt.limit) { - if (idt.limit < 35) { - cpu_state.abrt = 0; - softresetx86(); - cpu_set_edx(); + if ((num << 2UL) + 3UL > idt.limit) { + if (idt.limit < 35) { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); #ifdef ENABLE_386_COMMON_LOG - x386_common_log("Triple fault in real mode - reset\n"); + x386_common_log("Triple fault in real mode - reset\n"); #endif - } else - x86_int(8); - } else { - if (stack32) { - writememw(ss, ESP - 2, cpu_state.flags); - writememw(ss, ESP - 4, CS); - writememw(ss, ESP - 6, cpu_state.pc); - ESP -= 6; - } else { - writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags); - writememw(ss, ((SP - 4) & 0xFFFF), CS); - writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); - SP -= 6; - } + } else + x86_int(8); + } else { + if (stack32) { + writememw(ss, ESP - 2, cpu_state.flags); + writememw(ss, ESP - 4, CS); + writememw(ss, ESP - 6, cpu_state.pc); + ESP -= 6; + } else { + writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags); + writememw(ss, ((SP - 4) & 0xFFFF), CS); + writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); + SP -= 6; + } - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; #ifndef USE_NEW_DYNAREC - oxpc = cpu_state.pc; + oxpc = cpu_state.pc; #endif - cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); - } + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + } } cycles -= 70; CPU_BLOCK_END(); } - void x86_int_sw(int num) { @@ -1370,42 +1341,41 @@ x86_int_sw(int num) flags_rebuild(); cycles -= timing_int; - if (msw&1) - pmodeint(num,1); + if (msw & 1) + pmodeint(num, 1); else { - addr = (num << 2) + idt.base; + addr = (num << 2) + idt.base; - if ((num << 2UL) + 3UL > idt.limit) - x86_int(0x0d); - else { - if (stack32) { - writememw(ss, ESP - 2, cpu_state.flags); - writememw(ss, ESP - 4, CS); - writememw(ss, ESP - 6, cpu_state.pc); - ESP -= 6; - } else { - writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags); - writememw(ss, ((SP - 4) & 0xFFFF), CS); - writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); - SP -= 6; - } + if ((num << 2UL) + 3UL > idt.limit) + x86_int(0x0d); + else { + if (stack32) { + writememw(ss, ESP - 2, cpu_state.flags); + writememw(ss, ESP - 4, CS); + writememw(ss, ESP - 6, cpu_state.pc); + ESP -= 6; + } else { + writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags); + writememw(ss, ((SP - 4) & 0xFFFF), CS); + writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); + SP -= 6; + } - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; #ifndef USE_NEW_DYNAREC - oxpc = cpu_state.pc; + oxpc = cpu_state.pc; #endif - cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); - cycles -= timing_int_rm; - } + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + cycles -= timing_int_rm; + } } trap = 0; CPU_BLOCK_END(); } - int x86_int_sw_rm(int num) { @@ -1415,23 +1385,23 @@ x86_int_sw_rm(int num) flags_rebuild(); cycles -= timing_int; - addr = num << 2; + addr = num << 2; new_pc = readmemw(0, addr); new_cs = readmemw(0, addr + 2); if (cpu_state.abrt) - return 1; + return 1; writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags); if (cpu_state.abrt) - return 1; + return 1; writememw(ss, ((SP - 4) & 0xFFFF), CS); writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); if (cpu_state.abrt) - return 1; + return 1; SP -= 6; @@ -1450,49 +1420,47 @@ x86_int_sw_rm(int num) return 0; } - void x86illegal(void) { x86_int(6); } - int checkio(uint32_t port) { uint16_t t; - uint8_t d; + uint8_t d; cpl_override = 1; - t = readmemw(tr.base, 0x66); + t = readmemw(tr.base, 0x66); cpl_override = 0; if (cpu_state.abrt) - return 0; + return 0; if ((t + (port >> 3UL)) > tr.limit) - return 1; + return 1; cpl_override = 1; - d = readmembl(tr.base + t + (port >> 3)); + d = readmembl(tr.base + t + (port >> 3)); cpl_override = 0; return d & (1 << (port & 7)); } - #ifdef OLD_DIVEXCP -#define divexcp() { \ - x386_common_log("Divide exception at %04X(%06X):%04X\n",CS,cs,cpu_state.pc); \ - x86_int(0); \ -} +# define divexcp() \ + { \ + x386_common_log("Divide exception at %04X(%06X):%04X\n", CS, cs, cpu_state.pc); \ + x86_int(0); \ + } #else -#define divexcp() { \ - x86de(NULL, 0); \ -} +# define divexcp() \ + { \ + x86de(NULL, 0); \ + } #endif - int divl(uint32_t val) { @@ -1500,18 +1468,18 @@ divl(uint32_t val) uint32_t rem, quo32; if (val == 0) { - divexcp(); - return 1; + divexcp(); + return 1; } - num = (((uint64_t) EDX) << 32) | EAX; - quo = num / val; - rem = num % val; - quo32=(uint32_t)(quo&0xFFFFFFFF); + num = (((uint64_t) EDX) << 32) | EAX; + quo = num / val; + rem = num % val; + quo32 = (uint32_t) (quo & 0xFFFFFFFF); if (quo != (uint64_t) quo32) { - divexcp(); - return 1; + divexcp(); + return 1; } EDX = rem; @@ -1520,26 +1488,25 @@ divl(uint32_t val) return 0; } - int idivl(int32_t val) { int64_t num, quo; int32_t rem, quo32; - if (val == 0) { - divexcp(); - return 1; + if (val == 0) { + divexcp(); + return 1; } - num = (((uint64_t) EDX) << 32) | EAX; - quo = num / val; - rem = num % val; + num = (((uint64_t) EDX) << 32) | EAX; + quo = num / val; + rem = num % val; quo32 = (int32_t) (quo & 0xFFFFFFFF); if (quo != (int64_t) quo32) { - divexcp(); - return 1; + divexcp(); + return 1; } EDX = rem; @@ -1548,21 +1515,18 @@ idivl(int32_t val) return 0; } - void cpu_386_flags_extract(void) { flags_extract(); } - void cpu_386_flags_rebuild(void) { flags_rebuild(); } - int sysenter(uint32_t fetchdat) { @@ -1572,18 +1536,18 @@ sysenter(uint32_t fetchdat) if (!(msw & 1)) { #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SYSENTER: CPU not in protected mode"); + x386_common_log("SYSENTER: CPU not in protected mode"); #endif - x86gpf("SYSENTER: CPU not in protected mode", 0); - return cpu_state.abrt; + x86gpf("SYSENTER: CPU not in protected mode", 0); + return cpu_state.abrt; } if (!(msr.sysenter_cs & 0xFFF8)) { #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SYSENTER: CS MSR is zero"); + x386_common_log("SYSENTER: CS MSR is zero"); #endif - x86gpf("SYSENTER: CS MSR is zero", 0); - return cpu_state.abrt; + x86gpf("SYSENTER: CS MSR is zero", 0); + return cpu_state.abrt; } #ifdef ENABLE_386_COMMON_LOG @@ -1602,33 +1566,33 @@ sysenter(uint32_t fetchdat) oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; - ESP = msr.sysenter_esp; - cpu_state.pc = msr.sysenter_eip; + ESP = msr.sysenter_esp; + cpu_state.pc = msr.sysenter_eip; - cpu_state.seg_cs.seg = (msr.sysenter_cs & 0xfffc); - cpu_state.seg_cs.base = 0; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit = 0xffffffff; + cpu_state.seg_cs.seg = (msr.sysenter_cs & 0xfffc); + cpu_state.seg_cs.base = 0; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit = 0xffffffff; cpu_state.seg_cs.limit_high = 0xffffffff; - cpu_state.seg_cs.access = 0x9b; - cpu_state.seg_cs.ar_high = 0xcf; - cpu_state.seg_cs.checked = 1; - oldcpl = 0; + cpu_state.seg_cs.access = 0x9b; + cpu_state.seg_cs.ar_high = 0xcf; + cpu_state.seg_cs.checked = 1; + oldcpl = 0; - cpu_state.seg_ss.seg = ((msr.sysenter_cs + 8) & 0xfffc); - cpu_state.seg_ss.base = 0; - cpu_state.seg_ss.limit_low = 0; - cpu_state.seg_ss.limit = 0xffffffff; + cpu_state.seg_ss.seg = ((msr.sysenter_cs + 8) & 0xfffc); + cpu_state.seg_ss.base = 0; + cpu_state.seg_ss.limit_low = 0; + cpu_state.seg_ss.limit = 0xffffffff; cpu_state.seg_ss.limit_high = 0xffffffff; - cpu_state.seg_ss.access = 0x93; - cpu_state.seg_ss.ar_high = 0xcf; - cpu_state.seg_ss.checked = 1; + cpu_state.seg_ss.access = 0x93; + cpu_state.seg_ss.ar_high = 0xcf; + cpu_state.seg_ss.checked = 1; #ifdef USE_DYNAREC codegen_flat_ss = 0; #endif cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS | CPU_STATUS_V86); - cpu_cur_status |= (CPU_STATUS_USE32 | CPU_STATUS_STACK32/* | CPU_STATUS_PMODE*/); + cpu_cur_status |= (CPU_STATUS_USE32 | CPU_STATUS_STACK32 /* | CPU_STATUS_PMODE*/); set_use32(1); set_stack32(1); @@ -1645,7 +1609,6 @@ sysenter(uint32_t fetchdat) return 1; } - int sysexit(uint32_t fetchdat) { @@ -1655,26 +1618,26 @@ sysexit(uint32_t fetchdat) if (!(msr.sysenter_cs & 0xFFF8)) { #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SYSEXIT: CS MSR is zero"); + x386_common_log("SYSEXIT: CS MSR is zero"); #endif - x86gpf("SYSEXIT: CS MSR is zero", 0); - return cpu_state.abrt; + x86gpf("SYSEXIT: CS MSR is zero", 0); + return cpu_state.abrt; } if (!(msw & 1)) { #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SYSEXIT: CPU not in protected mode"); + x386_common_log("SYSEXIT: CPU not in protected mode"); #endif - x86gpf("SYSEXIT: CPU not in protected mode", 0); - return cpu_state.abrt; + x86gpf("SYSEXIT: CPU not in protected mode", 0); + return cpu_state.abrt; } if (CPL) { #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SYSEXIT: CPL not 0"); + x386_common_log("SYSEXIT: CPL not 0"); #endif - x86gpf("SYSEXIT: CPL not 0", 0); - return cpu_state.abrt; + x86gpf("SYSEXIT: CPL not 0", 0); + return cpu_state.abrt; } #ifdef ENABLE_386_COMMON_LOG @@ -1689,32 +1652,32 @@ sysexit(uint32_t fetchdat) oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; - ESP = ECX; - cpu_state.pc = EDX; + ESP = ECX; + cpu_state.pc = EDX; - cpu_state.seg_cs.seg = (((msr.sysenter_cs + 16) & 0xfffc) | 3); - cpu_state.seg_cs.base = 0; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit = 0xffffffff; + cpu_state.seg_cs.seg = (((msr.sysenter_cs + 16) & 0xfffc) | 3); + cpu_state.seg_cs.base = 0; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit = 0xffffffff; cpu_state.seg_cs.limit_high = 0xffffffff; - cpu_state.seg_cs.access = 0xfb; - cpu_state.seg_cs.ar_high = 0xcf; - cpu_state.seg_cs.checked = 1; - oldcpl = 3; + cpu_state.seg_cs.access = 0xfb; + cpu_state.seg_cs.ar_high = 0xcf; + cpu_state.seg_cs.checked = 1; + oldcpl = 3; - cpu_state.seg_ss.seg = (((msr.sysenter_cs + 24) & 0xfffc) | 3); - cpu_state.seg_ss.base = 0; - cpu_state.seg_ss.limit_low = 0; - cpu_state.seg_ss.limit = 0xffffffff; + cpu_state.seg_ss.seg = (((msr.sysenter_cs + 24) & 0xfffc) | 3); + cpu_state.seg_ss.base = 0; + cpu_state.seg_ss.limit_low = 0; + cpu_state.seg_ss.limit = 0xffffffff; cpu_state.seg_ss.limit_high = 0xffffffff; - cpu_state.seg_ss.access = 0xf3; - cpu_state.seg_ss.ar_high = 0xcf; - cpu_state.seg_ss.checked = 1; + cpu_state.seg_ss.access = 0xf3; + cpu_state.seg_ss.ar_high = 0xcf; + cpu_state.seg_ss.checked = 1; #ifdef USE_DYNAREC codegen_flat_ss = 0; #endif - cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS/* | CPU_STATUS_V86*/); + cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS /* | CPU_STATUS_V86*/); cpu_cur_status |= (CPU_STATUS_USE32 | CPU_STATUS_STACK32 | CPU_STATUS_PMODE); flushmmucache_cr3(); set_use32(1); @@ -1733,7 +1696,6 @@ sysexit(uint32_t fetchdat) return 1; } - int syscall_op(uint32_t fetchdat) { @@ -1750,28 +1712,28 @@ syscall_op(uint32_t fetchdat) oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; - ECX = cpu_state.pc; + ECX = cpu_state.pc; /* CS */ - CS = AMD_SYSCALL_SB & 0xfffc; - cpu_state.seg_cs.base = 0; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit = 0xffffffff; + CS = AMD_SYSCALL_SB & 0xfffc; + cpu_state.seg_cs.base = 0; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit = 0xffffffff; cpu_state.seg_cs.limit_high = 0xffffffff; - cpu_state.seg_cs.access = 0x9b; - cpu_state.seg_cs.ar_high = 0xcf; - cpu_state.seg_cs.checked = 1; - oldcpl = 0; + cpu_state.seg_cs.access = 0x9b; + cpu_state.seg_cs.ar_high = 0xcf; + cpu_state.seg_cs.checked = 1; + oldcpl = 0; /* SS */ - SS = (AMD_SYSCALL_SB + 8) & 0xfffc; - cpu_state.seg_ss.base = 0; - cpu_state.seg_ss.limit_low = 0; - cpu_state.seg_ss.limit = 0xffffffff; + SS = (AMD_SYSCALL_SB + 8) & 0xfffc; + cpu_state.seg_ss.base = 0; + cpu_state.seg_ss.limit_low = 0; + cpu_state.seg_ss.limit = 0xffffffff; cpu_state.seg_ss.limit_high = 0xffffffff; - cpu_state.seg_ss.access = 0x93; - cpu_state.seg_ss.ar_high = 0xcf; - cpu_state.seg_ss.checked = 1; + cpu_state.seg_ss.access = 0x93; + cpu_state.seg_ss.ar_high = 0xcf; + cpu_state.seg_ss.checked = 1; #ifdef USE_DYNAREC codegen_flat_ss = 0; #endif @@ -1786,7 +1748,6 @@ syscall_op(uint32_t fetchdat) return 1; } - int sysret(uint32_t fetchdat) { @@ -1796,10 +1757,10 @@ sysret(uint32_t fetchdat) if (CPL) { #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SYSRET: CPL not 0"); + x386_common_log("SYSRET: CPL not 0"); #endif - x86gpf("SYSRET: CPL not 0", 0); - return cpu_state.abrt; + x86gpf("SYSRET: CPL not 0", 0); + return cpu_state.abrt; } cpu_state.flags |= I_FLAG; @@ -1811,33 +1772,33 @@ sysret(uint32_t fetchdat) oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; - cpu_state.pc = ECX; + cpu_state.pc = ECX; /* CS */ - CS = (AMD_SYSRET_SB & 0xfffc) | 3; - cpu_state.seg_cs.base = 0; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit = 0xffffffff; + CS = (AMD_SYSRET_SB & 0xfffc) | 3; + cpu_state.seg_cs.base = 0; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit = 0xffffffff; cpu_state.seg_cs.limit_high = 0xffffffff; - cpu_state.seg_cs.access = 0xfb; - cpu_state.seg_cs.ar_high = 0xcf; - cpu_state.seg_cs.checked = 1; - oldcpl = 3; + cpu_state.seg_cs.access = 0xfb; + cpu_state.seg_cs.ar_high = 0xcf; + cpu_state.seg_cs.checked = 1; + oldcpl = 3; /* SS */ - SS = ((AMD_SYSRET_SB + 8) & 0xfffc) | 3; - cpu_state.seg_ss.base = 0; - cpu_state.seg_ss.limit_low = 0; - cpu_state.seg_ss.limit = 0xffffffff; + SS = ((AMD_SYSRET_SB + 8) & 0xfffc) | 3; + cpu_state.seg_ss.base = 0; + cpu_state.seg_ss.limit_low = 0; + cpu_state.seg_ss.limit = 0xffffffff; cpu_state.seg_ss.limit_high = 0xffffffff; - cpu_state.seg_ss.access = 0xf3; - cpu_state.seg_cs.ar_high = 0xcf; - cpu_state.seg_ss.checked = 1; + cpu_state.seg_ss.access = 0xf3; + cpu_state.seg_cs.ar_high = 0xcf; + cpu_state.seg_ss.checked = 1; #ifdef USE_DYNAREC codegen_flat_ss = 0; #endif - cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS/* | CPU_STATUS_V86*/); + cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS /* | CPU_STATUS_V86*/); cpu_cur_status |= (CPU_STATUS_USE32 | CPU_STATUS_STACK32 | CPU_STATUS_PMODE); flushmmucache_cr3(); set_use32(1); @@ -1848,23 +1809,20 @@ sysret(uint32_t fetchdat) return 1; } - void cpu_register_fast_off_handler(void *timer) { cpu_fast_off_timer = (pc_timer_t *) timer; } - void cpu_fast_off_advance(void) { timer_disable(cpu_fast_off_timer); if (cpu_fast_off_period != 0.0) - timer_on_auto(cpu_fast_off_timer, cpu_fast_off_period); + timer_on_auto(cpu_fast_off_timer, cpu_fast_off_period); } - void cpu_fast_off_period_set(uint16_t val, double period) { @@ -1872,7 +1830,6 @@ cpu_fast_off_period_set(uint16_t val, double period) cpu_fast_off_advance(); } - void cpu_fast_off_reset(void) { @@ -1881,31 +1838,29 @@ cpu_fast_off_reset(void) cpu_fast_off_advance(); } - void smi_raise(void) { if (is486 && (cpu_fast_off_flags & 0x80000000)) - cpu_fast_off_advance(); + cpu_fast_off_advance(); smi_line = 1; } - void nmi_raise(void) { if (is486 && (cpu_fast_off_flags & 0x20000000)) - cpu_fast_off_advance(); + cpu_fast_off_advance(); nmi = 1; } - #ifndef USE_DYNAREC /* This is for compatibility with new x87 code. */ -void codegen_set_rounding_mode(int mode) +void +codegen_set_rounding_mode(int mode) { - /* cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (mode << 10); */ + /* cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (mode << 10); */ } #endif diff --git a/src/cpu/386_common.h b/src/cpu/386_common.h index f99c143d9..6310ae642 100644 --- a/src/cpu/386_common.h +++ b/src/cpu/386_common.h @@ -21,308 +21,400 @@ #include -#define readmemb_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF)?readmembl_no_mmut((s)+(a),b): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uintptr_t)((s) + (a))) ) -#define readmemw_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1))?readmemwl_no_mmut((s)+(a),b):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -#define readmeml_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll_no_mmut((s)+(a),b):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -#define readmemb(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF)?readmembl((s)+(a)): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uintptr_t)((s) + (a))) ) -#define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1))?readmemwl((s)+(a)):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -#define readmeml(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll((s)+(a)):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -#define readmemq(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 7))?readmemql((s)+(a)):*(uint64_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uintptr_t)((s)+(a)))) +#define readmemb_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl_no_mmut((s) + (a), b) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) +#define readmemw_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl_no_mmut((s) + (a), b) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +#define readmeml_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll_no_mmut((s) + (a), b) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +#define readmemb(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl((s) + (a)) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) +#define readmemw(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl((s) + (a)) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +#define readmeml(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll((s) + (a)) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +#define readmemq(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) ? readmemql((s) + (a)) : *(uint64_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) -#define writememb_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) writemembl_no_mmut((s)+(a),b,v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememw_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) writememwl_no_mmut((s)+(a),b,v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememl_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) writememll_no_mmut((s)+(a),b,v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememb(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) writemembl((s)+(a),v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememw(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) writememwl((s)+(a),v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememl(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) writememll((s)+(a),v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememq(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 7)) writememql((s)+(a),v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v +#define writememb_n(s, a, b, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + writemembl_no_mmut((s) + (a), b, v); \ + else \ + *(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +#define writememw_n(s, a, b, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + writememwl_no_mmut((s) + (a), b, v); \ + else \ + *(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +#define writememl_n(s, a, b, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + writememll_no_mmut((s) + (a), b, v); \ + else \ + *(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +#define writememb(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + writemembl((s) + (a), v); \ + else \ + *(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +#define writememw(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + writememwl((s) + (a), v); \ + else \ + *(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +#define writememl(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + writememll((s) + (a), v); \ + else \ + *(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +#define writememq(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) \ + writememql((s) + (a), v); \ + else \ + *(uint64_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -#define do_mmut_rb(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 0) -#define do_mmut_rw(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 0) -#define do_mmut_rl(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 0) -#define do_mmut_rb2(s,a,b) old_rl2 = readlookup2[(uint32_t)((s)+(a))>>12]; if (old_rl2==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 0) -#define do_mmut_rw2(s,a,b) old_rl2 = readlookup2[(uint32_t)((s)+(a))>>12]; if (old_rl2==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 0) -#define do_mmut_rl2(s,a,b) old_rl2 = readlookup2[(uint32_t)((s)+(a))>>12]; if (old_rl2==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 0) - -#define do_mmut_wb(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 1) -#define do_mmut_ww(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 1) -#define do_mmut_wl(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 1) +#define do_mmut_rb(s, a, b) \ + if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + do_mmutranslate((s) + (a), b, 1, 0) +#define do_mmut_rw(s, a, b) \ + if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + do_mmutranslate((s) + (a), b, 2, 0) +#define do_mmut_rl(s, a, b) \ + if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + do_mmutranslate((s) + (a), b, 4, 0) +#define do_mmut_rb2(s, a, b) \ + old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ + if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + do_mmutranslate((s) + (a), b, 1, 0) +#define do_mmut_rw2(s, a, b) \ + old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ + if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + do_mmutranslate((s) + (a), b, 2, 0) +#define do_mmut_rl2(s, a, b) \ + old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ + if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + do_mmutranslate((s) + (a), b, 4, 0) +#define do_mmut_wb(s, a, b) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + do_mmutranslate((s) + (a), b, 1, 1) +#define do_mmut_ww(s, a, b) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + do_mmutranslate((s) + (a), b, 2, 1) +#define do_mmut_wl(s, a, b) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + do_mmutranslate((s) + (a), b, 4, 1) int checkio(uint32_t port); +#define check_io_perm(port) \ + if (msw & 1 && ((CPL > IOPL) || (cpu_state.eflags & VM_FLAG))) { \ + int tempi = checkio(port); \ + if (cpu_state.abrt) \ + return 1; \ + if (tempi) { \ + if (cpu_state.eflags & VM_FLAG) \ + x86gpf_expected(NULL, 0); \ + else \ + x86gpf(NULL, 0); \ + return 1; \ + } \ + } -#define check_io_perm(port) if (msw&1 && ((CPL > IOPL) || (cpu_state.eflags&VM_FLAG))) \ - { \ - int tempi = checkio(port); \ - if (cpu_state.abrt) return 1; \ - if (tempi) \ - { \ - if (cpu_state.eflags & VM_FLAG) \ - x86gpf_expected(NULL,0); \ - else \ - x86gpf(NULL,0); \ - return 1; \ - } \ - } +#define SEG_CHECK_READ(seg) \ + do { \ + if ((seg)->base == 0xffffffff) { \ + x86gpf("Segment can't read", 0); \ + return 1; \ + } \ + } while (0) -#define SEG_CHECK_READ(seg) \ - do \ - { \ - if ((seg)->base == 0xffffffff) \ - { \ - x86gpf("Segment can't read", 0);\ - return 1; \ - } \ - } while (0) +#define SEG_CHECK_WRITE(seg) \ + do { \ + if ((seg)->base == 0xffffffff) { \ + x86gpf("Segment can't write", 0); \ + return 1; \ + } \ + } while (0) -#define SEG_CHECK_WRITE(seg) \ - do \ - { \ - if ((seg)->base == 0xffffffff) \ - { \ - x86gpf("Segment can't write", 0);\ - return 1; \ - } \ - } while (0) +#define CHECK_READ(chseg, low, high) \ + if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && (((chseg)->access & 10) == 8))) { \ + x86gpf("Limit check (READ)", 0); \ + return 1; \ + } \ + if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !((chseg)->access & 0x80)) { \ + if ((chseg) == &cpu_state.seg_ss) \ + x86ss(NULL, (chseg)->seg & 0xfffc); \ + else \ + x86np("Read from seg not present", (chseg)->seg & 0xfffc); \ + return 1; \ + } -#define CHECK_READ(chseg, low, high) \ - if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && (((chseg)->access & 10) == 8))) \ - { \ - x86gpf("Limit check (READ)", 0); \ - return 1; \ - } \ - if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \ - { \ - if ((chseg) == &cpu_state.seg_ss) \ - x86ss(NULL,(chseg)->seg & 0xfffc); \ - else \ - x86np("Read from seg not present", (chseg)->seg & 0xfffc); \ - return 1; \ - } +#define CHECK_READ_REP(chseg, low, high) \ + if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) { \ + x86gpf("Limit check (READ)", 0); \ + break; \ + } \ + if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !((chseg)->access & 0x80)) { \ + if ((chseg) == &cpu_state.seg_ss) \ + x86ss(NULL, (chseg)->seg & 0xfffc); \ + else \ + x86np("Read from seg not present", (chseg)->seg & 0xfffc); \ + break; \ + } -#define CHECK_READ_REP(chseg, low, high) \ - if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) \ - { \ - x86gpf("Limit check (READ)", 0); \ - break; \ - } \ - if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \ - { \ - if ((chseg) == &cpu_state.seg_ss) \ - x86ss(NULL,(chseg)->seg & 0xfffc); \ - else \ - x86np("Read from seg not present", (chseg)->seg & 0xfffc); \ - break; \ - } +#define CHECK_WRITE_COMMON(chseg, low, high) \ + if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || !((chseg)->access & 2) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && ((chseg)->access & 8))) { \ + x86gpf("Limit check (WRITE)", 0); \ + return 1; \ + } \ + if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !((chseg)->access & 0x80)) { \ + if ((chseg) == &cpu_state.seg_ss) \ + x86ss(NULL, (chseg)->seg & 0xfffc); \ + else \ + x86np("Write to seg not present", (chseg)->seg & 0xfffc); \ + return 1; \ + } -#define CHECK_WRITE_COMMON(chseg, low, high) \ - if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || !((chseg)->access & 2) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && ((chseg)->access & 8))) \ - { \ - x86gpf("Limit check (WRITE)", 0); \ - return 1; \ - } \ - if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \ - { \ - if ((chseg) == &cpu_state.seg_ss) \ - x86ss(NULL,(chseg)->seg & 0xfffc); \ - else \ - x86np("Write to seg not present", (chseg)->seg & 0xfffc); \ - return 1; \ - } +#define CHECK_WRITE(chseg, low, high) \ + CHECK_WRITE_COMMON(chseg, low, high) -#define CHECK_WRITE(chseg, low, high) \ - CHECK_WRITE_COMMON(chseg, low, high) +#define CHECK_WRITE_REP(chseg, low, high) \ + if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) { \ + x86gpf("Limit check (WRITE REP)", 0); \ + break; \ + } \ + if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !((chseg)->access & 0x80)) { \ + if ((chseg) == &cpu_state.seg_ss) \ + x86ss(NULL, (chseg)->seg & 0xfffc); \ + else \ + x86np("Write (REP) to seg not present", (chseg)->seg & 0xfffc); \ + break; \ + } -#define CHECK_WRITE_REP(chseg, low, high) \ - if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) \ - { \ - x86gpf("Limit check (WRITE REP)", 0); \ - break; \ - } \ - if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \ - { \ - if ((chseg) == &cpu_state.seg_ss) \ - x86ss(NULL,(chseg)->seg & 0xfffc); \ - else \ - x86np("Write (REP) to seg not present", (chseg)->seg & 0xfffc); \ - break; \ - } +#define NOTRM \ + if (!(msw & 1) || (cpu_state.eflags & VM_FLAG)) { \ + x86_int(6); \ + return 1; \ + } - -#define NOTRM if (!(msw & 1) || (cpu_state.eflags & VM_FLAG))\ - { \ - x86_int(6); \ - return 1; \ - } - - - - -static __inline uint8_t fastreadb(uint32_t a) +static __inline uint8_t +fastreadb(uint32_t a) { - uint8_t *t; + uint8_t *t; - if ((a >> 12) == pccache) - return *((uint8_t *)&pccache2[a]); - t = getpccache(a); - if (cpu_state.abrt) - return 0; - pccache = a >> 12; - pccache2 = t; - return *((uint8_t *)&pccache2[a]); + if ((a >> 12) == pccache) + return *((uint8_t *) &pccache2[a]); + t = getpccache(a); + if (cpu_state.abrt) + return 0; + pccache = a >> 12; + pccache2 = t; + return *((uint8_t *) &pccache2[a]); } -static __inline uint16_t fastreadw(uint32_t a) +static __inline uint16_t +fastreadw(uint32_t a) { - uint8_t *t; - uint16_t val; - if ((a&0xFFF)>0xFFE) - { - val = fastreadb(a); - val |= (fastreadb(a + 1) << 8); - return val; - } - if ((a>>12)==pccache) return *((uint16_t *)&pccache2[a]); - t = getpccache(a); - if (cpu_state.abrt) - return 0; - - pccache = a >> 12; - pccache2 = t; - return *((uint16_t *)&pccache2[a]); -} - -static __inline uint32_t fastreadl(uint32_t a) -{ - uint8_t *t; - uint32_t val; - if ((a&0xFFF)<0xFFD) - { - if ((a>>12)!=pccache) - { - t = getpccache(a); - if (cpu_state.abrt) - return 0; - pccache2 = t; - pccache=a>>12; - } - return *((uint32_t *)&pccache2[a]); - } - val = fastreadw(a); - val |= (fastreadw(a + 2) << 16); + uint8_t *t; + uint16_t val; + if ((a & 0xFFF) > 0xFFE) { + val = fastreadb(a); + val |= (fastreadb(a + 1) << 8); return val; + } + if ((a >> 12) == pccache) + return *((uint16_t *) &pccache2[a]); + t = getpccache(a); + if (cpu_state.abrt) + return 0; + + pccache = a >> 12; + pccache2 = t; + return *((uint16_t *) &pccache2[a]); } -static __inline void *get_ram_ptr(uint32_t a) +static __inline uint32_t +fastreadl(uint32_t a) { - if ((a >> 12) == pccache) - return &pccache2[a]; - else - { - uint8_t *t = getpccache(a); - return &t[a]; + uint8_t *t; + uint32_t val; + if ((a & 0xFFF) < 0xFFD) { + if ((a >> 12) != pccache) { + t = getpccache(a); + if (cpu_state.abrt) + return 0; + pccache2 = t; + pccache = a >> 12; } + return *((uint32_t *) &pccache2[a]); + } + val = fastreadw(a); + val |= (fastreadw(a + 2) << 16); + return val; } -static __inline uint8_t getbyte(void) +static __inline void * +get_ram_ptr(uint32_t a) { - cpu_state.pc++; - return fastreadb(cs + (cpu_state.pc - 1)); + if ((a >> 12) == pccache) + return &pccache2[a]; + else { + uint8_t *t = getpccache(a); + return &t[a]; + } } -static __inline uint16_t getword(void) +static __inline uint8_t +getbyte(void) { - cpu_state.pc+=2; - return fastreadw(cs+(cpu_state.pc-2)); + cpu_state.pc++; + return fastreadb(cs + (cpu_state.pc - 1)); } -static __inline uint32_t getlong(void) +static __inline uint16_t +getword(void) { - cpu_state.pc+=4; - return fastreadl(cs+(cpu_state.pc-4)); + cpu_state.pc += 2; + return fastreadw(cs + (cpu_state.pc - 2)); } -static __inline uint64_t getquad(void) +static __inline uint32_t +getlong(void) { - cpu_state.pc+=8; - return fastreadl(cs+(cpu_state.pc-8)) | ((uint64_t)fastreadl(cs+(cpu_state.pc-4)) << 32); + cpu_state.pc += 4; + return fastreadl(cs + (cpu_state.pc - 4)); } - - -static __inline uint8_t geteab(void) +static __inline uint64_t +getquad(void) { - if (cpu_mod == 3) - return (cpu_rm & 4) ? cpu_state.regs[cpu_rm & 3].b.h : cpu_state.regs[cpu_rm&3].b.l; - if (eal_r) - return *(uint8_t *)eal_r; - return readmemb(easeg, cpu_state.eaaddr); + cpu_state.pc += 8; + return fastreadl(cs + (cpu_state.pc - 8)) | ((uint64_t) fastreadl(cs + (cpu_state.pc - 4)) << 32); } -static __inline uint16_t geteaw(void) +static __inline uint8_t +geteab(void) { - if (cpu_mod == 3) - return cpu_state.regs[cpu_rm].w; - if (eal_r) - return *(uint16_t *)eal_r; - return readmemw(easeg, cpu_state.eaaddr); + if (cpu_mod == 3) + return (cpu_rm & 4) ? cpu_state.regs[cpu_rm & 3].b.h : cpu_state.regs[cpu_rm & 3].b.l; + if (eal_r) + return *(uint8_t *) eal_r; + return readmemb(easeg, cpu_state.eaaddr); } -static __inline uint32_t geteal(void) +static __inline uint16_t +geteaw(void) { - if (cpu_mod == 3) - return cpu_state.regs[cpu_rm].l; - if (eal_r) - return *eal_r; - return readmeml(easeg, cpu_state.eaaddr); + if (cpu_mod == 3) + return cpu_state.regs[cpu_rm].w; + if (eal_r) + return *(uint16_t *) eal_r; + return readmemw(easeg, cpu_state.eaaddr); } -static __inline uint64_t geteaq(void) +static __inline uint32_t +geteal(void) { - return readmemq(easeg, cpu_state.eaaddr); + if (cpu_mod == 3) + return cpu_state.regs[cpu_rm].l; + if (eal_r) + return *eal_r; + return readmeml(easeg, cpu_state.eaaddr); } -static __inline uint8_t geteab_mem(void) +static __inline uint64_t +geteaq(void) { - if (eal_r) return *(uint8_t *)eal_r; - return readmemb(easeg,cpu_state.eaaddr); + return readmemq(easeg, cpu_state.eaaddr); } -static __inline uint16_t geteaw_mem(void) + +static __inline uint8_t +geteab_mem(void) { - if (eal_r) return *(uint16_t *)eal_r; - return readmemw(easeg,cpu_state.eaaddr); + if (eal_r) + return *(uint8_t *) eal_r; + return readmemb(easeg, cpu_state.eaaddr); } -static __inline uint32_t geteal_mem(void) +static __inline uint16_t +geteaw_mem(void) { - if (eal_r) return *eal_r; - return readmeml(easeg,cpu_state.eaaddr); + if (eal_r) + return *(uint16_t *) eal_r; + return readmemw(easeg, cpu_state.eaaddr); } - -static __inline int seteaq_cwc(void) +static __inline uint32_t +geteal_mem(void) { - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); - return 0; + if (eal_r) + return *eal_r; + return readmeml(easeg, cpu_state.eaaddr); } -static __inline void seteaq(uint64_t v) +static __inline int +seteaq_cwc(void) { - if (seteaq_cwc()) - return; - writememql(easeg + cpu_state.eaaddr, v); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); + return 0; } -#define seteab(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); if (eal_w) *(uint8_t *)eal_w=v; else writemembl(easeg+cpu_state.eaaddr,v); } else if (cpu_rm&4) cpu_state.regs[cpu_rm&3].b.h=v; else cpu_state.regs[cpu_rm].b.l=v -#define seteaw(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].w=v -#define seteal(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); if (eal_w) *eal_w=v; else writememll(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].l=v +static __inline void +seteaq(uint64_t v) +{ + if (seteaq_cwc()) + return; + writememql(easeg + cpu_state.eaaddr, v); +} -#define seteab_mem(v) if (eal_w) *(uint8_t *)eal_w=v; else writemembl(easeg+cpu_state.eaaddr,v); -#define seteaw_mem(v) if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg+cpu_state.eaaddr,v); -#define seteal_mem(v) if (eal_w) *eal_w=v; else writememll(easeg+cpu_state.eaaddr,v); +#define seteab(v) \ + if (cpu_mod != 3) { \ + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); \ + if (eal_w) \ + *(uint8_t *) eal_w = v; \ + else \ + writemembl(easeg + cpu_state.eaaddr, v); \ + } else if (cpu_rm & 4) \ + cpu_state.regs[cpu_rm & 3].b.h = v; \ + else \ + cpu_state.regs[cpu_rm].b.l = v +#define seteaw(v) \ + if (cpu_mod != 3) { \ + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \ + if (eal_w) \ + *(uint16_t *) eal_w = v; \ + else \ + writememwl(easeg + cpu_state.eaaddr, v); \ + } else \ + cpu_state.regs[cpu_rm].w = v +#define seteal(v) \ + if (cpu_mod != 3) { \ + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ + if (eal_w) \ + *eal_w = v; \ + else \ + writememll(easeg + cpu_state.eaaddr, v); \ + } else \ + cpu_state.regs[cpu_rm].l = v -#define getbytef() ((uint8_t)(fetchdat)); cpu_state.pc++ -#define getwordf() ((uint16_t)(fetchdat)); cpu_state.pc+=2 -#define getbyte2f() ((uint8_t)(fetchdat>>8)); cpu_state.pc++ -#define getword2f() ((uint16_t)(fetchdat>>8)); cpu_state.pc+=2 +#define seteab_mem(v) \ + if (eal_w) \ + *(uint8_t *) eal_w = v; \ + else \ + writemembl(easeg + cpu_state.eaaddr, v); +#define seteaw_mem(v) \ + if (eal_w) \ + *(uint16_t *) eal_w = v; \ + else \ + writememwl(easeg + cpu_state.eaaddr, v); +#define seteal_mem(v) \ + if (eal_w) \ + *eal_w = v; \ + else \ + writememll(easeg + cpu_state.eaaddr, v); + +#define getbytef() \ + ((uint8_t) (fetchdat)); \ + cpu_state.pc++ +#define getwordf() \ + ((uint16_t) (fetchdat)); \ + cpu_state.pc += 2 +#define getbyte2f() \ + ((uint8_t) (fetchdat >> 8)); \ + cpu_state.pc++ +#define getword2f() \ + ((uint16_t) (fetchdat >> 8)); \ + cpu_state.pc += 2 #endif diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index fb3534c9a..f2e04b54a 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -4,12 +4,12 @@ #include #include #if defined(__APPLE__) && defined(__aarch64__) -#include +# include #endif #include #include #ifndef INFINITY -# define INFINITY (__builtin_inff()) +# define INFINITY (__builtin_inff()) #endif #define HAVE_STDARG_H @@ -28,164 +28,161 @@ #include <86box/machine.h> #include <86box/gdbstub.h> #ifdef USE_DYNAREC -#include "codegen.h" -#ifdef USE_NEW_DYNAREC -#include "codegen_backend.h" -#endif +# include "codegen.h" +# ifdef USE_NEW_DYNAREC +# include "codegen_backend.h" +# endif #endif #ifdef IS_DYNAREC -#undef IS_DYNAREC +# undef IS_DYNAREC #endif #include "386_common.h" #if defined(__APPLE__) && defined(__aarch64__) -#include +# include #endif #define CPU_BLOCK_END() cpu_block_end = 1 - int inrecomp = 0, cpu_block_end = 0; int cpu_end_block_after_ins = 0; - #ifdef ENABLE_386_DYNAREC_LOG int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG; - void x386_dynarec_log(const char *fmt, ...) { va_list ap; if (x386_dynarec_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define x386_dynarec_log(fmt, ...) +# define x386_dynarec_log(fmt, ...) #endif - -static __inline void fetch_ea_32_long(uint32_t rmdat) +static __inline void +fetch_ea_32_long(uint32_t rmdat) { - eal_r = eal_w = NULL; - easeg = cpu_state.ea_seg->base; - if (cpu_rm == 4) - { - uint8_t sib = rmdat >> 8; + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (cpu_rm == 4) { + uint8_t sib = rmdat >> 8; - switch (cpu_mod) - { - case 0: - cpu_state.eaaddr = cpu_state.regs[sib & 7].l; - cpu_state.pc++; - break; - case 1: - cpu_state.pc++; - cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; - break; - case 2: - cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; - cpu_state.pc += 5; - break; - } - /*SIB byte present*/ - if ((sib & 7) == 5 && !cpu_mod) - cpu_state.eaaddr = getlong(); - else if ((sib & 6) == 4 && !cpu_state.ssegs) - { - easeg = ss; - cpu_state.ea_seg = &cpu_state.seg_ss; - } - if (((sib >> 3) & 7) != 4) - cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); - } - else - { - cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; - if (cpu_mod) - { - if (cpu_rm == 5 && !cpu_state.ssegs) - { - easeg = ss; - cpu_state.ea_seg = &cpu_state.seg_ss; - } - if (cpu_mod == 1) - { - cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); - cpu_state.pc++; - } - else - { - cpu_state.eaaddr += getlong(); - } - } - else if (cpu_rm == 5) - { - cpu_state.eaaddr = getlong(); - } - } - if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) - { - uint32_t addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != (uintptr_t) -1) - eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != (uintptr_t) -1) - eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); - } + switch (cpu_mod) { + case 0: + cpu_state.eaaddr = cpu_state.regs[sib & 7].l; + cpu_state.pc++; + break; + case 1: + cpu_state.pc++; + cpu_state.eaaddr = ((uint32_t) (int8_t) getbyte()) + cpu_state.regs[sib & 7].l; + break; + case 2: + cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; + cpu_state.pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !cpu_mod) + cpu_state.eaaddr = getlong(); + else if ((sib & 6) == 4 && !cpu_state.ssegs) { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (((sib >> 3) & 7) != 4) + cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); + } else { + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) { + if (cpu_rm == 5 && !cpu_state.ssegs) { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (cpu_mod == 1) { + cpu_state.eaaddr += ((uint32_t) (int8_t) (rmdat >> 8)); + cpu_state.pc++; + } else { + cpu_state.eaaddr += getlong(); + } + } else if (cpu_rm == 5) { + cpu_state.eaaddr = getlong(); + } + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { + uint32_t addr = easeg + cpu_state.eaaddr; + if (readlookup2[addr >> 12] != (uintptr_t) -1) + eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != (uintptr_t) -1) + eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr); + } } -static __inline void fetch_ea_16_long(uint32_t rmdat) +static __inline void +fetch_ea_16_long(uint32_t rmdat) { - eal_r = eal_w = NULL; - easeg = cpu_state.ea_seg->base; - if (!cpu_mod && cpu_rm == 6) - { - cpu_state.eaaddr = getword(); - } - else - { - switch (cpu_mod) - { - case 0: - cpu_state.eaaddr = 0; - break; - case 1: - cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++; - break; - case 2: - cpu_state.eaaddr = getword(); - break; - } - cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); - if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) - { - easeg = ss; - cpu_state.ea_seg = &cpu_state.seg_ss; - } - cpu_state.eaaddr &= 0xFFFF; - } - if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) - { - uint32_t addr = easeg + cpu_state.eaaddr; - if (readlookup2[addr >> 12] != (uintptr_t) -1) - eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != (uintptr_t) -1) - eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); - } + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (!cpu_mod && cpu_rm == 6) { + cpu_state.eaaddr = getword(); + } else { + switch (cpu_mod) { + case 0: + cpu_state.eaaddr = 0; + break; + case 1: + cpu_state.eaaddr = (uint16_t) (int8_t) (rmdat >> 8); + cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = getword(); + break; + } + cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + cpu_state.eaaddr &= 0xFFFF; + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { + uint32_t addr = easeg + cpu_state.eaaddr; + if (readlookup2[addr >> 12] != (uintptr_t) -1) + eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != (uintptr_t) -1) + eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr); + } } -#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; } -#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 1 +#define fetch_ea_16(rmdat) \ + cpu_state.pc++; \ + cpu_mod = (rmdat >> 6) & 3; \ + cpu_reg = (rmdat >> 3) & 7; \ + cpu_rm = rmdat & 7; \ + if (cpu_mod != 3) { \ + fetch_ea_16_long(rmdat); \ + if (cpu_state.abrt) \ + return 1; \ + } +#define fetch_ea_32(rmdat) \ + cpu_state.pc++; \ + cpu_mod = (rmdat >> 6) & 3; \ + cpu_reg = (rmdat >> 3) & 7; \ + cpu_rm = rmdat & 7; \ + if (cpu_mod != 3) { \ + fetch_ea_32_long(rmdat); \ + } \ + if (cpu_state.abrt) \ + return 1 #include "x86_flags.h" - /*Prefetch emulation is a fairly simplistic model: - All instruction bytes must be fetched before it starts. - Cycles used for non-instruction memory accesses are counted and subtracted @@ -195,150 +192,145 @@ static __inline void fetch_ea_16_long(uint32_t rmdat) Note that this is only used for 286 / 386 systems. It is disabled when the internal cache on 486+ CPUs is enabled. */ -static int prefetch_bytes = 0; +static int prefetch_bytes = 0; static int prefetch_prefixes = 0; -static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32) +static void +prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32) { - int mem_cycles = reads*cpu_cycles_read + reads_l*cpu_cycles_read_l + writes*cpu_cycles_write + writes_l*cpu_cycles_write_l; + int mem_cycles = reads * cpu_cycles_read + reads_l * cpu_cycles_read_l + writes * cpu_cycles_write + writes_l * cpu_cycles_write_l; - if (instr_cycles < mem_cycles) - instr_cycles = mem_cycles; + if (instr_cycles < mem_cycles) + instr_cycles = mem_cycles; - prefetch_bytes -= prefetch_prefixes; - prefetch_bytes -= bytes; - if (modrm != -1) - { - if (ea32) - { - if ((modrm & 7) == 4) - { - if ((modrm & 0x700) == 0x500) - prefetch_bytes -= 5; - else if ((modrm & 0xc0) == 0x40) - prefetch_bytes -= 2; - else if ((modrm & 0xc0) == 0x80) - prefetch_bytes -= 5; - } - else - { - if ((modrm & 0xc7) == 0x05) - prefetch_bytes -= 4; - else if ((modrm & 0xc0) == 0x40) - prefetch_bytes--; - else if ((modrm & 0xc0) == 0x80) - prefetch_bytes -= 4; - } - } - else - { - if ((modrm & 0xc7) == 0x06) - prefetch_bytes -= 2; - else if ((modrm & 0xc0) != 0xc0) - prefetch_bytes -= ((modrm & 0xc0) >> 6); - } - } + prefetch_bytes -= prefetch_prefixes; + prefetch_bytes -= bytes; + if (modrm != -1) { + if (ea32) { + if ((modrm & 7) == 4) { + if ((modrm & 0x700) == 0x500) + prefetch_bytes -= 5; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 5; + } else { + if ((modrm & 0xc7) == 0x05) + prefetch_bytes -= 4; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes--; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 4; + } + } else { + if ((modrm & 0xc7) == 0x06) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) != 0xc0) + prefetch_bytes -= ((modrm & 0xc0) >> 6); + } + } - /* Fill up prefetch queue */ - while (prefetch_bytes < 0) - { - prefetch_bytes += cpu_prefetch_width; - cycles -= cpu_prefetch_cycles; - } + /* Fill up prefetch queue */ + while (prefetch_bytes < 0) { + prefetch_bytes += cpu_prefetch_width; + cycles -= cpu_prefetch_cycles; + } - /* Subtract cycles used for memory access by instruction */ - instr_cycles -= mem_cycles; + /* Subtract cycles used for memory access by instruction */ + instr_cycles -= mem_cycles; - while (instr_cycles >= cpu_prefetch_cycles) - { - prefetch_bytes += cpu_prefetch_width; - instr_cycles -= cpu_prefetch_cycles; - } + while (instr_cycles >= cpu_prefetch_cycles) { + prefetch_bytes += cpu_prefetch_width; + instr_cycles -= cpu_prefetch_cycles; + } - prefetch_prefixes = 0; - if (prefetch_bytes > 16) - prefetch_bytes = 16; + prefetch_prefixes = 0; + if (prefetch_bytes > 16) + prefetch_bytes = 16; } -static void prefetch_flush(void) +static void +prefetch_flush(void) { - prefetch_bytes = 0; + prefetch_bytes = 0; } -#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \ - do { if (cpu_prefetch_cycles) prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); } while (0) +#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \ + do { \ + if (cpu_prefetch_cycles) \ + prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); \ + } while (0) -#define PREFETCH_PREFIX() do { if (cpu_prefetch_cycles) prefetch_prefixes++; } while (0) +#define PREFETCH_PREFIX() \ + do { \ + if (cpu_prefetch_cycles) \ + prefetch_prefixes++; \ + } while (0) #define PREFETCH_FLUSH() prefetch_flush() - -#define OP_TABLE(name) ops_ ## name +#define OP_TABLE(name) ops_##name #if 0 -#define CLOCK_CYCLES(c) \ - {\ - if (fpu_cycles > 0) {\ - fpu_cycles -= (c);\ - if (fpu_cycles < 0) {\ - cycles += fpu_cycles;\ - }\ - } else {\ - cycles -= (c);\ - }\ - } -#define CLOCK_CYCLES_FPU(c) cycles -= (c) -#define CONCURRENCY_CYCLES(c) fpu_cycles = (c) +# define CLOCK_CYCLES(c) \ + { \ + if (fpu_cycles > 0) { \ + fpu_cycles -= (c); \ + if (fpu_cycles < 0) { \ + cycles += fpu_cycles; \ + } \ + } else { \ + cycles -= (c); \ + } \ + } +# define CLOCK_CYCLES_FPU(c) cycles -= (c) +# define CONCURRENCY_CYCLES(c) fpu_cycles = (c) #else -#define CLOCK_CYCLES(c) cycles -= (c) -#define CLOCK_CYCLES_FPU(c) cycles -= (c) -#define CONCURRENCY_CYCLES(c) +# define CLOCK_CYCLES(c) cycles -= (c) +# define CLOCK_CYCLES_FPU(c) cycles -= (c) +# define CONCURRENCY_CYCLES(c) #endif #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) - #include "386_ops.h" - #define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) #ifdef USE_DYNAREC -int cycles_main = 0; -static int cycles_old = 0; -static uint64_t tsc_old = 0; +int cycles_main = 0; +static int cycles_old = 0; +static uint64_t tsc_old = 0; -#ifdef USE_ACYCS +# ifdef USE_ACYCS int acycs = 0; -#endif - +# endif void update_tsc(void) { - int cycdiff; + int cycdiff; uint64_t delta; cycdiff = cycles_old - cycles; -#ifdef USE_ACYCS +# ifdef USE_ACYCS if (inrecomp) - cycdiff += acycs; -#endif + cycdiff += acycs; +# endif delta = tsc - tsc_old; if (delta > 0) { - /* TSC has changed, this means interim timer processing has happened, - see how much we still need to add. */ - cycdiff -= delta; + /* TSC has changed, this means interim timer processing has happened, + see how much we still need to add. */ + cycdiff -= delta; } if (cycdiff > 0) - tsc += cycdiff; + tsc += cycdiff; if (cycdiff > 0) { - if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) - timer_process_inline(); + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) + timer_process_inline(); } } - static __inline void exec386_dynarec_int(void) { @@ -346,530 +338,523 @@ exec386_dynarec_int(void) x86_was_reset = 0; while (!cpu_block_end) { -#ifndef USE_NEW_DYNAREC - oldcs = CS; - oldcpl = CPL; -#endif - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; +# ifndef USE_NEW_DYNAREC + oldcs = CS; + oldcpl = CPL; +# endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; - cpu_state.ea_seg = &cpu_state.seg_ds; - cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; - fetchdat = fastreadl(cs + cpu_state.pc); -#ifdef ENABLE_386_DYNAREC_LOG - if (in_smm) - x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat); -#endif + fetchdat = fastreadl(cs + cpu_state.pc); +# ifdef ENABLE_386_DYNAREC_LOG + if (in_smm) + x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat); +# endif - if (!cpu_state.abrt) { - opcode = fetchdat & 0xFF; - fetchdat >>= 8; + if (!cpu_state.abrt) { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; - trap = cpu_state.flags & T_FLAG; + trap = cpu_state.flags & T_FLAG; - cpu_state.pc++; - x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); - } + cpu_state.pc++; + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + } -#ifndef USE_NEW_DYNAREC - if (!use32) - cpu_state.pc &= 0xffff; -#endif +# ifndef USE_NEW_DYNAREC + if (!use32) + cpu_state.pc &= 0xffff; +# endif - if (((cs + cpu_state.pc) >> 12) != pccache) - CPU_BLOCK_END(); + if (((cs + cpu_state.pc) >> 12) != pccache) + CPU_BLOCK_END(); - if (cpu_end_block_after_ins) { - cpu_end_block_after_ins--; - if (!cpu_end_block_after_ins) - CPU_BLOCK_END(); - } + if (cpu_end_block_after_ins) { + cpu_end_block_after_ins--; + if (!cpu_end_block_after_ins) + CPU_BLOCK_END(); + } - if (cpu_state.abrt) - CPU_BLOCK_END(); - if (smi_line) - CPU_BLOCK_END(); - else if (trap) - CPU_BLOCK_END(); - else if (nmi && nmi_enable && nmi_mask) - CPU_BLOCK_END(); - else if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) - CPU_BLOCK_END(); + if (cpu_state.abrt) + CPU_BLOCK_END(); + if (smi_line) + CPU_BLOCK_END(); + else if (trap) + CPU_BLOCK_END(); + else if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + else if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) + CPU_BLOCK_END(); } if (!cpu_state.abrt && trap) { - trap = 0; -#ifndef USE_NEW_DYNAREC - oldcs = CS; -#endif - cpu_state.oldpc = cpu_state.pc; - dr[6] |= 0x4000; - x86_int(1); + trap = 0; +# ifndef USE_NEW_DYNAREC + oldcs = CS; +# endif + cpu_state.oldpc = cpu_state.pc; + dr[6] |= 0x4000; + x86_int(1); } cpu_end_block_after_ins = 0; } - static __inline void exec386_dynarec_dyn(void) { uint32_t start_pc = 0, phys_addr = get_phys(cs + cpu_state.pc); - int hash = HASH(phys_addr); -#ifdef USE_NEW_DYNAREC + int hash = HASH(phys_addr); +# ifdef USE_NEW_DYNAREC codeblock_t *block = &codeblock[codeblock_hash[hash]]; -#else +# else codeblock_t *block = codeblock_hash[hash]; -#endif +# endif int valid_block = 0; -#ifdef USE_NEW_DYNAREC +# ifdef USE_NEW_DYNAREC if (!cpu_state.abrt) -#else +# else if (block && !cpu_state.abrt) -#endif +# endif { - page_t *page = &pages[phys_addr >> 12]; + page_t *page = &pages[phys_addr >> 12]; - /* Block must match current CS, PC, code segment size, - and physical address. The physical address check will - also catch any page faults at this stage */ - valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) && - (block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && - ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); - if (!valid_block) { - uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); -#ifdef USE_NEW_DYNAREC - int byte_offset = (phys_addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - uint64_t byte_mask = 1ull << (PAGE_BYTE_MASK_MASK & 0x3f); + /* Block must match current CS, PC, code segment size, + and physical address. The physical address check will + also catch any page faults at this stage */ + valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) && (block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (!valid_block) { + uint64_t mask = (uint64_t) 1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); +# ifdef USE_NEW_DYNAREC + int byte_offset = (phys_addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = 1ull << (PAGE_BYTE_MASK_MASK & 0x3f); - if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask)) -#else - if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask) -#endif - { - /* Walk page tree to see if we find the correct block */ - codeblock_t *new_block = codeblock_tree_find(phys_addr, cs); - if (new_block) { - valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && - (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && - ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); - if (valid_block) { - block = new_block; -#ifdef USE_NEW_DYNAREC - codeblock_hash[hash] = get_block_nr(block); -#endif - } - } - } - } + if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask)) +# else + if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask) +# endif + { + /* Walk page tree to see if we find the correct block */ + codeblock_t *new_block = codeblock_tree_find(phys_addr, cs); + if (new_block) { + valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (valid_block) { + block = new_block; +# ifdef USE_NEW_DYNAREC + codeblock_hash[hash] = get_block_nr(block); +# endif + } + } + } + } - if (valid_block && (block->page_mask & *block->dirty_mask)) { -#ifdef USE_NEW_DYNAREC - codegen_check_flush(page, page->dirty_mask, phys_addr); - if (block->pc == BLOCK_PC_INVALID) - valid_block = 0; - else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - block->flags &= ~CODEBLOCK_WAS_RECOMPILED; -#else - codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr); - page->dirty_mask[(phys_addr >> 10) & 3] = 0; - if (!block->valid) - valid_block = 0; -#endif - } - if (valid_block && block->page_mask2) { - /* We don't want the second page to cause a page - fault at this stage - that would break any - code crossing a page boundary where the first - page is present but the second isn't. Instead - allow the first page to be interpreted and for - the page fault to occur when the page boundary - is actually crossed.*/ -#ifdef USE_NEW_DYNAREC - uint32_t phys_addr_2 = get_phys_noabrt(block->pc + ((block->flags & CODEBLOCK_BYTE_MASK) ? 0x40 : 0x400)); -#else - uint32_t phys_addr_2 = get_phys_noabrt(block->endpc); -#endif - page_t *page_2 = &pages[phys_addr_2 >> 12]; + if (valid_block && (block->page_mask & *block->dirty_mask)) { +# ifdef USE_NEW_DYNAREC + codegen_check_flush(page, page->dirty_mask, phys_addr); + if (block->pc == BLOCK_PC_INVALID) + valid_block = 0; + else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; +# else + codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr); + page->dirty_mask[(phys_addr >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; +# endif + } + if (valid_block && block->page_mask2) { + /* We don't want the second page to cause a page + fault at this stage - that would break any + code crossing a page boundary where the first + page is present but the second isn't. Instead + allow the first page to be interpreted and for + the page fault to occur when the page boundary + is actually crossed.*/ +# ifdef USE_NEW_DYNAREC + uint32_t phys_addr_2 = get_phys_noabrt(block->pc + ((block->flags & CODEBLOCK_BYTE_MASK) ? 0x40 : 0x400)); +# else + uint32_t phys_addr_2 = get_phys_noabrt(block->endpc); +# endif + page_t *page_2 = &pages[phys_addr_2 >> 12]; - if ((block->phys_2 ^ phys_addr_2) & ~0xfff) - valid_block = 0; - else if (block->page_mask2 & *block->dirty_mask2) { -#ifdef USE_NEW_DYNAREC - codegen_check_flush(page_2, page_2->dirty_mask, phys_addr_2); - if (block->pc == BLOCK_PC_INVALID) - valid_block = 0; - else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - block->flags &= ~CODEBLOCK_WAS_RECOMPILED; -#else - codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2); - page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0; - if (!block->valid) - valid_block = 0; -#endif - } - } -#ifdef USE_NEW_DYNAREC - if (valid_block && (block->flags & CODEBLOCK_IN_DIRTY_LIST)) { - block->flags &= ~CODEBLOCK_WAS_RECOMPILED; - if (block->flags & CODEBLOCK_BYTE_MASK) - block->flags |= CODEBLOCK_NO_IMMEDIATES; - else - block->flags |= CODEBLOCK_BYTE_MASK; - } - if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7)) -#else - if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP) -#endif - { - /* FPU top-of-stack does not match the value this block was compiled - with, re-compile using dynamic top-of-stack*/ -#ifdef USE_NEW_DYNAREC - block->flags &= ~(CODEBLOCK_STATIC_TOP | CODEBLOCK_WAS_RECOMPILED); -#else - block->flags &= ~CODEBLOCK_STATIC_TOP; - block->was_recompiled = 0; -#endif - } + if ((block->phys_2 ^ phys_addr_2) & ~0xfff) + valid_block = 0; + else if (block->page_mask2 & *block->dirty_mask2) { +# ifdef USE_NEW_DYNAREC + codegen_check_flush(page_2, page_2->dirty_mask, phys_addr_2); + if (block->pc == BLOCK_PC_INVALID) + valid_block = 0; + else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; +# else + codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2); + page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; +# endif + } + } +# ifdef USE_NEW_DYNAREC + if (valid_block && (block->flags & CODEBLOCK_IN_DIRTY_LIST)) { + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; + if (block->flags & CODEBLOCK_BYTE_MASK) + block->flags |= CODEBLOCK_NO_IMMEDIATES; + else + block->flags |= CODEBLOCK_BYTE_MASK; + } + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7)) +# else + if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP) +# endif + { + /* FPU top-of-stack does not match the value this block was compiled + with, re-compile using dynamic top-of-stack*/ +# ifdef USE_NEW_DYNAREC + block->flags &= ~(CODEBLOCK_STATIC_TOP | CODEBLOCK_WAS_RECOMPILED); +# else + block->flags &= ~CODEBLOCK_STATIC_TOP; + block->was_recompiled = 0; +# endif + } } -#ifdef USE_NEW_DYNAREC +# ifdef USE_NEW_DYNAREC if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED)) -#else +# else if (valid_block && block->was_recompiled) -#endif +# endif { - void (*code)(void) = (void *)&block->data[BLOCK_START]; + void (*code)(void) = (void *) &block->data[BLOCK_START]; -#ifndef USE_NEW_DYNAREC - codeblock_hash[hash] = block; -#endif - inrecomp = 1; - code(); -#ifdef USE_ACYCS - acycs = 0; -#endif - inrecomp = 0; +# ifndef USE_NEW_DYNAREC + codeblock_hash[hash] = block; +# endif + inrecomp = 1; + code(); +# ifdef USE_ACYCS + acycs = 0; +# endif + inrecomp = 0; -#ifndef USE_NEW_DYNAREC - if (!use32) cpu_state.pc &= 0xffff; -#endif +# ifndef USE_NEW_DYNAREC + if (!use32) + cpu_state.pc &= 0xffff; +# endif } else if (valid_block && !cpu_state.abrt) { -#ifdef USE_NEW_DYNAREC - start_pc = cs + cpu_state.pc; - const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; -#else - start_pc = cpu_state.pc; -#endif +# ifdef USE_NEW_DYNAREC + start_pc = cs + cpu_state.pc; + const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; +# else + start_pc = cpu_state.pc; +# endif - cpu_block_end = 0; - x86_was_reset = 0; + cpu_block_end = 0; + x86_was_reset = 0; -#if defined(__APPLE__) && defined(__aarch64__) - pthread_jit_write_protect_np(0); -#endif - codegen_block_start_recompile(block); - codegen_in_recompile = 1; +# if defined(__APPLE__) && defined(__aarch64__) + pthread_jit_write_protect_np(0); +# endif + codegen_block_start_recompile(block); + codegen_in_recompile = 1; - while (!cpu_block_end) { -#ifndef USE_NEW_DYNAREC - oldcs = CS; - oldcpl = CPL; -#endif - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; + while (!cpu_block_end) { +# ifndef USE_NEW_DYNAREC + oldcs = CS; + oldcpl = CPL; +# endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; - cpu_state.ea_seg = &cpu_state.seg_ds; - cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; - fetchdat = fastreadl(cs + cpu_state.pc); -#ifdef ENABLE_386_DYNAREC_LOG - if (in_smm) - x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat); -#endif + fetchdat = fastreadl(cs + cpu_state.pc); +# ifdef ENABLE_386_DYNAREC_LOG + if (in_smm) + x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat); +# endif - if (!cpu_state.abrt) { - opcode = fetchdat & 0xFF; - fetchdat >>= 8; + if (!cpu_state.abrt) { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; - cpu_state.pc++; + cpu_state.pc++; - codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1); + codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc - 1); - x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); - if (x86_was_reset) - break; - } + if (x86_was_reset) + break; + } -#ifndef USE_NEW_DYNAREC - if (!use32) - cpu_state.pc &= 0xffff; -#endif +# ifndef USE_NEW_DYNAREC + if (!use32) + cpu_state.pc &= 0xffff; +# endif - /* Cap source code at 4000 bytes per block; this - will prevent any block from spanning more than - 2 pages. In practice this limit will never be - hit, as host block size is only 2kB*/ -#ifdef USE_NEW_DYNAREC - if (((cs + cpu_state.pc) - start_pc) >= max_block_size) -#else - if ((cpu_state.pc - start_pc) > 1000) -#endif - CPU_BLOCK_END(); + /* Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ +# ifdef USE_NEW_DYNAREC + if (((cs + cpu_state.pc) - start_pc) >= max_block_size) +# else + if ((cpu_state.pc - start_pc) > 1000) +# endif + CPU_BLOCK_END(); - if (cpu_state.flags & T_FLAG) - CPU_BLOCK_END(); - if (smi_line) - CPU_BLOCK_END(); - if (nmi && nmi_enable && nmi_mask) - CPU_BLOCK_END(); - if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) - CPU_BLOCK_END(); + if (cpu_state.flags & T_FLAG) + CPU_BLOCK_END(); + if (smi_line) + CPU_BLOCK_END(); + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) + CPU_BLOCK_END(); - if (cpu_end_block_after_ins) { - cpu_end_block_after_ins--; - if (!cpu_end_block_after_ins) - CPU_BLOCK_END(); - } + if (cpu_end_block_after_ins) { + cpu_end_block_after_ins--; + if (!cpu_end_block_after_ins) + CPU_BLOCK_END(); + } - if (cpu_state.abrt) { - if (!(cpu_state.abrt & ABRT_EXPECTED)) - codegen_block_remove(); - CPU_BLOCK_END(); - } - } + if (cpu_state.abrt) { + if (!(cpu_state.abrt & ABRT_EXPECTED)) + codegen_block_remove(); + CPU_BLOCK_END(); + } + } - cpu_end_block_after_ins = 0; + cpu_end_block_after_ins = 0; - if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset) - codegen_block_end_recompile(block); + if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset) + codegen_block_end_recompile(block); - if (x86_was_reset) - codegen_reset(); + if (x86_was_reset) + codegen_reset(); - codegen_in_recompile = 0; -#if defined(__APPLE__) && defined(__aarch64__) - pthread_jit_write_protect_np(1); -#endif + codegen_in_recompile = 0; +# if defined(__APPLE__) && defined(__aarch64__) + pthread_jit_write_protect_np(1); +# endif } else if (!cpu_state.abrt) { - /* Mark block but do not recompile */ -#ifdef USE_NEW_DYNAREC - start_pc = cs + cpu_state.pc; - const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; -#else - start_pc = cpu_state.pc; -#endif + /* Mark block but do not recompile */ +# ifdef USE_NEW_DYNAREC + start_pc = cs + cpu_state.pc; + const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; +# else + start_pc = cpu_state.pc; +# endif - cpu_block_end = 0; - x86_was_reset = 0; + cpu_block_end = 0; + x86_was_reset = 0; - codegen_block_init(phys_addr); + codegen_block_init(phys_addr); - while (!cpu_block_end) { -#ifndef USE_NEW_DYNAREC - oldcs = CS; - oldcpl = CPL; -#endif - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; + while (!cpu_block_end) { +# ifndef USE_NEW_DYNAREC + oldcs = CS; + oldcpl = CPL; +# endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; - cpu_state.ea_seg = &cpu_state.seg_ds; - cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; - codegen_endpc = (cs + cpu_state.pc) + 8; - fetchdat = fastreadl(cs + cpu_state.pc); + codegen_endpc = (cs + cpu_state.pc) + 8; + fetchdat = fastreadl(cs + cpu_state.pc); -#ifdef ENABLE_386_DYNAREC_LOG - if (in_smm) - x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat); -#endif +# ifdef ENABLE_386_DYNAREC_LOG + if (in_smm) + x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat); +# endif - if (!cpu_state.abrt) { - opcode = fetchdat & 0xFF; - fetchdat >>= 8; + if (!cpu_state.abrt) { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; - cpu_state.pc++; + cpu_state.pc++; - x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); - if (x86_was_reset) - break; - } + if (x86_was_reset) + break; + } -#ifndef USE_NEW_DYNAREC - if (!use32) - cpu_state.pc &= 0xffff; -#endif +# ifndef USE_NEW_DYNAREC + if (!use32) + cpu_state.pc &= 0xffff; +# endif - /* Cap source code at 4000 bytes per block; this - will prevent any block from spanning more than - 2 pages. In practice this limit will never be - hit, as host block size is only 2kB */ -#ifdef USE_NEW_DYNAREC - if (((cs + cpu_state.pc) - start_pc) >= max_block_size) -#else - if ((cpu_state.pc - start_pc) > 1000) -#endif - CPU_BLOCK_END(); + /* Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB */ +# ifdef USE_NEW_DYNAREC + if (((cs + cpu_state.pc) - start_pc) >= max_block_size) +# else + if ((cpu_state.pc - start_pc) > 1000) +# endif + CPU_BLOCK_END(); - if (cpu_state.flags & T_FLAG) - CPU_BLOCK_END(); - if (smi_line) - CPU_BLOCK_END(); - if (nmi && nmi_enable && nmi_mask) - CPU_BLOCK_END(); - if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) - CPU_BLOCK_END(); + if (cpu_state.flags & T_FLAG) + CPU_BLOCK_END(); + if (smi_line) + CPU_BLOCK_END(); + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) + CPU_BLOCK_END(); - if (cpu_end_block_after_ins) { - cpu_end_block_after_ins--; - if (!cpu_end_block_after_ins) - CPU_BLOCK_END(); - } + if (cpu_end_block_after_ins) { + cpu_end_block_after_ins--; + if (!cpu_end_block_after_ins) + CPU_BLOCK_END(); + } - if (cpu_state.abrt) { - if (!(cpu_state.abrt & ABRT_EXPECTED)) - codegen_block_remove(); - CPU_BLOCK_END(); - } - } + if (cpu_state.abrt) { + if (!(cpu_state.abrt & ABRT_EXPECTED)) + codegen_block_remove(); + CPU_BLOCK_END(); + } + } - cpu_end_block_after_ins = 0; + cpu_end_block_after_ins = 0; - if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset) - codegen_block_end(); + if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset) + codegen_block_end(); - if (x86_was_reset) - codegen_reset(); + if (x86_was_reset) + codegen_reset(); } -#ifdef USE_NEW_DYNAREC +# ifdef USE_NEW_DYNAREC else - cpu_state.oldpc = cpu_state.pc; -#endif + cpu_state.oldpc = cpu_state.pc; +# endif } - void exec386_dynarec(int cycs) { - int vector, tempi; - int cycdiff; - int oldcyc, oldcyc2; + int vector, tempi; + int cycdiff; + int oldcyc, oldcyc2; uint64_t oldtsc, delta; int cyc_period = cycs / 2000; /*5us*/ -#ifdef USE_ACYCS +# ifdef USE_ACYCS acycs = 0; -#endif +# endif cycles_main += cycs; while (cycles_main > 0) { - int cycles_start; + int cycles_start; - cycles += cyc_period; - cycles_start = cycles; + cycles += cyc_period; + cycles_start = cycles; - while (cycles > 0) { -#ifndef USE_NEW_DYNAREC - oldcs = CS; - cpu_state.oldpc = cpu_state.pc; - oldcpl = CPL; - cpu_state.op32 = use32; + while (cycles > 0) { +# ifndef USE_NEW_DYNAREC + oldcs = CS; + cpu_state.oldpc = cpu_state.pc; + oldcpl = CPL; + cpu_state.op32 = use32; - cycdiff = 0; -#endif - oldcyc = oldcyc2 = cycles; - cycles_old = cycles; - oldtsc = tsc; - tsc_old = tsc; - if (!CACHE_ON()) /*Interpret block*/ - { - exec386_dynarec_int(); - } - else - { - exec386_dynarec_dyn(); - } + cycdiff = 0; +# endif + oldcyc = oldcyc2 = cycles; + cycles_old = cycles; + oldtsc = tsc; + tsc_old = tsc; + if (!CACHE_ON()) /*Interpret block*/ + { + exec386_dynarec_int(); + } else { + exec386_dynarec_dyn(); + } - if (cpu_state.abrt) { - flags_rebuild(); - tempi = cpu_state.abrt & ABRT_MASK; - cpu_state.abrt = 0; - x86_doabrt(tempi); - if (cpu_state.abrt) { - cpu_state.abrt = 0; - cpu_state.pc = cpu_state.oldpc; -#ifndef USE_NEW_DYNAREC - CS = oldcs; -#endif - pmodeint(8, 0); - if (cpu_state.abrt) { - cpu_state.abrt = 0; - softresetx86(); - cpu_set_edx(); -#ifdef ENABLE_386_DYNAREC_LOG - x386_dynarec_log("Triple fault - reset\n"); -#endif - } - } - } + if (cpu_state.abrt) { + flags_rebuild(); + tempi = cpu_state.abrt & ABRT_MASK; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) { + cpu_state.abrt = 0; + cpu_state.pc = cpu_state.oldpc; +# ifndef USE_NEW_DYNAREC + CS = oldcs; +# endif + pmodeint(8, 0); + if (cpu_state.abrt) { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); +# ifdef ENABLE_386_DYNAREC_LOG + x386_dynarec_log("Triple fault - reset\n"); +# endif + } + } + } - if (smi_line) - enter_smm_check(0); - else if (nmi && nmi_enable && nmi_mask) { -#ifndef USE_NEW_DYNAREC - oldcs = CS; -#endif - cpu_state.oldpc = cpu_state.pc; - x86_int(2); - nmi_enable = 0; -#ifdef OLD_NMI_BEHAVIOR - if (nmi_auto_clear) { - nmi_auto_clear = 0; - nmi = 0; - } -#else - nmi = 0; -#endif - } else if ((cpu_state.flags & I_FLAG) && pic.int_pending) { - vector = picinterrupt(); - if (vector != -1) { -#ifndef USE_NEW_DYNAREC - oldcs = CS; -#endif - cpu_state.oldpc = cpu_state.pc; - x86_int(vector); - } - } + if (smi_line) + enter_smm_check(0); + else if (nmi && nmi_enable && nmi_mask) { +# ifndef USE_NEW_DYNAREC + oldcs = CS; +# endif + cpu_state.oldpc = cpu_state.pc; + x86_int(2); + nmi_enable = 0; +# ifdef OLD_NMI_BEHAVIOR + if (nmi_auto_clear) { + nmi_auto_clear = 0; + nmi = 0; + } +# else + nmi = 0; +# endif + } else if ((cpu_state.flags & I_FLAG) && pic.int_pending) { + vector = picinterrupt(); + if (vector != -1) { +# ifndef USE_NEW_DYNAREC + oldcs = CS; +# endif + cpu_state.oldpc = cpu_state.pc; + x86_int(vector); + } + } - cycdiff = oldcyc - cycles; - delta = tsc - oldtsc; - if (delta > 0) { - /* TSC has changed, this means interim timer processing has happened, - see how much we still need to add. */ - cycdiff -= delta; - if (cycdiff > 0) - tsc += cycdiff; - } else { - /* TSC has not changed. */ - tsc += cycdiff; - } + cycdiff = oldcyc - cycles; + delta = tsc - oldtsc; + if (delta > 0) { + /* TSC has changed, this means interim timer processing has happened, + see how much we still need to add. */ + cycdiff -= delta; + if (cycdiff > 0) + tsc += cycdiff; + } else { + /* TSC has not changed. */ + tsc += cycdiff; + } - if (cycdiff > 0) { - if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) - timer_process_inline(); - } + if (cycdiff > 0) { + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) + timer_process_inline(); + } -#ifdef USE_GDBSTUB - if (gdbstub_instruction()) - return; -#endif - } +# ifdef USE_GDBSTUB + if (gdbstub_instruction()) + return; +# endif + } - cycles_main -= (cycles_start - cycles); + cycles_main -= (cycles_start - cycles); } } #endif diff --git a/src/cpu/386_dynarec_ops.c b/src/cpu/386_dynarec_ops.c index 0b02676f8..f3e2f6e6e 100644 --- a/src/cpu/386_dynarec_ops.c +++ b/src/cpu/386_dynarec_ops.c @@ -5,7 +5,7 @@ #include #include #ifndef INFINITY -# define INFINITY (__builtin_inff()) +# define INFINITY (__builtin_inff()) #endif #include <86box/86box.h> @@ -25,57 +25,61 @@ #define CPU_BLOCK_END() cpu_block_end = 1 #ifndef IS_DYNAREC -#define IS_DYNAREC +# define IS_DYNAREC #endif #include "386_common.h" - -static __inline void fetch_ea_32_long(uint32_t rmdat) +static __inline void +fetch_ea_32_long(uint32_t rmdat) { - eal_r = eal_w = NULL; - easeg = cpu_state.ea_seg->base; - if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) - { - uint32_t addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) - eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) - eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); - } + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { + uint32_t addr = easeg + cpu_state.eaaddr; + if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) + eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) + eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr); + } } -static __inline void fetch_ea_16_long(uint32_t rmdat) +static __inline void +fetch_ea_16_long(uint32_t rmdat) { - eal_r = eal_w = NULL; - easeg = cpu_state.ea_seg->base; - if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) - { - uint32_t addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) - eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) - eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); - } + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { + uint32_t addr = easeg + cpu_state.eaaddr; + if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) + eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) + eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr); + } } -#define fetch_ea_16(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_16_long(rmdat); -#define fetch_ea_32(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_32_long(rmdat); - +#define fetch_ea_16(rmdat) \ + cpu_state.pc++; \ + if (cpu_mod != 3) \ + fetch_ea_16_long(rmdat); +#define fetch_ea_32(rmdat) \ + cpu_state.pc++; \ + if (cpu_mod != 3) \ + fetch_ea_32_long(rmdat); #define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, read_ls, writes, write_ls, ea32) #define PREFETCH_PREFIX() #define PREFETCH_FLUSH() -#define OP_TABLE(name) dynarec_ops_ ## name +#define OP_TABLE(name) dynarec_ops_##name #define CLOCK_CYCLES(c) #if 0 -#define CLOCK_CYCLES_FPU(c) -#define CONCURRENCY_CYCLES(c) fpu_cycles = (c) +# define CLOCK_CYCLES_FPU(c) +# define CONCURRENCY_CYCLES(c) fpu_cycles = (c) #else -#define CLOCK_CYCLES_FPU(c) -#define CONCURRENCY_CYCLES(c) +# define CLOCK_CYCLES_FPU(c) +# define CONCURRENCY_CYCLES(c) #endif #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h index d5f62f74f..cad5a7b05 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.h @@ -40,128 +40,137 @@ */ #include "x86_ops.h" +#define ILLEGAL_ON(cond) \ + do { \ + if ((cond)) { \ + cpu_state.pc = cpu_state.oldpc; \ + x86illegal(); \ + return 0; \ + } \ + } while (0) -#define ILLEGAL_ON(cond) \ - do \ - { \ - if ((cond)) \ - { \ - cpu_state.pc = cpu_state.oldpc; \ - x86illegal(); \ - return 0; \ - } \ - } while (0) - -static __inline void PUSH_W(uint16_t val) +static __inline void +PUSH_W(uint16_t val) { - if (stack32) - { - writememw(ss, ESP - 2, val); if (cpu_state.abrt) return; - ESP -= 2; - } - else - { - writememw(ss, (SP - 2) & 0xFFFF, val); if (cpu_state.abrt) return; - SP -= 2; - } + if (stack32) { + writememw(ss, ESP - 2, val); + if (cpu_state.abrt) + return; + ESP -= 2; + } else { + writememw(ss, (SP - 2) & 0xFFFF, val); + if (cpu_state.abrt) + return; + SP -= 2; + } } -static __inline void PUSH_L(uint32_t val) +static __inline void +PUSH_L(uint32_t val) { - if (stack32) - { - writememl(ss, ESP - 4, val); if (cpu_state.abrt) return; - ESP -= 4; - } - else - { - writememl(ss, (SP - 4) & 0xFFFF, val); if (cpu_state.abrt) return; - SP -= 4; - } + if (stack32) { + writememl(ss, ESP - 4, val); + if (cpu_state.abrt) + return; + ESP -= 4; + } else { + writememl(ss, (SP - 4) & 0xFFFF, val); + if (cpu_state.abrt) + return; + SP -= 4; + } } -static __inline uint16_t POP_W(void) +static __inline uint16_t +POP_W(void) { - uint16_t ret; - if (stack32) - { - ret = readmemw(ss, ESP); if (cpu_state.abrt) return 0; - ESP += 2; - } - else - { - ret = readmemw(ss, SP); if (cpu_state.abrt) return 0; - SP += 2; - } - return ret; + uint16_t ret; + if (stack32) { + ret = readmemw(ss, ESP); + if (cpu_state.abrt) + return 0; + ESP += 2; + } else { + ret = readmemw(ss, SP); + if (cpu_state.abrt) + return 0; + SP += 2; + } + return ret; } -static __inline uint32_t POP_L(void) +static __inline uint32_t +POP_L(void) { - uint32_t ret; - if (stack32) - { - ret = readmeml(ss, ESP); if (cpu_state.abrt) return 0; - ESP += 4; - } - else - { - ret = readmeml(ss, SP); if (cpu_state.abrt) return 0; - SP += 4; - } - return ret; + uint32_t ret; + if (stack32) { + ret = readmeml(ss, ESP); + if (cpu_state.abrt) + return 0; + ESP += 4; + } else { + ret = readmeml(ss, SP); + if (cpu_state.abrt) + return 0; + SP += 4; + } + return ret; } -static __inline uint16_t POP_W_seg(uint32_t seg) +static __inline uint16_t +POP_W_seg(uint32_t seg) { - uint16_t ret; - if (stack32) - { - ret = readmemw(seg, ESP); if (cpu_state.abrt) return 0; - ESP += 2; - } - else - { - ret = readmemw(seg, SP); if (cpu_state.abrt) return 0; - SP += 2; - } - return ret; + uint16_t ret; + if (stack32) { + ret = readmemw(seg, ESP); + if (cpu_state.abrt) + return 0; + ESP += 2; + } else { + ret = readmemw(seg, SP); + if (cpu_state.abrt) + return 0; + SP += 2; + } + return ret; } -static __inline uint32_t POP_L_seg(uint32_t seg) +static __inline uint32_t +POP_L_seg(uint32_t seg) { - uint32_t ret; - if (stack32) - { - ret = readmeml(seg, ESP); if (cpu_state.abrt) return 0; - ESP += 4; - } - else - { - ret = readmeml(seg, SP); if (cpu_state.abrt) return 0; - SP += 4; - } - return ret; + uint32_t ret; + if (stack32) { + ret = readmeml(seg, ESP); + if (cpu_state.abrt) + return 0; + ESP += 4; + } else { + ret = readmeml(seg, SP); + if (cpu_state.abrt) + return 0; + SP += 4; + } + return ret; } static int fopcode; -static int ILLEGAL(uint32_t fetchdat) +static int +ILLEGAL(uint32_t fetchdat) { - pclog("[%04X:%08X] Illegal instruction %08X (%02X)\n", CS, cpu_state.pc, fetchdat, fopcode); - cpu_state.pc = cpu_state.oldpc; + pclog("[%04X:%08X] Illegal instruction %08X (%02X)\n", CS, cpu_state.pc, fetchdat, fopcode); + cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 0; + x86illegal(); + return 0; } - #ifdef ENABLE_386_DYNAREC_LOG -extern void x386_dynarec_log(const char *fmt, ...); +extern void x386_dynarec_log(const char *fmt, ...); #else -#ifndef x386_dynarec_log -#define x386_dynarec_log(fmt, ...) -#endif +# ifndef x386_dynarec_log +# define x386_dynarec_log(fmt, ...) +# endif #endif #include "x86seg.h" @@ -196,9 +205,9 @@ extern void x386_dynarec_log(const char *fmt, ...); #include "x86_ops_pmode.h" #include "x86_ops_prefix.h" #ifdef IS_DYNAREC -#include "x86_ops_rep_dyn.h" +# include "x86_ops_rep_dyn.h" #else -#include "x86_ops_rep.h" +# include "x86_ops_rep.h" #endif #include "x86_ops_ret.h" #include "x86_ops_set.h" @@ -211,157 +220,160 @@ extern void x386_dynarec_log(const char *fmt, ...); #include "x86_ops_3dnow.h" #include - -static int opVPCEXT(uint32_t fetchdat) +static int +opVPCEXT(uint32_t fetchdat) { - uint8_t b1, b2; - uint16_t cent; - time_t now; - struct tm *tm; + uint8_t b1, b2; + uint16_t cent; + time_t now; + struct tm *tm; - if (!is_vpc) /* only emulate this on Virtual PC machines */ - return ILLEGAL(fetchdat); + if (!is_vpc) /* only emulate this on Virtual PC machines */ + return ILLEGAL(fetchdat); - cpu_state.pc += 2; + cpu_state.pc += 2; - b1 = fetchdat & 0xff; - b2 = (fetchdat >> 8) & 0xff; + b1 = fetchdat & 0xff; + b2 = (fetchdat >> 8) & 0xff; - /* a lot of these opcodes (which?) return illegal instruction in user mode */ - ILLEGAL_ON(CPL > 0); + /* a lot of these opcodes (which?) return illegal instruction in user mode */ + ILLEGAL_ON(CPL > 0); - CLOCK_CYCLES(1); + CLOCK_CYCLES(1); - /* 0f 3f 03 xx opcodes are mostly related to the host clock, so fetch it now */ - if (b1 == 0x03) { - (void)time(&now); - tm = localtime(&now); - } + /* 0f 3f 03 xx opcodes are mostly related to the host clock, so fetch it now */ + if (b1 == 0x03) { + (void) time(&now); + tm = localtime(&now); + } - if ((b1 == 0x07) && (b2 == 0x0b)) { - /* 0f 3f 07 0b: unknown, EDX output depends on EAX input */ - switch (EAX) { - case 0x00000000: - EDX = 0x00000003; - break; + if ((b1 == 0x07) && (b2 == 0x0b)) { + /* 0f 3f 07 0b: unknown, EDX output depends on EAX input */ + switch (EAX) { + case 0x00000000: + EDX = 0x00000003; + break; - case 0x00000001: - EDX = 0x00000012; - break; + case 0x00000001: + EDX = 0x00000012; + break; - case 0x00000002: - case 0x00000003: - case 0x00000004: - case 0x00000005: - EDX = 0x00000001; - break; + case 0x00000002: + case 0x00000003: + case 0x00000004: + case 0x00000005: + EDX = 0x00000001; + break; - case 0x00000007: - EDX = 0x0000009c; - break; + case 0x00000007: + EDX = 0x0000009c; + break; - default: - EDX = 0x00000000; - if (EAX > 0x00000012) /* unknown EAX values set zero flag */ - cpu_state.flags &= ~(Z_FLAG); - } - } else if ((b1 == 0x03) && (b2 == 0x00)) { - /* 0f 3f 03 00: host time in BCD */ - EDX = BCD8(tm->tm_hour); - ECX = BCD8(tm->tm_min); - EAX = BCD8(tm->tm_sec); - } else if ((b1 == 0x03) && (b2 == 0x01)) { - /* 0f 3f 03 00: host date in BCD */ - EDX = BCD8(tm->tm_year % 100); - ECX = BCD8(tm->tm_mon + 1); - EAX = BCD8(tm->tm_mday); - cent = (((tm->tm_year - (tm->tm_year % 100)) / 100) % 4); /* Sunday = 0 */ - EBX = ((tm->tm_mday + tm->tm_mon + (tm->tm_year % 100) + cent + 3) % 7); - } else if ((b1 == 0x03) && (b2 == 0x03)) { - /* 0f 3f 03 03: host time in binary */ - EDX = tm->tm_hour; - ECX = tm->tm_min; - EAX = tm->tm_sec; - } else if ((b1 == 0x03) && (b2 == 0x04)) { - /* 0f 3f 03 04: host date in binary */ - EDX = 1900 + tm->tm_year; - ECX = tm->tm_mon + 1; - EBX = tm->tm_mday; - } else if ((b1 == 0x03) && (b2 == 0x05)) { - /* 0f 3f 03 05: unknown */ - EBX = 0x0000000F; - ECX = 0x0000000A; - } else if ((b1 == 0x03) && (b2 == 0x06)) { - /* 0f 3f 03 06: some kind of timestamp. BX jumps around very quickly, CX not so much. */ - EBX = 0x00000000; - ECX = 0x00000000; - } else if ((b1 == 0x03) && (b2 >= 0x07)) { - /* 0f 3f 03 07+: set zero flag */ - cpu_state.flags &= ~(Z_FLAG); - } else if ((b1 == 0x0a) && (b2 == 0x00)) { - /* 0f 3f 0a 00: memory size in KB */ - EAX = mem_size; - } else if ((b1 == 0x11) && (b2 == 0x00)) { - /* 0f 3f 11 00: unknown, set EAX to 0 */ - EAX = 0x00000000; - } else if ((b1 == 0x11) && (b2 == 0x01)) { - /* 0f 3f 11 00: unknown, set EAX to 0 and set zero flag */ - EAX = 0x00000000; - cpu_state.flags &= ~(Z_FLAG); - } else if ((b1 == 0x11) && (b2 == 0x02)) { - /* 0f 3f 11 02: unknown, no-op */ - } else { - /* other unknown opcodes: illegal instruction */ - cpu_state.pc = cpu_state.oldpc; + default: + EDX = 0x00000000; + if (EAX > 0x00000012) /* unknown EAX values set zero flag */ + cpu_state.flags &= ~(Z_FLAG); + } + } else if ((b1 == 0x03) && (b2 == 0x00)) { + /* 0f 3f 03 00: host time in BCD */ + EDX = BCD8(tm->tm_hour); + ECX = BCD8(tm->tm_min); + EAX = BCD8(tm->tm_sec); + } else if ((b1 == 0x03) && (b2 == 0x01)) { + /* 0f 3f 03 00: host date in BCD */ + EDX = BCD8(tm->tm_year % 100); + ECX = BCD8(tm->tm_mon + 1); + EAX = BCD8(tm->tm_mday); + cent = (((tm->tm_year - (tm->tm_year % 100)) / 100) % 4); /* Sunday = 0 */ + EBX = ((tm->tm_mday + tm->tm_mon + (tm->tm_year % 100) + cent + 3) % 7); + } else if ((b1 == 0x03) && (b2 == 0x03)) { + /* 0f 3f 03 03: host time in binary */ + EDX = tm->tm_hour; + ECX = tm->tm_min; + EAX = tm->tm_sec; + } else if ((b1 == 0x03) && (b2 == 0x04)) { + /* 0f 3f 03 04: host date in binary */ + EDX = 1900 + tm->tm_year; + ECX = tm->tm_mon + 1; + EBX = tm->tm_mday; + } else if ((b1 == 0x03) && (b2 == 0x05)) { + /* 0f 3f 03 05: unknown */ + EBX = 0x0000000F; + ECX = 0x0000000A; + } else if ((b1 == 0x03) && (b2 == 0x06)) { + /* 0f 3f 03 06: some kind of timestamp. BX jumps around very quickly, CX not so much. */ + EBX = 0x00000000; + ECX = 0x00000000; + } else if ((b1 == 0x03) && (b2 >= 0x07)) { + /* 0f 3f 03 07+: set zero flag */ + cpu_state.flags &= ~(Z_FLAG); + } else if ((b1 == 0x0a) && (b2 == 0x00)) { + /* 0f 3f 0a 00: memory size in KB */ + EAX = mem_size; + } else if ((b1 == 0x11) && (b2 == 0x00)) { + /* 0f 3f 11 00: unknown, set EAX to 0 */ + EAX = 0x00000000; + } else if ((b1 == 0x11) && (b2 == 0x01)) { + /* 0f 3f 11 00: unknown, set EAX to 0 and set zero flag */ + EAX = 0x00000000; + cpu_state.flags &= ~(Z_FLAG); + } else if ((b1 == 0x11) && (b2 == 0x02)) { + /* 0f 3f 11 02: unknown, no-op */ + } else { + /* other unknown opcodes: illegal instruction */ + cpu_state.pc = cpu_state.oldpc; - pclog("Illegal VPCEXT %08X (%02X %02X)\n", fetchdat, b1, b2); - x86illegal(); - return 0; - } + pclog("Illegal VPCEXT %08X (%02X %02X)\n", fetchdat, b1, b2); + x86illegal(); + return 0; + } - return 1; + return 1; } - -static int op0F_w_a16(uint32_t fetchdat) +static int +op0F_w_a16(uint32_t fetchdat) { - int opcode = fetchdat & 0xff; - fopcode = opcode; - cpu_state.pc++; + int opcode = fetchdat & 0xff; + fopcode = opcode; + cpu_state.pc++; - PREFETCH_PREFIX(); + PREFETCH_PREFIX(); - return x86_opcodes_0f[opcode](fetchdat >> 8); + return x86_opcodes_0f[opcode](fetchdat >> 8); } -static int op0F_l_a16(uint32_t fetchdat) +static int +op0F_l_a16(uint32_t fetchdat) { - int opcode = fetchdat & 0xff; - fopcode = opcode; - cpu_state.pc++; + int opcode = fetchdat & 0xff; + fopcode = opcode; + cpu_state.pc++; - PREFETCH_PREFIX(); + PREFETCH_PREFIX(); - return x86_opcodes_0f[opcode | 0x100](fetchdat >> 8); + return x86_opcodes_0f[opcode | 0x100](fetchdat >> 8); } -static int op0F_w_a32(uint32_t fetchdat) +static int +op0F_w_a32(uint32_t fetchdat) { - int opcode = fetchdat & 0xff; - fopcode = opcode; - cpu_state.pc++; + int opcode = fetchdat & 0xff; + fopcode = opcode; + cpu_state.pc++; - PREFETCH_PREFIX(); + PREFETCH_PREFIX(); - return x86_opcodes_0f[opcode | 0x200](fetchdat >> 8); + return x86_opcodes_0f[opcode | 0x200](fetchdat >> 8); } -static int op0F_l_a32(uint32_t fetchdat) +static int +op0F_l_a32(uint32_t fetchdat) { - int opcode = fetchdat & 0xff; - fopcode = opcode; - cpu_state.pc++; + int opcode = fetchdat & 0xff; + fopcode = opcode; + cpu_state.pc++; - PREFETCH_PREFIX(); + PREFETCH_PREFIX(); - return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8); + return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8); } const OpFn OP_TABLE(186_0f)[1024] = diff --git a/src/cpu/8080.c b/src/cpu/8080.c index afea3625c..6f3dd4267 100644 --- a/src/cpu/8080.c +++ b/src/cpu/8080.c @@ -13,7 +13,6 @@ * Copyright 2022 Cacodemon345 */ - #include #include #include "cpu.h" @@ -38,15 +37,14 @@ clock_start(void) cycdiff = cycles; } - static void clock_end(void) { int diff = cycdiff - cycles; /* On 808x systems, clock speed is usually crystal frequency divided by an integer. */ - tsc += (uint64_t)diff * ((uint64_t)xt_cpu_multi >> 32ULL); /* Shift xt_cpu_multi by 32 bits to the right and then multiply. */ - if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + tsc += (uint64_t) diff * ((uint64_t) xt_cpu_multi >> 32ULL); /* Shift xt_cpu_multi by 32 bits to the right and then multiply. */ + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) timer_process(); } @@ -73,7 +71,7 @@ readmemb(uint32_t a) } static uint8_t -ins_fetch(i8080* cpu) +ins_fetch(i8080 *cpu) { uint8_t ret = cpu->readmembyte(cpu->pmembase + cpu->pc); @@ -83,22 +81,22 @@ ins_fetch(i8080* cpu) #endif void -transfer_from_808x(i8080* cpu) +transfer_from_808x(i8080 *cpu) { - cpu->hl = BX; - cpu->bc = CX; - cpu->de = DX; - cpu->a = AL; - cpu->flags = cpu_state.flags & 0xFF; - cpu->sp = BP; - cpu->pc = cpu_state.pc; - cpu->oldpc = cpu_state.oldpc; + cpu->hl = BX; + cpu->bc = CX; + cpu->de = DX; + cpu->a = AL; + cpu->flags = cpu_state.flags & 0xFF; + cpu->sp = BP; + cpu->pc = cpu_state.pc; + cpu->oldpc = cpu_state.oldpc; cpu->pmembase = cs; cpu->dmembase = ds; } void -transfer_to_808x(i8080* cpu) +transfer_to_808x(i8080 *cpu) { BX = cpu->hl; CX = cpu->bc; @@ -106,7 +104,7 @@ transfer_to_808x(i8080* cpu) AL = cpu->a; cpu_state.flags &= 0xFF00; cpu_state.flags |= cpu->flags & 0xFF; - BP = cpu->sp; + BP = cpu->sp; cpu_state.pc = cpu->pc; } @@ -114,16 +112,31 @@ uint8_t getreg_i8080(i8080 *cpu, uint8_t reg) { uint8_t ret = 0xFF; - switch(reg) - { - case 0x0: ret = cpu->b; break; - case 0x1: ret = cpu->c; break; - case 0x2: ret = cpu->d; break; - case 0x3: ret = cpu->e; break; - case 0x4: ret = cpu->h; break; - case 0x5: ret = cpu->l; break; - case 0x6: ret = cpu->readmembyte(cpu->dmembase + cpu->sp); break; - case 0x7: ret = cpu->a; break; + switch (reg) { + case 0x0: + ret = cpu->b; + break; + case 0x1: + ret = cpu->c; + break; + case 0x2: + ret = cpu->d; + break; + case 0x3: + ret = cpu->e; + break; + case 0x4: + ret = cpu->h; + break; + case 0x5: + ret = cpu->l; + break; + case 0x6: + ret = cpu->readmembyte(cpu->dmembase + cpu->sp); + break; + case 0x7: + ret = cpu->a; + break; } return ret; } @@ -132,16 +145,31 @@ uint8_t getreg_i8080_emu(i8080 *cpu, uint8_t reg) { uint8_t ret = 0xFF; - switch(reg) - { - case 0x0: ret = CH; break; - case 0x1: ret = CL; break; - case 0x2: ret = DH; break; - case 0x3: ret = DL; break; - case 0x4: ret = BH; break; - case 0x5: ret = BL; break; - case 0x6: ret = cpu->readmembyte(cpu->dmembase + BP); break; - case 0x7: ret = AL; break; + switch (reg) { + case 0x0: + ret = CH; + break; + case 0x1: + ret = CL; + break; + case 0x2: + ret = DH; + break; + case 0x3: + ret = DL; + break; + case 0x4: + ret = BH; + break; + case 0x5: + ret = BL; + break; + case 0x6: + ret = cpu->readmembyte(cpu->dmembase + BP); + break; + case 0x7: + ret = AL; + break; } return ret; } @@ -149,57 +177,87 @@ getreg_i8080_emu(i8080 *cpu, uint8_t reg) void setreg_i8080_emu(i8080 *cpu, uint8_t reg, uint8_t val) { - switch(reg) - { - case 0x0: CH = val; break; - case 0x1: CL = val; break; - case 0x2: DH = val; break; - case 0x3: DL = val; break; - case 0x4: BH = val; break; - case 0x5: BL = val; break; - case 0x6: cpu->writemembyte(cpu->dmembase + BP, val); break; - case 0x7: AL = val; break; + switch (reg) { + case 0x0: + CH = val; + break; + case 0x1: + CL = val; + break; + case 0x2: + DH = val; + break; + case 0x3: + DL = val; + break; + case 0x4: + BH = val; + break; + case 0x5: + BL = val; + break; + case 0x6: + cpu->writemembyte(cpu->dmembase + BP, val); + break; + case 0x7: + AL = val; + break; } } void setreg_i8080(i8080 *cpu, uint8_t reg, uint8_t val) { - switch(reg) - { - case 0x0: cpu->b = val; break; - case 0x1: cpu->c = val; break; - case 0x2: cpu->d = val; break; - case 0x3: cpu->e = val; break; - case 0x4: cpu->h = val; break; - case 0x5: cpu->l = val; break; - case 0x6: cpu->writemembyte(cpu->dmembase + cpu->sp, val); break; - case 0x7: cpu->a = val; break; + switch (reg) { + case 0x0: + cpu->b = val; + break; + case 0x1: + cpu->c = val; + break; + case 0x2: + cpu->d = val; + break; + case 0x3: + cpu->e = val; + break; + case 0x4: + cpu->h = val; + break; + case 0x5: + cpu->l = val; + break; + case 0x6: + cpu->writemembyte(cpu->dmembase + cpu->sp, val); + break; + case 0x7: + cpu->a = val; + break; } } void -interpret_exec8080(i8080* cpu, uint8_t opcode) +interpret_exec8080(i8080 *cpu, uint8_t opcode) { switch (opcode) { case 0x00: - { - break; - } + { + break; + } } } /* Actually implement i8080 emulation. */ void -exec8080(i8080* cpu, int cycs) +exec8080(i8080 *cpu, int cycs) { #ifdef UNUSED_8080_VARS - uint8_t temp = 0, temp2; - uint8_t old_af; - uint8_t handled = 0; + uint8_t temp = 0, temp2; + uint8_t old_af; + uint8_t handled = 0; uint16_t addr, tempw; uint16_t new_ip; - int bits; + int bits; #endif cycles += cycs; @@ -209,17 +267,18 @@ exec8080(i8080* cpu, int cycs) if (!repeating) { cpu->oldpc = cpu->pc; - opcode = cpu->fetchinstruction(cpu); - oldc = cpu->flags & C_FLAG_I8080; + opcode = cpu->fetchinstruction(cpu); + oldc = cpu->flags & C_FLAG_I8080; i8080_wait(1, 0); } completed = 1; if (completed) { - repeating = 0; - in_rep = 0; + repeating = 0; + in_rep = 0; rep_c_flag = 0; cpu->endclock(); - if (cpu->checkinterrupts) cpu->checkinterrupts(); + if (cpu->checkinterrupts) + cpu->checkinterrupts(); } } } diff --git a/src/cpu/808x.c b/src/cpu/808x.c index cc8cbc903..b2859153a 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -1085,9 +1085,9 @@ rep_action(int bits) access(71, bits); pfq_clear(); if (is_nec && (ovr_seg != NULL)) - set_ip(cpu_state.pc - 3); + set_ip(cpu_state.pc - 3); else - set_ip(cpu_state.pc - 2); + set_ip(cpu_state.pc - 2); t = 0; } if (t == 0) { @@ -1683,7 +1683,7 @@ execx86(int cycs) // pclog("[%04X:%04X] Opcode: %02X\n", CS, cpu_state.pc, opcode); if (is186) { switch (opcode) { - case 0x60: /*PUSHA/PUSH R*/ + case 0x60: /*PUSHA/PUSH R*/ orig_sp = SP; wait(1, 0); push(&AX); @@ -1696,12 +1696,12 @@ execx86(int cycs) push(&DI); handled = 1; break; - case 0x61: /*POPA/POP R*/ + case 0x61: /*POPA/POP R*/ wait(9, 0); - DI = pop(); - SI = pop(); - BP = pop(); - (void) pop(); /* former orig_sp */ + DI = pop(); + SI = pop(); + BP = pop(); + (void) pop(); /* former orig_sp */ BX = pop(); DX = pop(); CX = pop(); @@ -1710,9 +1710,9 @@ execx86(int cycs) break; case 0x62: /* BOUND r/m */ - lowbound = 0; + lowbound = 0; highbound = 0; - regval = 0; + regval = 0; do_mod_rm(); lowbound = readmemw(easeg, cpu_state.eaaddr); @@ -1733,7 +1733,7 @@ execx86(int cycs) in_rep = (opcode == 0x64 ? 1 : 2); rep_c_flag = 1; completed = 0; - handled = 1; + handled = 1; } break; @@ -1746,7 +1746,7 @@ execx86(int cycs) case 0x69: immediate = 0; - bits = 16; + bits = 16; do_mod_rm(); read_ea(0, 16); immediate = pfq_fetchw(); @@ -1764,7 +1764,7 @@ execx86(int cycs) case 0x6b: /* IMUL reg16,reg16/mem16,imm8 */ immediate = 0; - bits = 16; + bits = 16; do_mod_rm(); read_ea(0, 16); immediate = pfq_fetchb(); @@ -1805,13 +1805,13 @@ execx86(int cycs) case 0x6e: case 0x6f: /* OUTM DW, src/OUTS DX, src */ dest_seg = ovr_seg ? *ovr_seg : ds; - bits = 8 << (opcode & 1); - handled = 1; + bits = 8 << (opcode & 1); + handled = 1; if (!repeating) wait(2, 0); if (rep_action(bits)) - break; + break; else if (!repeating) wait(7, 0); @@ -1832,9 +1832,9 @@ execx86(int cycs) case 0xc8: /* ENTER/PREPARE */ tempw_int = 0; - size = pfq_fetchw(); - nests = pfq_fetchb(); - i = 0; + size = pfq_fetchw(); + nests = pfq_fetchb(); + i = 0; push(&BP); tempw_int = SP; @@ -1984,7 +1984,7 @@ execx86(int cycs) handled = 1; break; - case 0x2a: /* ROR4 r/m */ + case 0x2a: /* ROR4 r/m */ do_mod_rm(); wait(21, 0); @@ -2081,10 +2081,10 @@ execx86(int cycs) odd = !!(CL % 2); zero = 1; nibbles_count = CL - odd; - i = 0; - carry = 0; - nibble = 0; - srcseg = ovr_seg ? *ovr_seg : ds; + i = 0; + carry = 0; + nibble = 0; + srcseg = ovr_seg ? *ovr_seg : ds; wait(5, 0); for (i = 0; i < ((nibbles_count / 2) + odd); i++) { @@ -2116,10 +2116,10 @@ execx86(int cycs) odd = !!(CL % 2); zero = 1; nibbles_count = CL - odd; - i = 0; - carry = 0; - nibble = 0; - srcseg = ovr_seg ? *ovr_seg : ds; + i = 0; + carry = 0; + nibble = 0; + srcseg = ovr_seg ? *ovr_seg : ds; wait(5, 0); for (i = 0; i < ((nibbles_count / 2) + odd); i++) { @@ -2151,10 +2151,10 @@ execx86(int cycs) odd = !!(CL % 2); zero = 1; nibbles_count = CL - odd; - i = 0; - carry = 0; - nibble = 0; - srcseg = ovr_seg ? *ovr_seg : ds; + i = 0; + carry = 0; + nibble = 0; + srcseg = ovr_seg ? *ovr_seg : ds; wait(5, 0); for (i = 0; i < ((nibbles_count / 2) + odd); i++) { @@ -2206,7 +2206,7 @@ execx86(int cycs) } } setr8(cpu_rm, bit_offset); - + handled = 1; break; @@ -2501,9 +2501,9 @@ execx86(int cycs) wait(1, 0); break; - case 0x60: /*JO alias*/ - case 0x70: /*JO*/ - case 0x61: /*JNO alias*/ + case 0x60: /*JO alias*/ + case 0x70: /*JO*/ + case 0x61: /*JNO alias*/ case 0x71: /*JNO*/ jcc(opcode, cpu_state.flags & V_FLAG); break; @@ -2525,15 +2525,15 @@ execx86(int cycs) case 0x77: /*JNBE*/ jcc(opcode, cpu_state.flags & (C_FLAG | Z_FLAG)); break; - case 0x68: /*JS alias*/ - case 0x78: /*JS*/ - case 0x69: /*JNS alias*/ + case 0x68: /*JS alias*/ + case 0x78: /*JS*/ + case 0x69: /*JNS alias*/ case 0x79: /*JNS*/ jcc(opcode, cpu_state.flags & N_FLAG); break; - case 0x6A: /*JP alias*/ - case 0x7A: /*JP*/ - case 0x6B: /*JNP alias*/ + case 0x6A: /*JP alias*/ + case 0x7A: /*JP*/ + case 0x6B: /*JNP alias*/ case 0x7B: /*JNP*/ jcc(opcode, cpu_state.flags & P_FLAG); break; diff --git a/src/cpu/codegen_public.h b/src/cpu/codegen_public.h index fa7dad8a5..36393296e 100644 --- a/src/cpu/codegen_public.h +++ b/src/cpu/codegen_public.h @@ -36,29 +36,27 @@ #define _CODEGEN_PUBLIC_H_ #ifndef USE_NEW_DYNAREC -#define PAGE_MASK_INDEX_MASK 3 -#define PAGE_MASK_INDEX_SHIFT 10 -#define PAGE_MASK_SHIFT 4 +# define PAGE_MASK_INDEX_MASK 3 +# define PAGE_MASK_INDEX_SHIFT 10 +# define PAGE_MASK_SHIFT 4 #else -#define PAGE_MASK_SHIFT 6 +# define PAGE_MASK_SHIFT 6 #endif #define PAGE_MASK_MASK 63 #ifdef USE_NEW_DYNAREC -#define BLOCK_PC_INVALID 0xffffffff -#define BLOCK_INVALID 0 +# define BLOCK_PC_INVALID 0xffffffff +# define BLOCK_INVALID 0 #endif - -extern void codegen_init(void); +extern void codegen_init(void); #ifdef USE_NEW_DYNAREC -extern void codegen_close(void); +extern void codegen_close(void); #endif -extern void codegen_flush(void); - +extern void codegen_flush(void); /*Current physical page of block being recompiled. -1 if no recompilation taking place */ -extern uint32_t recomp_page; -extern int codegen_in_recompile; +extern uint32_t recomp_page; +extern int codegen_in_recompile; #endif diff --git a/src/cpu/codegen_timing_common.h b/src/cpu/codegen_timing_common.h index a3faca27d..679997802 100644 --- a/src/cpu/codegen_timing_common.h +++ b/src/cpu/codegen_timing_common.h @@ -3,11 +3,11 @@ /*Instruction has input dependency on register in REG field*/ #define SRCDEP_REG (1ull << 0) /*Instruction has input dependency on register in R/M field*/ -#define SRCDEP_RM (1ull << 1) +#define SRCDEP_RM (1ull << 1) /*Instruction modifies register in REG field*/ #define DSTDEP_REG (1ull << 2) /*Instruction modifies register in R/M field*/ -#define DSTDEP_RM (1ull << 3) +#define DSTDEP_RM (1ull << 3) #define SRCDEP_SHIFT 4 #define DSTDEP_SHIFT 12 @@ -40,48 +40,45 @@ /*Instruction is MMX shift or pack/unpack instruction*/ #define MMX_SHIFTPACK (1ull << 22) /*Instruction is MMX multiply instruction*/ -#define MMX_MULTIPLY (1ull << 23) +#define MMX_MULTIPLY (1ull << 23) /*Instruction pops the FPU stack*/ -#define FPU_POP (1ull << 24) +#define FPU_POP (1ull << 24) /*Instruction pops the FPU stack twice*/ -#define FPU_POP2 (1ull << 25) +#define FPU_POP2 (1ull << 25) /*Instruction pushes onto the FPU stack*/ -#define FPU_PUSH (1ull << 26) +#define FPU_PUSH (1ull << 26) /*Instruction writes to ST(0)*/ -#define FPU_WRITE_ST0 (1ull << 27) +#define FPU_WRITE_ST0 (1ull << 27) /*Instruction reads from ST(0)*/ -#define FPU_READ_ST0 (1ull << 28) +#define FPU_READ_ST0 (1ull << 28) /*Instruction reads from and writes to ST(0)*/ -#define FPU_RW_ST0 (3ull << 27) +#define FPU_RW_ST0 (3ull << 27) /*Instruction reads from ST(1)*/ -#define FPU_READ_ST1 (1ull << 29) +#define FPU_READ_ST1 (1ull << 29) /*Instruction writes to ST(1)*/ -#define FPU_WRITE_ST1 (1ull << 30) +#define FPU_WRITE_ST1 (1ull << 30) /*Instruction reads from and writes to ST(1)*/ -#define FPU_RW_ST1 (3ull << 29) +#define FPU_RW_ST1 (3ull << 29) /*Instruction reads from ST(reg)*/ -#define FPU_READ_STREG (1ull << 31) +#define FPU_READ_STREG (1ull << 31) /*Instruction writes to ST(reg)*/ #define FPU_WRITE_STREG (1ull << 32) /*Instruction reads from and writes to ST(reg)*/ -#define FPU_RW_STREG (3ull << 31) +#define FPU_RW_STREG (3ull << 31) -#define FPU_FXCH (1ull << 33) +#define FPU_FXCH (1ull << 33) +#define HAS_IMM8 (1ull << 34) +#define HAS_IMM1632 (1ull << 35) -#define HAS_IMM8 (1ull << 34) -#define HAS_IMM1632 (1ull << 35) - - -#define REGMASK_IMPL_ESP (1 << 8) +#define REGMASK_IMPL_ESP (1 << 8) #define REGMASK_SHIFTPACK (1 << 9) #define REGMASK_MULTIPLY (1 << 9) - extern uint64_t opcode_deps[256]; extern uint64_t opcode_deps_mod3[256]; extern uint64_t opcode_deps_0f[256]; @@ -119,114 +116,116 @@ extern uint64_t opcode_deps_81_mod3[8]; extern uint64_t opcode_deps_8x[8]; extern uint64_t opcode_deps_8x_mod3[8]; - - -static inline uint32_t get_addr_regmask(uint64_t data, uint32_t fetchdat, int op_32) +static inline uint32_t +get_addr_regmask(uint64_t data, uint32_t fetchdat, int op_32) { - uint32_t addr_regmask = 0; + uint32_t addr_regmask = 0; - if (data & MODRM) - { - uint8_t modrm = fetchdat & 0xff; + if (data & MODRM) { + uint8_t modrm = fetchdat & 0xff; - if ((modrm & 0xc0) != 0xc0) - { - if (op_32 & 0x200) - { - if ((modrm & 0x7) == 4) - { - uint8_t sib = (fetchdat >> 8) & 0xff; + if ((modrm & 0xc0) != 0xc0) { + if (op_32 & 0x200) { + if ((modrm & 0x7) == 4) { + uint8_t sib = (fetchdat >> 8) & 0xff; - if ((modrm & 0xc0) != 0xc0 && (sib & 7) != 5) - { - addr_regmask = 1 << (sib & 7); - if ((sib & 0x38) != 0x20) - addr_regmask |= 1 << ((sib >> 3) & 7); - } - } - else if ((modrm & 0xc7) != 5) - { - addr_regmask = 1 << (modrm & 7); - } - } - else - { - if ((modrm & 0xc7) != 0x06) - { - switch (modrm & 7) - { - case 0: addr_regmask = REG_BX | REG_SI; break; - case 1: addr_regmask = REG_BX | REG_DI; break; - case 2: addr_regmask = REG_BP | REG_SI; break; - case 3: addr_regmask = REG_BP | REG_DI; break; - case 4: addr_regmask = REG_SI; break; - case 5: addr_regmask = REG_DI; break; - case 6: addr_regmask = REG_BP; break; - case 7: addr_regmask = REG_BX; break; - } - } - } + if ((modrm & 0xc0) != 0xc0 && (sib & 7) != 5) { + addr_regmask = 1 << (sib & 7); + if ((sib & 0x38) != 0x20) + addr_regmask |= 1 << ((sib >> 3) & 7); + } + } else if ((modrm & 0xc7) != 5) { + addr_regmask = 1 << (modrm & 7); } + } else { + if ((modrm & 0xc7) != 0x06) { + switch (modrm & 7) { + case 0: + addr_regmask = REG_BX | REG_SI; + break; + case 1: + addr_regmask = REG_BX | REG_DI; + break; + case 2: + addr_regmask = REG_BP | REG_SI; + break; + case 3: + addr_regmask = REG_BP | REG_DI; + break; + case 4: + addr_regmask = REG_SI; + break; + case 5: + addr_regmask = REG_DI; + break; + case 6: + addr_regmask = REG_BP; + break; + case 7: + addr_regmask = REG_BX; + break; + } + } + } } + } - if (data & IMPL_ESP) - addr_regmask |= REGMASK_IMPL_ESP; + if (data & IMPL_ESP) + addr_regmask |= REGMASK_IMPL_ESP; - return addr_regmask; + return addr_regmask; } -static inline uint32_t get_srcdep_mask(uint64_t data, uint32_t fetchdat, int bit8, int op_32) +static inline uint32_t +get_srcdep_mask(uint64_t data, uint32_t fetchdat, int bit8, int op_32) { - uint32_t mask = 0; - if (data & SRCDEP_REG) - { - int reg = (fetchdat >> 3) & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - if (data & SRCDEP_RM) - { - int reg = fetchdat & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - mask |= ((data >> SRCDEP_SHIFT) & 0xff); - if (data & MMX_SHIFTPACK) - mask |= REGMASK_SHIFTPACK; - if (data & MMX_MULTIPLY) - mask |= REGMASK_MULTIPLY; + uint32_t mask = 0; + if (data & SRCDEP_REG) { + int reg = (fetchdat >> 3) & 7; + if (bit8) + reg &= 3; + mask |= (1 << reg); + } + if (data & SRCDEP_RM) { + int reg = fetchdat & 7; + if (bit8) + reg &= 3; + mask |= (1 << reg); + } + mask |= ((data >> SRCDEP_SHIFT) & 0xff); + if (data & MMX_SHIFTPACK) + mask |= REGMASK_SHIFTPACK; + if (data & MMX_MULTIPLY) + mask |= REGMASK_MULTIPLY; - mask |= get_addr_regmask(data, fetchdat, op_32); + mask |= get_addr_regmask(data, fetchdat, op_32); - return mask; + return mask; } -static inline uint32_t get_dstdep_mask(uint64_t data, uint32_t fetchdat, int bit8) +static inline uint32_t +get_dstdep_mask(uint64_t data, uint32_t fetchdat, int bit8) { - uint32_t mask = 0; - if (data & DSTDEP_REG) - { - int reg = (fetchdat >> 3) & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - if (data & DSTDEP_RM) - { - int reg = fetchdat & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - mask |= ((data >> DSTDEP_SHIFT) & 0xff); - if (data & MMX_SHIFTPACK) - mask |= REGMASK_SHIFTPACK; - if (data & MMX_MULTIPLY) - mask |= REGMASK_MULTIPLY; - if (data & IMPL_ESP) - mask |= REGMASK_IMPL_ESP | (1 << REG_ESP); + uint32_t mask = 0; + if (data & DSTDEP_REG) { + int reg = (fetchdat >> 3) & 7; + if (bit8) + reg &= 3; + mask |= (1 << reg); + } + if (data & DSTDEP_RM) { + int reg = fetchdat & 7; + if (bit8) + reg &= 3; + mask |= (1 << reg); + } + mask |= ((data >> DSTDEP_SHIFT) & 0xff); + if (data & MMX_SHIFTPACK) + mask |= REGMASK_SHIFTPACK; + if (data & MMX_MULTIPLY) + mask |= REGMASK_MULTIPLY; + if (data & IMPL_ESP) + mask |= REGMASK_IMPL_ESP | (1 << REG_ESP); - return mask; + return mask; } diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index ea90814c9..58ddf8dc6 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -1169,7 +1169,7 @@ cpu_set(void) #endif if ((cpu_s->cpu_type == CPU_K6_2P) || (cpu_s->cpu_type == CPU_K6_3P)) { - x86_opcodes_3DNOW = ops_3DNOWE; + x86_opcodes_3DNOW = ops_3DNOWE; x86_dynarec_opcodes_3DNOW = dynarec_ops_3DNOWE; } diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 8ddf101c2..11e1bc93c 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -35,9 +35,9 @@ enum { enum { CPU_8088 = 1, /* 808x class CPUs */ CPU_8086, - CPU_V20, /* NEC 808x class CPUs */ + CPU_V20, /* NEC 808x class CPUs */ CPU_V30, - CPU_188, /* 18x class CPUs */ + CPU_188, /* 18x class CPUs */ CPU_186, CPU_286, /* 286 class CPUs */ CPU_386SX, /* 386 class CPUs */ diff --git a/src/cpu/fpu.c b/src/cpu/fpu.c index d41a58508..f75d07231 100644 --- a/src/cpu/fpu.c +++ b/src/cpu/fpu.c @@ -25,11 +25,9 @@ #include <86box/86box.h> #include "cpu.h" - #ifdef ENABLE_FPU_LOG int fpu_do_log = ENABLE_FPU_LOG; - void fpu_log(const char *fmt, ...) { @@ -42,17 +40,16 @@ fpu_log(const char *fmt, ...) } } #else -#define fpu_log(fmt, ...) +# define fpu_log(fmt, ...) #endif - int fpu_get_type(const cpu_family_t *cpu_family, int cpu, const char *internal_name) { - const CPU *cpu_s = &cpu_family->cpus[cpu]; - const FPU *fpus = cpu_s->fpus; - int fpu_type = fpus[0].type; - int c = 0; + const CPU *cpu_s = &cpu_family->cpus[cpu]; + const FPU *fpus = cpu_s->fpus; + int fpu_type = fpus[0].type; + int c = 0; while (fpus[c].internal_name) { if (!strcmp(internal_name, fpus[c].internal_name)) @@ -63,13 +60,12 @@ fpu_get_type(const cpu_family_t *cpu_family, int cpu, const char *internal_name) return fpu_type; } - const char * fpu_get_internal_name(const cpu_family_t *cpu_family, int cpu, int type) { const CPU *cpu_s = &cpu_family->cpus[cpu]; - const FPU *fpus = cpu_s->fpus; - int c = 0; + const FPU *fpus = cpu_s->fpus; + int c = 0; while (fpus[c].internal_name) { if (fpus[c].type == type) @@ -80,22 +76,20 @@ fpu_get_internal_name(const cpu_family_t *cpu_family, int cpu, int type) return fpus[0].internal_name; } - const char * fpu_get_name_from_index(const cpu_family_t *cpu_family, int cpu, int c) { const CPU *cpu_s = &cpu_family->cpus[cpu]; - const FPU *fpus = cpu_s->fpus; + const FPU *fpus = cpu_s->fpus; return fpus[c].name; } - int fpu_get_type_from_index(const cpu_family_t *cpu_family, int cpu, int c) { const CPU *cpu_s = &cpu_family->cpus[cpu]; - const FPU *fpus = cpu_s->fpus; + const FPU *fpus = cpu_s->fpus; return fpus[c].type; } diff --git a/src/cpu/x86.c b/src/cpu/x86.c index df0c2244a..eb1dc463f 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -43,7 +43,7 @@ uint8_t opcode; /* The tables to speed up the setting of the Z, N, and P cpu_state.flags. */ -uint8_t znptable8[256]; +uint8_t znptable8[256]; uint16_t znptable16[65536]; /* A 16-bit zero, needed because some speed-up arrays contain pointers to it. */ @@ -52,7 +52,7 @@ uint16_t zero = 0; /* MOD and R/M stuff. */ uint16_t *mod1add[2][8]; uint32_t *mod1seg[8]; -uint32_t rmdat; +uint32_t rmdat; /* XT CPU multiplier. */ uint64_t xt_cpu_multi; @@ -72,13 +72,11 @@ uint32_t easeg; /* This is for the OPTI 283 special reset handling mode. */ int reset_on_hlt, hlt_reset_pending; - #ifdef ENABLE_X86_LOG -void dumpregs(int); +void dumpregs(int); int x86_do_log = ENABLE_X86_LOG; -int indump = 0; - +int indump = 0; static void x808x_log(const char *fmt, ...) @@ -86,60 +84,58 @@ x808x_log(const char *fmt, ...) va_list ap; if (x808x_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } - void dumpregs(int force) { - int c; + int c; char *seg_names[4] = { "ES", "CS", "SS", "DS" }; /* Only dump when needed, and only once.. */ if (indump || (!force && !dump_on_exit)) - return; + return; x808x_log("EIP=%08X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n", - cpu_state.pc, CS, DS, ES, SS, cpu_state.flags); + cpu_state.pc, CS, DS, ES, SS, cpu_state.flags); x808x_log("Old CS:EIP: %04X:%08X; %i ins\n", oldcs, cpu_state.oldpc, ins); for (c = 0; c < 4; c++) { - x808x_log("%s : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", - seg_names[c], _opseg[c]->base, _opseg[c]->limit, - _opseg[c]->access, _opseg[c]->limit_low, _opseg[c]->limit_high); + x808x_log("%s : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", + seg_names[c], _opseg[c]->base, _opseg[c]->limit, + _opseg[c]->access, _opseg[c]->limit_low, _opseg[c]->limit_high); } if (is386) { - x808x_log("FS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", - seg_fs, cpu_state.seg_fs.limit, cpu_state.seg_fs.access, cpu_state.seg_fs.limit_low, cpu_state.seg_fs.limit_high); - x808x_log("GS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", - gs, cpu_state.seg_gs.limit, cpu_state.seg_gs.access, cpu_state.seg_gs.limit_low, cpu_state.seg_gs.limit_high); - x808x_log("GDT : base=%06X limit=%04X\n", gdt.base, gdt.limit); - x808x_log("LDT : base=%06X limit=%04X\n", ldt.base, ldt.limit); - x808x_log("IDT : base=%06X limit=%04X\n", idt.base, idt.limit); - x808x_log("TR : base=%06X limit=%04X\n", tr.base, tr.limit); - x808x_log("386 in %s mode: %i-bit data, %-i-bit stack\n", - (msw & 1) ? ((cpu_state.eflags & VM_FLAG) ? "V86" : "protected") : "real", - (use32) ? 32 : 16, (stack32) ? 32 : 16); - x808x_log("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n", cr0, cr2, cr3, cr4); - x808x_log("EAX=%08X EBX=%08X ECX=%08X EDX=%08X\nEDI=%08X ESI=%08X EBP=%08X ESP=%08X\n", - EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP); + x808x_log("FS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", + seg_fs, cpu_state.seg_fs.limit, cpu_state.seg_fs.access, cpu_state.seg_fs.limit_low, cpu_state.seg_fs.limit_high); + x808x_log("GS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", + gs, cpu_state.seg_gs.limit, cpu_state.seg_gs.access, cpu_state.seg_gs.limit_low, cpu_state.seg_gs.limit_high); + x808x_log("GDT : base=%06X limit=%04X\n", gdt.base, gdt.limit); + x808x_log("LDT : base=%06X limit=%04X\n", ldt.base, ldt.limit); + x808x_log("IDT : base=%06X limit=%04X\n", idt.base, idt.limit); + x808x_log("TR : base=%06X limit=%04X\n", tr.base, tr.limit); + x808x_log("386 in %s mode: %i-bit data, %-i-bit stack\n", + (msw & 1) ? ((cpu_state.eflags & VM_FLAG) ? "V86" : "protected") : "real", + (use32) ? 32 : 16, (stack32) ? 32 : 16); + x808x_log("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n", cr0, cr2, cr3, cr4); + x808x_log("EAX=%08X EBX=%08X ECX=%08X EDX=%08X\nEDI=%08X ESI=%08X EBP=%08X ESP=%08X\n", + EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP); } else { - x808x_log("808x/286 in %s mode\n", (msw & 1) ? "protected" : "real"); - x808x_log("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n", - AX, BX, CX, DX, DI, SI, BP, SP); + x808x_log("808x/286 in %s mode\n", (msw & 1) ? "protected" : "real"); + x808x_log("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n", + AX, BX, CX, DX, DI, SI, BP, SP); } x808x_log("Entries in readlookup : %i writelookup : %i\n", readlnum, writelnum); x87_dumpregs(); indump = 0; } #else -#define x808x_log(fmt, ...) +# define x808x_log(fmt, ...) #endif - /* Preparation of the various arrays needed to speed up the MOD and R/M work. */ static void makemod1table(void) @@ -160,143 +156,141 @@ makemod1table(void) mod1add[1][5] = &zero; mod1add[1][6] = &zero; mod1add[1][7] = &zero; - mod1seg[0] = &ds; - mod1seg[1] = &ds; - mod1seg[2] = &ss; - mod1seg[3] = &ss; - mod1seg[4] = &ds; - mod1seg[5] = &ds; - mod1seg[6] = &ss; - mod1seg[7] = &ds; + mod1seg[0] = &ds; + mod1seg[1] = &ds; + mod1seg[2] = &ss; + mod1seg[3] = &ss; + mod1seg[4] = &ds; + mod1seg[5] = &ds; + mod1seg[6] = &ss; + mod1seg[7] = &ds; } - /* Prepare the ZNP table needed to speed up the setting of the Z, N, and P cpu_state.flags. */ static void makeznptable(void) { int c, d, e; for (c = 0; c < 256; c++) { - d = 0; - for (e = 0; e < 8; e++) { - if (c & (1 << e)) - d++; - } - if (d & 1) - znptable8[c] = 0; - else - znptable8[c] = P_FLAG; + d = 0; + for (e = 0; e < 8; e++) { + if (c & (1 << e)) + d++; + } + if (d & 1) + znptable8[c] = 0; + else + znptable8[c] = P_FLAG; #ifdef ENABLE_808X_LOG - if (c == 0xb1) - x808x_log("znp8 b1 = %i %02X\n", d, znptable8[c]); + if (c == 0xb1) + x808x_log("znp8 b1 = %i %02X\n", d, znptable8[c]); #endif - if (!c) - znptable8[c] |= Z_FLAG; - if (c & 0x80) - znptable8[c] |= N_FLAG; + if (!c) + znptable8[c] |= Z_FLAG; + if (c & 0x80) + znptable8[c] |= N_FLAG; } for (c = 0; c < 65536; c++) { - d = 0; - for (e = 0; e < 8; e++) { - if (c & (1 << e)) - d++; - } - if (d & 1) - znptable16[c] = 0; - else - znptable16[c] = P_FLAG; + d = 0; + for (e = 0; e < 8; e++) { + if (c & (1 << e)) + d++; + } + if (d & 1) + znptable16[c] = 0; + else + znptable16[c] = P_FLAG; #ifdef ENABLE_808X_LOG - if (c == 0xb1) - x808x_log("znp16 b1 = %i %02X\n", d, znptable16[c]); - if (c == 0x65b1) - x808x_log("znp16 65b1 = %i %02X\n", d, znptable16[c]); + if (c == 0xb1) + x808x_log("znp16 b1 = %i %02X\n", d, znptable16[c]); + if (c == 0x65b1) + x808x_log("znp16 65b1 = %i %02X\n", d, znptable16[c]); #endif - if (!c) - znptable16[c] |= Z_FLAG; - if (c & 0x8000) - znptable16[c] |= N_FLAG; + if (!c) + znptable16[c] |= Z_FLAG; + if (c & 0x8000) + znptable16[c] |= N_FLAG; } } - /* Common reset function. */ static void reset_common(int hard) { #ifdef ENABLE_808X_LOG if (hard) - x808x_log("x86 reset\n"); + x808x_log("x86 reset\n"); #endif if (!hard && reset_on_hlt) { - hlt_reset_pending++; - pclog("hlt_reset_pending = %i\n", hlt_reset_pending); - if (hlt_reset_pending == 2) - hlt_reset_pending = 0; - else - return; + hlt_reset_pending++; + pclog("hlt_reset_pending = %i\n", hlt_reset_pending); + if (hlt_reset_pending == 2) + hlt_reset_pending = 0; + else + return; } /* Make sure to gracefully leave SMM. */ if (in_smm) - leave_smm(); + leave_smm(); /* Needed for the ALi M1533. */ if (is486 && (hard || soft_reset_pci)) { - pci_reset(); - if (!hard && soft_reset_pci) { - dma_reset(); - /* TODO: Hack, but will do for time being, because all AT machines currently are 286+, - and vice-versa. */ - dma_set_at(is286); - device_reset_all(); - } + pci_reset(); + if (!hard && soft_reset_pci) { + dma_reset(); + /* TODO: Hack, but will do for time being, because all AT machines currently are 286+, + and vice-versa. */ + dma_set_at(is286); + device_reset_all(); + } } - use32 = 0; + use32 = 0; cpu_cur_status = 0; - stack32 = 0; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - msw = 0; + stack32 = 0; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + msw = 0; if (hascache) - cr0 = 1 << 30; + cr0 = 1 << 30; else - cr0 = 0; + cr0 = 0; cpu_cache_int_enabled = 0; cpu_update_waitstates(); - cr4 = 0; + cr4 = 0; cpu_state.eflags = 0; - cgate32 = 0; + cgate32 = 0; if (is286) { - loadcs(0xF000); - cpu_state.pc = 0xFFF0; - rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; - if (is6117) - rammask |= 0x03000000; + loadcs(0xF000); + cpu_state.pc = 0xFFF0; + rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; + if (is6117) + rammask |= 0x03000000; } - idt.base = 0; + idt.base = 0; cpu_state.flags = 2; - trap = 0; + trap = 0; idt.limit = is386 ? 0x03ff : 0xffff; if (is386 || hard) - EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0; + EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0; if (hard) { - makeznptable(); - resetreadlookup(); - makemod1table(); - cpu_set_edx(); - mmu_perm = 4; + makeznptable(); + resetreadlookup(); + makemod1table(); + cpu_set_edx(); + mmu_perm = 4; } x86seg_reset(); #ifdef USE_DYNAREC if (hard) - codegen_reset(); + codegen_reset(); #endif if (!hard) - flushmmucache(); + flushmmucache(); x86_was_reset = 1; cpu_alt_reset = 0; @@ -304,12 +298,12 @@ reset_common(int hard) in_smm = smi_latched = 0; smi_line = smm_in_hlt = 0; - smi_block = 0; + smi_block = 0; if (hard) { - if (is486) - smbase = is_am486dxl ? 0x00060000 : 0x00030000; - ppi_reset(); + if (is486) + smbase = is_am486dxl ? 0x00060000 : 0x00030000; + ppi_reset(); } in_sys = 0; @@ -317,17 +311,16 @@ reset_common(int hard) alt_access = cpu_end_block_after_ins = 0; if (hard) { - reset_on_hlt = hlt_reset_pending = 0; - cache_index = 0; - memset(_tr, 0x00, sizeof(_tr)); - memset(_cache, 0x00, sizeof(_cache)); + reset_on_hlt = hlt_reset_pending = 0; + cache_index = 0; + memset(_tr, 0x00, sizeof(_tr)); + memset(_cache, 0x00, sizeof(_cache)); } if (!is286) - reset_808x(hard); + reset_808x(hard); } - /* Hard reset. */ void resetx86(void) @@ -337,13 +330,12 @@ resetx86(void) soft_reset_mask = 0; } - /* Soft reset. */ void softresetx86(void) { if (soft_reset_mask) - return; + return; if (ibm8514_enabled || xga_enabled) vga_on = 1; @@ -351,7 +343,6 @@ softresetx86(void) reset_common(0); } - /* Actual hard reset. */ void hardresetx86(void) diff --git a/src/cpu/x86.h b/src/cpu/x86.h index b468ba4aa..337619fa4 100644 --- a/src/cpu/x86.h +++ b/src/cpu/x86.h @@ -7,77 +7,78 @@ This distinction is used by the dynarec; a block that hits an 'expected' exception would be compiled, a block that hits an 'unexpected' exception would be rejected so that we don't end up with an unnecessarily short block*/ -#define ABRT_EXPECTED 0x80 +#define ABRT_EXPECTED 0x80 -extern uint8_t opcode, opcode2; -extern uint8_t flags_p; -extern uint8_t znptable8[256]; +extern uint8_t opcode, opcode2; +extern uint8_t flags_p; +extern uint8_t znptable8[256]; -extern uint16_t zero, oldcs; -extern uint16_t lastcs, lastpc; +extern uint16_t zero, oldcs; +extern uint16_t lastcs, lastpc; extern uint16_t *mod1add[2][8]; -extern uint16_t znptable16[65536]; +extern uint16_t znptable16[65536]; -extern int x86_was_reset, trap; -extern int codegen_flat_ss, codegen_flat_ds; -extern int timetolive, keyboardtimer, trap; -extern int optype, stack32; -extern int oldcpl, cgate32, cpl_override; -extern int nmi_enable; -extern int oddeven, inttype; +extern int x86_was_reset, trap; +extern int codegen_flat_ss, codegen_flat_ds; +extern int timetolive, keyboardtimer, trap; +extern int optype, stack32; +extern int oldcpl, cgate32, cpl_override; +extern int nmi_enable; +extern int oddeven, inttype; -extern uint32_t use32; -extern uint32_t rmdat, easeg; -extern uint32_t oxpc, flags_zn; -extern uint32_t abrt_error; -extern uint32_t backupregs[16]; +extern uint32_t use32; +extern uint32_t rmdat, easeg; +extern uint32_t oxpc, flags_zn; +extern uint32_t abrt_error; +extern uint32_t backupregs[16]; extern uint32_t *mod1seg[8]; extern uint32_t *eal_r, *eal_w; -#define fetchdat rmdat +#define fetchdat rmdat #define setznp168 setznp16 -#define getr8(r) ((r&4)?cpu_state.regs[r&3].b.h:cpu_state.regs[r&3].b.l) -#define getr16(r) cpu_state.regs[r].w -#define getr32(r) cpu_state.regs[r].l +#define getr8(r) ((r & 4) ? cpu_state.regs[r & 3].b.h : cpu_state.regs[r & 3].b.l) +#define getr16(r) cpu_state.regs[r].w +#define getr32(r) cpu_state.regs[r].l -#define setr8(r,v) if (r&4) cpu_state.regs[r&3].b.h=v; \ - else cpu_state.regs[r&3].b.l=v; -#define setr16(r,v) cpu_state.regs[r].w=v -#define setr32(r,v) cpu_state.regs[r].l=v +#define setr8(r, v) \ + if (r & 4) \ + cpu_state.regs[r & 3].b.h = v; \ + else \ + cpu_state.regs[r & 3].b.l = v; +#define setr16(r, v) cpu_state.regs[r].w = v +#define setr32(r, v) cpu_state.regs[r].l = v -#define fetchea() { \ - rmdat = readmemb(cs + pc); \ - pc++; \ - reg = (rmdat >> 3) & 7; \ - mod = (rmdat >> 6) & 3; \ - rm = rmdat & 7; \ - if (mod!=3) \ - fetcheal(); \ - } +#define fetchea() \ + { \ + rmdat = readmemb(cs + pc); \ + pc++; \ + reg = (rmdat >> 3) & 7; \ + mod = (rmdat >> 6) & 3; \ + rm = rmdat & 7; \ + if (mod != 3) \ + fetcheal(); \ + } -#define JMP 1 -#define CALL 2 -#define IRET 3 +#define JMP 1 +#define CALL 2 +#define IRET 3 #define OPTYPE_INT 4 - -enum -{ - ABRT_NONE = 0, - ABRT_GEN, - 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. */ +enum { + ABRT_NONE = 0, + ABRT_GEN, + 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); +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); diff --git a/src/cpu/x86_flags.h b/src/cpu/x86_flags.h index 6b2293322..b8b1a706a 100644 --- a/src/cpu/x86_flags.h +++ b/src/cpu/x86_flags.h @@ -1,781 +1,823 @@ extern int tempc; -enum -{ - FLAGS_UNKNOWN, +enum { + FLAGS_UNKNOWN, - FLAGS_ZN8, - FLAGS_ZN16, - FLAGS_ZN32, + FLAGS_ZN8, + FLAGS_ZN16, + FLAGS_ZN32, - FLAGS_ADD8, - FLAGS_ADD16, - FLAGS_ADD32, + FLAGS_ADD8, + FLAGS_ADD16, + FLAGS_ADD32, - FLAGS_SUB8, - FLAGS_SUB16, - FLAGS_SUB32, + FLAGS_SUB8, + FLAGS_SUB16, + FLAGS_SUB32, - FLAGS_SHL8, - FLAGS_SHL16, - FLAGS_SHL32, + FLAGS_SHL8, + FLAGS_SHL16, + FLAGS_SHL32, - FLAGS_SHR8, - FLAGS_SHR16, - FLAGS_SHR32, + FLAGS_SHR8, + FLAGS_SHR16, + FLAGS_SHR32, - FLAGS_SAR8, - FLAGS_SAR16, - FLAGS_SAR32, + FLAGS_SAR8, + FLAGS_SAR16, + FLAGS_SAR32, #ifdef USE_NEW_DYNAREC - FLAGS_ROL8, - FLAGS_ROL16, - FLAGS_ROL32, + FLAGS_ROL8, + FLAGS_ROL16, + FLAGS_ROL32, - FLAGS_ROR8, - FLAGS_ROR16, - FLAGS_ROR32, + FLAGS_ROR8, + FLAGS_ROR16, + FLAGS_ROR32, #endif - FLAGS_INC8, - FLAGS_INC16, - FLAGS_INC32, + FLAGS_INC8, + FLAGS_INC16, + FLAGS_INC32, - FLAGS_DEC8, - FLAGS_DEC16, - FLAGS_DEC32 + FLAGS_DEC8, + FLAGS_DEC16, + FLAGS_DEC32 #ifdef USE_NEW_DYNAREC -, + , - FLAGS_ADC8, - FLAGS_ADC16, - FLAGS_ADC32, + FLAGS_ADC8, + FLAGS_ADC16, + FLAGS_ADC32, - FLAGS_SBC8, - FLAGS_SBC16, - FLAGS_SBC32 + FLAGS_SBC8, + FLAGS_SBC16, + FLAGS_SBC32 #endif }; -static __inline int ZF_SET(void) +static __inline int +ZF_SET(void) { - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - case FLAGS_ADD8: - case FLAGS_ADD16: - case FLAGS_ADD32: - case FLAGS_SUB8: - case FLAGS_SUB16: - case FLAGS_SUB32: - case FLAGS_SHL8: - case FLAGS_SHL16: - case FLAGS_SHL32: - case FLAGS_SHR8: - case FLAGS_SHR16: - case FLAGS_SHR32: - case FLAGS_SAR8: - case FLAGS_SAR16: - case FLAGS_SAR32: - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32: + switch (cpu_state.flags_op) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + case FLAGS_ADD8: + case FLAGS_ADD16: + case FLAGS_ADD32: + case FLAGS_SUB8: + case FLAGS_SUB16: + case FLAGS_SUB32: + case FLAGS_SHL8: + case FLAGS_SHL16: + case FLAGS_SHL32: + case FLAGS_SHR8: + case FLAGS_SHR16: + case FLAGS_SHR32: + case FLAGS_SAR8: + case FLAGS_SAR16: + case FLAGS_SAR32: + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: #ifdef USE_NEW_DYNAREC - case FLAGS_ADC8: - case FLAGS_ADC16: - case FLAGS_ADC32: - case FLAGS_SBC8: - case FLAGS_SBC16: - case FLAGS_SBC32: + case FLAGS_ADC8: + case FLAGS_ADC16: + case FLAGS_ADC32: + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: #endif - return !cpu_state.flags_res; + return !cpu_state.flags_res; #ifdef USE_NEW_DYNAREC - case FLAGS_ROL8: - case FLAGS_ROL16: - case FLAGS_ROL32: - case FLAGS_ROR8: - case FLAGS_ROR16: - case FLAGS_ROR32: + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: #endif - case FLAGS_UNKNOWN: - return cpu_state.flags & Z_FLAG; + case FLAGS_UNKNOWN: + return cpu_state.flags & Z_FLAG; #ifndef USE_NEW_DYNAREC - default: - return 0; + default: + return 0; #endif - } + } #ifdef USE_NEW_DYNAREC - return 0; + return 0; #endif } -static __inline int NF_SET(void) +static __inline int +NF_SET(void) { - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ADD8: - case FLAGS_SUB8: - case FLAGS_SHL8: - case FLAGS_SHR8: - case FLAGS_SAR8: - case FLAGS_INC8: - case FLAGS_DEC8: + switch (cpu_state.flags_op) { + case FLAGS_ZN8: + case FLAGS_ADD8: + case FLAGS_SUB8: + case FLAGS_SHL8: + case FLAGS_SHR8: + case FLAGS_SAR8: + case FLAGS_INC8: + case FLAGS_DEC8: #ifdef USE_NEW_DYNAREC - case FLAGS_ADC8: - case FLAGS_SBC8: + case FLAGS_ADC8: + case FLAGS_SBC8: #endif - return cpu_state.flags_res & 0x80; + return cpu_state.flags_res & 0x80; - case FLAGS_ZN16: - case FLAGS_ADD16: - case FLAGS_SUB16: - case FLAGS_SHL16: - case FLAGS_SHR16: - case FLAGS_SAR16: - case FLAGS_INC16: - case FLAGS_DEC16: + case FLAGS_ZN16: + case FLAGS_ADD16: + case FLAGS_SUB16: + case FLAGS_SHL16: + case FLAGS_SHR16: + case FLAGS_SAR16: + case FLAGS_INC16: + case FLAGS_DEC16: #ifdef USE_NEW_DYNAREC - case FLAGS_ADC16: - case FLAGS_SBC16: + case FLAGS_ADC16: + case FLAGS_SBC16: #endif - return cpu_state.flags_res & 0x8000; + return cpu_state.flags_res & 0x8000; - case FLAGS_ZN32: - case FLAGS_ADD32: - case FLAGS_SUB32: - case FLAGS_SHL32: - case FLAGS_SHR32: - case FLAGS_SAR32: - case FLAGS_INC32: - case FLAGS_DEC32: + case FLAGS_ZN32: + case FLAGS_ADD32: + case FLAGS_SUB32: + case FLAGS_SHL32: + case FLAGS_SHR32: + case FLAGS_SAR32: + case FLAGS_INC32: + case FLAGS_DEC32: #ifdef USE_NEW_DYNAREC - case FLAGS_ADC32: - case FLAGS_SBC32: + case FLAGS_ADC32: + case FLAGS_SBC32: #endif - return cpu_state.flags_res & 0x80000000; + return cpu_state.flags_res & 0x80000000; #ifdef USE_NEW_DYNAREC - case FLAGS_ROL8: - case FLAGS_ROL16: - case FLAGS_ROL32: - case FLAGS_ROR8: - case FLAGS_ROR16: - case FLAGS_ROR32: + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: #endif - case FLAGS_UNKNOWN: - return cpu_state.flags & N_FLAG; + case FLAGS_UNKNOWN: + return cpu_state.flags & N_FLAG; #ifndef USE_NEW_DYNAREC - default: - return 0; + default: + return 0; #endif - } + } #ifdef USE_NEW_DYNAREC - return 0; + return 0; #endif } -static __inline int PF_SET(void) +static __inline int +PF_SET(void) { - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - case FLAGS_ADD8: - case FLAGS_ADD16: - case FLAGS_ADD32: - case FLAGS_SUB8: - case FLAGS_SUB16: - case FLAGS_SUB32: - case FLAGS_SHL8: - case FLAGS_SHL16: - case FLAGS_SHL32: - case FLAGS_SHR8: - case FLAGS_SHR16: - case FLAGS_SHR32: - case FLAGS_SAR8: - case FLAGS_SAR16: - case FLAGS_SAR32: - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32: + switch (cpu_state.flags_op) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + case FLAGS_ADD8: + case FLAGS_ADD16: + case FLAGS_ADD32: + case FLAGS_SUB8: + case FLAGS_SUB16: + case FLAGS_SUB32: + case FLAGS_SHL8: + case FLAGS_SHL16: + case FLAGS_SHL32: + case FLAGS_SHR8: + case FLAGS_SHR16: + case FLAGS_SHR32: + case FLAGS_SAR8: + case FLAGS_SAR16: + case FLAGS_SAR32: + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: #ifdef USE_NEW_DYNAREC - case FLAGS_ADC8: - case FLAGS_ADC16: - case FLAGS_ADC32: - case FLAGS_SBC8: - case FLAGS_SBC16: - case FLAGS_SBC32: + case FLAGS_ADC8: + case FLAGS_ADC16: + case FLAGS_ADC32: + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: #endif - return znptable8[cpu_state.flags_res & 0xff] & P_FLAG; + return znptable8[cpu_state.flags_res & 0xff] & P_FLAG; #ifdef USE_NEW_DYNAREC - case FLAGS_ROL8: - case FLAGS_ROL16: - case FLAGS_ROL32: - case FLAGS_ROR8: - case FLAGS_ROR16: - case FLAGS_ROR32: + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: #endif - case FLAGS_UNKNOWN: - return cpu_state.flags & P_FLAG; + case FLAGS_UNKNOWN: + return cpu_state.flags & P_FLAG; #ifndef USE_NEW_DYNAREC - default: - return 0; + default: + return 0; #endif - } + } #ifdef USE_NEW_DYNAREC - return 0; + return 0; #endif } -static __inline int VF_SET(void) +static __inline int +VF_SET(void) { - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - case FLAGS_SAR8: - case FLAGS_SAR16: - case FLAGS_SAR32: - return 0; + switch (cpu_state.flags_op) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + case FLAGS_SAR8: + case FLAGS_SAR16: + case FLAGS_SAR32: + return 0; #ifdef USE_NEW_DYNAREC - case FLAGS_ADC8: + case FLAGS_ADC8: #endif - case FLAGS_ADD8: - case FLAGS_INC8: - return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80); + case FLAGS_ADD8: + case FLAGS_INC8: + return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80); #ifdef USE_NEW_DYNAREC - case FLAGS_ADC16: + case FLAGS_ADC16: #endif - case FLAGS_ADD16: - case FLAGS_INC16: - return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x8000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000); + case FLAGS_ADD16: + case FLAGS_INC16: + return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x8000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000); #ifdef USE_NEW_DYNAREC - case FLAGS_ADC32: + case FLAGS_ADC32: #endif - case FLAGS_ADD32: - case FLAGS_INC32: - return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80000000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000); + case FLAGS_ADD32: + case FLAGS_INC32: + return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80000000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000); #ifdef USE_NEW_DYNAREC - case FLAGS_SBC8: + case FLAGS_SBC8: #endif - case FLAGS_SUB8: - case FLAGS_DEC8: - return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80); + case FLAGS_SUB8: + case FLAGS_DEC8: + return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80); #ifdef USE_NEW_DYNAREC - case FLAGS_SBC16: + case FLAGS_SBC16: #endif - case FLAGS_SUB16: - case FLAGS_DEC16: - return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000); + case FLAGS_SUB16: + case FLAGS_DEC16: + return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000); #ifdef USE_NEW_DYNAREC - case FLAGS_SBC32: + case FLAGS_SBC32: #endif - case FLAGS_SUB32: - case FLAGS_DEC32: - return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000); + case FLAGS_SUB32: + case FLAGS_DEC32: + return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000); - case FLAGS_SHL8: - return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x80); - case FLAGS_SHL16: - return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x8000); - case FLAGS_SHL32: - return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x80000000); + case FLAGS_SHL8: + return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x80); + case FLAGS_SHL16: + return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x8000); + case FLAGS_SHL32: + return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x80000000); - case FLAGS_SHR8: - return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80)); - case FLAGS_SHR16: - return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x8000)); - case FLAGS_SHR32: - return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80000000)); + case FLAGS_SHR8: + return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80)); + case FLAGS_SHR16: + return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x8000)); + case FLAGS_SHR32: + return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80000000)); #ifdef USE_NEW_DYNAREC - case FLAGS_ROL8: - return (cpu_state.flags_res ^ (cpu_state.flags_res >> 7)) & 1; - case FLAGS_ROL16: - return (cpu_state.flags_res ^ (cpu_state.flags_res >> 15)) & 1; - case FLAGS_ROL32: - return (cpu_state.flags_res ^ (cpu_state.flags_res >> 31)) & 1; + case FLAGS_ROL8: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 7)) & 1; + case FLAGS_ROL16: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 15)) & 1; + case FLAGS_ROL32: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 31)) & 1; - case FLAGS_ROR8: - return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40; - case FLAGS_ROR16: - return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x4000; - case FLAGS_ROR32: - return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40000000; + case FLAGS_ROR8: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40; + case FLAGS_ROR16: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x4000; + case FLAGS_ROR32: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40000000; #endif - case FLAGS_UNKNOWN: - return cpu_state.flags & V_FLAG; + case FLAGS_UNKNOWN: + return cpu_state.flags & V_FLAG; #ifndef USE_NEW_DYNAREC - default: - return 0; + default: + return 0; #endif - } + } #ifdef USE_NEW_DYNAREC - return 0; + return 0; #endif } -static __inline int AF_SET(void) +static __inline int +AF_SET(void) { - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - case FLAGS_SHL8: - case FLAGS_SHL16: - case FLAGS_SHL32: - case FLAGS_SHR8: - case FLAGS_SHR16: - case FLAGS_SHR32: - case FLAGS_SAR8: - case FLAGS_SAR16: - case FLAGS_SAR32: - return 0; + switch (cpu_state.flags_op) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + case FLAGS_SHL8: + case FLAGS_SHL16: + case FLAGS_SHL32: + case FLAGS_SHR8: + case FLAGS_SHR16: + case FLAGS_SHR32: + case FLAGS_SAR8: + case FLAGS_SAR16: + case FLAGS_SAR32: + return 0; - case FLAGS_ADD8: - case FLAGS_ADD16: - case FLAGS_ADD32: - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - return ((cpu_state.flags_op1 & 0xF) + (cpu_state.flags_op2 & 0xF)) & 0x10; + case FLAGS_ADD8: + case FLAGS_ADD16: + case FLAGS_ADD32: + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: + return ((cpu_state.flags_op1 & 0xF) + (cpu_state.flags_op2 & 0xF)) & 0x10; #ifdef USE_NEW_DYNAREC - case FLAGS_ADC8: - return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || - ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xff); - case FLAGS_ADC16: - return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || - ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xffff); - case FLAGS_ADC32: - return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || - ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xffffffff); + case FLAGS_ADC8: + return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xff); + case FLAGS_ADC16: + return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xffff); + case FLAGS_ADC32: + return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xffffffff); #endif - case FLAGS_SUB8: - case FLAGS_SUB16: - case FLAGS_SUB32: - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32: - return ((cpu_state.flags_op1 & 0xF) - (cpu_state.flags_op2 & 0xF)) & 0x10; + case FLAGS_SUB8: + case FLAGS_SUB16: + case FLAGS_SUB32: + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: + return ((cpu_state.flags_op1 & 0xF) - (cpu_state.flags_op2 & 0xF)) & 0x10; #ifdef USE_NEW_DYNAREC - case FLAGS_SBC8: - case FLAGS_SBC16: - case FLAGS_SBC32: - return ((cpu_state.flags_op1 & 0xf) < (cpu_state.flags_op2 & 0xf)) || - ((cpu_state.flags_op1 & 0xf) == (cpu_state.flags_op2 & 0xf) && (cpu_state.flags_res & 0xf) != 0); + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: + return ((cpu_state.flags_op1 & 0xf) < (cpu_state.flags_op2 & 0xf)) || ((cpu_state.flags_op1 & 0xf) == (cpu_state.flags_op2 & 0xf) && (cpu_state.flags_res & 0xf) != 0); - case FLAGS_ROL8: - case FLAGS_ROL16: - case FLAGS_ROL32: - case FLAGS_ROR8: - case FLAGS_ROR16: - case FLAGS_ROR32: + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: #endif - case FLAGS_UNKNOWN: - return cpu_state.flags & A_FLAG; + case FLAGS_UNKNOWN: + return cpu_state.flags & A_FLAG; #ifndef USE_NEW_DYNAREC - default: - return 0; + default: + return 0; #endif - } + } #ifdef USE_NEW_DYNAREC - return 0; + return 0; #endif } -static __inline int CF_SET(void) +static __inline int +CF_SET(void) { - switch (cpu_state.flags_op) - { - case FLAGS_ADD8: - return ((cpu_state.flags_op1 + cpu_state.flags_op2) & 0x100) ? 1 : 0; - case FLAGS_ADD16: - return ((cpu_state.flags_op1 + cpu_state.flags_op2) & 0x10000) ? 1 : 0; - case FLAGS_ADD32: - return (cpu_state.flags_res < cpu_state.flags_op1); + switch (cpu_state.flags_op) { + case FLAGS_ADD8: + return ((cpu_state.flags_op1 + cpu_state.flags_op2) & 0x100) ? 1 : 0; + case FLAGS_ADD16: + return ((cpu_state.flags_op1 + cpu_state.flags_op2) & 0x10000) ? 1 : 0; + case FLAGS_ADD32: + return (cpu_state.flags_res < cpu_state.flags_op1); #ifdef USE_NEW_DYNAREC - case FLAGS_ADC8: - return (cpu_state.flags_res < cpu_state.flags_op1) || - (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xff); - case FLAGS_ADC16: - return (cpu_state.flags_res < cpu_state.flags_op1) || - (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xffff); - case FLAGS_ADC32: - return (cpu_state.flags_res < cpu_state.flags_op1) || - (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xffffffff); + case FLAGS_ADC8: + return (cpu_state.flags_res < cpu_state.flags_op1) || (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xff); + case FLAGS_ADC16: + return (cpu_state.flags_res < cpu_state.flags_op1) || (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xffff); + case FLAGS_ADC32: + return (cpu_state.flags_res < cpu_state.flags_op1) || (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xffffffff); #endif - case FLAGS_SUB8: - case FLAGS_SUB16: - case FLAGS_SUB32: - return (cpu_state.flags_op1 < cpu_state.flags_op2); + case FLAGS_SUB8: + case FLAGS_SUB16: + case FLAGS_SUB32: + return (cpu_state.flags_op1 < cpu_state.flags_op2); #ifdef USE_NEW_DYNAREC - case FLAGS_SBC8: - case FLAGS_SBC16: - case FLAGS_SBC32: - return (cpu_state.flags_op1 < cpu_state.flags_op2) || - (cpu_state.flags_op1 == cpu_state.flags_op2 && cpu_state.flags_res != 0); + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: + return (cpu_state.flags_op1 < cpu_state.flags_op2) || (cpu_state.flags_op1 == cpu_state.flags_op2 && cpu_state.flags_res != 0); #endif - case FLAGS_SHL8: - return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80) ? 1 : 0; - case FLAGS_SHL16: - return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x8000) ? 1 : 0; - case FLAGS_SHL32: - return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80000000) ? 1 : 0; + case FLAGS_SHL8: + return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80) ? 1 : 0; + case FLAGS_SHL16: + return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x8000) ? 1 : 0; + case FLAGS_SHL32: + return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80000000) ? 1 : 0; - case FLAGS_SHR8: - case FLAGS_SHR16: - case FLAGS_SHR32: - return (cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; + case FLAGS_SHR8: + case FLAGS_SHR16: + case FLAGS_SHR32: + return (cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; - case FLAGS_SAR8: - return ((int8_t)cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; - case FLAGS_SAR16: - return ((int16_t)cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; - case FLAGS_SAR32: - return ((int32_t)cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; + case FLAGS_SAR8: + return ((int8_t) cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; + case FLAGS_SAR16: + return ((int16_t) cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; + case FLAGS_SAR32: + return ((int32_t) cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - return 0; + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + return 0; #ifdef USE_NEW_DYNAREC - case FLAGS_ROL8: - case FLAGS_ROL16: - case FLAGS_ROL32: - return cpu_state.flags_res & 1; + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + return cpu_state.flags_res & 1; - case FLAGS_ROR8: - return (cpu_state.flags_res & 0x80) ? 1 : 0; - case FLAGS_ROR16: - return (cpu_state.flags_res & 0x8000) ? 1 :0; - case FLAGS_ROR32: - return (cpu_state.flags_res & 0x80000000) ? 1 : 0; + case FLAGS_ROR8: + return (cpu_state.flags_res & 0x80) ? 1 : 0; + case FLAGS_ROR16: + return (cpu_state.flags_res & 0x8000) ? 1 : 0; + case FLAGS_ROR32: + return (cpu_state.flags_res & 0x80000000) ? 1 : 0; #endif - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32: - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - case FLAGS_UNKNOWN: - return cpu_state.flags & C_FLAG; + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: + case FLAGS_UNKNOWN: + return cpu_state.flags & C_FLAG; #ifndef USE_NEW_DYNAREC - default: - return 0; + default: + return 0; #endif - } + } #ifdef USE_NEW_DYNAREC - return 0; + return 0; #endif } -static __inline void flags_rebuild(void) -{ - if (cpu_state.flags_op != FLAGS_UNKNOWN) - { - uint16_t tempf = 0; - if (CF_SET()) tempf |= C_FLAG; - if (PF_SET()) tempf |= P_FLAG; - if (AF_SET()) tempf |= A_FLAG; - if (ZF_SET()) tempf |= Z_FLAG; - if (NF_SET()) tempf |= N_FLAG; - if (VF_SET()) tempf |= V_FLAG; - cpu_state.flags = (cpu_state.flags & ~0x8d5) | tempf; - cpu_state.flags_op = FLAGS_UNKNOWN; - } -} - -static __inline void flags_extract(void) +static __inline void +flags_rebuild(void) { + if (cpu_state.flags_op != FLAGS_UNKNOWN) { + uint16_t tempf = 0; + if (CF_SET()) + tempf |= C_FLAG; + if (PF_SET()) + tempf |= P_FLAG; + if (AF_SET()) + tempf |= A_FLAG; + if (ZF_SET()) + tempf |= Z_FLAG; + if (NF_SET()) + tempf |= N_FLAG; + if (VF_SET()) + tempf |= V_FLAG; + cpu_state.flags = (cpu_state.flags & ~0x8d5) | tempf; cpu_state.flags_op = FLAGS_UNKNOWN; + } } -static __inline void flags_rebuild_c(void) +static __inline void +flags_extract(void) { - if (cpu_state.flags_op != FLAGS_UNKNOWN) - { - if (CF_SET()) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - } + cpu_state.flags_op = FLAGS_UNKNOWN; +} + +static __inline void +flags_rebuild_c(void) +{ + if (cpu_state.flags_op != FLAGS_UNKNOWN) { + if (CF_SET()) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + } } #ifdef USE_NEW_DYNAREC -static __inline int flags_res_valid(void) +static __inline int +flags_res_valid(void) { - if (cpu_state.flags_op == FLAGS_UNKNOWN || - (cpu_state.flags_op >= FLAGS_ROL8 && cpu_state.flags_op <= FLAGS_ROR32)) - return 0; + if (cpu_state.flags_op == FLAGS_UNKNOWN || (cpu_state.flags_op >= FLAGS_ROL8 && cpu_state.flags_op <= FLAGS_ROR32)) + return 0; - return 1; + return 1; } #endif -static __inline void setznp8(uint8_t val) +static __inline void +setznp8(uint8_t val) { - cpu_state.flags_op = FLAGS_ZN8; - cpu_state.flags_res = val; + cpu_state.flags_op = FLAGS_ZN8; + cpu_state.flags_res = val; } -static __inline void setznp16(uint16_t val) +static __inline void +setznp16(uint16_t val) { - cpu_state.flags_op = FLAGS_ZN16; - cpu_state.flags_res = val; + cpu_state.flags_op = FLAGS_ZN16; + cpu_state.flags_res = val; } -static __inline void setznp32(uint32_t val) +static __inline void +setznp32(uint32_t val) { - cpu_state.flags_op = FLAGS_ZN32; - cpu_state.flags_res = val; + cpu_state.flags_op = FLAGS_ZN32; + cpu_state.flags_res = val; } #define set_flags_shift(op, orig, shift, res) \ - cpu_state.flags_op = op; \ - cpu_state.flags_res = res; \ - cpu_state.flags_op1 = orig; \ - cpu_state.flags_op2 = shift; + cpu_state.flags_op = op; \ + cpu_state.flags_res = res; \ + cpu_state.flags_op1 = orig; \ + cpu_state.flags_op2 = shift; #ifdef USE_NEW_DYNAREC -#define set_flags_rotate(op, res) \ - cpu_state.flags_op = op; \ +# define set_flags_rotate(op, res) \ + cpu_state.flags_op = op; \ cpu_state.flags_res = res; #endif -static __inline void setadd8(uint8_t a, uint8_t b) +static __inline void +setadd8(uint8_t a, uint8_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b) & 0xff; - cpu_state.flags_op = FLAGS_ADD8; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a + b) & 0xff; + cpu_state.flags_op = FLAGS_ADD8; } -static __inline void setadd16(uint16_t a, uint16_t b) +static __inline void +setadd16(uint16_t a, uint16_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b) & 0xffff; - cpu_state.flags_op = FLAGS_ADD16; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a + b) & 0xffff; + cpu_state.flags_op = FLAGS_ADD16; } -static __inline void setadd32(uint32_t a, uint32_t b) +static __inline void +setadd32(uint32_t a, uint32_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a + b; - cpu_state.flags_op = FLAGS_ADD32; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = a + b; + cpu_state.flags_op = FLAGS_ADD32; } -static __inline void setadd8nc(uint8_t a, uint8_t b) +static __inline void +setadd8nc(uint8_t a, uint8_t b) { - flags_rebuild_c(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b) & 0xff; - cpu_state.flags_op = FLAGS_INC8; + flags_rebuild_c(); + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a + b) & 0xff; + cpu_state.flags_op = FLAGS_INC8; } -static __inline void setadd16nc(uint16_t a, uint16_t b) +static __inline void +setadd16nc(uint16_t a, uint16_t b) { - flags_rebuild_c(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b) & 0xffff; - cpu_state.flags_op = FLAGS_INC16; + flags_rebuild_c(); + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a + b) & 0xffff; + cpu_state.flags_op = FLAGS_INC16; } -static __inline void setadd32nc(uint32_t a, uint32_t b) +static __inline void +setadd32nc(uint32_t a, uint32_t b) { - flags_rebuild_c(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a + b; - cpu_state.flags_op = FLAGS_INC32; + flags_rebuild_c(); + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = a + b; + cpu_state.flags_op = FLAGS_INC32; } -static __inline void setsub8(uint8_t a, uint8_t b) +static __inline void +setsub8(uint8_t a, uint8_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - b) & 0xff; - cpu_state.flags_op = FLAGS_SUB8; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a - b) & 0xff; + cpu_state.flags_op = FLAGS_SUB8; } -static __inline void setsub16(uint16_t a, uint16_t b) +static __inline void +setsub16(uint16_t a, uint16_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - b) & 0xffff; - cpu_state.flags_op = FLAGS_SUB16; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a - b) & 0xffff; + cpu_state.flags_op = FLAGS_SUB16; } -static __inline void setsub32(uint32_t a, uint32_t b) +static __inline void +setsub32(uint32_t a, uint32_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a - b; - cpu_state.flags_op = FLAGS_SUB32; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = a - b; + cpu_state.flags_op = FLAGS_SUB32; } -static __inline void setsub8nc(uint8_t a, uint8_t b) +static __inline void +setsub8nc(uint8_t a, uint8_t b) { - flags_rebuild_c(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - b) & 0xff; - cpu_state.flags_op = FLAGS_DEC8; + flags_rebuild_c(); + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a - b) & 0xff; + cpu_state.flags_op = FLAGS_DEC8; } -static __inline void setsub16nc(uint16_t a, uint16_t b) +static __inline void +setsub16nc(uint16_t a, uint16_t b) { - flags_rebuild_c(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - b) & 0xffff; - cpu_state.flags_op = FLAGS_DEC16; + flags_rebuild_c(); + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a - b) & 0xffff; + cpu_state.flags_op = FLAGS_DEC16; } -static __inline void setsub32nc(uint32_t a, uint32_t b) +static __inline void +setsub32nc(uint32_t a, uint32_t b) { - flags_rebuild_c(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a - b; - cpu_state.flags_op = FLAGS_DEC32; + flags_rebuild_c(); + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = a - b; + cpu_state.flags_op = FLAGS_DEC32; } #ifdef USE_NEW_DYNAREC -static __inline void setadc8(uint8_t a, uint8_t b) +static __inline void +setadc8(uint8_t a, uint8_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b + tempc) & 0xff; - cpu_state.flags_op = FLAGS_ADC8; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a + b + tempc) & 0xff; + cpu_state.flags_op = FLAGS_ADC8; } -static __inline void setadc16(uint16_t a, uint16_t b) +static __inline void +setadc16(uint16_t a, uint16_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b + tempc) & 0xffff; - cpu_state.flags_op = FLAGS_ADC16; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a + b + tempc) & 0xffff; + cpu_state.flags_op = FLAGS_ADC16; } -static __inline void setadc32(uint32_t a, uint32_t b) +static __inline void +setadc32(uint32_t a, uint32_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a + b + tempc; - cpu_state.flags_op = FLAGS_ADC32; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = a + b + tempc; + cpu_state.flags_op = FLAGS_ADC32; } -static __inline void setsbc8(uint8_t a, uint8_t b) +static __inline void +setsbc8(uint8_t a, uint8_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - (b + tempc)) & 0xff; - cpu_state.flags_op = FLAGS_SBC8; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a - (b + tempc)) & 0xff; + cpu_state.flags_op = FLAGS_SBC8; } -static __inline void setsbc16(uint16_t a, uint16_t b) +static __inline void +setsbc16(uint16_t a, uint16_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - (b + tempc)) & 0xffff; - cpu_state.flags_op = FLAGS_SBC16; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a - (b + tempc)) & 0xffff; + cpu_state.flags_op = FLAGS_SBC16; } -static __inline void setsbc32(uint32_t a, uint32_t b) +static __inline void +setsbc32(uint32_t a, uint32_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a - (b + tempc); - cpu_state.flags_op = FLAGS_SBC32; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = a - (b + tempc); + cpu_state.flags_op = FLAGS_SBC32; } #else -static __inline void setadc8(uint8_t a, uint8_t b) +static __inline void +setadc8(uint8_t a, uint8_t b) { - uint16_t c=(uint16_t)a+(uint16_t)b+tempc; - cpu_state.flags_op = FLAGS_UNKNOWN; - cpu_state.flags&=~0x8D5; - cpu_state.flags|=znptable8[c&0xFF]; - if (c&0x100) cpu_state.flags|=C_FLAG; - if (!((a^b)&0x80)&&((a^c)&0x80)) cpu_state.flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) cpu_state.flags|=A_FLAG; + uint16_t c = (uint16_t) a + (uint16_t) b + tempc; + cpu_state.flags_op = FLAGS_UNKNOWN; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= znptable8[c & 0xFF]; + if (c & 0x100) + cpu_state.flags |= C_FLAG; + if (!((a ^ b) & 0x80) && ((a ^ c) & 0x80)) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) + (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } -static __inline void setadc16(uint16_t a, uint16_t b) +static __inline void +setadc16(uint16_t a, uint16_t b) { - uint32_t c=(uint32_t)a+(uint32_t)b+tempc; - cpu_state.flags_op = FLAGS_UNKNOWN; - cpu_state.flags&=~0x8D5; - cpu_state.flags|=znptable16[c&0xFFFF]; - if (c&0x10000) cpu_state.flags|=C_FLAG; - if (!((a^b)&0x8000)&&((a^c)&0x8000)) cpu_state.flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) cpu_state.flags|=A_FLAG; + uint32_t c = (uint32_t) a + (uint32_t) b + tempc; + cpu_state.flags_op = FLAGS_UNKNOWN; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= znptable16[c & 0xFFFF]; + if (c & 0x10000) + cpu_state.flags |= C_FLAG; + if (!((a ^ b) & 0x8000) && ((a ^ c) & 0x8000)) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) + (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } -static __inline void setadc32(uint32_t a, uint32_t b) +static __inline void +setadc32(uint32_t a, uint32_t b) { - uint32_t c=(uint32_t)a+(uint32_t)b+tempc; - cpu_state.flags_op = FLAGS_UNKNOWN; - cpu_state.flags&=~0x8D5; - cpu_state.flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0)); - cpu_state.flags|=(znptable8[c&0xFF]&P_FLAG); - if ((ca) || (c==a && tempc)) cpu_state.flags|=C_FLAG; - if ((a^b)&(a^c)&0x80000000) cpu_state.flags|=V_FLAG; - if (((a&0xF)-((b&0xF)+tempc))&0x10) cpu_state.flags|=A_FLAG; + uint32_t c = (uint32_t) a - (((uint32_t) b) + tempc); + cpu_state.flags_op = FLAGS_UNKNOWN; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= ((c & 0x80000000) ? N_FLAG : ((!c) ? Z_FLAG : 0)); + cpu_state.flags |= (znptable8[c & 0xFF] & P_FLAG); + if ((c > a) || (c == a && tempc)) + cpu_state.flags |= C_FLAG; + if ((a ^ b) & (a ^ c) & 0x80000000) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) - ((b & 0xF) + tempc)) & 0x10) + cpu_state.flags |= A_FLAG; } #endif diff --git a/src/cpu/x86_ops.h b/src/cpu/x86_ops.h index a1ab95125..a5e82d78e 100644 --- a/src/cpu/x86_ops.h +++ b/src/cpu/x86_ops.h @@ -39,16 +39,14 @@ #ifndef _X86_OPS_H #define _X86_OPS_H - -#define UN_USED(x) (void)(x) - +#define UN_USED(x) (void) (x) typedef int (*OpFn)(uint32_t fetchdat); #ifdef USE_DYNAREC void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f, - const OpFn *dynarec_opcodes, - const OpFn *dynarec_opcodes_0f); + const OpFn *dynarec_opcodes, + const OpFn *dynarec_opcodes_0f); extern const OpFn *x86_dynarec_opcodes; extern const OpFn *x86_dynarec_opcodes_0f; @@ -92,10 +90,10 @@ extern const OpFn dynarec_ops_winchip2_0f[1024]; extern const OpFn dynarec_ops_pentium_0f[1024]; extern const OpFn dynarec_ops_pentiummmx_0f[1024]; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +# if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) extern const OpFn dynarec_ops_c6x86_0f[1024]; extern const OpFn dynarec_ops_c6x86mx_0f[1024]; -#endif +# endif extern const OpFn dynarec_ops_k6_0f[1024]; extern const OpFn dynarec_ops_k62_0f[1024]; @@ -253,9 +251,9 @@ extern const OpFn ops_REPNE[1024]; extern const OpFn ops_3DNOW[256]; extern const OpFn ops_3DNOWE[256]; -#define C0 (1<<8) -#define C1 (1<<9) -#define C2 (1<<10) -#define C3 (1<<14) +#define C0 (1 << 8) +#define C1 (1 << 9) +#define C2 (1 << 10) +#define C3 (1 << 14) #endif /*_X86_OPS_H*/ diff --git a/src/cpu/x86_ops_3dnow.h b/src/cpu/x86_ops_3dnow.h index d24a6cc33..ca1f9c80a 100644 --- a/src/cpu/x86_ops_3dnow.h +++ b/src/cpu/x86_ops_3dnow.h @@ -1,360 +1,381 @@ #include -static int opPREFETCH_a16(uint32_t fetchdat) +static int +opPREFETCH_a16(uint32_t fetchdat) { - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + CLOCK_CYCLES(1); + return 0; +} +static int +opPREFETCH_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + + CLOCK_CYCLES(1); + return 0; +} + +static int +opFEMMS(uint32_t fetchdat) +{ + ILLEGAL_ON(!cpu_has_feature(CPU_FEATURE_MMX)); + if (cr0 & 0xc) { + x86_int(7); + return 1; + } + x87_emms(); + CLOCK_CYCLES(1); + return 0; +} + +static int +opPAVGUSB(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] + src.b[0] + 1) >> 1; + cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] + src.b[1] + 1) >> 1; + cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] + src.b[2] + 1) >> 1; + cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] + src.b[3] + 1) >> 1; + cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] + src.b[4] + 1) >> 1; + cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] + src.b[5] + 1) >> 1; + cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] + src.b[6] + 1) >> 1; + cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] + src.b[7] + 1) >> 1; + + return 0; +} +static int +opPF2ID(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].sl[0] = (int32_t) src.f[0]; + cpu_state.MM[cpu_reg].sl[1] = (int32_t) src.f[1]; + + return 0; +} +static int +opPF2IW(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].sw[0] = (int32_t) src.f[0]; + cpu_state.MM[cpu_reg].sw[1] = (int32_t) src.f[1]; + + return 0; +} +static int +opPFACC(uint32_t fetchdat) +{ + MMX_REG src; + float tempf; + + MMX_GETSRC(); + + tempf = cpu_state.MM[cpu_reg].f[0] + cpu_state.MM[cpu_reg].f[1]; + cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1]; + cpu_state.MM[cpu_reg].f[0] = tempf; + + return 0; +} +static int +opPFNACC(uint32_t fetchdat) +{ + MMX_REG src; + float tempf; + + MMX_GETSRC(); + + tempf = cpu_state.MM[cpu_reg].f[0] - cpu_state.MM[cpu_reg].f[1]; + cpu_state.MM[cpu_reg].f[1] = src.f[0] - src.f[1]; + cpu_state.MM[cpu_reg].f[0] = tempf; + + return 0; +} +static int +opPFPNACC(uint32_t fetchdat) +{ + MMX_REG src; + float tempf; + + MMX_GETSRC(); + + tempf = cpu_state.MM[cpu_reg].f[0] - cpu_state.MM[cpu_reg].f[1]; + cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1]; + cpu_state.MM[cpu_reg].f[0] = tempf; + + return 0; +} +static int +opPSWAPD(uint32_t fetchdat) +{ + MMX_REG src; + float tempf, tempf2; + + MMX_GETSRC(); + + /* We have to do this in case source and destination overlap. */ + tempf = src.f[0]; + tempf2 = src.f[1]; + cpu_state.MM[cpu_reg].f[1] = tempf; + cpu_state.MM[cpu_reg].f[0] = tempf2; + + return 0; +} +static int +opPFADD(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] += src.f[0]; + cpu_state.MM[cpu_reg].f[1] += src.f[1]; + + return 0; +} +static int +opPFCMPEQ(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] == src.f[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] == src.f[1]) ? 0xffffffff : 0; + + return 0; +} +static int +opPFCMPGE(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] >= src.f[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] >= src.f[1]) ? 0xffffffff : 0; + + return 0; +} +static int +opPFCMPGT(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] > src.f[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] > src.f[1]) ? 0xffffffff : 0; + + return 0; +} +static int +opPFMAX(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + if (src.f[0] > cpu_state.MM[cpu_reg].f[0]) + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + if (src.f[1] > cpu_state.MM[cpu_reg].f[1]) + cpu_state.MM[cpu_reg].f[1] = src.f[1]; + + return 0; +} +static int +opPFMIN(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + if (src.f[0] < cpu_state.MM[cpu_reg].f[0]) + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + if (src.f[1] < cpu_state.MM[cpu_reg].f[1]) + cpu_state.MM[cpu_reg].f[1] = src.f[1]; + + return 0; +} +static int +opPFMUL(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] *= src.f[0]; + cpu_state.MM[cpu_reg].f[1] *= src.f[1]; + + return 0; +} +static int +opPFRCP(uint32_t fetchdat) +{ + union { + uint32_t i; + float f; + } src; + + if (cpu_mod == 3) { + src.f = cpu_state.MM[cpu_rm].f[0]; CLOCK_CYCLES(1); - return 0; -} -static int opPREFETCH_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + src.i = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } - CLOCK_CYCLES(1); - return 0; -} + cpu_state.MM[cpu_reg].f[0] = 1.0 / src.f; + cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; -static int opFEMMS(uint32_t fetchdat) -{ - ILLEGAL_ON(!cpu_has_feature(CPU_FEATURE_MMX)); - if (cr0 & 0xc) - { - x86_int(7); - return 1; - } - x87_emms(); - CLOCK_CYCLES(1); - return 0; -} - -static int opPAVGUSB(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] + src.b[0] + 1) >> 1; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] + src.b[1] + 1) >> 1; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] + src.b[2] + 1) >> 1; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] + src.b[3] + 1) >> 1; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] + src.b[4] + 1) >> 1; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] + src.b[5] + 1) >> 1; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] + src.b[6] + 1) >> 1; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] + src.b[7] + 1) >> 1; - - return 0; -} -static int opPF2ID(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sl[0] = (int32_t)src.f[0]; - cpu_state.MM[cpu_reg].sl[1] = (int32_t)src.f[1]; - - return 0; -} -static int opPF2IW(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sw[0] = (int32_t)src.f[0]; - cpu_state.MM[cpu_reg].sw[1] = (int32_t)src.f[1]; - - return 0; -} -static int opPFACC(uint32_t fetchdat) -{ - MMX_REG src; - float tempf; - - MMX_GETSRC(); - - tempf = cpu_state.MM[cpu_reg].f[0] + cpu_state.MM[cpu_reg].f[1]; - cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1]; - cpu_state.MM[cpu_reg].f[0] = tempf; - - return 0; -} -static int opPFNACC(uint32_t fetchdat) -{ - MMX_REG src; - float tempf; - - MMX_GETSRC(); - - tempf = cpu_state.MM[cpu_reg].f[0] - cpu_state.MM[cpu_reg].f[1]; - cpu_state.MM[cpu_reg].f[1] = src.f[0] - src.f[1]; - cpu_state.MM[cpu_reg].f[0] = tempf; - - return 0; -} -static int opPFPNACC(uint32_t fetchdat) -{ - MMX_REG src; - float tempf; - - MMX_GETSRC(); - - tempf = cpu_state.MM[cpu_reg].f[0] - cpu_state.MM[cpu_reg].f[1]; - cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1]; - cpu_state.MM[cpu_reg].f[0] = tempf; - - return 0; -} -static int opPSWAPD(uint32_t fetchdat) -{ - MMX_REG src; - float tempf, tempf2; - - MMX_GETSRC(); - - /* We have to do this in case source and destination overlap. */ - tempf = src.f[0]; - tempf2 = src.f[1]; - cpu_state.MM[cpu_reg].f[1] = tempf; - cpu_state.MM[cpu_reg].f[0] = tempf2; - - return 0; -} -static int opPFADD(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].f[0] += src.f[0]; - cpu_state.MM[cpu_reg].f[1] += src.f[1]; - - return 0; -} -static int opPFCMPEQ(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] == src.f[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] == src.f[1]) ? 0xffffffff : 0; - - return 0; -} -static int opPFCMPGE(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] >= src.f[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] >= src.f[1]) ? 0xffffffff : 0; - - return 0; -} -static int opPFCMPGT(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] > src.f[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] > src.f[1]) ? 0xffffffff : 0; - - return 0; -} -static int opPFMAX(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - if (src.f[0] > cpu_state.MM[cpu_reg].f[0]) - cpu_state.MM[cpu_reg].f[0] = src.f[0]; - if (src.f[1] > cpu_state.MM[cpu_reg].f[1]) - cpu_state.MM[cpu_reg].f[1] = src.f[1]; - - return 0; -} -static int opPFMIN(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - if (src.f[0] < cpu_state.MM[cpu_reg].f[0]) - cpu_state.MM[cpu_reg].f[0] = src.f[0]; - if (src.f[1] < cpu_state.MM[cpu_reg].f[1]) - cpu_state.MM[cpu_reg].f[1] = src.f[1]; - - return 0; -} -static int opPFMUL(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].f[0] *= src.f[0]; - cpu_state.MM[cpu_reg].f[1] *= src.f[1]; - - return 0; -} -static int opPFRCP(uint32_t fetchdat) -{ - union - { - uint32_t i; - float f; - } src; - - if (cpu_mod == 3) - { - src.f = cpu_state.MM[cpu_rm].f[0]; - CLOCK_CYCLES(1); - } - else - { - SEG_CHECK_READ(cpu_state.ea_seg); - src.i = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; - CLOCK_CYCLES(2); - } - - cpu_state.MM[cpu_reg].f[0] = 1.0/src.f; - cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; - - return 0; + return 0; } /*Since opPFRCP() calculates a full precision reciprocal, treat the followup iterations as MOVs*/ -static int opPFRCPIT1(uint32_t fetchdat) +static int +opPFRCPIT1(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_GETSRC(); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] = src.f[0]; - cpu_state.MM[cpu_reg].f[1] = src.f[1]; + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + cpu_state.MM[cpu_reg].f[1] = src.f[1]; - return 0; + return 0; } -static int opPFRCPIT2(uint32_t fetchdat) +static int +opPFRCPIT2(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_GETSRC(); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] = src.f[0]; - cpu_state.MM[cpu_reg].f[1] = src.f[1]; + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + cpu_state.MM[cpu_reg].f[1] = src.f[1]; - return 0; + return 0; } -static int opPFRSQRT(uint32_t fetchdat) +static int +opPFRSQRT(uint32_t fetchdat) { - union - { - uint32_t i; - float f; - } src; + union { + uint32_t i; + float f; + } src; - if (cpu_mod == 3) - { - src.f = cpu_state.MM[cpu_rm].f[0]; - CLOCK_CYCLES(1); - } - else - { - SEG_CHECK_READ(cpu_state.ea_seg); - src.i = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; - CLOCK_CYCLES(2); - } + if (cpu_mod == 3) { + src.f = cpu_state.MM[cpu_rm].f[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + src.i = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } - cpu_state.MM[cpu_reg].f[0] = 1.0/sqrt(src.f); - cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; + cpu_state.MM[cpu_reg].f[0] = 1.0 / sqrt(src.f); + cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; - return 0; + return 0; } /*Since opPFRSQRT() calculates a full precision inverse square root, treat the followup iteration as a NOP*/ -static int opPFRSQIT1(uint32_t fetchdat) +static int +opPFRSQIT1(uint32_t fetchdat) { + MMX_REG src; + + MMX_GETSRC(); + UN_USED(src); + + return 0; +} +static int +opPFSUB(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] -= src.f[0]; + cpu_state.MM[cpu_reg].f[1] -= src.f[1]; + + return 0; +} +static int +opPFSUBR(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] = src.f[0] - cpu_state.MM[cpu_reg].f[0]; + cpu_state.MM[cpu_reg].f[1] = src.f[1] - cpu_state.MM[cpu_reg].f[1]; + + return 0; +} +static int +opPI2FD(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] = (float) src.sl[0]; + cpu_state.MM[cpu_reg].f[1] = (float) src.sl[1]; + + return 0; +} +static int +opPI2FW(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] = (float) src.sw[0]; + cpu_state.MM[cpu_reg].f[1] = (float) src.sw[1]; + + return 0; +} +static int +opPMULHRW(uint32_t fetchdat) +{ + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].w[0] = (((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) cpu_state.MM[cpu_rm].sw[0]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[1] = (((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) cpu_state.MM[cpu_rm].sw[1]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[2] = (((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) cpu_state.MM[cpu_rm].sw[2]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[3] = (((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) cpu_state.MM[cpu_rm].sw[3]) + 0x8000) >> 16; + CLOCK_CYCLES(1); + } else { MMX_REG src; - MMX_GETSRC(); - UN_USED(src); - - return 0; -} -static int opPFSUB(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].f[0] -= src.f[0]; - cpu_state.MM[cpu_reg].f[1] -= src.f[1]; - - return 0; -} -static int opPFSUBR(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].f[0] = src.f[0] - cpu_state.MM[cpu_reg].f[0]; - cpu_state.MM[cpu_reg].f[1] = src.f[1] - cpu_state.MM[cpu_reg].f[1]; - - return 0; -} -static int opPI2FD(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].f[0] = (float)src.sl[0]; - cpu_state.MM[cpu_reg].f[1] = (float)src.sl[1]; - - return 0; -} -static int opPI2FW(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].f[0] = (float)src.sw[0]; - cpu_state.MM[cpu_reg].f[1] = (float)src.sw[1]; - - return 0; -} -static int opPMULHRW(uint32_t fetchdat) -{ - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].w[0] = (((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)cpu_state.MM[cpu_rm].sw[0]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[1] = (((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)cpu_state.MM[cpu_rm].sw[1]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[2] = (((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)cpu_state.MM[cpu_rm].sw[2]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[3] = (((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)cpu_state.MM[cpu_rm].sw[3]) + 0x8000) >> 16; - CLOCK_CYCLES(1); - } - else - { - MMX_REG src; - - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].w[0] = ((int32_t)(cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t)(cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t)(cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t)(cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]) + 0x8000) >> 16; - CLOCK_CYCLES(2); - } - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].w[0] = ((int32_t) (cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[1] = ((int32_t) (cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[2] = ((int32_t) (cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[3] = ((int32_t) (cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]) + 0x8000) >> 16; + CLOCK_CYCLES(2); + } + return 0; } const OpFn OP_TABLE(3DNOW)[256] = @@ -405,29 +426,33 @@ const OpFn OP_TABLE(3DNOWE)[256] = /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, }; -static int op3DNOW_a16(uint32_t fetchdat) +static int +op3DNOW_a16(uint32_t fetchdat) { - uint8_t opcode; + uint8_t opcode; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - opcode = fastreadb(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetch_ea_16(fetchdat); + opcode = fastreadb(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - return x86_opcodes_3DNOW[opcode](0); + return x86_opcodes_3DNOW[opcode](0); } -static int op3DNOW_a32(uint32_t fetchdat) +static int +op3DNOW_a32(uint32_t fetchdat) { - uint8_t opcode; + uint8_t opcode; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - opcode = fastreadb(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetch_ea_32(fetchdat); + opcode = fastreadb(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - return x86_opcodes_3DNOW[opcode](0); + return x86_opcodes_3DNOW[opcode](0); } diff --git a/src/cpu/x86_ops_amd.h b/src/cpu/x86_ops_amd.h index 2b640ede4..9e6bcce55 100644 --- a/src/cpu/x86_ops_amd.h +++ b/src/cpu/x86_ops_amd.h @@ -23,16 +23,15 @@ opSYSCALL(uint32_t fetchdat) ret = syscall_op(fetchdat); if (ret <= 1) { - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 7, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - CPU_BLOCK_END(); + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 7, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + CPU_BLOCK_END(); } return ret; } - static int opSYSRET(uint32_t fetchdat) { @@ -43,10 +42,10 @@ opSYSRET(uint32_t fetchdat) ret = sysret(fetchdat); if (ret <= 1) { - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 7, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - CPU_BLOCK_END(); + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 7, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + CPU_BLOCK_END(); } return ret; diff --git a/src/cpu/x86_ops_arith.h b/src/cpu/x86_ops_arith.h index b56abb26a..41c655d09 100644 --- a/src/cpu/x86_ops_arith.h +++ b/src/cpu/x86_ops_arith.h @@ -1,827 +1,1012 @@ -#define OP_ARITH(name, operation, setflags, flagops, gettempc) \ - static int op ## name ## _b_rmw_a16(uint32_t fetchdat) \ - { \ - uint8_t dst; \ - uint8_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = getr8(cpu_rm); \ - src = getr8(cpu_reg); \ - setflags ## 8 flagops; \ - setr8(cpu_rm, operation); \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); \ - } \ - else \ - { \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - dst = geteab(); if (cpu_state.abrt) return 1; \ - src = getr8(cpu_reg); \ - seteab(operation); if (cpu_state.abrt) return 1; \ - setflags ## 8 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_mr, 2, rmdat, 1,0,1,0, 0); \ - } \ - return 0; \ - } \ - static int op ## name ## _b_rmw_a32(uint32_t fetchdat) \ - { \ - uint8_t dst; \ - uint8_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = getr8(cpu_rm); \ - src = getr8(cpu_reg); \ - setflags ## 8 flagops; \ - setr8(cpu_rm, operation); \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); \ - } \ - else \ - { \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - dst = geteab(); if (cpu_state.abrt) return 1; \ - src = getr8(cpu_reg); \ - seteab(operation); if (cpu_state.abrt) return 1; \ - setflags ## 8 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_mr, 2, rmdat, 1,0,1,0, 1); \ - } \ - return 0; \ - } \ - \ - static int op ## name ## _w_rmw_a16(uint32_t fetchdat) \ - { \ - uint16_t dst; \ - uint16_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = cpu_state.regs[cpu_rm].w; \ - src = cpu_state.regs[cpu_reg].w; \ - setflags ## 16 flagops; \ - cpu_state.regs[cpu_rm].w = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); \ - } \ - else \ - { \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - dst = geteaw(); if (cpu_state.abrt) return 1; \ - src = cpu_state.regs[cpu_reg].w; \ - seteaw(operation); if (cpu_state.abrt) return 1; \ - setflags ## 16 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 1,0,1,0, 0); \ - } \ - return 0; \ - } \ - static int op ## name ## _w_rmw_a32(uint32_t fetchdat) \ - { \ - uint16_t dst; \ - uint16_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = cpu_state.regs[cpu_rm].w; \ - src = cpu_state.regs[cpu_reg].w; \ - setflags ## 16 flagops; \ - cpu_state.regs[cpu_rm].w = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); \ - } \ - else \ - { \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - dst = geteaw(); if (cpu_state.abrt) return 1; \ - src = cpu_state.regs[cpu_reg].w; \ - seteaw(operation); if (cpu_state.abrt) return 1; \ - setflags ## 16 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 1,0,1,0, 1); \ - } \ - return 0; \ - } \ - \ - static int op ## name ## _l_rmw_a16(uint32_t fetchdat) \ - { \ - uint32_t dst; \ - uint32_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = cpu_state.regs[cpu_rm].l; \ - src = cpu_state.regs[cpu_reg].l; \ - setflags ## 32 flagops; \ - cpu_state.regs[cpu_rm].l = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); \ - } \ - else \ - { \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - dst = geteal(); if (cpu_state.abrt) return 1; \ - src = cpu_state.regs[cpu_reg].l; \ - seteal(operation); if (cpu_state.abrt) return 1; \ - setflags ## 32 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,1,0,1, 0); \ - } \ - return 0; \ - } \ - static int op ## name ## _l_rmw_a32(uint32_t fetchdat) \ - { \ - uint32_t dst; \ - uint32_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = cpu_state.regs[cpu_rm].l; \ - src = cpu_state.regs[cpu_reg].l; \ - setflags ## 32 flagops; \ - cpu_state.regs[cpu_rm].l = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); \ - } \ - else \ - { \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - dst = geteal(); if (cpu_state.abrt) return 1; \ - src = cpu_state.regs[cpu_reg].l; \ - seteal(operation); if (cpu_state.abrt) return 1; \ - setflags ## 32 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,1,0,1, 1); \ - } \ - return 0; \ - } \ - \ - static int op ## name ## _b_rm_a16(uint32_t fetchdat) \ - { \ - uint8_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - dst = getr8(cpu_reg); \ - src = geteab(); if (cpu_state.abrt) return 1; \ - setflags ## 8 flagops; \ - setr8(cpu_reg, operation); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); \ - return 0; \ - } \ - static int op ## name ## _b_rm_a32(uint32_t fetchdat) \ - { \ - uint8_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - dst = getr8(cpu_reg); \ - src = geteab(); if (cpu_state.abrt) return 1; \ - setflags ## 8 flagops; \ - setr8(cpu_reg, operation); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); \ - return 0; \ - } \ - \ - static int op ## name ## _w_rm_a16(uint32_t fetchdat) \ - { \ - uint16_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - dst = cpu_state.regs[cpu_reg].w; \ - src = geteaw(); if (cpu_state.abrt) return 1; \ - setflags ## 16 flagops; \ - cpu_state.regs[cpu_reg].w = operation; \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); \ - return 0; \ - } \ - static int op ## name ## _w_rm_a32(uint32_t fetchdat) \ - { \ - uint16_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - dst = cpu_state.regs[cpu_reg].w; \ - src = geteaw(); if (cpu_state.abrt) return 1; \ - setflags ## 16 flagops; \ - cpu_state.regs[cpu_reg].w = operation; \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); \ - return 0; \ - } \ - \ - static int op ## name ## _l_rm_a16(uint32_t fetchdat) \ - { \ - uint32_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - dst = cpu_state.regs[cpu_reg].l; \ - src = geteal(); if (cpu_state.abrt) return 1; \ - setflags ## 32 flagops; \ - cpu_state.regs[cpu_reg].l = operation; \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0); \ - return 0; \ - } \ - static int op ## name ## _l_rm_a32(uint32_t fetchdat) \ - { \ - uint32_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - dst = cpu_state.regs[cpu_reg].l; \ - src = geteal(); if (cpu_state.abrt) return 1; \ - setflags ## 32 flagops; \ - cpu_state.regs[cpu_reg].l = operation; \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1); \ - return 0; \ - } \ - \ - static int op ## name ## _AL_imm(uint32_t fetchdat) \ - { \ - uint8_t dst = AL; \ - uint8_t src = getbytef(); \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - setflags ## 8 flagops; \ - AL = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); \ - return 0; \ - } \ - \ - static int op ## name ## _AX_imm(uint32_t fetchdat) \ - { \ - uint16_t dst = AX; \ - uint16_t src = getwordf(); \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - setflags ## 16 flagops; \ - AX = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); \ - return 0; \ - } \ - \ - static int op ## name ## _EAX_imm(uint32_t fetchdat) \ - { \ - uint32_t dst = EAX; \ - uint32_t src = getlong(); if (cpu_state.abrt) return 1; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - setflags ## 32 flagops; \ - EAX = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); \ - return 0; \ - } +#define OP_ARITH(name, operation, setflags, flagops, gettempc) \ + static int op##name##_b_rmw_a16(uint32_t fetchdat) \ + { \ + uint8_t dst; \ + uint8_t src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_16(fetchdat); \ + if (cpu_mod == 3) { \ + dst = getr8(cpu_rm); \ + src = getr8(cpu_reg); \ + setflags##8 flagops; \ + setr8(cpu_rm, operation); \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); \ + } else { \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteab(); \ + if (cpu_state.abrt) \ + return 1; \ + src = getr8(cpu_reg); \ + seteab(operation); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##8 flagops; \ + CLOCK_CYCLES(timing_mr); \ + PREFETCH_RUN(timing_mr, 2, rmdat, 1, 0, 1, 0, 0); \ + } \ + return 0; \ + } \ + static int op##name##_b_rmw_a32(uint32_t fetchdat) \ + { \ + uint8_t dst; \ + uint8_t src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_32(fetchdat); \ + if (cpu_mod == 3) { \ + dst = getr8(cpu_rm); \ + src = getr8(cpu_reg); \ + setflags##8 flagops; \ + setr8(cpu_rm, operation); \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); \ + } else { \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteab(); \ + if (cpu_state.abrt) \ + return 1; \ + src = getr8(cpu_reg); \ + seteab(operation); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##8 flagops; \ + CLOCK_CYCLES(timing_mr); \ + PREFETCH_RUN(timing_mr, 2, rmdat, 1, 0, 1, 0, 1); \ + } \ + return 0; \ + } \ + \ + static int op##name##_w_rmw_a16(uint32_t fetchdat) \ + { \ + uint16_t dst; \ + uint16_t src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_16(fetchdat); \ + if (cpu_mod == 3) { \ + dst = cpu_state.regs[cpu_rm].w; \ + src = cpu_state.regs[cpu_reg].w; \ + setflags##16 flagops; \ + cpu_state.regs[cpu_rm].w = operation; \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); \ + } else { \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + src = cpu_state.regs[cpu_reg].w; \ + seteaw(operation); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##16 flagops; \ + CLOCK_CYCLES(timing_mr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 1, 0, 1, 0, 0); \ + } \ + return 0; \ + } \ + static int op##name##_w_rmw_a32(uint32_t fetchdat) \ + { \ + uint16_t dst; \ + uint16_t src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_32(fetchdat); \ + if (cpu_mod == 3) { \ + dst = cpu_state.regs[cpu_rm].w; \ + src = cpu_state.regs[cpu_reg].w; \ + setflags##16 flagops; \ + cpu_state.regs[cpu_rm].w = operation; \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); \ + } else { \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + src = cpu_state.regs[cpu_reg].w; \ + seteaw(operation); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##16 flagops; \ + CLOCK_CYCLES(timing_mr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 1, 0, 1, 0, 1); \ + } \ + return 0; \ + } \ + \ + static int op##name##_l_rmw_a16(uint32_t fetchdat) \ + { \ + uint32_t dst; \ + uint32_t src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_16(fetchdat); \ + if (cpu_mod == 3) { \ + dst = cpu_state.regs[cpu_rm].l; \ + src = cpu_state.regs[cpu_reg].l; \ + setflags##32 flagops; \ + cpu_state.regs[cpu_rm].l = operation; \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); \ + } else { \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + src = cpu_state.regs[cpu_reg].l; \ + seteal(operation); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##32 flagops; \ + CLOCK_CYCLES(timing_mr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 1, 0, 1, 0); \ + } \ + return 0; \ + } \ + static int op##name##_l_rmw_a32(uint32_t fetchdat) \ + { \ + uint32_t dst; \ + uint32_t src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_32(fetchdat); \ + if (cpu_mod == 3) { \ + dst = cpu_state.regs[cpu_rm].l; \ + src = cpu_state.regs[cpu_reg].l; \ + setflags##32 flagops; \ + cpu_state.regs[cpu_rm].l = operation; \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); \ + } else { \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + src = cpu_state.regs[cpu_reg].l; \ + seteal(operation); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##32 flagops; \ + CLOCK_CYCLES(timing_mr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 1, 0, 1, 1); \ + } \ + return 0; \ + } \ + \ + static int op##name##_b_rm_a16(uint32_t fetchdat) \ + { \ + uint8_t dst, src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + dst = getr8(cpu_reg); \ + src = geteab(); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##8 flagops; \ + setr8(cpu_reg, operation); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); \ + return 0; \ + } \ + static int op##name##_b_rm_a32(uint32_t fetchdat) \ + { \ + uint8_t dst, src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + dst = getr8(cpu_reg); \ + src = geteab(); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##8 flagops; \ + setr8(cpu_reg, operation); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); \ + return 0; \ + } \ + \ + static int op##name##_w_rm_a16(uint32_t fetchdat) \ + { \ + uint16_t dst, src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + dst = cpu_state.regs[cpu_reg].w; \ + src = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##16 flagops; \ + cpu_state.regs[cpu_reg].w = operation; \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); \ + return 0; \ + } \ + static int op##name##_w_rm_a32(uint32_t fetchdat) \ + { \ + uint16_t dst, src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + dst = cpu_state.regs[cpu_reg].w; \ + src = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##16 flagops; \ + cpu_state.regs[cpu_reg].w = operation; \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); \ + return 0; \ + } \ + \ + static int op##name##_l_rm_a16(uint32_t fetchdat) \ + { \ + uint32_t dst, src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + dst = cpu_state.regs[cpu_reg].l; \ + src = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##32 flagops; \ + cpu_state.regs[cpu_reg].l = operation; \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); \ + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); \ + return 0; \ + } \ + static int op##name##_l_rm_a32(uint32_t fetchdat) \ + { \ + uint32_t dst, src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + dst = cpu_state.regs[cpu_reg].l; \ + src = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##32 flagops; \ + cpu_state.regs[cpu_reg].l = operation; \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); \ + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); \ + return 0; \ + } \ + \ + static int op##name##_AL_imm(uint32_t fetchdat) \ + { \ + uint8_t dst = AL; \ + uint8_t src = getbytef(); \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + setflags##8 flagops; \ + AL = operation; \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); \ + return 0; \ + } \ + \ + static int op##name##_AX_imm(uint32_t fetchdat) \ + { \ + uint16_t dst = AX; \ + uint16_t src = getwordf(); \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + setflags##16 flagops; \ + AX = operation; \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); \ + return 0; \ + } \ + \ + static int op##name##_EAX_imm(uint32_t fetchdat) \ + { \ + uint32_t dst = EAX; \ + uint32_t src = getlong(); \ + if (cpu_state.abrt) \ + return 1; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + setflags##32 flagops; \ + EAX = operation; \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); \ + return 0; \ + } -OP_ARITH(ADD, dst + src, setadd, (dst, src), 0) -OP_ARITH(ADC, dst + src + tempc, setadc, (dst, src), 1) -OP_ARITH(SUB, dst - src, setsub, (dst, src), 0) +OP_ARITH(ADD, dst + src, setadd, (dst, src), 0) +OP_ARITH(ADC, dst + src + tempc, setadc, (dst, src), 1) +OP_ARITH(SUB, dst - src, setsub, (dst, src), 0) OP_ARITH(SBB, dst - (src + tempc), setsbc, (dst, src), 1) -OP_ARITH(OR, dst | src, setznp, (dst | src), 0) -OP_ARITH(AND, dst & src, setznp, (dst & src), 0) -OP_ARITH(XOR, dst ^ src, setznp, (dst ^ src), 0) +OP_ARITH(OR, dst | src, setznp, (dst | src), 0) +OP_ARITH(AND, dst &src, setznp, (dst & src), 0) +OP_ARITH(XOR, dst ^ src, setznp, (dst ^ src), 0) -static int opCMP_b_rmw_a16(uint32_t fetchdat) +static int +opCMP_b_rmw_a16(uint32_t fetchdat) { - uint8_t dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteab(); if (cpu_state.abrt) return 1; - setsub8(dst, getr8(cpu_reg)); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; + uint8_t dst; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + dst = geteab(); + if (cpu_state.abrt) + return 1; + setsub8(dst, getr8(cpu_reg)); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opCMP_b_rmw_a32(uint32_t fetchdat) +static int +opCMP_b_rmw_a32(uint32_t fetchdat) { - uint8_t dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteab(); if (cpu_state.abrt) return 1; - setsub8(dst, getr8(cpu_reg)); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; + uint8_t dst; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + dst = geteab(); + if (cpu_state.abrt) + return 1; + setsub8(dst, getr8(cpu_reg)); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opCMP_w_rmw_a16(uint32_t fetchdat) +static int +opCMP_w_rmw_a16(uint32_t fetchdat) { - uint16_t dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteaw(); if (cpu_state.abrt) return 1; - setsub16(dst, cpu_state.regs[cpu_reg].w); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; + uint16_t dst; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + dst = geteaw(); + if (cpu_state.abrt) + return 1; + setsub16(dst, cpu_state.regs[cpu_reg].w); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opCMP_w_rmw_a32(uint32_t fetchdat) +static int +opCMP_w_rmw_a32(uint32_t fetchdat) { - uint16_t dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteaw(); if (cpu_state.abrt) return 1; - setsub16(dst, cpu_state.regs[cpu_reg].w); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; + uint16_t dst; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + dst = geteaw(); + if (cpu_state.abrt) + return 1; + setsub16(dst, cpu_state.regs[cpu_reg].w); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opCMP_l_rmw_a16(uint32_t fetchdat) +static int +opCMP_l_rmw_a16(uint32_t fetchdat) { - uint32_t dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteal(); if (cpu_state.abrt) return 1; - setsub32(dst, cpu_state.regs[cpu_reg].l); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0); - return 0; + uint32_t dst; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + dst = geteal(); + if (cpu_state.abrt) + return 1; + setsub32(dst, cpu_state.regs[cpu_reg].l); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + return 0; } -static int opCMP_l_rmw_a32(uint32_t fetchdat) +static int +opCMP_l_rmw_a32(uint32_t fetchdat) { - uint32_t dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteal(); if (cpu_state.abrt) return 1; - setsub32(dst, cpu_state.regs[cpu_reg].l); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1); - return 0; + uint32_t dst; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + dst = geteal(); + if (cpu_state.abrt) + return 1; + setsub32(dst, cpu_state.regs[cpu_reg].l); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + return 0; } -static int opCMP_b_rm_a16(uint32_t fetchdat) +static int +opCMP_b_rm_a16(uint32_t fetchdat) { - uint8_t src; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - src = geteab(); if (cpu_state.abrt) return 1; - setsub8(getr8(cpu_reg), src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; + uint8_t src; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + src = geteab(); + if (cpu_state.abrt) + return 1; + setsub8(getr8(cpu_reg), src); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opCMP_b_rm_a32(uint32_t fetchdat) +static int +opCMP_b_rm_a32(uint32_t fetchdat) { - uint8_t src; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - src = geteab(); if (cpu_state.abrt) return 1; - setsub8(getr8(cpu_reg), src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; + uint8_t src; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + src = geteab(); + if (cpu_state.abrt) + return 1; + setsub8(getr8(cpu_reg), src); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opCMP_w_rm_a16(uint32_t fetchdat) +static int +opCMP_w_rm_a16(uint32_t fetchdat) { - uint16_t src; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - src = geteaw(); if (cpu_state.abrt) return 1; - setsub16(cpu_state.regs[cpu_reg].w, src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; + uint16_t src; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + src = geteaw(); + if (cpu_state.abrt) + return 1; + setsub16(cpu_state.regs[cpu_reg].w, src); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opCMP_w_rm_a32(uint32_t fetchdat) +static int +opCMP_w_rm_a32(uint32_t fetchdat) { - uint16_t src; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - src = geteaw(); if (cpu_state.abrt) return 1; - setsub16(cpu_state.regs[cpu_reg].w, src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; + uint16_t src; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + src = geteaw(); + if (cpu_state.abrt) + return 1; + setsub16(cpu_state.regs[cpu_reg].w, src); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opCMP_l_rm_a16(uint32_t fetchdat) +static int +opCMP_l_rm_a16(uint32_t fetchdat) { - uint32_t src; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - src = geteal(); if (cpu_state.abrt) return 1; - setsub32(cpu_state.regs[cpu_reg].l, src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0); - return 0; + uint32_t src; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + src = geteal(); + if (cpu_state.abrt) + return 1; + setsub32(cpu_state.regs[cpu_reg].l, src); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + return 0; } -static int opCMP_l_rm_a32(uint32_t fetchdat) +static int +opCMP_l_rm_a32(uint32_t fetchdat) { - uint32_t src; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - src = geteal(); if (cpu_state.abrt) return 1; - setsub32(cpu_state.regs[cpu_reg].l, src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1); - return 0; + uint32_t src; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + src = geteal(); + if (cpu_state.abrt) + return 1; + setsub32(cpu_state.regs[cpu_reg].l, src); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + return 0; } -static int opCMP_AL_imm(uint32_t fetchdat) +static int +opCMP_AL_imm(uint32_t fetchdat) { - uint8_t src = getbytef(); - setsub8(AL, src); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + uint8_t src = getbytef(); + setsub8(AL, src); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opCMP_AX_imm(uint32_t fetchdat) +static int +opCMP_AX_imm(uint32_t fetchdat) { - uint16_t src = getwordf(); - setsub16(AX, src); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + uint16_t src = getwordf(); + setsub16(AX, src); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opCMP_EAX_imm(uint32_t fetchdat) +static int +opCMP_EAX_imm(uint32_t fetchdat) { - uint32_t src = getlong(); if (cpu_state.abrt) return 1; - setsub32(EAX, src); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t src = getlong(); + if (cpu_state.abrt) + return 1; + setsub32(EAX, src); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opTEST_b_a16(uint32_t fetchdat) +static int +opTEST_b_a16(uint32_t fetchdat) { - uint8_t temp, temp2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - temp2 = getr8(cpu_reg); - setznp8(temp & temp2); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; + uint8_t temp, temp2; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + temp2 = getr8(cpu_reg); + setznp8(temp & temp2); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opTEST_b_a32(uint32_t fetchdat) +static int +opTEST_b_a32(uint32_t fetchdat) { - uint8_t temp, temp2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - temp2 = getr8(cpu_reg); - setznp8(temp & temp2); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; + uint8_t temp, temp2; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + temp2 = getr8(cpu_reg); + setznp8(temp & temp2); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opTEST_w_a16(uint32_t fetchdat) +static int +opTEST_w_a16(uint32_t fetchdat) { - uint16_t temp, temp2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - temp2 = cpu_state.regs[cpu_reg].w; - setznp16(temp & temp2); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; + uint16_t temp, temp2; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + temp2 = cpu_state.regs[cpu_reg].w; + setznp16(temp & temp2); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opTEST_w_a32(uint32_t fetchdat) +static int +opTEST_w_a32(uint32_t fetchdat) { - uint16_t temp, temp2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - temp2 = cpu_state.regs[cpu_reg].w; - setznp16(temp & temp2); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; + uint16_t temp, temp2; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + temp2 = cpu_state.regs[cpu_reg].w; + setznp16(temp & temp2); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opTEST_l_a16(uint32_t fetchdat) +static int +opTEST_l_a16(uint32_t fetchdat) { - uint32_t temp, temp2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - temp2 = cpu_state.regs[cpu_reg].l; - setznp32(temp & temp2); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0,(cpu_mod == 3) ? 0 : 1,0,0, 0); - return 0; + uint32_t temp, temp2; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + temp2 = cpu_state.regs[cpu_reg].l; + setznp32(temp & temp2); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + return 0; } -static int opTEST_l_a32(uint32_t fetchdat) +static int +opTEST_l_a32(uint32_t fetchdat) { - uint32_t temp, temp2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - temp2 = cpu_state.regs[cpu_reg].l; - setznp32(temp & temp2); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0,(cpu_mod == 3) ? 0 : 1,0,0, 1); - return 0; + uint32_t temp, temp2; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + temp2 = cpu_state.regs[cpu_reg].l; + setznp32(temp & temp2); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + return 0; } -static int opTEST_AL(uint32_t fetchdat) +static int +opTEST_AL(uint32_t fetchdat) { - uint8_t temp = getbytef(); - setznp8(AL & temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + uint8_t temp = getbytef(); + setznp8(AL & temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opTEST_AX(uint32_t fetchdat) +static int +opTEST_AX(uint32_t fetchdat) { - uint16_t temp = getwordf(); - setznp16(AX & temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + uint16_t temp = getwordf(); + setznp16(AX & temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opTEST_EAX(uint32_t fetchdat) +static int +opTEST_EAX(uint32_t fetchdat) { - uint32_t temp = getlong(); if (cpu_state.abrt) return 1; - setznp32(EAX & temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t temp = getlong(); + if (cpu_state.abrt) + return 1; + setznp32(EAX & temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } +#define ARITH_MULTI(ea_width, flag_width) \ + dst = getea##ea_width(); \ + if (cpu_state.abrt) \ + return 1; \ + switch (rmdat & 0x38) { \ + case 0x00: /*ADD ea, #*/ \ + setea##ea_width(dst + src); \ + if (cpu_state.abrt) \ + return 1; \ + setadd##flag_width(dst, src); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ + break; \ + case 0x08: /*OR ea, #*/ \ + dst |= src; \ + setea##ea_width(dst); \ + if (cpu_state.abrt) \ + return 1; \ + setznp##flag_width(dst); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ + break; \ + case 0x10: /*ADC ea, #*/ \ + tempc = CF_SET() ? 1 : 0; \ + setea##ea_width(dst + src + tempc); \ + if (cpu_state.abrt) \ + return 1; \ + setadc##flag_width(dst, src); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ + break; \ + case 0x18: /*SBB ea, #*/ \ + tempc = CF_SET() ? 1 : 0; \ + setea##ea_width(dst - (src + tempc)); \ + if (cpu_state.abrt) \ + return 1; \ + setsbc##flag_width(dst, src); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ + break; \ + case 0x20: /*AND ea, #*/ \ + dst &= src; \ + setea##ea_width(dst); \ + if (cpu_state.abrt) \ + return 1; \ + setznp##flag_width(dst); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ + break; \ + case 0x28: /*SUB ea, #*/ \ + setea##ea_width(dst - src); \ + if (cpu_state.abrt) \ + return 1; \ + setsub##flag_width(dst, src); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ + break; \ + case 0x30: /*XOR ea, #*/ \ + dst ^= src; \ + setea##ea_width(dst); \ + if (cpu_state.abrt) \ + return 1; \ + setznp##flag_width(dst); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ + break; \ + case 0x38: /*CMP ea, #*/ \ + setsub##flag_width(dst, src); \ + if (is486) { \ + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); \ + } else { \ + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 7); \ + } \ + break; \ + } -#define ARITH_MULTI(ea_width, flag_width) \ - dst = getea ## ea_width(); if (cpu_state.abrt) return 1; \ - switch (rmdat&0x38) \ - { \ - case 0x00: /*ADD ea, #*/ \ - setea ## ea_width(dst + src); if (cpu_state.abrt) return 1; \ - setadd ## flag_width(dst, src); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x08: /*OR ea, #*/ \ - dst |= src; \ - setea ## ea_width(dst); if (cpu_state.abrt) return 1; \ - setznp ## flag_width(dst); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x10: /*ADC ea, #*/ \ - tempc = CF_SET() ? 1 : 0; \ - setea ## ea_width(dst + src + tempc); if (cpu_state.abrt) return 1; \ - setadc ## flag_width(dst, src); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x18: /*SBB ea, #*/ \ - tempc = CF_SET() ? 1 : 0; \ - setea ## ea_width(dst - (src + tempc)); if (cpu_state.abrt) return 1; \ - setsbc ## flag_width(dst, src); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x20: /*AND ea, #*/ \ - dst &= src; \ - setea ## ea_width(dst); if (cpu_state.abrt) return 1; \ - setznp ## flag_width(dst); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x28: /*SUB ea, #*/ \ - setea ## ea_width(dst - src); if (cpu_state.abrt) return 1; \ - setsub ## flag_width(dst, src); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x30: /*XOR ea, #*/ \ - dst ^= src; \ - setea ## ea_width(dst); if (cpu_state.abrt) return 1; \ - setznp ## flag_width(dst); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x38: /*CMP ea, #*/ \ - setsub ## flag_width(dst, src); \ - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } \ - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 7); } \ - break; \ - } - - -static int op80_a16(uint32_t fetchdat) +static int +op80_a16(uint32_t fetchdat) { - uint8_t src, dst; + uint8_t src, dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getbyte(); if (cpu_state.abrt) return 1; - ARITH_MULTI(b, 8); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - } + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getbyte(); + if (cpu_state.abrt) + return 1; + ARITH_MULTI(b, 8); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + } - return 0; + return 0; } -static int op80_a32(uint32_t fetchdat) +static int +op80_a32(uint32_t fetchdat) { - uint8_t src, dst; + uint8_t src, dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getbyte(); if (cpu_state.abrt) return 1; - ARITH_MULTI(b, 8); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - } + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getbyte(); + if (cpu_state.abrt) + return 1; + ARITH_MULTI(b, 8); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + } - return 0; + return 0; } -static int op81_w_a16(uint32_t fetchdat) +static int +op81_w_a16(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src, dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getword(); if (cpu_state.abrt) return 1; - ARITH_MULTI(w, 16); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 4, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - } + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getword(); + if (cpu_state.abrt) + return 1; + ARITH_MULTI(w, 16); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 4, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 4, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + } - return 0; + return 0; } -static int op81_w_a32(uint32_t fetchdat) +static int +op81_w_a32(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src, dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getword(); if (cpu_state.abrt) return 1; - ARITH_MULTI(w, 16); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 4, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - } + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getword(); + if (cpu_state.abrt) + return 1; + ARITH_MULTI(w, 16); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 4, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 4, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + } - return 0; + return 0; } -static int op81_l_a16(uint32_t fetchdat) +static int +op81_l_a16(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src, dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getlong(); if (cpu_state.abrt) return 1; - ARITH_MULTI(l, 32); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - } + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getlong(); + if (cpu_state.abrt) + return 1; + ARITH_MULTI(l, 32); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 6, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 6, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + } - return 0; + return 0; } -static int op81_l_a32(uint32_t fetchdat) +static int +op81_l_a32(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src, dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getlong(); if (cpu_state.abrt) return 1; - ARITH_MULTI(l, 32); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - } + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getlong(); + if (cpu_state.abrt) + return 1; + ARITH_MULTI(l, 32); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 6, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 6, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + } - return 0; + return 0; } -static int op83_w_a16(uint32_t fetchdat) +static int +op83_w_a16(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src, dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getbyte(); if (cpu_state.abrt) return 1; - if (src & 0x80) src |= 0xff00; - ARITH_MULTI(w, 16); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - } + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getbyte(); + if (cpu_state.abrt) + return 1; + if (src & 0x80) + src |= 0xff00; + ARITH_MULTI(w, 16); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + } - return 0; + return 0; } -static int op83_w_a32(uint32_t fetchdat) +static int +op83_w_a32(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src, dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getbyte(); if (cpu_state.abrt) return 1; - if (src & 0x80) src |= 0xff00; - ARITH_MULTI(w, 16); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - } + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getbyte(); + if (cpu_state.abrt) + return 1; + if (src & 0x80) + src |= 0xff00; + ARITH_MULTI(w, 16); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + } - return 0; + return 0; } -static int op83_l_a16(uint32_t fetchdat) +static int +op83_l_a16(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src, dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getbyte(); if (cpu_state.abrt) return 1; - if (src & 0x80) src |= 0xffffff00; - ARITH_MULTI(l, 32); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - } + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getbyte(); + if (cpu_state.abrt) + return 1; + if (src & 0x80) + src |= 0xffffff00; + ARITH_MULTI(l, 32); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + } - return 0; + return 0; } -static int op83_l_a32(uint32_t fetchdat) +static int +op83_l_a32(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src, dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getbyte(); if (cpu_state.abrt) return 1; - if (src & 0x80) src |= 0xffffff00; - ARITH_MULTI(l, 32); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - } + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getbyte(); + if (cpu_state.abrt) + return 1; + if (src & 0x80) + src |= 0xffffff00; + ARITH_MULTI(l, 32); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + } - return 0; + return 0; } diff --git a/src/cpu/x86_ops_atomic.h b/src/cpu/x86_ops_atomic.h index 13b672e31..7c7b409d2 100644 --- a/src/cpu/x86_ops_atomic.h +++ b/src/cpu/x86_ops_atomic.h @@ -1,227 +1,295 @@ -static int opCMPXCHG_b_a16(uint32_t fetchdat) +static int +opCMPXCHG_b_a16(uint32_t fetchdat) { - uint8_t temp, temp2 = AL; - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - if (AL == temp) seteab(getr8(cpu_reg)); - else AL = temp; - if (cpu_state.abrt) return 1; - setsub8(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; + uint8_t temp, temp2 = AL; + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + if (AL == temp) + seteab(getr8(cpu_reg)); + else + AL = temp; + if (cpu_state.abrt) + return 1; + setsub8(temp2, temp); + CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); + return 0; } -static int opCMPXCHG_b_a32(uint32_t fetchdat) +static int +opCMPXCHG_b_a32(uint32_t fetchdat) { - uint8_t temp, temp2 = AL; - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - if (AL == temp) seteab(getr8(cpu_reg)); - else AL = temp; - if (cpu_state.abrt) return 1; - setsub8(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; + uint8_t temp, temp2 = AL; + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + if (AL == temp) + seteab(getr8(cpu_reg)); + else + AL = temp; + if (cpu_state.abrt) + return 1; + setsub8(temp2, temp); + CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); + return 0; } -static int opCMPXCHG_w_a16(uint32_t fetchdat) +static int +opCMPXCHG_w_a16(uint32_t fetchdat) { - uint16_t temp, temp2 = AX; - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - if (AX == temp) seteaw(cpu_state.regs[cpu_reg].w); - else AX = temp; - if (cpu_state.abrt) return 1; - setsub16(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; + uint16_t temp, temp2 = AX; + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + if (AX == temp) + seteaw(cpu_state.regs[cpu_reg].w); + else + AX = temp; + if (cpu_state.abrt) + return 1; + setsub16(temp2, temp); + CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); + return 0; } -static int opCMPXCHG_w_a32(uint32_t fetchdat) +static int +opCMPXCHG_w_a32(uint32_t fetchdat) { - uint16_t temp, temp2 = AX; - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - if (AX == temp) seteaw(cpu_state.regs[cpu_reg].w); - else AX = temp; - if (cpu_state.abrt) return 1; - setsub16(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; + uint16_t temp, temp2 = AX; + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + if (AX == temp) + seteaw(cpu_state.regs[cpu_reg].w); + else + AX = temp; + if (cpu_state.abrt) + return 1; + setsub16(temp2, temp); + CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); + return 0; } -static int opCMPXCHG_l_a16(uint32_t fetchdat) +static int +opCMPXCHG_l_a16(uint32_t fetchdat) { - uint32_t temp, temp2 = EAX; - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - if (EAX == temp) seteal(cpu_state.regs[cpu_reg].l); - else EAX = temp; - if (cpu_state.abrt) return 1; - setsub32(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; + uint32_t temp, temp2 = EAX; + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + if (EAX == temp) + seteal(cpu_state.regs[cpu_reg].l); + else + EAX = temp; + if (cpu_state.abrt) + return 1; + setsub32(temp2, temp); + CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); + return 0; } -static int opCMPXCHG_l_a32(uint32_t fetchdat) +static int +opCMPXCHG_l_a32(uint32_t fetchdat) { - uint32_t temp, temp2 = EAX; - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - if (EAX == temp) seteal(cpu_state.regs[cpu_reg].l); - else EAX = temp; - if (cpu_state.abrt) return 1; - setsub32(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; + uint32_t temp, temp2 = EAX; + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + if (EAX == temp) + seteal(cpu_state.regs[cpu_reg].l); + else + EAX = temp; + if (cpu_state.abrt) + return 1; + setsub32(temp2, temp); + CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); + return 0; } -static int opCMPXCHG8B_a16(uint32_t fetchdat) +static int +opCMPXCHG8B_a16(uint32_t fetchdat) { - uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX; - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); - temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - if (EAX == temp && EDX == temp_hi) - { - seteal(EBX); - writememl(easeg, cpu_state.eaaddr+4, ECX); - } - else - { - EAX = temp; - EDX = temp_hi; - } - if (cpu_state.abrt) return 0; - flags_rebuild(); - if (temp == temp2 && temp_hi == temp2_hi) - cpu_state.flags |= Z_FLAG; - else - cpu_state.flags &= ~Z_FLAG; - cycles -= (cpu_mod == 3) ? 6 : 10; + uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX; + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) return 0; + if (EAX == temp && EDX == temp_hi) { + seteal(EBX); + writememl(easeg, cpu_state.eaaddr + 4, ECX); + } else { + EAX = temp; + EDX = temp_hi; + } + if (cpu_state.abrt) + return 0; + flags_rebuild(); + if (temp == temp2 && temp_hi == temp2_hi) + cpu_state.flags |= Z_FLAG; + else + cpu_state.flags &= ~Z_FLAG; + cycles -= (cpu_mod == 3) ? 6 : 10; + return 0; } -static int opCMPXCHG8B_a32(uint32_t fetchdat) +static int +opCMPXCHG8B_a32(uint32_t fetchdat) { - uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX; - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); - temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - if (EAX == temp && EDX == temp_hi) - { - seteal(EBX); - writememl(easeg, cpu_state.eaaddr+4, ECX); - } - else - { - EAX = temp; - EDX = temp_hi; - } - if (cpu_state.abrt) return 0; - flags_rebuild(); - if (temp == temp2 && temp_hi == temp2_hi) - cpu_state.flags |= Z_FLAG; - else - cpu_state.flags &= ~Z_FLAG; - cycles -= (cpu_mod == 3) ? 6 : 10; + uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX; + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) return 0; + if (EAX == temp && EDX == temp_hi) { + seteal(EBX); + writememl(easeg, cpu_state.eaaddr + 4, ECX); + } else { + EAX = temp; + EDX = temp_hi; + } + if (cpu_state.abrt) + return 0; + flags_rebuild(); + if (temp == temp2 && temp_hi == temp2_hi) + cpu_state.flags |= Z_FLAG; + else + cpu_state.flags &= ~Z_FLAG; + cycles -= (cpu_mod == 3) ? 6 : 10; + return 0; } /* dest = eab, src = r8 */ -static int opXADD_b_a16(uint32_t fetchdat) +static int +opXADD_b_a16(uint32_t fetchdat) { - uint8_t temp; - uint8_t src, dest; - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getr8(cpu_reg); - dest = geteab(); if (cpu_state.abrt) return 1; - temp = src + dest; - seteab(temp); if (cpu_state.abrt) return 1; - setadd8(src, dest); - setr8(cpu_reg, dest); - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; + uint8_t temp; + uint8_t src, dest; + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getr8(cpu_reg); + dest = geteab(); + if (cpu_state.abrt) + return 1; + temp = src + dest; + seteab(temp); + if (cpu_state.abrt) + return 1; + setadd8(src, dest); + setr8(cpu_reg, dest); + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); + return 0; } -static int opXADD_b_a32(uint32_t fetchdat) +static int +opXADD_b_a32(uint32_t fetchdat) { - uint8_t temp; - uint8_t src, dest; - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getr8(cpu_reg); - dest = geteab(); if (cpu_state.abrt) return 1; - temp = src + dest; - seteab(temp); if (cpu_state.abrt) return 1; - setadd8(src, dest); - setr8(cpu_reg, dest); - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; + uint8_t temp; + uint8_t src, dest; + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getr8(cpu_reg); + dest = geteab(); + if (cpu_state.abrt) + return 1; + temp = src + dest; + seteab(temp); + if (cpu_state.abrt) + return 1; + setadd8(src, dest); + setr8(cpu_reg, dest); + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); + return 0; } -static int opXADD_w_a16(uint32_t fetchdat) +static int +opXADD_w_a16(uint32_t fetchdat) { - uint16_t temp; - uint16_t src, dest; - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = cpu_state.regs[cpu_reg].w; - dest = geteaw(); if (cpu_state.abrt) return 1; - temp = src + dest; - seteaw(temp); if (cpu_state.abrt) return 1; - setadd16(src, dest); - cpu_state.regs[cpu_reg].w = dest; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; + uint16_t temp; + uint16_t src, dest; + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = cpu_state.regs[cpu_reg].w; + dest = geteaw(); + if (cpu_state.abrt) + return 1; + temp = src + dest; + seteaw(temp); + if (cpu_state.abrt) + return 1; + setadd16(src, dest); + cpu_state.regs[cpu_reg].w = dest; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); + return 0; } -static int opXADD_w_a32(uint32_t fetchdat) +static int +opXADD_w_a32(uint32_t fetchdat) { - uint16_t temp; - uint16_t src, dest; - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = cpu_state.regs[cpu_reg].w; - dest = geteaw(); if (cpu_state.abrt) return 1; - temp = src + dest; - seteaw(temp); if (cpu_state.abrt) return 1; - setadd16(src, dest); - cpu_state.regs[cpu_reg].w = dest; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; + uint16_t temp; + uint16_t src, dest; + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = cpu_state.regs[cpu_reg].w; + dest = geteaw(); + if (cpu_state.abrt) + return 1; + temp = src + dest; + seteaw(temp); + if (cpu_state.abrt) + return 1; + setadd16(src, dest); + cpu_state.regs[cpu_reg].w = dest; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); + return 0; } -static int opXADD_l_a16(uint32_t fetchdat) +static int +opXADD_l_a16(uint32_t fetchdat) { - uint32_t temp; - uint32_t src, dest; - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = cpu_state.regs[cpu_reg].l; - dest = geteal(); if (cpu_state.abrt) return 1; - temp = src + dest; - seteal(temp); if (cpu_state.abrt) return 1; - setadd32(src, dest); - cpu_state.regs[cpu_reg].l = dest; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; + uint32_t temp; + uint32_t src, dest; + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = cpu_state.regs[cpu_reg].l; + dest = geteal(); + if (cpu_state.abrt) + return 1; + temp = src + dest; + seteal(temp); + if (cpu_state.abrt) + return 1; + setadd32(src, dest); + cpu_state.regs[cpu_reg].l = dest; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); + return 0; } -static int opXADD_l_a32(uint32_t fetchdat) +static int +opXADD_l_a32(uint32_t fetchdat) { - uint32_t temp; - uint32_t src, dest; - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = cpu_state.regs[cpu_reg].l; - dest = geteal(); if (cpu_state.abrt) return 1; - temp = src + dest; - seteal(temp); if (cpu_state.abrt) return 1; - setadd32(src, dest); - cpu_state.regs[cpu_reg].l = dest; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; + uint32_t temp; + uint32_t src, dest; + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = cpu_state.regs[cpu_reg].l; + dest = geteal(); + if (cpu_state.abrt) + return 1; + temp = src + dest; + seteal(temp); + if (cpu_state.abrt) + return 1; + setadd32(src, dest); + cpu_state.regs[cpu_reg].l = dest; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); + return 0; } diff --git a/src/cpu/x86_ops_bcd.h b/src/cpu/x86_ops_bcd.h index 385d63cd7..d3ff97ead 100644 --- a/src/cpu/x86_ops_bcd.h +++ b/src/cpu/x86_ops_bcd.h @@ -1,129 +1,130 @@ -static int opAAA(uint32_t fetchdat) +static int +opAAA(uint32_t fetchdat) { - flags_rebuild(); - if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) - { - /* On 286, it's indeed AX - behavior difference from 808x. */ - AX += 6; - AH++; - cpu_state.flags |= (A_FLAG | C_FLAG); - } - else - cpu_state.flags &= ~(A_FLAG | C_FLAG); - AL &= 0xF; - CLOCK_CYCLES(is486 ? 3 : 4); - PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0,0,0,0, 0); - return 0; + flags_rebuild(); + if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { + /* On 286, it's indeed AX - behavior difference from 808x. */ + AX += 6; + AH++; + cpu_state.flags |= (A_FLAG | C_FLAG); + } else + cpu_state.flags &= ~(A_FLAG | C_FLAG); + AL &= 0xF; + CLOCK_CYCLES(is486 ? 3 : 4); + PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opAAD(uint32_t fetchdat) +static int +opAAD(uint32_t fetchdat) { - int base = getbytef(); - if (!cpu_isintel) base = 10; - AL = (AH * base) + AL; - AH = 0; - setznp16(AX); - CLOCK_CYCLES((is486) ? 14 : 19); - PREFETCH_RUN(is486 ? 14 : 19, 2, -1, 0,0,0,0, 0); - return 0; + int base = getbytef(); + if (!cpu_isintel) + base = 10; + AL = (AH * base) + AL; + AH = 0; + setznp16(AX); + CLOCK_CYCLES((is486) ? 14 : 19); + PREFETCH_RUN(is486 ? 14 : 19, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opAAM(uint32_t fetchdat) +static int +opAAM(uint32_t fetchdat) { - int base = getbytef(); - if (!base || !cpu_isintel) base = 10; - AH = AL / base; - AL %= base; - setznp16(AX); - CLOCK_CYCLES((is486) ? 15 : 17); - PREFETCH_RUN(is486 ? 15 : 17, 2, -1, 0,0,0,0, 0); - return 0; + int base = getbytef(); + if (!base || !cpu_isintel) + base = 10; + AH = AL / base; + AL %= base; + setznp16(AX); + CLOCK_CYCLES((is486) ? 15 : 17); + PREFETCH_RUN(is486 ? 15 : 17, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opAAS(uint32_t fetchdat) +static int +opAAS(uint32_t fetchdat) { - flags_rebuild(); - if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) - { - /* On 286, it's indeed AX - behavior difference from 808x. */ - AX -= 6; - AH--; - cpu_state.flags |= (A_FLAG | C_FLAG); - } - else - cpu_state.flags &= ~(A_FLAG | C_FLAG); - AL &= 0xF; - CLOCK_CYCLES(is486 ? 3 : 4); - PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0,0,0,0, 0); - return 0; + flags_rebuild(); + if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { + /* On 286, it's indeed AX - behavior difference from 808x. */ + AX -= 6; + AH--; + cpu_state.flags |= (A_FLAG | C_FLAG); + } else + cpu_state.flags &= ~(A_FLAG | C_FLAG); + AL &= 0xF; + CLOCK_CYCLES(is486 ? 3 : 4); + PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opDAA(uint32_t fetchdat) +static int +opDAA(uint32_t fetchdat) { - uint16_t tempw, old_AL, old_CF; + uint16_t tempw, old_AL, old_CF; - flags_rebuild(); - old_AL = AL; - old_CF = cpu_state.flags & C_FLAG; - cpu_state.flags &= ~C_FLAG; + flags_rebuild(); + old_AL = AL; + old_CF = cpu_state.flags & C_FLAG; + cpu_state.flags &= ~C_FLAG; - if (((AL & 0xf) > 9) || (cpu_state.flags & A_FLAG)) { - int tempi = ((uint16_t)AL) + 6; - AL += 6; - if (old_CF || (tempi & 0x100)) - cpu_state.flags |= C_FLAG; - cpu_state.flags |= A_FLAG; - } else - cpu_state.flags &= ~A_FLAG; + if (((AL & 0xf) > 9) || (cpu_state.flags & A_FLAG)) { + int tempi = ((uint16_t) AL) + 6; + AL += 6; + if (old_CF || (tempi & 0x100)) + cpu_state.flags |= C_FLAG; + cpu_state.flags |= A_FLAG; + } else + cpu_state.flags &= ~A_FLAG; - if ((old_AL > 0x99) || old_CF) - { - AL += 0x60; - cpu_state.flags |= C_FLAG; - } else - cpu_state.flags &= ~C_FLAG; + if ((old_AL > 0x99) || old_CF) { + AL += 0x60; + cpu_state.flags |= C_FLAG; + } else + cpu_state.flags &= ~C_FLAG; - tempw = cpu_state.flags & (C_FLAG | A_FLAG); - setznp8(AL); - flags_rebuild(); - cpu_state.flags = (cpu_state.flags & ~(C_FLAG | A_FLAG)) | tempw; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,0,0, 0); + tempw = cpu_state.flags & (C_FLAG | A_FLAG); + setznp8(AL); + flags_rebuild(); + cpu_state.flags = (cpu_state.flags & ~(C_FLAG | A_FLAG)) | tempw; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 0, 0, 0); - return 0; + return 0; } -static int opDAS(uint32_t fetchdat) +static int +opDAS(uint32_t fetchdat) { - uint16_t tempw, old_AL, old_CF; + uint16_t tempw, old_AL, old_CF; - flags_rebuild(); - old_AL = AL; - old_CF = cpu_state.flags & C_FLAG; - cpu_state.flags &= ~C_FLAG; + flags_rebuild(); + old_AL = AL; + old_CF = cpu_state.flags & C_FLAG; + cpu_state.flags &= ~C_FLAG; - if (((AL & 0xf) > 9) || (cpu_state.flags & A_FLAG)) - { - int tempi = ((uint16_t)AL) - 6; - AL -= 6; - if (old_CF || (tempi & 0x100)) - cpu_state.flags |= C_FLAG; - cpu_state.flags |= A_FLAG; - } else - cpu_state.flags &= ~A_FLAG; + if (((AL & 0xf) > 9) || (cpu_state.flags & A_FLAG)) { + int tempi = ((uint16_t) AL) - 6; + AL -= 6; + if (old_CF || (tempi & 0x100)) + cpu_state.flags |= C_FLAG; + cpu_state.flags |= A_FLAG; + } else + cpu_state.flags &= ~A_FLAG; - if ((old_AL > 0x99) || old_CF) - { - AL -= 0x60; - cpu_state.flags |= C_FLAG; - } + if ((old_AL > 0x99) || old_CF) { + AL -= 0x60; + cpu_state.flags |= C_FLAG; + } - tempw = cpu_state.flags & (C_FLAG | A_FLAG); - setznp8(AL); - flags_rebuild(); - cpu_state.flags = (cpu_state.flags & ~(C_FLAG | A_FLAG)) | tempw; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,0,0, 0); + tempw = cpu_state.flags & (C_FLAG | A_FLAG); + setznp8(AL); + flags_rebuild(); + cpu_state.flags = (cpu_state.flags & ~(C_FLAG | A_FLAG)) | tempw; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 0, 0, 0); - return 0; + return 0; } diff --git a/src/cpu/x86_ops_bit.h b/src/cpu/x86_ops_bit.h index 4fc8ac0f7..8514e8e1c 100644 --- a/src/cpu/x86_ops_bit.h +++ b/src/cpu/x86_ops_bit.h @@ -1,328 +1,411 @@ -static int opBT_w_r_a16(uint32_t fetchdat) +static int +opBT_w_r_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0; - temp = geteaw(); if (cpu_state.abrt) return 1; - flags_rebuild(); - if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); + eal_r = 0; + temp = geteaw(); + if (cpu_state.abrt) + return 1; + flags_rebuild(); + if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, 1,0,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, 1, 0, 0, 0, 0); + return 0; } -static int opBT_w_r_a32(uint32_t fetchdat) +static int +opBT_w_r_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0; - temp = geteaw(); if (cpu_state.abrt) return 1; - flags_rebuild(); - if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); + eal_r = 0; + temp = geteaw(); + if (cpu_state.abrt) + return 1; + flags_rebuild(); + if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, 1,0,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, 1, 0, 0, 0, 1); + return 0; } -static int opBT_l_r_a16(uint32_t fetchdat) +static int +opBT_l_r_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0; - temp = geteal(); if (cpu_state.abrt) return 1; - flags_rebuild(); - if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); + eal_r = 0; + temp = geteal(); + if (cpu_state.abrt) + return 1; + flags_rebuild(); + if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, 0,1,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, 0, 1, 0, 0, 0); + return 0; } -static int opBT_l_r_a32(uint32_t fetchdat) +static int +opBT_l_r_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0; - temp = geteal(); if (cpu_state.abrt) return 1; - flags_rebuild(); - if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); + eal_r = 0; + temp = geteal(); + if (cpu_state.abrt) + return 1; + flags_rebuild(); + if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, 0,1,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, 0, 1, 0, 0, 1); + return 0; } -#define opBT(name, operation) \ - static int opBT ## name ## _w_r_a16(uint32_t fetchdat) \ - { \ - int tempc; \ - uint16_t temp; \ - \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = eal_w = 0; \ - temp = geteaw(); if (cpu_state.abrt) return 1; \ - tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \ - temp operation (1 << (cpu_state.regs[cpu_reg].w & 15)); \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - else cpu_state.flags &= ~C_FLAG; \ - \ - CLOCK_CYCLES(6); \ - PREFETCH_RUN(6, 2, rmdat, 1,0,1,0, 0); \ - return 0; \ - } \ - static int opBT ## name ## _w_r_a32(uint32_t fetchdat) \ - { \ - int tempc; \ - uint16_t temp; \ - \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = eal_w = 0; \ - temp = geteaw(); if (cpu_state.abrt) return 1; \ - tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \ - temp operation (1 << (cpu_state.regs[cpu_reg].w & 15)); \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - else cpu_state.flags &= ~C_FLAG; \ - \ - CLOCK_CYCLES(6); \ - PREFETCH_RUN(6, 2, rmdat, 1,0,1,0, 1); \ - return 0; \ - } \ - static int opBT ## name ## _l_r_a16(uint32_t fetchdat) \ - { \ - int tempc; \ - uint32_t temp; \ - \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = eal_w = 0; \ - temp = geteal(); if (cpu_state.abrt) return 1; \ - tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \ - temp operation (1 << (cpu_state.regs[cpu_reg].l & 31)); \ - seteal(temp); if (cpu_state.abrt) return 1; \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - else cpu_state.flags &= ~C_FLAG; \ - \ - CLOCK_CYCLES(6); \ - PREFETCH_RUN(6, 2, rmdat, 0,1,0,1, 0); \ - return 0; \ - } \ - static int opBT ## name ## _l_r_a32(uint32_t fetchdat) \ - { \ - int tempc; \ - uint32_t temp; \ - \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = eal_w = 0; \ - temp = geteal(); if (cpu_state.abrt) return 1; \ - tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \ - temp operation (1 << (cpu_state.regs[cpu_reg].l & 31)); \ - seteal(temp); if (cpu_state.abrt) return 1; \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - else cpu_state.flags &= ~C_FLAG; \ - \ - CLOCK_CYCLES(6); \ - PREFETCH_RUN(6, 2, rmdat, 0,1,0,1, 1); \ - return 0; \ - } +#define opBT(name, operation) \ + static int opBT##name##_w_r_a16(uint32_t fetchdat) \ + { \ + int tempc; \ + uint16_t temp; \ + \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); \ + eal_r = eal_w = 0; \ + temp = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \ + temp operation(1 << (cpu_state.regs[cpu_reg].w & 15)); \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + flags_rebuild(); \ + if (tempc) \ + cpu_state.flags |= C_FLAG; \ + else \ + cpu_state.flags &= ~C_FLAG; \ + \ + CLOCK_CYCLES(6); \ + PREFETCH_RUN(6, 2, rmdat, 1, 0, 1, 0, 0); \ + return 0; \ + } \ + static int opBT##name##_w_r_a32(uint32_t fetchdat) \ + { \ + int tempc; \ + uint16_t temp; \ + \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); \ + eal_r = eal_w = 0; \ + temp = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \ + temp operation(1 << (cpu_state.regs[cpu_reg].w & 15)); \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + flags_rebuild(); \ + if (tempc) \ + cpu_state.flags |= C_FLAG; \ + else \ + cpu_state.flags &= ~C_FLAG; \ + \ + CLOCK_CYCLES(6); \ + PREFETCH_RUN(6, 2, rmdat, 1, 0, 1, 0, 1); \ + return 0; \ + } \ + static int opBT##name##_l_r_a16(uint32_t fetchdat) \ + { \ + int tempc; \ + uint32_t temp; \ + \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); \ + eal_r = eal_w = 0; \ + temp = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \ + temp operation(1 << (cpu_state.regs[cpu_reg].l & 31)); \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + flags_rebuild(); \ + if (tempc) \ + cpu_state.flags |= C_FLAG; \ + else \ + cpu_state.flags &= ~C_FLAG; \ + \ + CLOCK_CYCLES(6); \ + PREFETCH_RUN(6, 2, rmdat, 0, 1, 0, 1, 0); \ + return 0; \ + } \ + static int opBT##name##_l_r_a32(uint32_t fetchdat) \ + { \ + int tempc; \ + uint32_t temp; \ + \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); \ + eal_r = eal_w = 0; \ + temp = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \ + temp operation(1 << (cpu_state.regs[cpu_reg].l & 31)); \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + flags_rebuild(); \ + if (tempc) \ + cpu_state.flags |= C_FLAG; \ + else \ + cpu_state.flags &= ~C_FLAG; \ + \ + CLOCK_CYCLES(6); \ + PREFETCH_RUN(6, 2, rmdat, 0, 1, 0, 1, 1); \ + return 0; \ + } opBT(C, ^=) -opBT(R, &=~) -opBT(S, |=) + opBT(R, &= ~) + opBT(S, |=) -static int opBA_w_a16(uint32_t fetchdat) + static int opBA_w_a16(uint32_t fetchdat) { - int tempc, count; - uint16_t temp; + int tempc, count; + uint16_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); - count = getbyte(); if (cpu_state.abrt) return 1; - tempc = temp & (1 << count); - flags_rebuild(); - switch (rmdat & 0x38) - { - case 0x20: /*BT w,imm*/ - if (tempc) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; - case 0x28: /*BTS w,imm*/ - temp |= (1 << count); - break; - case 0x30: /*BTR w,imm*/ - temp &= ~(1 << count); - break; - case 0x38: /*BTC w,imm*/ - temp ^= (1 << count); - break; + temp = geteaw(); + count = getbyte(); + if (cpu_state.abrt) + return 1; + tempc = temp & (1 << count); + flags_rebuild(); + switch (rmdat & 0x38) { + case 0x20: /*BT w,imm*/ + if (tempc) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; + case 0x28: /*BTS w,imm*/ + temp |= (1 << count); + break; + case 0x30: /*BTR w,imm*/ + temp &= ~(1 << count); + break; + case 0x38: /*BTC w,imm*/ + temp ^= (1 << count); + break; - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - seteaw(temp); if (cpu_state.abrt) return 1; - if (tempc) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - return 0; + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + seteaw(temp); + if (cpu_state.abrt) + return 1; + if (tempc) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + return 0; } -static int opBA_w_a32(uint32_t fetchdat) +static int +opBA_w_a32(uint32_t fetchdat) { - int tempc, count; - uint16_t temp; + int tempc, count; + uint16_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); - count = getbyte(); if (cpu_state.abrt) return 1; - tempc = temp & (1 << count); - flags_rebuild(); - switch (rmdat & 0x38) - { - case 0x20: /*BT w,imm*/ - if (tempc) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; - case 0x28: /*BTS w,imm*/ - temp |= (1 << count); - break; - case 0x30: /*BTR w,imm*/ - temp &= ~(1 << count); - break; - case 0x38: /*BTC w,imm*/ - temp ^= (1 << count); - break; + temp = geteaw(); + count = getbyte(); + if (cpu_state.abrt) + return 1; + tempc = temp & (1 << count); + flags_rebuild(); + switch (rmdat & 0x38) { + case 0x20: /*BT w,imm*/ + if (tempc) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; + case 0x28: /*BTS w,imm*/ + temp |= (1 << count); + break; + case 0x30: /*BTR w,imm*/ + temp &= ~(1 << count); + break; + case 0x38: /*BTC w,imm*/ + temp ^= (1 << count); + break; - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - seteaw(temp); if (cpu_state.abrt) return 1; - if (tempc) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - return 0; + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + seteaw(temp); + if (cpu_state.abrt) + return 1; + if (tempc) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + return 0; } -static int opBA_l_a16(uint32_t fetchdat) +static int +opBA_l_a16(uint32_t fetchdat) { - int tempc, count; - uint32_t temp; + int tempc, count; + uint32_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); - count = getbyte(); if (cpu_state.abrt) return 1; - tempc = temp & (1 << count); - flags_rebuild(); - switch (rmdat & 0x38) - { - case 0x20: /*BT w,imm*/ - if (tempc) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - return 0; - case 0x28: /*BTS w,imm*/ - temp |= (1 << count); - break; - case 0x30: /*BTR w,imm*/ - temp &= ~(1 << count); - break; - case 0x38: /*BTC w,imm*/ - temp ^= (1 << count); - break; + temp = geteal(); + count = getbyte(); + if (cpu_state.abrt) + return 1; + tempc = temp & (1 << count); + flags_rebuild(); + switch (rmdat & 0x38) { + case 0x20: /*BT w,imm*/ + if (tempc) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + return 0; + case 0x28: /*BTS w,imm*/ + temp |= (1 << count); + break; + case 0x30: /*BTR w,imm*/ + temp &= ~(1 << count); + break; + case 0x38: /*BTC w,imm*/ + temp ^= (1 << count); + break; - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - seteal(temp); if (cpu_state.abrt) return 1; - if (tempc) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - return 0; + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + seteal(temp); + if (cpu_state.abrt) + return 1; + if (tempc) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + return 0; } -static int opBA_l_a32(uint32_t fetchdat) +static int +opBA_l_a32(uint32_t fetchdat) { - int tempc, count; - uint32_t temp; + int tempc, count; + uint32_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); - count = getbyte(); if (cpu_state.abrt) return 1; - tempc = temp & (1 << count); - flags_rebuild(); - switch (rmdat & 0x38) - { - case 0x20: /*BT w,imm*/ - if (tempc) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - return 0; - case 0x28: /*BTS w,imm*/ - temp |= (1 << count); - break; - case 0x30: /*BTR w,imm*/ - temp &= ~(1 << count); - break; - case 0x38: /*BTC w,imm*/ - temp ^= (1 << count); - break; + temp = geteal(); + count = getbyte(); + if (cpu_state.abrt) + return 1; + tempc = temp & (1 << count); + flags_rebuild(); + switch (rmdat & 0x38) { + case 0x20: /*BT w,imm*/ + if (tempc) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + return 0; + case 0x28: /*BTS w,imm*/ + temp |= (1 << count); + break; + case 0x30: /*BTR w,imm*/ + temp &= ~(1 << count); + break; + case 0x38: /*BTC w,imm*/ + temp ^= (1 << count); + break; - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - seteal(temp); if (cpu_state.abrt) return 1; - if (tempc) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - return 0; + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + seteal(temp); + if (cpu_state.abrt) + return 1; + if (tempc) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + return 0; } diff --git a/src/cpu/x86_ops_bitscan.h b/src/cpu/x86_ops_bitscan.h index af87a545d..358131c1e 100644 --- a/src/cpu/x86_ops_bitscan.h +++ b/src/cpu/x86_ops_bitscan.h @@ -1,211 +1,227 @@ #ifdef IS_DYNAREC -#define BS_common(start, end, dir, dest, time) \ - flags_rebuild(); \ - if (temp) \ - { \ - int c; \ - cpu_state.flags &= ~Z_FLAG; \ - for (c = start; c != end; c += dir) \ - { \ - CLOCK_CYCLES(time); \ - if (temp & (1 << c)) \ - { \ - dest = c; \ - break; \ - } \ - } \ - } \ - else \ - cpu_state.flags |= Z_FLAG; +# define BS_common(start, end, dir, dest, time) \ + flags_rebuild(); \ + if (temp) { \ + int c; \ + cpu_state.flags &= ~Z_FLAG; \ + for (c = start; c != end; c += dir) { \ + CLOCK_CYCLES(time); \ + if (temp & (1 << c)) { \ + dest = c; \ + break; \ + } \ + } \ + } else \ + cpu_state.flags |= Z_FLAG; #else -#define BS_common(start, end, dir, dest, time) \ - flags_rebuild(); \ - instr_cycles = 0; \ - if (temp) \ - { \ - int c; \ - cpu_state.flags &= ~Z_FLAG; \ - for (c = start; c != end; c += dir) \ - { \ - CLOCK_CYCLES(time); \ - instr_cycles += time; \ - if (temp & (1 << c)) \ - { \ - dest = c; \ - break; \ - } \ - } \ - } \ - else \ - cpu_state.flags |= Z_FLAG; +# define BS_common(start, end, dir, dest, time) \ + flags_rebuild(); \ + instr_cycles = 0; \ + if (temp) { \ + int c; \ + cpu_state.flags &= ~Z_FLAG; \ + for (c = start; c != end; c += dir) { \ + CLOCK_CYCLES(time); \ + instr_cycles += time; \ + if (temp & (1 << c)) { \ + dest = c; \ + break; \ + } \ + } \ + } else \ + cpu_state.flags |= Z_FLAG; #endif -static int opBSF_w_a16(uint32_t fetchdat) +static int +opBSF_w_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; #ifndef IS_DYNAREC - int instr_cycles = 0; + int instr_cycles = 0; #endif - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; - BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3); + BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3); - CLOCK_CYCLES((is486) ? 6 : 10); + CLOCK_CYCLES((is486) ? 6 : 10); #ifndef IS_DYNAREC - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); + instr_cycles += ((is486) ? 6 : 10); + PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); #endif - return 0; + return 0; } -static int opBSF_w_a32(uint32_t fetchdat) +static int +opBSF_w_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; #ifndef IS_DYNAREC - int instr_cycles = 0; + int instr_cycles = 0; #endif - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; - BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3); + BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3); - CLOCK_CYCLES((is486) ? 6 : 10); + CLOCK_CYCLES((is486) ? 6 : 10); #ifndef IS_DYNAREC - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); + instr_cycles += ((is486) ? 6 : 10); + PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); #endif - return 0; + return 0; } -static int opBSF_l_a16(uint32_t fetchdat) +static int +opBSF_l_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; #ifndef IS_DYNAREC - int instr_cycles = 0; + int instr_cycles = 0; #endif - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; - BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3); + BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3); - CLOCK_CYCLES((is486) ? 6 : 10); + CLOCK_CYCLES((is486) ? 6 : 10); #ifndef IS_DYNAREC - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); + instr_cycles += ((is486) ? 6 : 10); + PREFETCH_RUN(instr_cycles, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); #endif - return 0; + return 0; } -static int opBSF_l_a32(uint32_t fetchdat) +static int +opBSF_l_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; #ifndef IS_DYNAREC - int instr_cycles = 0; + int instr_cycles = 0; #endif - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; - BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3); + BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3); - CLOCK_CYCLES((is486) ? 6 : 10); + CLOCK_CYCLES((is486) ? 6 : 10); #ifndef IS_DYNAREC - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); + instr_cycles += ((is486) ? 6 : 10); + PREFETCH_RUN(instr_cycles, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); #endif - return 0; + return 0; } -static int opBSR_w_a16(uint32_t fetchdat) +static int +opBSR_w_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; #ifndef IS_DYNAREC - int instr_cycles = 0; + int instr_cycles = 0; #endif - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; - BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3); + BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3); - CLOCK_CYCLES((is486) ? 6 : 10); + CLOCK_CYCLES((is486) ? 6 : 10); #ifndef IS_DYNAREC - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); + instr_cycles += ((is486) ? 6 : 10); + PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); #endif - return 0; + return 0; } -static int opBSR_w_a32(uint32_t fetchdat) +static int +opBSR_w_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; #ifndef IS_DYNAREC - int instr_cycles = 0; + int instr_cycles = 0; #endif - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; - BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3); + BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3); - CLOCK_CYCLES((is486) ? 6 : 10); + CLOCK_CYCLES((is486) ? 6 : 10); #ifndef IS_DYNAREC - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); + instr_cycles += ((is486) ? 6 : 10); + PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); #endif - return 0; + return 0; } -static int opBSR_l_a16(uint32_t fetchdat) +static int +opBSR_l_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; #ifndef IS_DYNAREC - int instr_cycles = 0; + int instr_cycles = 0; #endif - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; - BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3); + BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3); - CLOCK_CYCLES((is486) ? 6 : 10); + CLOCK_CYCLES((is486) ? 6 : 10); #ifndef IS_DYNAREC - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); + instr_cycles += ((is486) ? 6 : 10); + PREFETCH_RUN(instr_cycles, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); #endif - return 0; + return 0; } -static int opBSR_l_a32(uint32_t fetchdat) +static int +opBSR_l_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; #ifndef IS_DYNAREC - int instr_cycles = 0; + int instr_cycles = 0; #endif - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; - BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3); + BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3); - CLOCK_CYCLES((is486) ? 6 : 10); + CLOCK_CYCLES((is486) ? 6 : 10); #ifndef IS_DYNAREC - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); + instr_cycles += ((is486) ? 6 : 10); + PREFETCH_RUN(instr_cycles, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); #endif - return 0; + return 0; } diff --git a/src/cpu/x86_ops_call.h b/src/cpu/x86_ops_call.h index ecd50f107..88899cef8 100644 --- a/src/cpu/x86_ops_call.h +++ b/src/cpu/x86_ops_call.h @@ -1,627 +1,879 @@ #ifdef USE_NEW_DYNAREC -#define CALL_FAR_w(new_seg, new_pc) \ - old_cs = CS; \ - old_pc = cpu_state.pc; \ - cpu_state.pc = new_pc; \ - optype = CALL; \ - cgate16 = cgate32 = 0; \ - if (msw & 1) loadcscall(new_seg, old_pc); \ - else \ - { \ - loadcs(new_seg); \ - cycles -= timing_call_rm; \ - } \ - optype = 0; \ - if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - oldss = ss; \ - if (cgate32) \ - { \ - uint32_t old_esp = ESP; \ - PUSH_L(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } \ - PUSH_L(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ - } \ - else \ - { \ - uint32_t old_esp = ESP; \ - PUSH_W(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } \ - PUSH_W(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ +# define CALL_FAR_w(new_seg, new_pc) \ + old_cs = CS; \ + old_pc = cpu_state.pc; \ + cpu_state.pc = new_pc; \ + optype = CALL; \ + cgate16 = cgate32 = 0; \ + if (msw & 1) \ + loadcscall(new_seg, old_pc); \ + else { \ + loadcs(new_seg); \ + cycles -= timing_call_rm; \ + } \ + optype = 0; \ + if (cpu_state.abrt) { \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + oldss = ss; \ + if (cgate32) { \ + uint32_t old_esp = ESP; \ + PUSH_L(old_cs); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_L(old_pc); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + ESP = old_esp; \ + return 1; \ + } \ + } else { \ + uint32_t old_esp = ESP; \ + PUSH_W(old_cs); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_W(old_pc); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + ESP = old_esp; \ + return 1; \ + } \ } -#define CALL_FAR_l(new_seg, new_pc) \ - old_cs = CS; \ - old_pc = cpu_state.pc; \ - cpu_state.pc = new_pc; \ - optype = CALL; \ - cgate16 = cgate32 = 0; \ - if (msw & 1) loadcscall(new_seg, old_pc); \ - else \ - { \ - loadcs(new_seg); \ - cycles -= timing_call_rm; \ - } \ - optype = 0; \ - if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - oldss = ss; \ - if (cgate16) \ - { \ - uint32_t old_esp = ESP; \ - PUSH_W(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } \ - PUSH_W(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ - } \ - else \ - { \ - uint32_t old_esp = ESP; \ - PUSH_L(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } \ - PUSH_L(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ +# define CALL_FAR_l(new_seg, new_pc) \ + old_cs = CS; \ + old_pc = cpu_state.pc; \ + cpu_state.pc = new_pc; \ + optype = CALL; \ + cgate16 = cgate32 = 0; \ + if (msw & 1) \ + loadcscall(new_seg, old_pc); \ + else { \ + loadcs(new_seg); \ + cycles -= timing_call_rm; \ + } \ + optype = 0; \ + if (cpu_state.abrt) { \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + oldss = ss; \ + if (cgate16) { \ + uint32_t old_esp = ESP; \ + PUSH_W(old_cs); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_W(old_pc); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + ESP = old_esp; \ + return 1; \ + } \ + } else { \ + uint32_t old_esp = ESP; \ + PUSH_L(old_cs); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_L(old_pc); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + ESP = old_esp; \ + return 1; \ + } \ } #else -#define CALL_FAR_w(new_seg, new_pc) \ - old_cs = CS; \ - old_pc = cpu_state.pc; \ - oxpc = cpu_state.pc; \ - cpu_state.pc = new_pc; \ - optype = CALL; \ - cgate16 = cgate32 = 0; \ - if (msw & 1) loadcscall(new_seg); \ - else \ - { \ - loadcs(new_seg); \ - cycles -= timing_call_rm; \ - } \ - optype = 0; \ - if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - oldss = ss; \ - if (cgate32) \ - { \ - uint32_t old_esp = ESP; \ - PUSH_L(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - PUSH_L(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ - } \ - else \ - { \ - uint32_t old_esp = ESP; \ - PUSH_W(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - PUSH_W(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ +# define CALL_FAR_w(new_seg, new_pc) \ + old_cs = CS; \ + old_pc = cpu_state.pc; \ + oxpc = cpu_state.pc; \ + cpu_state.pc = new_pc; \ + optype = CALL; \ + cgate16 = cgate32 = 0; \ + if (msw & 1) \ + loadcscall(new_seg); \ + else { \ + loadcs(new_seg); \ + cycles -= timing_call_rm; \ + } \ + optype = 0; \ + if (cpu_state.abrt) { \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + oldss = ss; \ + if (cgate32) { \ + uint32_t old_esp = ESP; \ + PUSH_L(old_cs); \ + if (cpu_state.abrt) { \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_L(old_pc); \ + if (cpu_state.abrt) { \ + ESP = old_esp; \ + return 1; \ + } \ + } else { \ + uint32_t old_esp = ESP; \ + PUSH_W(old_cs); \ + if (cpu_state.abrt) { \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_W(old_pc); \ + if (cpu_state.abrt) { \ + ESP = old_esp; \ + return 1; \ + } \ } -#define CALL_FAR_l(new_seg, new_pc) \ - old_cs = CS; \ - old_pc = cpu_state.pc; \ - oxpc = cpu_state.pc; \ - cpu_state.pc = new_pc; \ - optype = CALL; \ - cgate16 = cgate32 = 0; \ - if (msw & 1) loadcscall(new_seg); \ - else \ - { \ - loadcs(new_seg); \ - cycles -= timing_call_rm; \ - } \ - optype = 0; \ - if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - oldss = ss; \ - if (cgate16) \ - { \ - uint32_t old_esp = ESP; \ - PUSH_W(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - PUSH_W(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ - } \ - else \ - { \ - uint32_t old_esp = ESP; \ - PUSH_L(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - PUSH_L(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ +# define CALL_FAR_l(new_seg, new_pc) \ + old_cs = CS; \ + old_pc = cpu_state.pc; \ + oxpc = cpu_state.pc; \ + cpu_state.pc = new_pc; \ + optype = CALL; \ + cgate16 = cgate32 = 0; \ + if (msw & 1) \ + loadcscall(new_seg); \ + else { \ + loadcs(new_seg); \ + cycles -= timing_call_rm; \ + } \ + optype = 0; \ + if (cpu_state.abrt) { \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + oldss = ss; \ + if (cgate16) { \ + uint32_t old_esp = ESP; \ + PUSH_W(old_cs); \ + if (cpu_state.abrt) { \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_W(old_pc); \ + if (cpu_state.abrt) { \ + ESP = old_esp; \ + return 1; \ + } \ + } else { \ + uint32_t old_esp = ESP; \ + PUSH_L(old_cs); \ + if (cpu_state.abrt) { \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_L(old_pc); \ + if (cpu_state.abrt) { \ + ESP = old_esp; \ + return 1; \ + } \ } #endif - -static int opCALL_far_w(uint32_t fetchdat) +static int +opCALL_far_w(uint32_t fetchdat) { - uint32_t old_cs, old_pc; - uint16_t new_cs, new_pc; - int cycles_old = cycles; UN_USED(cycles_old); + uint32_t old_cs, old_pc; + uint16_t new_cs, new_pc; + int cycles_old = cycles; + UN_USED(cycles_old); - new_pc = getwordf(); - new_cs = getword(); if (cpu_state.abrt) return 1; + new_pc = getwordf(); + new_cs = getword(); + if (cpu_state.abrt) + return 1; - CALL_FAR_w(new_cs, new_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 5, -1, 0,0,cgate16 ? 2:0,cgate16 ? 0:2, 0); - PREFETCH_FLUSH(); + CALL_FAR_w(new_cs, new_pc); + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 5, -1, 0, 0, cgate16 ? 2 : 0, cgate16 ? 0 : 2, 0); + PREFETCH_FLUSH(); - return 0; + return 0; } -static int opCALL_far_l(uint32_t fetchdat) +static int +opCALL_far_l(uint32_t fetchdat) { - uint32_t old_cs, old_pc; - uint32_t new_cs, new_pc; - int cycles_old = cycles; UN_USED(cycles_old); + uint32_t old_cs, old_pc; + uint32_t new_cs, new_pc; + int cycles_old = cycles; + UN_USED(cycles_old); - new_pc = getlong(); - new_cs = getword(); if (cpu_state.abrt) return 1; + new_pc = getlong(); + new_cs = getword(); + if (cpu_state.abrt) + return 1; - CALL_FAR_l(new_cs, new_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 7, -1, 0,0,cgate16 ? 2:0,cgate16 ? 0:2, 0); - PREFETCH_FLUSH(); + CALL_FAR_l(new_cs, new_pc); + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 7, -1, 0, 0, cgate16 ? 2 : 0, cgate16 ? 0 : 2, 0); + PREFETCH_FLUSH(); - return 0; + return 0; } - -static int opFF_w_a16(uint32_t fetchdat) +static int +opFF_w_a16(uint32_t fetchdat) { - uint16_t old_cs, new_cs; - uint32_t old_pc, new_pc; - int cycles_old = cycles; UN_USED(cycles_old); + uint16_t old_cs, new_cs; + uint32_t old_pc, new_pc; + int cycles_old = cycles; + UN_USED(cycles_old); - uint16_t temp; + uint16_t temp; - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); - switch (rmdat & 0x38) - { - case 0x00: /*INC w*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - temp = geteaw(); if (cpu_state.abrt) return 1; - if (cpu_mod != 3) { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - seteaw(temp + 1); if (cpu_state.abrt) return 1; - setadd16nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - break; - case 0x08: /*DEC w*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - temp = geteaw(); if (cpu_state.abrt) return 1; - if (cpu_mod != 3) { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - seteaw(temp - 1); if (cpu_state.abrt) return 1; - setsub16nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - break; - case 0x10: /*CALL*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - new_pc = geteaw(); if (cpu_state.abrt) return 1; - PUSH_W(cpu_state.pc); - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) { CLOCK_CYCLES(5); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } - PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 0); - PREFETCH_FLUSH(); - break; - case 0x18: /*CALL far*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - new_pc = readmemw(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, (cpu_state.eaaddr + 2)); if (cpu_state.abrt) return 1; + switch (rmdat & 0x38) { + case 0x00: /*INC w*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + temp = geteaw(); + if (cpu_state.abrt) + return 1; + if (cpu_mod != 3) { + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + seteaw(temp + 1); + if (cpu_state.abrt) + return 1; + setadd16nc(temp, 1); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + break; + case 0x08: /*DEC w*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + temp = geteaw(); + if (cpu_state.abrt) + return 1; + if (cpu_mod != 3) { + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + seteaw(temp - 1); + if (cpu_state.abrt) + return 1; + setsub16nc(temp, 1); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + break; + case 0x10: /*CALL*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + new_pc = geteaw(); + if (cpu_state.abrt) + return 1; + PUSH_W(cpu_state.pc); + cpu_state.pc = new_pc; + CPU_BLOCK_END(); + if (is486) { + CLOCK_CYCLES(5); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + } + PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 1, 0, 0); + PREFETCH_FLUSH(); + break; + case 0x18: /*CALL far*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + new_pc = readmemw(easeg, cpu_state.eaaddr); + new_cs = readmemw(easeg, (cpu_state.eaaddr + 2)); + if (cpu_state.abrt) + return 1; - CALL_FAR_w(new_cs, new_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 2,0,cgate16 ? 2:0,cgate16 ? 0:2, 0); - PREFETCH_FLUSH(); - break; - case 0x20: /*JMP*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - new_pc = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) { CLOCK_CYCLES(5); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } - PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - PREFETCH_FLUSH(); - break; - case 0x28: /*JMP far*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } + CALL_FAR_w(new_cs, new_pc); + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 2, 0, cgate16 ? 2 : 0, cgate16 ? 0 : 2, 0); + PREFETCH_FLUSH(); + break; + case 0x20: /*JMP*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + new_pc = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; + CPU_BLOCK_END(); + if (is486) { + CLOCK_CYCLES(5); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + } + PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + PREFETCH_FLUSH(); + break; + case 0x28: /*JMP far*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } #ifdef USE_NEW_DYNAREC - old_pc = cpu_state.pc; + old_pc = cpu_state.pc; #else - oxpc = cpu_state.pc; + oxpc = cpu_state.pc; #endif - new_pc = readmemw(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; + new_pc = readmemw(easeg, cpu_state.eaaddr); + new_cs = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; #ifdef USE_NEW_DYNAREC - loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, old_pc); + if (cpu_state.abrt) + return 1; #else - loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, oxpc); + if (cpu_state.abrt) + return 1; #endif - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 2,0,0,0, 0); - PREFETCH_FLUSH(); - break; - case 0x30: /*PUSH w*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - temp = geteaw(); if (cpu_state.abrt) return 1; - PUSH_W(temp); - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 0); - break; + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + break; + case 0x30: /*PUSH w*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + temp = geteaw(); + if (cpu_state.abrt) + return 1; + PUSH_W(temp); + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 1, 0, 0); + break; - default: -// fatal("Bad FF opcode %02X\n",rmdat&0x38); - x86illegal(); - } - return cpu_state.abrt; + default: + // fatal("Bad FF opcode %02X\n",rmdat&0x38); + x86illegal(); + } + return cpu_state.abrt; } -static int opFF_w_a32(uint32_t fetchdat) +static int +opFF_w_a32(uint32_t fetchdat) { - uint16_t old_cs, new_cs; - uint32_t old_pc, new_pc; - int cycles_old = cycles; UN_USED(cycles_old); + uint16_t old_cs, new_cs; + uint32_t old_pc, new_pc; + int cycles_old = cycles; + UN_USED(cycles_old); - uint16_t temp; + uint16_t temp; - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); - switch (rmdat & 0x38) - { - case 0x00: /*INC w*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - temp = geteaw(); if (cpu_state.abrt) return 1; - if (cpu_mod != 3) { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - seteaw(temp + 1); if (cpu_state.abrt) return 1; - setadd16nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - break; - case 0x08: /*DEC w*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - temp = geteaw(); if (cpu_state.abrt) return 1; - if (cpu_mod != 3) { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - seteaw(temp - 1); if (cpu_state.abrt) return 1; - setsub16nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - break; - case 0x10: /*CALL*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - new_pc = geteaw(); if (cpu_state.abrt) return 1; - PUSH_W(cpu_state.pc); - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) { CLOCK_CYCLES(5); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } - PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 1); - PREFETCH_FLUSH(); - break; - case 0x18: /*CALL far*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - new_pc = readmemw(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, (cpu_state.eaaddr + 2)); if (cpu_state.abrt) return 1; + switch (rmdat & 0x38) { + case 0x00: /*INC w*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + temp = geteaw(); + if (cpu_state.abrt) + return 1; + if (cpu_mod != 3) { + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + seteaw(temp + 1); + if (cpu_state.abrt) + return 1; + setadd16nc(temp, 1); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + break; + case 0x08: /*DEC w*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + temp = geteaw(); + if (cpu_state.abrt) + return 1; + if (cpu_mod != 3) { + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + seteaw(temp - 1); + if (cpu_state.abrt) + return 1; + setsub16nc(temp, 1); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + break; + case 0x10: /*CALL*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + new_pc = geteaw(); + if (cpu_state.abrt) + return 1; + PUSH_W(cpu_state.pc); + cpu_state.pc = new_pc; + CPU_BLOCK_END(); + if (is486) { + CLOCK_CYCLES(5); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + } + PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 1, 0, 1); + PREFETCH_FLUSH(); + break; + case 0x18: /*CALL far*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + new_pc = readmemw(easeg, cpu_state.eaaddr); + new_cs = readmemw(easeg, (cpu_state.eaaddr + 2)); + if (cpu_state.abrt) + return 1; - CALL_FAR_w(new_cs, new_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 2,0,cgate16 ? 2:0,cgate16 ? 0:2, 1); - PREFETCH_FLUSH(); - break; - case 0x20: /*JMP*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - new_pc = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) { CLOCK_CYCLES(5); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,0,0,0, 1); - PREFETCH_FLUSH(); - break; - case 0x28: /*JMP far*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } + CALL_FAR_w(new_cs, new_pc); + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 2, 0, cgate16 ? 2 : 0, cgate16 ? 0 : 2, 1); + PREFETCH_FLUSH(); + break; + case 0x20: /*JMP*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + new_pc = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; + CPU_BLOCK_END(); + if (is486) { + CLOCK_CYCLES(5); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + } + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 0, 0, 0, 1); + PREFETCH_FLUSH(); + break; + case 0x28: /*JMP far*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } #ifdef USE_NEW_DYNAREC - old_pc = cpu_state.pc; + old_pc = cpu_state.pc; #else - oxpc = cpu_state.pc; + oxpc = cpu_state.pc; #endif - new_pc = readmemw(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; + new_pc = readmemw(easeg, cpu_state.eaaddr); + new_cs = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; #ifdef USE_NEW_DYNAREC - loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, old_pc); + if (cpu_state.abrt) + return 1; #else - loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, oxpc); + if (cpu_state.abrt) + return 1; #endif - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 2,0,0,0, 1); - PREFETCH_FLUSH(); - break; - case 0x30: /*PUSH w*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - temp = geteaw(); if (cpu_state.abrt) return 1; - PUSH_W(temp); - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 1); - break; + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 2, 0, 0, 0, 1); + PREFETCH_FLUSH(); + break; + case 0x30: /*PUSH w*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + temp = geteaw(); + if (cpu_state.abrt) + return 1; + PUSH_W(temp); + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 1, 0, 1); + break; - default: -// fatal("Bad FF opcode %02X\n",rmdat&0x38); - x86illegal(); - } - return cpu_state.abrt; + default: + // fatal("Bad FF opcode %02X\n",rmdat&0x38); + x86illegal(); + } + return cpu_state.abrt; } -static int opFF_l_a16(uint32_t fetchdat) +static int +opFF_l_a16(uint32_t fetchdat) { - uint16_t old_cs, new_cs; - uint32_t old_pc, new_pc; - int cycles_old = cycles; UN_USED(cycles_old); + uint16_t old_cs, new_cs; + uint32_t old_pc, new_pc; + int cycles_old = cycles; + UN_USED(cycles_old); - uint32_t temp; + uint32_t temp; - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); - switch (rmdat & 0x38) - { - case 0x00: /*INC l*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - temp = geteal(); if (cpu_state.abrt) return 1; - if (cpu_mod != 3) { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - seteal(temp + 1); if (cpu_state.abrt) return 1; - setadd32nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - break; - case 0x08: /*DEC l*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - temp = geteal(); if (cpu_state.abrt) return 1; - if (cpu_mod != 3) { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - seteal(temp - 1); if (cpu_state.abrt) return 1; - setsub32nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - break; - case 0x10: /*CALL*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - new_pc = geteal(); if (cpu_state.abrt) return 1; - PUSH_L(cpu_state.pc); - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) { CLOCK_CYCLES(5); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } - PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 0); - PREFETCH_FLUSH(); - break; - case 0x18: /*CALL far*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5UL); - } - new_pc = readmeml(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, (cpu_state.eaaddr + 4)); if (cpu_state.abrt) return 1; + switch (rmdat & 0x38) { + case 0x00: /*INC l*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + temp = geteal(); + if (cpu_state.abrt) + return 1; + if (cpu_mod != 3) { + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + seteal(temp + 1); + if (cpu_state.abrt) + return 1; + setadd32nc(temp, 1); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + break; + case 0x08: /*DEC l*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + temp = geteal(); + if (cpu_state.abrt) + return 1; + if (cpu_mod != 3) { + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + seteal(temp - 1); + if (cpu_state.abrt) + return 1; + setsub32nc(temp, 1); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + break; + case 0x10: /*CALL*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + new_pc = geteal(); + if (cpu_state.abrt) + return 1; + PUSH_L(cpu_state.pc); + cpu_state.pc = new_pc; + CPU_BLOCK_END(); + if (is486) { + CLOCK_CYCLES(5); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + } + PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 1, 0); + PREFETCH_FLUSH(); + break; + case 0x18: /*CALL far*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5UL); + } + new_pc = readmeml(easeg, cpu_state.eaaddr); + new_cs = readmemw(easeg, (cpu_state.eaaddr + 4)); + if (cpu_state.abrt) + return 1; - CALL_FAR_l(new_cs, new_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,cgate16 ? 2:0,cgate16 ? 0:2, 0); - PREFETCH_FLUSH(); - break; - case 0x20: /*JMP*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - new_pc = geteal(); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) { CLOCK_CYCLES(5); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 0,1,0,0, 0); - PREFETCH_FLUSH(); - break; - case 0x28: /*JMP far*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5UL); - } + CALL_FAR_l(new_cs, new_pc); + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 1, cgate16 ? 2 : 0, cgate16 ? 0 : 2, 0); + PREFETCH_FLUSH(); + break; + case 0x20: /*JMP*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + new_pc = geteal(); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; + CPU_BLOCK_END(); + if (is486) { + CLOCK_CYCLES(5); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + } + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 0, 1, 0, 0, 0); + PREFETCH_FLUSH(); + break; + case 0x28: /*JMP far*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5UL); + } #ifdef USE_NEW_DYNAREC - old_pc = cpu_state.pc; + old_pc = cpu_state.pc; #else - oxpc = cpu_state.pc; + oxpc = cpu_state.pc; #endif - new_pc = readmeml(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; + new_pc = readmeml(easeg, cpu_state.eaaddr); + new_cs = readmemw(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; #ifdef USE_NEW_DYNAREC - loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, old_pc); + if (cpu_state.abrt) + return 1; #else - loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, oxpc); + if (cpu_state.abrt) + return 1; #endif - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,0,0, 0); - PREFETCH_FLUSH(); - break; - case 0x30: /*PUSH l*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - temp = geteal(); if (cpu_state.abrt) return 1; - PUSH_L(temp); - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 0); - break; + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 1, 0, 0, 0); + PREFETCH_FLUSH(); + break; + case 0x30: /*PUSH l*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + temp = geteal(); + if (cpu_state.abrt) + return 1; + PUSH_L(temp); + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 1, 0); + break; - default: -// fatal("Bad FF opcode %02X\n",rmdat&0x38); - x86illegal(); - } - return cpu_state.abrt; + default: + // fatal("Bad FF opcode %02X\n",rmdat&0x38); + x86illegal(); + } + return cpu_state.abrt; } -static int opFF_l_a32(uint32_t fetchdat) +static int +opFF_l_a32(uint32_t fetchdat) { - uint16_t old_cs, new_cs; - uint32_t old_pc, new_pc; - int cycles_old = cycles; UN_USED(cycles_old); + uint16_t old_cs, new_cs; + uint32_t old_pc, new_pc; + int cycles_old = cycles; + UN_USED(cycles_old); - uint32_t temp; + uint32_t temp; - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); - switch (rmdat & 0x38) - { - case 0x00: /*INC l*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - temp = geteal(); if (cpu_state.abrt) return 1; - if (cpu_mod != 3) { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - seteal(temp + 1); if (cpu_state.abrt) return 1; - setadd32nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - break; - case 0x08: /*DEC l*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - temp = geteal(); if (cpu_state.abrt) return 1; - if (cpu_mod != 3) { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - seteal(temp - 1); if (cpu_state.abrt) return 1; - setsub32nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - break; - case 0x10: /*CALL*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - new_pc = geteal(); if (cpu_state.abrt) return 1; - PUSH_L(cpu_state.pc); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) { CLOCK_CYCLES(5); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } - PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 1); - PREFETCH_FLUSH(); - break; - case 0x18: /*CALL far*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5UL); - } - new_pc = readmeml(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, (cpu_state.eaaddr + 4)); if (cpu_state.abrt) return 1; + switch (rmdat & 0x38) { + case 0x00: /*INC l*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + temp = geteal(); + if (cpu_state.abrt) + return 1; + if (cpu_mod != 3) { + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + seteal(temp + 1); + if (cpu_state.abrt) + return 1; + setadd32nc(temp, 1); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + break; + case 0x08: /*DEC l*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + temp = geteal(); + if (cpu_state.abrt) + return 1; + if (cpu_mod != 3) { + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + seteal(temp - 1); + if (cpu_state.abrt) + return 1; + setsub32nc(temp, 1); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + break; + case 0x10: /*CALL*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + new_pc = geteal(); + if (cpu_state.abrt) + return 1; + PUSH_L(cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; + CPU_BLOCK_END(); + if (is486) { + CLOCK_CYCLES(5); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + } + PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 1, 1); + PREFETCH_FLUSH(); + break; + case 0x18: /*CALL far*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5UL); + } + new_pc = readmeml(easeg, cpu_state.eaaddr); + new_cs = readmemw(easeg, (cpu_state.eaaddr + 4)); + if (cpu_state.abrt) + return 1; - CALL_FAR_l(new_cs, new_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,cgate16 ? 2:0,cgate16 ? 0:2, 1); - PREFETCH_FLUSH(); - break; - case 0x20: /*JMP*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - new_pc = geteal(); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) { CLOCK_CYCLES(5); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,0,0, 1); - PREFETCH_FLUSH(); - break; - case 0x28: /*JMP far*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5UL); - } + CALL_FAR_l(new_cs, new_pc); + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 1, cgate16 ? 2 : 0, cgate16 ? 0 : 2, 1); + PREFETCH_FLUSH(); + break; + case 0x20: /*JMP*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + new_pc = geteal(); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; + CPU_BLOCK_END(); + if (is486) { + CLOCK_CYCLES(5); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + } + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 1, 0, 0, 1); + PREFETCH_FLUSH(); + break; + case 0x28: /*JMP far*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5UL); + } #ifdef USE_NEW_DYNAREC - old_pc = cpu_state.pc; + old_pc = cpu_state.pc; #else - oxpc = cpu_state.pc; + oxpc = cpu_state.pc; #endif - new_pc = readmeml(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; + new_pc = readmeml(easeg, cpu_state.eaaddr); + new_cs = readmemw(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; #ifdef USE_NEW_DYNAREC - loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, old_pc); + if (cpu_state.abrt) + return 1; #else - loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, oxpc); + if (cpu_state.abrt) + return 1; #endif - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,0,0, 1); - PREFETCH_FLUSH(); - break; - case 0x30: /*PUSH l*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - temp = geteal(); if (cpu_state.abrt) return 1; - PUSH_L(temp); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 1); - break; + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 1, 0, 0, 1); + PREFETCH_FLUSH(); + break; + case 0x30: /*PUSH l*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + temp = geteal(); + if (cpu_state.abrt) + return 1; + PUSH_L(temp); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 1, 1); + break; - default: -// fatal("Bad FF opcode %02X\n",rmdat&0x38); - x86illegal(); - } - return cpu_state.abrt; + default: + // fatal("Bad FF opcode %02X\n",rmdat&0x38); + x86illegal(); + } + return cpu_state.abrt; } diff --git a/src/cpu/x86_ops_cyrix.h b/src/cpu/x86_ops_cyrix.h index 500b119fb..672ebd08e 100644 --- a/src/cpu/x86_ops_cyrix.h +++ b/src/cpu/x86_ops_cyrix.h @@ -1,272 +1,265 @@ /*Cyrix-only instructions*/ /*System Management Mode*/ -static void opSVDC_common(uint32_t fetchdat) +static void +opSVDC_common(uint32_t fetchdat) { - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_es); - writememw(0, easeg+cpu_state.eaaddr+8, ES); - break; - case 0x08: /*CS*/ - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_cs); - writememw(0, easeg+cpu_state.eaaddr+8, CS); - break; - case 0x18: /*DS*/ - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ds); - writememw(0, easeg+cpu_state.eaaddr+8, DS); - break; - case 0x10: /*SS*/ - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ss); - writememw(0, easeg+cpu_state.eaaddr+8, SS); - break; - case 0x20: /*FS*/ - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_fs); - writememw(0, easeg+cpu_state.eaaddr+8, FS); - break; - case 0x28: /*GS*/ - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_gs); - writememw(0, easeg+cpu_state.eaaddr+8, GS); - break; - default: - x86illegal(); - } + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_es); + writememw(0, easeg + cpu_state.eaaddr + 8, ES); + break; + case 0x08: /*CS*/ + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_cs); + writememw(0, easeg + cpu_state.eaaddr + 8, CS); + break; + case 0x18: /*DS*/ + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ds); + writememw(0, easeg + cpu_state.eaaddr + 8, DS); + break; + case 0x10: /*SS*/ + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ss); + writememw(0, easeg + cpu_state.eaaddr + 8, SS); + break; + case 0x20: /*FS*/ + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_fs); + writememw(0, easeg + cpu_state.eaaddr + 8, FS); + break; + case 0x28: /*GS*/ + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_gs); + writememw(0, easeg + cpu_state.eaaddr + 8, GS); + break; + default: + x86illegal(); + } } -static int opSVDC_a16(uint32_t fetchdat) +static int +opSVDC_a16(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - opSVDC_common(fetchdat); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + opSVDC_common(fetchdat); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opSVDC_a32(uint32_t fetchdat) +static int +opSVDC_a32(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - opSVDC_common(fetchdat); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + opSVDC_common(fetchdat); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static void opRSDC_common(uint32_t fetchdat) +static void +opRSDC_common(uint32_t fetchdat) { - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ - cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_es); - break; - case 0x18: /*DS*/ - cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ds); - break; - case 0x10: /*SS*/ - cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ss); - break; - case 0x20: /*FS*/ - cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_fs); - break; - case 0x28: /*GS*/ - cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_gs); - break; - default: - x86illegal(); - } + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_es); + break; + case 0x18: /*DS*/ + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ds); + break; + case 0x10: /*SS*/ + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ss); + break; + case 0x20: /*FS*/ + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_fs); + break; + case 0x28: /*GS*/ + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_gs); + break; + default: + x86illegal(); + } } -static int opRSDC_a16(uint32_t fetchdat) +static int +opRSDC_a16(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - opRSDC_common(fetchdat); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + opRSDC_common(fetchdat); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opRSDC_a32(uint32_t fetchdat) +static int +opRSDC_a32(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - opRSDC_common(fetchdat); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + opRSDC_common(fetchdat); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opSVLDT_a16(uint32_t fetchdat) +static int +opSVLDT_a16(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &ldt); - writememw(0, easeg+cpu_state.eaaddr+8, ldt.seg); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &ldt); + writememw(0, easeg + cpu_state.eaaddr + 8, ldt.seg); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opSVLDT_a32(uint32_t fetchdat) +static int +opSVLDT_a32(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &ldt); - writememw(0, easeg+cpu_state.eaaddr+8, ldt.seg); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &ldt); + writememw(0, easeg + cpu_state.eaaddr + 8, ldt.seg); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opRSLDT_a16(uint32_t fetchdat) +static int +opRSLDT_a16(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &ldt); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &ldt); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opRSLDT_a32(uint32_t fetchdat) +static int +opRSLDT_a32(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &ldt); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &ldt); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opSVTS_a16(uint32_t fetchdat) +static int +opSVTS_a16(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr); - writememw(0, easeg+cpu_state.eaaddr+8, tr.seg); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr); + writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opSVTS_a32(uint32_t fetchdat) +static int +opSVTS_a32(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr); - writememw(0, easeg+cpu_state.eaaddr+8, tr.seg); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr); + writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opRSTS_a16(uint32_t fetchdat) +static int +opRSTS_a16(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr); - writememw(0, easeg+cpu_state.eaaddr+8, tr.seg); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr); + writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opRSTS_a32(uint32_t fetchdat) +static int +opRSTS_a32(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr); - writememw(0, easeg+cpu_state.eaaddr+8, tr.seg); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr); + writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opSMINT(uint32_t fetchdat) +static int +opSMINT(uint32_t fetchdat) { - if (in_smm) - fatal("opSMINT\n"); - else - x86illegal(); + if (in_smm) + fatal("opSMINT\n"); + else + x86illegal(); - return 1; + return 1; } -static int opRDSHR_a16(uint32_t fetchdat) +static int +opRDSHR_a16(uint32_t fetchdat) { - if (in_smm) - fatal("opRDSHR_a16\n"); - else - x86illegal(); + if (in_smm) + fatal("opRDSHR_a16\n"); + else + x86illegal(); - return 1; + return 1; } -static int opRDSHR_a32(uint32_t fetchdat) +static int +opRDSHR_a32(uint32_t fetchdat) { - if (in_smm) - fatal("opRDSHR_a32\n"); - else - x86illegal(); + if (in_smm) + fatal("opRDSHR_a32\n"); + else + x86illegal(); - return 1; + return 1; } -static int opWRSHR_a16(uint32_t fetchdat) +static int +opWRSHR_a16(uint32_t fetchdat) { - if (in_smm) - fatal("opWRSHR_a16\n"); - else - x86illegal(); + if (in_smm) + fatal("opWRSHR_a16\n"); + else + x86illegal(); - return 1; + return 1; } -static int opWRSHR_a32(uint32_t fetchdat) +static int +opWRSHR_a32(uint32_t fetchdat) { - if (in_smm) - fatal("opWRSHR_a32\n"); - else - x86illegal(); + if (in_smm) + fatal("opWRSHR_a32\n"); + else + x86illegal(); - return 1; + return 1; } diff --git a/src/cpu/x86_ops_flag.h b/src/cpu/x86_ops_flag.h index 16215b525..f08b30fce 100644 --- a/src/cpu/x86_ops_flag.h +++ b/src/cpu/x86_ops_flag.h @@ -1,313 +1,319 @@ -static int opCMC(uint32_t fetchdat) +static int +opCMC(uint32_t fetchdat) { - flags_rebuild(); - cpu_state.flags ^= C_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; + flags_rebuild(); + cpu_state.flags ^= C_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; } - -static int opCLC(uint32_t fetchdat) +static int +opCLC(uint32_t fetchdat) { - flags_rebuild(); - cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; + flags_rebuild(); + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opCLD(uint32_t fetchdat) +static int +opCLD(uint32_t fetchdat) { - cpu_state.flags &= ~D_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; + cpu_state.flags &= ~D_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opCLI(uint32_t fetchdat) +static int +opCLI(uint32_t fetchdat) { - if (!IOPLp) - { - if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || - ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) - { - cpu_state.eflags &= ~VIF_FLAG; - } - else - { - x86gpf(NULL,0); - return 1; - } + if (!IOPLp) { + if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) { + cpu_state.eflags &= ~VIF_FLAG; + } else { + x86gpf(NULL, 0); + return 1; } + } else + cpu_state.flags &= ~I_FLAG; + + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; +} + +static int +opSTC(uint32_t fetchdat) +{ + flags_rebuild(); + cpu_state.flags |= C_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; +} +static int +opSTD(uint32_t fetchdat) +{ + cpu_state.flags |= D_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; +} +static int +opSTI(uint32_t fetchdat) +{ + if (!IOPLp) { + if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) { + if (cpu_state.eflags & VIP_FLAG) { + x86gpf(NULL, 0); + return 1; + } else + cpu_state.eflags |= VIF_FLAG; + } else { + x86gpf(NULL, 0); + return 1; + } + } else + cpu_state.flags |= I_FLAG; + + /*First instruction after STI will always execute, regardless of whether + there is a pending interrupt*/ + cpu_end_block_after_ins = 2; + + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; +} + +static int +opSAHF(uint32_t fetchdat) +{ + flags_rebuild(); + cpu_state.flags = (cpu_state.flags & 0xff00) | (AH & 0xd5) | 2; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + +#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) + codegen_flags_changed = 0; +#endif + + return 0; +} +static int +opLAHF(uint32_t fetchdat) +{ + flags_rebuild(); + AH = cpu_state.flags & 0xff; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; +} + +static int +opPUSHF(uint32_t fetchdat) +{ + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + if (cr4 & CR4_VME) { + uint16_t temp; + + flags_rebuild(); + temp = (cpu_state.flags & ~I_FLAG) | 0x3000; + if (cpu_state.eflags & VIF_FLAG) + temp |= I_FLAG; + PUSH_W(temp); + } else { + x86gpf(NULL, 0); + return 1; + } + } else { + flags_rebuild(); + PUSH_W(cpu_state.flags); + } + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 0); + return cpu_state.abrt; +} +static int +opPUSHFD(uint32_t fetchdat) +{ + uint16_t tempw; + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + x86gpf(NULL, 0); + return 1; + } + if (cpu_CR4_mask & CR4_VME) + tempw = cpu_state.eflags & 0x3c; + else if (CPUID) + tempw = cpu_state.eflags & 0x24; + else + tempw = cpu_state.eflags & 4; + flags_rebuild(); + PUSH_L(cpu_state.flags | (tempw << 16)); + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0); + return cpu_state.abrt; +} + +static int +opPOPF_186(uint32_t fetchdat) +{ + uint16_t tempw; + + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + x86gpf(NULL, 0); + return 1; + } + + tempw = POP_W(); + if (cpu_state.abrt) + return 1; + + if (!(msw & 1)) + cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2; + else if (!(CPL)) + cpu_state.flags = (tempw & 0x7fd5) | 2; + else if (IOPLp) + cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; + else + cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; + flags_extract(); + + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + +#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) + codegen_flags_changed = 0; +#endif + + return 0; +} +static int +opPOPF_286(uint32_t fetchdat) +{ + uint16_t tempw; + + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + x86gpf(NULL, 0); + return 1; + } + + tempw = POP_W(); + if (cpu_state.abrt) + return 1; + + if (!(msw & 1)) + cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2; + else if (!(CPL)) + cpu_state.flags = (tempw & 0x7fd5) | 2; + else if (IOPLp) + cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; + else + cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; + flags_extract(); + + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + +#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) + codegen_flags_changed = 0; +#endif + + return 0; +} +static int +opPOPF(uint32_t fetchdat) +{ + uint16_t tempw; + + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + if (cr4 & CR4_VME) { + uint32_t old_esp = ESP; + + tempw = POP_W(); + if (cpu_state.abrt) { + + ESP = old_esp; + return 1; + } + + if ((tempw & T_FLAG) || ((tempw & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) { + ESP = old_esp; + x86gpf(NULL, 0); + return 1; + } + if (tempw & I_FLAG) + cpu_state.eflags |= VIF_FLAG; + else + cpu_state.eflags &= ~VIF_FLAG; + cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; + } else { + x86gpf(NULL, 0); + return 1; + } + } else { + tempw = POP_W(); + if (cpu_state.abrt) + return 1; + + if (!(CPL) || !(msw & 1)) + cpu_state.flags = (tempw & 0x7fd5) | 2; + else if (IOPLp) + cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; else - cpu_state.flags &= ~I_FLAG; + cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; + } + flags_extract(); - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} - -static int opSTC(uint32_t fetchdat) -{ - flags_rebuild(); - cpu_state.flags |= C_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opSTD(uint32_t fetchdat) -{ - cpu_state.flags |= D_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opSTI(uint32_t fetchdat) -{ - if (!IOPLp) - { - if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || - ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) - { - if (cpu_state.eflags & VIP_FLAG) - { - x86gpf(NULL,0); - return 1; - } - else - cpu_state.eflags |= VIF_FLAG; - } - else - { - x86gpf(NULL,0); - return 1; - } - } - else - cpu_state.flags |= I_FLAG; - - /*First instruction after STI will always execute, regardless of whether - there is a pending interrupt*/ - cpu_end_block_after_ins = 2; - - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; -} - -static int opSAHF(uint32_t fetchdat) -{ - flags_rebuild(); - cpu_state.flags = (cpu_state.flags & 0xff00) | (AH & 0xd5) | 2; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); #if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) - codegen_flags_changed = 0; + codegen_flags_changed = 0; #endif - return 0; + return 0; } -static int opLAHF(uint32_t fetchdat) +static int +opPOPFD(uint32_t fetchdat) { - flags_rebuild(); - AH = cpu_state.flags & 0xff; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} + uint32_t templ; -static int opPUSHF(uint32_t fetchdat) -{ - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) - { - if (cr4 & CR4_VME) - { - uint16_t temp; + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + x86gpf(NULL, 0); + return 1; + } - flags_rebuild(); - temp = (cpu_state.flags & ~I_FLAG) | 0x3000; - if (cpu_state.eflags & VIF_FLAG) - temp |= I_FLAG; - PUSH_W(temp); - } - else - { - x86gpf(NULL,0); - return 1; - } - } - else - { - flags_rebuild(); - PUSH_W(cpu_state.flags); - } - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0); - return cpu_state.abrt; -} -static int opPUSHFD(uint32_t fetchdat) -{ - uint16_t tempw; - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) - { - x86gpf(NULL, 0); - return 1; - } - if (cpu_CR4_mask & CR4_VME) tempw = cpu_state.eflags & 0x3c; - else if (CPUID) tempw = cpu_state.eflags & 0x24; - else tempw = cpu_state.eflags & 4; - flags_rebuild(); - PUSH_L(cpu_state.flags | (tempw << 16)); - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,0,1, 0); - return cpu_state.abrt; -} + templ = POP_L(); + if (cpu_state.abrt) + return 1; -static int opPOPF_186(uint32_t fetchdat) -{ - uint16_t tempw; + if (!(CPL) || !(msw & 1)) + cpu_state.flags = (templ & 0x7fd5) | 2; + else if (IOPLp) + cpu_state.flags = (cpu_state.flags & 0x3000) | (templ & 0x4fd5) | 2; + else + cpu_state.flags = (cpu_state.flags & 0x3200) | (templ & 0x4dd5) | 2; - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) - { - x86gpf(NULL, 0); - return 1; - } + templ &= (is486 || isibm486) ? 0x3c0000 : 0; + templ |= ((cpu_state.eflags & 3) << 16); + if (cpu_CR4_mask & CR4_VME) + cpu_state.eflags = (templ >> 16) & 0x3f; + else if (CPUID) + cpu_state.eflags = (templ >> 16) & 0x27; + else if (is486 || isibm486) + cpu_state.eflags = (templ >> 16) & 7; + else + cpu_state.eflags = (templ >> 16) & 3; - tempw = POP_W(); if (cpu_state.abrt) return 1; + flags_extract(); - if (!(msw & 1)) cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2; - else if (!(CPL)) cpu_state.flags = (tempw & 0x7fd5) | 2; - else if (IOPLp) cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; - else cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; - flags_extract(); - - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 0); #if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) - codegen_flags_changed = 0; + codegen_flags_changed = 0; #endif - return 0; -} -static int opPOPF_286(uint32_t fetchdat) -{ - uint16_t tempw; - - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) - { - x86gpf(NULL, 0); - return 1; - } - - tempw = POP_W(); if (cpu_state.abrt) return 1; - - if (!(msw & 1)) cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2; - else if (!(CPL)) cpu_state.flags = (tempw & 0x7fd5) | 2; - else if (IOPLp) cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; - else cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; - flags_extract(); - - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); - -#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) - codegen_flags_changed = 0; -#endif - - return 0; -} -static int opPOPF(uint32_t fetchdat) -{ - uint16_t tempw; - - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) - { - if (cr4 & CR4_VME) - { - uint32_t old_esp = ESP; - - tempw = POP_W(); - if (cpu_state.abrt) - { - - ESP = old_esp; - return 1; - } - - if ((tempw & T_FLAG) || ((tempw & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) - { - ESP = old_esp; - x86gpf(NULL, 0); - return 1; - } - if (tempw & I_FLAG) - cpu_state.eflags |= VIF_FLAG; - else - cpu_state.eflags &= ~VIF_FLAG; - cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; - } - else - { - x86gpf(NULL, 0); - return 1; - } - } - else - { - tempw = POP_W(); - if (cpu_state.abrt) - return 1; - - if (!(CPL) || !(msw & 1)) - cpu_state.flags = (tempw & 0x7fd5) | 2; - else if (IOPLp) - cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; - else - cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; - } - flags_extract(); - - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); - -#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) - codegen_flags_changed = 0; -#endif - - return 0; -} -static int opPOPFD(uint32_t fetchdat) -{ - uint32_t templ; - - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) - { - x86gpf(NULL, 0); - return 1; - } - - templ = POP_L(); if (cpu_state.abrt) return 1; - - if (!(CPL) || !(msw & 1)) cpu_state.flags = (templ & 0x7fd5) | 2; - else if (IOPLp) cpu_state.flags = (cpu_state.flags & 0x3000) | (templ & 0x4fd5) | 2; - else cpu_state.flags = (cpu_state.flags & 0x3200) | (templ & 0x4dd5) | 2; - - templ &= (is486 || isibm486) ? 0x3c0000 : 0; - templ |= ((cpu_state.eflags&3) << 16); - if (cpu_CR4_mask & CR4_VME) cpu_state.eflags = (templ >> 16) & 0x3f; - else if (CPUID) cpu_state.eflags = (templ >> 16) & 0x27; - else if (is486 || isibm486) cpu_state.eflags = (templ >> 16) & 7; - else cpu_state.eflags = (templ >> 16) & 3; - - flags_extract(); - - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 0,1,0,0, 0); - -#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) - codegen_flags_changed = 0; -#endif - - return 0; + return 0; } diff --git a/src/cpu/x86_ops_fpu.h b/src/cpu/x86_ops_fpu.h index a1976f268..314ec321b 100644 --- a/src/cpu/x86_ops_fpu.h +++ b/src/cpu/x86_ops_fpu.h @@ -1,85 +1,101 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ -static int opESCAPE_d8_a16(uint32_t fetchdat) +static int +opESCAPE_d8_a16(uint32_t fetchdat) { - return x86_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat); + return x86_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat); } -static int opESCAPE_d8_a32(uint32_t fetchdat) +static int +opESCAPE_d8_a32(uint32_t fetchdat) { - return x86_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat); + return x86_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat); } -static int opESCAPE_d9_a16(uint32_t fetchdat) +static int +opESCAPE_d9_a16(uint32_t fetchdat) { - return x86_opcodes_d9_a16[fetchdat & 0xff](fetchdat); + return x86_opcodes_d9_a16[fetchdat & 0xff](fetchdat); } -static int opESCAPE_d9_a32(uint32_t fetchdat) +static int +opESCAPE_d9_a32(uint32_t fetchdat) { - return x86_opcodes_d9_a32[fetchdat & 0xff](fetchdat); + return x86_opcodes_d9_a32[fetchdat & 0xff](fetchdat); } -static int opESCAPE_da_a16(uint32_t fetchdat) +static int +opESCAPE_da_a16(uint32_t fetchdat) { - return x86_opcodes_da_a16[fetchdat & 0xff](fetchdat); + return x86_opcodes_da_a16[fetchdat & 0xff](fetchdat); } -static int opESCAPE_da_a32(uint32_t fetchdat) +static int +opESCAPE_da_a32(uint32_t fetchdat) { - return x86_opcodes_da_a32[fetchdat & 0xff](fetchdat); + return x86_opcodes_da_a32[fetchdat & 0xff](fetchdat); } -static int opESCAPE_db_a16(uint32_t fetchdat) +static int +opESCAPE_db_a16(uint32_t fetchdat) { - return x86_opcodes_db_a16[fetchdat & 0xff](fetchdat); + return x86_opcodes_db_a16[fetchdat & 0xff](fetchdat); } -static int opESCAPE_db_a32(uint32_t fetchdat) +static int +opESCAPE_db_a32(uint32_t fetchdat) { - return x86_opcodes_db_a32[fetchdat & 0xff](fetchdat); + return x86_opcodes_db_a32[fetchdat & 0xff](fetchdat); } -static int opESCAPE_dc_a16(uint32_t fetchdat) +static int +opESCAPE_dc_a16(uint32_t fetchdat) { - return x86_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat); + return x86_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat); } -static int opESCAPE_dc_a32(uint32_t fetchdat) +static int +opESCAPE_dc_a32(uint32_t fetchdat) { - return x86_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat); + return x86_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat); } -static int opESCAPE_dd_a16(uint32_t fetchdat) +static int +opESCAPE_dd_a16(uint32_t fetchdat) { - return x86_opcodes_dd_a16[fetchdat & 0xff](fetchdat); + return x86_opcodes_dd_a16[fetchdat & 0xff](fetchdat); } -static int opESCAPE_dd_a32(uint32_t fetchdat) +static int +opESCAPE_dd_a32(uint32_t fetchdat) { - return x86_opcodes_dd_a32[fetchdat & 0xff](fetchdat); + return x86_opcodes_dd_a32[fetchdat & 0xff](fetchdat); } -static int opESCAPE_de_a16(uint32_t fetchdat) +static int +opESCAPE_de_a16(uint32_t fetchdat) { - return x86_opcodes_de_a16[fetchdat & 0xff](fetchdat); + return x86_opcodes_de_a16[fetchdat & 0xff](fetchdat); } -static int opESCAPE_de_a32(uint32_t fetchdat) +static int +opESCAPE_de_a32(uint32_t fetchdat) { - return x86_opcodes_de_a32[fetchdat & 0xff](fetchdat); + return x86_opcodes_de_a32[fetchdat & 0xff](fetchdat); } -static int opESCAPE_df_a16(uint32_t fetchdat) +static int +opESCAPE_df_a16(uint32_t fetchdat) { - return x86_opcodes_df_a16[fetchdat & 0xff](fetchdat); + return x86_opcodes_df_a16[fetchdat & 0xff](fetchdat); } -static int opESCAPE_df_a32(uint32_t fetchdat) +static int +opESCAPE_df_a32(uint32_t fetchdat) { - return x86_opcodes_df_a32[fetchdat & 0xff](fetchdat); + return x86_opcodes_df_a32[fetchdat & 0xff](fetchdat); } -static int opWAIT(uint32_t fetchdat) +static int +opWAIT(uint32_t fetchdat) { - if ((cr0 & 0xa) == 0xa) - { - x86_int(7); - return 1; - } - CLOCK_CYCLES(4); - return 0; + if ((cr0 & 0xa) == 0xa) { + x86_int(7); + return 1; + } + CLOCK_CYCLES(4); + return 0; } diff --git a/src/cpu/x86_ops_i686.h b/src/cpu/x86_ops_i686.h index 2394e18f4..8940a98a0 100644 --- a/src/cpu/x86_ops_i686.h +++ b/src/cpu/x86_ops_i686.h @@ -19,65 +19,63 @@ opSYSENTER(uint32_t fetchdat) int ret = sysenter(fetchdat); if (ret <= 1) { - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 7, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - CPU_BLOCK_END(); + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 7, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + CPU_BLOCK_END(); } return ret; } - static int opSYSEXIT(uint32_t fetchdat) { int ret = sysexit(fetchdat); if (ret <= 1) { - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 7, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - CPU_BLOCK_END(); + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 7, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + CPU_BLOCK_END(); } return ret; } - static int fx_save_stor_common(uint32_t fetchdat, int bits) { - uint8_t fxinst = 0; - uint16_t twd = x87_gettag(); - uint32_t old_eaaddr = 0; - uint8_t ftwb = 0; - uint16_t rec_ftw = 0; - uint16_t fpus = 0; + uint8_t fxinst = 0; + uint16_t twd = x87_gettag(); + uint32_t old_eaaddr = 0; + uint8_t ftwb = 0; + uint16_t rec_ftw = 0; + uint16_t fpus = 0; uint64_t *p; if (CPUID < 0x650) - return ILLEGAL(fetchdat); + return ILLEGAL(fetchdat); FP_ENTER(); if (bits == 32) { - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); } else { - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); } if (cpu_state.eaaddr & 0xf) { - x386_dynarec_log("Effective address %08X not on 16-byte boundary\n", cpu_state.eaaddr); - x86gpf(NULL, 0); - return cpu_state.abrt; + x386_dynarec_log("Effective address %08X not on 16-byte boundary\n", cpu_state.eaaddr); + x86gpf(NULL, 0); + return cpu_state.abrt; } fxinst = (rmdat >> 3) & 7; if ((fxinst > 1) || (cpu_mod == 3)) { - x86illegal(); - return cpu_state.abrt; + x86illegal(); + return cpu_state.abrt; } FP_ENTER(); @@ -85,170 +83,186 @@ fx_save_stor_common(uint32_t fetchdat, int bits) old_eaaddr = cpu_state.eaaddr; if (fxinst == 1) { - /* FXRSTOR */ - cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - fpus = readmemw(easeg, cpu_state.eaaddr + 2); - cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040; - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - cpu_state.TOP = (fpus >> 11) & 7; - cpu_state.npxs &= fpus & ~0x3800; + /* FXRSTOR */ + cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); + fpus = readmemw(easeg, cpu_state.eaaddr + 2); + cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040; + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + cpu_state.TOP = (fpus >> 11) & 7; + cpu_state.npxs &= fpus & ~0x3800; - x87_pc_off = readmeml(easeg, cpu_state.eaaddr+8); - x87_pc_seg = readmemw(easeg, cpu_state.eaaddr+12); + x87_pc_off = readmeml(easeg, cpu_state.eaaddr + 8); + x87_pc_seg = readmemw(easeg, cpu_state.eaaddr + 12); - ftwb = readmemb(easeg, cpu_state.eaaddr + 4); + ftwb = readmemb(easeg, cpu_state.eaaddr + 4); - if (ftwb & 0x01) rec_ftw |= 0x0003; - if (ftwb & 0x02) rec_ftw |= 0x000C; - if (ftwb & 0x04) rec_ftw |= 0x0030; - if (ftwb & 0x08) rec_ftw |= 0x00C0; - if (ftwb & 0x10) rec_ftw |= 0x0300; - if (ftwb & 0x20) rec_ftw |= 0x0C00; - if (ftwb & 0x40) rec_ftw |= 0x3000; - if (ftwb & 0x80) rec_ftw |= 0xC000; + if (ftwb & 0x01) + rec_ftw |= 0x0003; + if (ftwb & 0x02) + rec_ftw |= 0x000C; + if (ftwb & 0x04) + rec_ftw |= 0x0030; + if (ftwb & 0x08) + rec_ftw |= 0x00C0; + if (ftwb & 0x10) + rec_ftw |= 0x0300; + if (ftwb & 0x20) + rec_ftw |= 0x0C00; + if (ftwb & 0x40) + rec_ftw |= 0x3000; + if (ftwb & 0x80) + rec_ftw |= 0xC000; - x87_op_off = readmeml(easeg, cpu_state.eaaddr+16); - x87_op_off |= (readmemw(easeg, cpu_state.eaaddr + 6) >> 12) << 16; - x87_op_seg = readmemw(easeg, cpu_state.eaaddr+20); + x87_op_off = readmeml(easeg, cpu_state.eaaddr + 16); + x87_op_off |= (readmemw(easeg, cpu_state.eaaddr + 6) >> 12) << 16; + x87_op_seg = readmemw(easeg, cpu_state.eaaddr + 20); - cpu_state.eaaddr = old_eaaddr + 32; - x87_ldmmx(&(cpu_state.MM[0]), &(cpu_state.MM_w4[0])); x87_ld_frstor(0); + cpu_state.eaaddr = old_eaaddr + 32; + x87_ldmmx(&(cpu_state.MM[0]), &(cpu_state.MM_w4[0])); + x87_ld_frstor(0); - cpu_state.eaaddr = old_eaaddr + 48; - x87_ldmmx(&(cpu_state.MM[1]), &(cpu_state.MM_w4[1])); x87_ld_frstor(1); + cpu_state.eaaddr = old_eaaddr + 48; + x87_ldmmx(&(cpu_state.MM[1]), &(cpu_state.MM_w4[1])); + x87_ld_frstor(1); - cpu_state.eaaddr = old_eaaddr + 64; - x87_ldmmx(&(cpu_state.MM[2]), &(cpu_state.MM_w4[2])); x87_ld_frstor(2); + cpu_state.eaaddr = old_eaaddr + 64; + x87_ldmmx(&(cpu_state.MM[2]), &(cpu_state.MM_w4[2])); + x87_ld_frstor(2); - cpu_state.eaaddr = old_eaaddr + 80; - x87_ldmmx(&(cpu_state.MM[3]), &(cpu_state.MM_w4[3])); x87_ld_frstor(3); + cpu_state.eaaddr = old_eaaddr + 80; + x87_ldmmx(&(cpu_state.MM[3]), &(cpu_state.MM_w4[3])); + x87_ld_frstor(3); - cpu_state.eaaddr = old_eaaddr + 96; - x87_ldmmx(&(cpu_state.MM[4]), &(cpu_state.MM_w4[4])); x87_ld_frstor(4); + cpu_state.eaaddr = old_eaaddr + 96; + x87_ldmmx(&(cpu_state.MM[4]), &(cpu_state.MM_w4[4])); + x87_ld_frstor(4); - cpu_state.eaaddr = old_eaaddr + 112; - x87_ldmmx(&(cpu_state.MM[5]), &(cpu_state.MM_w4[5])); x87_ld_frstor(5); + cpu_state.eaaddr = old_eaaddr + 112; + x87_ldmmx(&(cpu_state.MM[5]), &(cpu_state.MM_w4[5])); + x87_ld_frstor(5); - cpu_state.eaaddr = old_eaaddr + 128; - x87_ldmmx(&(cpu_state.MM[6]), &(cpu_state.MM_w4[6])); x87_ld_frstor(6); + cpu_state.eaaddr = old_eaaddr + 128; + x87_ldmmx(&(cpu_state.MM[6]), &(cpu_state.MM_w4[6])); + x87_ld_frstor(6); - cpu_state.eaaddr = old_eaaddr + 144; - x87_ldmmx(&(cpu_state.MM[7]), &(cpu_state.MM_w4[7])); x87_ld_frstor(7); + cpu_state.eaaddr = old_eaaddr + 144; + x87_ldmmx(&(cpu_state.MM[7]), &(cpu_state.MM_w4[7])); + x87_ld_frstor(7); - cpu_state.ismmx = 0; - /*Horrible hack, but as 86Box doesn't keep the FPU stack in 80-bit precision at all times - something like this is needed*/ - p = (uint64_t *) cpu_state.tag; + cpu_state.ismmx = 0; + /*Horrible hack, but as 86Box doesn't keep the FPU stack in 80-bit precision at all times + something like this is needed*/ + p = (uint64_t *) cpu_state.tag; #ifdef USE_NEW_DYNAREC - if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && - cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && - !cpu_state.TOP && (*p == 0x0101010101010101ull)) + if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && !cpu_state.TOP && (*p == 0x0101010101010101ull)) #else - if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && - cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && - !cpu_state.TOP && !(*p)) + if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && !cpu_state.TOP && !(*p)) #endif - cpu_state.ismmx = 1; + cpu_state.ismmx = 1; - x87_settag(rec_ftw); + x87_settag(rec_ftw); - CLOCK_CYCLES((cr0 & 1) ? 34 : 44); + CLOCK_CYCLES((cr0 & 1) ? 34 : 44); } else { - /* FXSAVE */ - if ((twd & 0x0003) == 0x0003) ftwb |= 0x01; - if ((twd & 0x000C) == 0x000C) ftwb |= 0x02; - if ((twd & 0x0030) == 0x0030) ftwb |= 0x04; - if ((twd & 0x00C0) == 0x00C0) ftwb |= 0x08; - if ((twd & 0x0300) == 0x0300) ftwb |= 0x10; - if ((twd & 0x0C00) == 0x0C00) ftwb |= 0x20; - if ((twd & 0x3000) == 0x3000) ftwb |= 0x40; - if ((twd & 0xC000) == 0xC000) ftwb |= 0x80; + /* FXSAVE */ + if ((twd & 0x0003) == 0x0003) + ftwb |= 0x01; + if ((twd & 0x000C) == 0x000C) + ftwb |= 0x02; + if ((twd & 0x0030) == 0x0030) + ftwb |= 0x04; + if ((twd & 0x00C0) == 0x00C0) + ftwb |= 0x08; + if ((twd & 0x0300) == 0x0300) + ftwb |= 0x10; + if ((twd & 0x0C00) == 0x0C00) + ftwb |= 0x20; + if ((twd & 0x3000) == 0x3000) + ftwb |= 0x40; + if ((twd & 0xC000) == 0xC000) + ftwb |= 0x80; - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); - writememb(easeg,cpu_state.eaaddr+4,ftwb); + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 2, cpu_state.npxs); + writememb(easeg, cpu_state.eaaddr + 4, ftwb); - writememw(easeg,cpu_state.eaaddr+6,(x87_op_off>>16)<<12); - writememl(easeg,cpu_state.eaaddr+8,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+12,x87_pc_seg); + writememw(easeg, cpu_state.eaaddr + 6, (x87_op_off >> 16) << 12); + writememl(easeg, cpu_state.eaaddr + 8, x87_pc_off); + writememw(easeg, cpu_state.eaaddr + 12, x87_pc_seg); - writememl(easeg,cpu_state.eaaddr+16,x87_op_off); - writememw(easeg,cpu_state.eaaddr+20,x87_op_seg); + writememl(easeg, cpu_state.eaaddr + 16, x87_op_off); + writememw(easeg, cpu_state.eaaddr + 20, x87_op_seg); - cpu_state.eaaddr = old_eaaddr + 32; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[0]) : x87_st_fsave(0); + cpu_state.eaaddr = old_eaaddr + 32; + cpu_state.ismmx ? x87_stmmx(cpu_state.MM[0]) : x87_st_fsave(0); - cpu_state.eaaddr = old_eaaddr + 48; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[1]) : x87_st_fsave(1); + cpu_state.eaaddr = old_eaaddr + 48; + cpu_state.ismmx ? x87_stmmx(cpu_state.MM[1]) : x87_st_fsave(1); - cpu_state.eaaddr = old_eaaddr + 64; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[2]) : x87_st_fsave(2); + cpu_state.eaaddr = old_eaaddr + 64; + cpu_state.ismmx ? x87_stmmx(cpu_state.MM[2]) : x87_st_fsave(2); - cpu_state.eaaddr = old_eaaddr + 80; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[3]) : x87_st_fsave(3); + cpu_state.eaaddr = old_eaaddr + 80; + cpu_state.ismmx ? x87_stmmx(cpu_state.MM[3]) : x87_st_fsave(3); - cpu_state.eaaddr = old_eaaddr + 96; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[4]) : x87_st_fsave(4); + cpu_state.eaaddr = old_eaaddr + 96; + cpu_state.ismmx ? x87_stmmx(cpu_state.MM[4]) : x87_st_fsave(4); - cpu_state.eaaddr = old_eaaddr + 112; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[5]) : x87_st_fsave(5); + cpu_state.eaaddr = old_eaaddr + 112; + cpu_state.ismmx ? x87_stmmx(cpu_state.MM[5]) : x87_st_fsave(5); - cpu_state.eaaddr = old_eaaddr + 128; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[6]) : x87_st_fsave(6); + cpu_state.eaaddr = old_eaaddr + 128; + cpu_state.ismmx ? x87_stmmx(cpu_state.MM[6]) : x87_st_fsave(6); - cpu_state.eaaddr = old_eaaddr + 144; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[7]) : x87_st_fsave(7); + cpu_state.eaaddr = old_eaaddr + 144; + cpu_state.ismmx ? x87_stmmx(cpu_state.MM[7]) : x87_st_fsave(7); - cpu_state.eaaddr = old_eaaddr; + cpu_state.eaaddr = old_eaaddr; - cpu_state.npxc = 0x37F; + cpu_state.npxc = 0x37F; codegen_set_rounding_mode(X87_ROUNDING_NEAREST); - cpu_state.npxs = 0; - p = (uint64_t *)cpu_state.tag; + cpu_state.npxs = 0; + p = (uint64_t *) cpu_state.tag; #ifdef USE_NEW_DYNAREC *p = 0; #else *p = 0x0303030303030303ll; #endif - cpu_state.TOP = 0; - cpu_state.ismmx = 0; + cpu_state.TOP = 0; + cpu_state.ismmx = 0; - CLOCK_CYCLES((cr0 & 1) ? 56 : 67); + CLOCK_CYCLES((cr0 & 1) ? 56 : 67); } return cpu_state.abrt; } - static int opFXSAVESTOR_a16(uint32_t fetchdat) { return fx_save_stor_common(fetchdat, 16); } - static int opFXSAVESTOR_a32(uint32_t fetchdat) { return fx_save_stor_common(fetchdat, 32); } - static int opHINT_NOP_a16(uint32_t fetchdat) { fetch_ea_16(fetchdat); CLOCK_CYCLES((is486) ? 1 : 3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); return 0; } - static int opHINT_NOP_a32(uint32_t fetchdat) { fetch_ea_32(fetchdat); CLOCK_CYCLES((is486) ? 1 : 3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); return 0; } diff --git a/src/cpu/x86_ops_inc_dec.h b/src/cpu/x86_ops_inc_dec.h index 682662851..3eb908c57 100644 --- a/src/cpu/x86_ops_inc_dec.h +++ b/src/cpu/x86_ops_inc_dec.h @@ -1,12 +1,12 @@ -#define INC_DEC_OP(name, reg, inc, setflags) \ - static int op ## name (uint32_t fetchdat) \ - { \ - setflags(reg, 1); \ - reg += inc; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 1, -1, 0,0,0,0, 0); \ - return 0; \ - } +#define INC_DEC_OP(name, reg, inc, setflags) \ + static int op##name(uint32_t fetchdat) \ + { \ + setflags(reg, 1); \ + reg += inc; \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 1, -1, 0, 0, 0, 0, 0); \ + return 0; \ + } INC_DEC_OP(INC_AX, AX, 1, setadd16nc) INC_DEC_OP(INC_BX, BX, 1, setadd16nc) @@ -44,50 +44,57 @@ INC_DEC_OP(DEC_EDI, EDI, -1, setsub32nc) INC_DEC_OP(DEC_EBP, EBP, -1, setsub32nc) INC_DEC_OP(DEC_ESP, ESP, -1, setsub32nc) - -static int opINCDEC_b_a16(uint32_t fetchdat) +static int +opINCDEC_b_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp=geteab(); if (cpu_state.abrt) return 1; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; - if (rmdat&0x38) - { - seteab(temp - 1); if (cpu_state.abrt) return 1; - setsub8nc(temp, 1); - } - else - { - seteab(temp + 1); if (cpu_state.abrt) return 1; - setadd8nc(temp, 1); - } - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - return 0; + if (rmdat & 0x38) { + seteab(temp - 1); + if (cpu_state.abrt) + return 1; + setsub8nc(temp, 1); + } else { + seteab(temp + 1); + if (cpu_state.abrt) + return 1; + setadd8nc(temp, 1); + } + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + return 0; } -static int opINCDEC_b_a32(uint32_t fetchdat) +static int +opINCDEC_b_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp=geteab(); if (cpu_state.abrt) return 1; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; - if (rmdat&0x38) - { - seteab(temp - 1); if (cpu_state.abrt) return 1; - setsub8nc(temp, 1); - } - else - { - seteab(temp + 1); if (cpu_state.abrt) return 1; - setadd8nc(temp, 1); - } - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - return 0; + if (rmdat & 0x38) { + seteab(temp - 1); + if (cpu_state.abrt) + return 1; + setsub8nc(temp, 1); + } else { + seteab(temp + 1); + if (cpu_state.abrt) + return 1; + setadd8nc(temp, 1); + } + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + return 0; } diff --git a/src/cpu/x86_ops_int.h b/src/cpu/x86_ops_int.h index 0074aec29..a73ed62e0 100644 --- a/src/cpu/x86_ops_int.h +++ b/src/cpu/x86_ops_int.h @@ -1,94 +1,96 @@ -static int opINT3(uint32_t fetchdat) +static int +opINT3(uint32_t fetchdat) { - int cycles_old = cycles; UN_USED(cycles_old); + int cycles_old = cycles; + UN_USED(cycles_old); #ifdef USE_GDBSTUB - if (gdbstub_int3()) - return 1; + if (gdbstub_int3()) + return 1; #endif - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf(NULL,0); - return 1; - } - x86_int_sw(3); - CLOCK_CYCLES((is486) ? 44 : 59); - PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,0,0,0, 0); + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf(NULL, 0); return 1; + } + x86_int_sw(3); + CLOCK_CYCLES((is486) ? 44 : 59); + PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 0, 0, 0, 0); + return 1; } -static int opINT1(uint32_t fetchdat) +static int +opINT1(uint32_t fetchdat) { - int cycles_old = cycles; UN_USED(cycles_old); - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf(NULL,0); - return 1; - } - x86_int_sw(1); - CLOCK_CYCLES((is486) ? 44 : 59); - PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,0,0,0, 0); + int cycles_old = cycles; + UN_USED(cycles_old); + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf(NULL, 0); return 1; + } + x86_int_sw(1); + CLOCK_CYCLES((is486) ? 44 : 59); + PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 0, 0, 0, 0); + return 1; } -static int opINT(uint32_t fetchdat) +static int +opINT(uint32_t fetchdat) { - int cycles_old = cycles; UN_USED(cycles_old); - uint8_t temp = getbytef(); + int cycles_old = cycles; + UN_USED(cycles_old); + uint8_t temp = getbytef(); - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) - { - if (cr4 & CR4_VME) - { - uint16_t t; - uint8_t d; + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + if (cr4 & CR4_VME) { + uint16_t t; + uint8_t d; - cpl_override = 1; - t = readmemw(tr.base, 0x66) - 32; - cpl_override = 0; - if (cpu_state.abrt) return 1; + cpl_override = 1; + t = readmemw(tr.base, 0x66) - 32; + cpl_override = 0; + if (cpu_state.abrt) + return 1; - t += (temp >> 3); - if (t <= tr.limit) - { - cpl_override = 1; - d = readmemb(tr.base, t);// + (temp >> 3)); - cpl_override = 0; - if (cpu_state.abrt) return 1; + t += (temp >> 3); + if (t <= tr.limit) { + cpl_override = 1; + d = readmemb(tr.base, t); // + (temp >> 3)); + cpl_override = 0; + if (cpu_state.abrt) + return 1; - if (!(d & (1 << (temp & 7)))) - { - x86_int_sw_rm(temp); - PREFETCH_RUN(cycles_old-cycles, 2, -1, 0,0,0,0, 0); - return 1; - } - } + if (!(d & (1 << (temp & 7)))) { + x86_int_sw_rm(temp); + PREFETCH_RUN(cycles_old - cycles, 2, -1, 0, 0, 0, 0, 0); + return 1; } - x86gpf_expected(NULL,0); - return 1; + } } - - x86_int_sw(temp); - PREFETCH_RUN(cycles_old-cycles, 2, -1, 0,0,0,0, 0); + x86gpf_expected(NULL, 0); return 1; + } + + x86_int_sw(temp); + PREFETCH_RUN(cycles_old - cycles, 2, -1, 0, 0, 0, 0, 0); + return 1; } -static int opINTO(uint32_t fetchdat) +static int +opINTO(uint32_t fetchdat) { - int cycles_old = cycles; UN_USED(cycles_old); + int cycles_old = cycles; + UN_USED(cycles_old); - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf(NULL,0); - return 1; - } - if (VF_SET()) - { - cpu_state.oldpc = cpu_state.pc; - x86_int_sw(4); - PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,0,0,0, 0); - return 1; - } - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf(NULL, 0); + return 1; + } + if (VF_SET()) { + cpu_state.oldpc = cpu_state.pc; + x86_int_sw(4); + PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 0, 0, 0, 0); + return 1; + } + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } diff --git a/src/cpu/x86_ops_io.h b/src/cpu/x86_ops_io.h index 50d7d94d1..c4d46404d 100644 --- a/src/cpu/x86_ops_io.h +++ b/src/cpu/x86_ops_io.h @@ -1,146 +1,158 @@ -static int opIN_AL_imm(uint32_t fetchdat) +static int +opIN_AL_imm(uint32_t fetchdat) { - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - AL = inb(port); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 2, -1, 1,0,0,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + uint16_t port = (uint16_t) getbytef(); + check_io_perm(port); + AL = inb(port); + CLOCK_CYCLES(12); + PREFETCH_RUN(12, 2, -1, 1, 0, 0, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; } -static int opIN_AX_imm(uint32_t fetchdat) +static int +opIN_AX_imm(uint32_t fetchdat) { - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - check_io_perm(port + 1); - AX = inw(port); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 2, -1, 1,0,0,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + uint16_t port = (uint16_t) getbytef(); + check_io_perm(port); + check_io_perm(port + 1); + AX = inw(port); + CLOCK_CYCLES(12); + PREFETCH_RUN(12, 2, -1, 1, 0, 0, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; } -static int opIN_EAX_imm(uint32_t fetchdat) +static int +opIN_EAX_imm(uint32_t fetchdat) { - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - check_io_perm(port + 1); - check_io_perm(port + 2); - check_io_perm(port + 3); - EAX = inl(port); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 2, -1, 0,1,0,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + uint16_t port = (uint16_t) getbytef(); + check_io_perm(port); + check_io_perm(port + 1); + check_io_perm(port + 2); + check_io_perm(port + 3); + EAX = inl(port); + CLOCK_CYCLES(12); + PREFETCH_RUN(12, 2, -1, 0, 1, 0, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; } -static int opOUT_AL_imm(uint32_t fetchdat) +static int +opOUT_AL_imm(uint32_t fetchdat) { - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - outb(port, AL); - CLOCK_CYCLES(10); - PREFETCH_RUN(10, 2, -1, 0,0,1,0, 0); - if (port == 0x64) - return x86_was_reset; - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} -static int opOUT_AX_imm(uint32_t fetchdat) -{ - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - check_io_perm(port + 1); - outw(port, AX); - CLOCK_CYCLES(10); - PREFETCH_RUN(10, 2, -1, 0,0,1,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} -static int opOUT_EAX_imm(uint32_t fetchdat) -{ - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - check_io_perm(port + 1); - check_io_perm(port + 2); - check_io_perm(port + 3); - outl(port, EAX); - CLOCK_CYCLES(10); - PREFETCH_RUN(10, 2, -1, 0,0,0,1, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} - -static int opIN_AL_DX(uint32_t fetchdat) -{ - check_io_perm(DX); - AL = inb(DX); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 1, -1, 1,0,0,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} -static int opIN_AX_DX(uint32_t fetchdat) -{ - check_io_perm(DX); - check_io_perm(DX + 1); - AX = inw(DX); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 1, -1, 1,0,0,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} -static int opIN_EAX_DX(uint32_t fetchdat) -{ - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - EAX = inl(DX); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 1, -1, 0,1,0,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} - -static int opOUT_AL_DX(uint32_t fetchdat) -{ - check_io_perm(DX); - outb(DX, AL); - CLOCK_CYCLES(11); - PREFETCH_RUN(11, 1, -1, 0,0,1,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; + uint16_t port = (uint16_t) getbytef(); + check_io_perm(port); + outb(port, AL); + CLOCK_CYCLES(10); + PREFETCH_RUN(10, 2, -1, 0, 0, 1, 0, 0); + if (port == 0x64) return x86_was_reset; + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; } -static int opOUT_AX_DX(uint32_t fetchdat) +static int +opOUT_AX_imm(uint32_t fetchdat) { - check_io_perm(DX); - check_io_perm(DX + 1); - outw(DX, AX); - CLOCK_CYCLES(11); - PREFETCH_RUN(11, 1, -1, 0,0,1,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + uint16_t port = (uint16_t) getbytef(); + check_io_perm(port); + check_io_perm(port + 1); + outw(port, AX); + CLOCK_CYCLES(10); + PREFETCH_RUN(10, 2, -1, 0, 0, 1, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; } -static int opOUT_EAX_DX(uint32_t fetchdat) +static int +opOUT_EAX_imm(uint32_t fetchdat) { - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - outl(DX, EAX); - PREFETCH_RUN(11, 1, -1, 0,0,0,1, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + uint16_t port = (uint16_t) getbytef(); + check_io_perm(port); + check_io_perm(port + 1); + check_io_perm(port + 2); + check_io_perm(port + 3); + outl(port, EAX); + CLOCK_CYCLES(10); + PREFETCH_RUN(10, 2, -1, 0, 0, 0, 1, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; +} + +static int +opIN_AL_DX(uint32_t fetchdat) +{ + check_io_perm(DX); + AL = inb(DX); + CLOCK_CYCLES(12); + PREFETCH_RUN(12, 1, -1, 1, 0, 0, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; +} +static int +opIN_AX_DX(uint32_t fetchdat) +{ + check_io_perm(DX); + check_io_perm(DX + 1); + AX = inw(DX); + CLOCK_CYCLES(12); + PREFETCH_RUN(12, 1, -1, 1, 0, 0, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; +} +static int +opIN_EAX_DX(uint32_t fetchdat) +{ + check_io_perm(DX); + check_io_perm(DX + 1); + check_io_perm(DX + 2); + check_io_perm(DX + 3); + EAX = inl(DX); + CLOCK_CYCLES(12); + PREFETCH_RUN(12, 1, -1, 0, 1, 0, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; +} + +static int +opOUT_AL_DX(uint32_t fetchdat) +{ + check_io_perm(DX); + outb(DX, AL); + CLOCK_CYCLES(11); + PREFETCH_RUN(11, 1, -1, 0, 0, 1, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return x86_was_reset; +} +static int +opOUT_AX_DX(uint32_t fetchdat) +{ + check_io_perm(DX); + check_io_perm(DX + 1); + outw(DX, AX); + CLOCK_CYCLES(11); + PREFETCH_RUN(11, 1, -1, 0, 0, 1, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; +} +static int +opOUT_EAX_DX(uint32_t fetchdat) +{ + check_io_perm(DX); + check_io_perm(DX + 1); + check_io_perm(DX + 2); + check_io_perm(DX + 3); + outl(DX, EAX); + PREFETCH_RUN(11, 1, -1, 0, 0, 0, 1, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; } diff --git a/src/cpu/x86_ops_jump.h b/src/cpu/x86_ops_jump.h index 7f9df37d7..2a338afdc 100644 --- a/src/cpu/x86_ops_jump.h +++ b/src/cpu/x86_ops_jump.h @@ -1,74 +1,73 @@ -#define cond_O ( VF_SET()) +#define cond_O (VF_SET()) #define cond_NO (!VF_SET()) -#define cond_B ( CF_SET()) +#define cond_B (CF_SET()) #define cond_NB (!CF_SET()) -#define cond_E ( ZF_SET()) +#define cond_E (ZF_SET()) #define cond_NE (!ZF_SET()) -#define cond_BE ( CF_SET() || ZF_SET()) +#define cond_BE (CF_SET() || ZF_SET()) #define cond_NBE (!CF_SET() && !ZF_SET()) -#define cond_S ( NF_SET()) +#define cond_S (NF_SET()) #define cond_NS (!NF_SET()) -#define cond_P ( PF_SET()) +#define cond_P (PF_SET()) #define cond_NP (!PF_SET()) #define cond_L (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0)) #define cond_NL (((NF_SET()) ? 1 : 0) == ((VF_SET()) ? 1 : 0)) -#define cond_LE (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0) || (ZF_SET())) +#define cond_LE (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0) || (ZF_SET())) #define cond_NLE (((NF_SET()) ? 1 : 0) == ((VF_SET()) ? 1 : 0) && (!ZF_SET())) -#define opJ(condition) \ - static int opJ ## condition(uint32_t fetchdat) \ - { \ - int8_t offset = (int8_t)getbytef(); \ - CLOCK_CYCLES(timing_bnt); \ - if (cond_ ## condition) \ - { \ - cpu_state.pc += offset; \ - if (!(cpu_state.op32 & 0x100)) \ - cpu_state.pc &= 0xffff; \ - CLOCK_CYCLES_ALWAYS(timing_bt); \ - CPU_BLOCK_END(); \ - PREFETCH_RUN(timing_bt+timing_bnt, 2, -1, 0,0,0,0, 0); \ - PREFETCH_FLUSH(); \ - return 1; \ - } \ - PREFETCH_RUN(timing_bnt, 2, -1, 0,0,0,0, 0); \ - return 0; \ - } \ - \ - static int opJ ## condition ## _w(uint32_t fetchdat) \ - { \ - int16_t offset = (int16_t)getwordf(); \ - CLOCK_CYCLES(timing_bnt); \ - if (cond_ ## condition) \ - { \ - cpu_state.pc += offset; \ - cpu_state.pc &= 0xffff; \ - CLOCK_CYCLES_ALWAYS(timing_bt); \ - CPU_BLOCK_END(); \ - PREFETCH_RUN(timing_bt+timing_bnt, 3, -1, 0,0,0,0, 0); \ - PREFETCH_FLUSH(); \ - return 1; \ - } \ - PREFETCH_RUN(timing_bnt, 3, -1, 0,0,0,0, 0); \ - return 0; \ - } \ - \ - static int opJ ## condition ## _l(uint32_t fetchdat) \ - { \ - uint32_t offset = getlong(); if (cpu_state.abrt) return 1; \ - CLOCK_CYCLES(timing_bnt); \ - if (cond_ ## condition) \ - { \ - cpu_state.pc += offset; \ - CLOCK_CYCLES_ALWAYS(timing_bt); \ - CPU_BLOCK_END(); \ - PREFETCH_RUN(timing_bt+timing_bnt, 5, -1, 0,0,0,0, 0); \ - PREFETCH_FLUSH(); \ - return 1; \ - } \ - PREFETCH_RUN(timing_bnt, 5, -1, 0,0,0,0, 0); \ - return 0; \ - } \ +#define opJ(condition) \ + static int opJ##condition(uint32_t fetchdat) \ + { \ + int8_t offset = (int8_t) getbytef(); \ + CLOCK_CYCLES(timing_bnt); \ + if (cond_##condition) { \ + cpu_state.pc += offset; \ + if (!(cpu_state.op32 & 0x100)) \ + cpu_state.pc &= 0xffff; \ + CLOCK_CYCLES_ALWAYS(timing_bt); \ + CPU_BLOCK_END(); \ + PREFETCH_RUN(timing_bt + timing_bnt, 2, -1, 0, 0, 0, 0, 0); \ + PREFETCH_FLUSH(); \ + return 1; \ + } \ + PREFETCH_RUN(timing_bnt, 2, -1, 0, 0, 0, 0, 0); \ + return 0; \ + } \ + \ + static int opJ##condition##_w(uint32_t fetchdat) \ + { \ + int16_t offset = (int16_t) getwordf(); \ + CLOCK_CYCLES(timing_bnt); \ + if (cond_##condition) { \ + cpu_state.pc += offset; \ + cpu_state.pc &= 0xffff; \ + CLOCK_CYCLES_ALWAYS(timing_bt); \ + CPU_BLOCK_END(); \ + PREFETCH_RUN(timing_bt + timing_bnt, 3, -1, 0, 0, 0, 0, 0); \ + PREFETCH_FLUSH(); \ + return 1; \ + } \ + PREFETCH_RUN(timing_bnt, 3, -1, 0, 0, 0, 0, 0); \ + return 0; \ + } \ + \ + static int opJ##condition##_l(uint32_t fetchdat) \ + { \ + uint32_t offset = getlong(); \ + if (cpu_state.abrt) \ + return 1; \ + CLOCK_CYCLES(timing_bnt); \ + if (cond_##condition) { \ + cpu_state.pc += offset; \ + CLOCK_CYCLES_ALWAYS(timing_bt); \ + CPU_BLOCK_END(); \ + PREFETCH_RUN(timing_bt + timing_bnt, 5, -1, 0, 0, 0, 0, 0); \ + PREFETCH_FLUSH(); \ + return 1; \ + } \ + PREFETCH_RUN(timing_bnt, 5, -1, 0, 0, 0, 0, 0); \ + return 0; \ + } opJ(O) opJ(NO) @@ -87,294 +86,321 @@ opJ(NL) opJ(LE) opJ(NLE) - - -static int opLOOPNE_w(uint32_t fetchdat) + static int opLOOPNE_w(uint32_t fetchdat) { - int8_t offset = (int8_t)getbytef(); - CX--; - CLOCK_CYCLES((is486) ? 7 : 11); - PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0); - if (CX && !ZF_SET()) - { - cpu_state.pc += offset; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; -} -static int opLOOPNE_l(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - ECX--; - CLOCK_CYCLES((is486) ? 7 : 11); - PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0); - if (ECX && !ZF_SET()) - { - cpu_state.pc += offset; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; -} - -static int opLOOPE_w(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - CX--; - CLOCK_CYCLES((is486) ? 7 : 11); - PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0); - if (CX && ZF_SET()) - { - cpu_state.pc += offset; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; -} -static int opLOOPE_l(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - ECX--; - CLOCK_CYCLES((is486) ? 7 : 11); - PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0); - if (ECX && ZF_SET()) - { - cpu_state.pc += offset; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; -} - -static int opLOOP_w(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - CX--; - CLOCK_CYCLES((is486) ? 7 : 11); - PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0); - if (CX) - { - cpu_state.pc += offset; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; -} -static int opLOOP_l(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - ECX--; - CLOCK_CYCLES((is486) ? 7 : 11); - PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0); - if (ECX) - { - cpu_state.pc += offset; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; -} - -static int opJCXZ(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - CLOCK_CYCLES(5); - if (!CX) - { - cpu_state.pc += offset; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CLOCK_CYCLES(4); - CPU_BLOCK_END(); - PREFETCH_RUN(9, 2, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - return 1; - } - PREFETCH_RUN(5, 2, -1, 0,0,0,0, 0); - return 0; -} -static int opJECXZ(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - CLOCK_CYCLES(5); - if (!ECX) - { - cpu_state.pc += offset; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CLOCK_CYCLES(4); - CPU_BLOCK_END(); - PREFETCH_RUN(9, 2, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - return 1; - } - PREFETCH_RUN(5, 2, -1, 0,0,0,0, 0); - return 0; -} - - -static int opJMP_r8(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); + int8_t offset = (int8_t) getbytef(); + CX--; + CLOCK_CYCLES((is486) ? 7 : 11); + PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0); + if (CX && !ZF_SET()) { cpu_state.pc += offset; if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); - CLOCK_CYCLES((is486) ? 3 : 7); - PREFETCH_RUN(7, 2, -1, 0,0,0,0, 0); PREFETCH_FLUSH(); - return 0; + return 1; + } + return 0; } -static int opJMP_r16(uint32_t fetchdat) +static int +opLOOPNE_l(uint32_t fetchdat) { - int16_t offset = (int16_t)getwordf(); + int8_t offset = (int8_t) getbytef(); + ECX--; + CLOCK_CYCLES((is486) ? 7 : 11); + PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0); + if (ECX && !ZF_SET()) { cpu_state.pc += offset; - cpu_state.pc &= 0xffff; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); - CLOCK_CYCLES((is486) ? 3 : 7); - PREFETCH_RUN(7, 3, -1, 0,0,0,0, 0); PREFETCH_FLUSH(); - return 0; + return 1; + } + return 0; } -static int opJMP_r32(uint32_t fetchdat) + +static int +opLOOPE_w(uint32_t fetchdat) { - int32_t offset = (int32_t)getlong(); if (cpu_state.abrt) return 1; + int8_t offset = (int8_t) getbytef(); + CX--; + CLOCK_CYCLES((is486) ? 7 : 11); + PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0); + if (CX && ZF_SET()) { cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); - CLOCK_CYCLES((is486) ? 3 : 7); - PREFETCH_RUN(7, 5, -1, 0,0,0,0, 0); PREFETCH_FLUSH(); - return 0; + return 1; + } + return 0; +} +static int +opLOOPE_l(uint32_t fetchdat) +{ + int8_t offset = (int8_t) getbytef(); + ECX--; + CLOCK_CYCLES((is486) ? 7 : 11); + PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0); + if (ECX && ZF_SET()) { + cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; + CPU_BLOCK_END(); + PREFETCH_FLUSH(); + return 1; + } + return 0; } -static int opJMP_far_a16(uint32_t fetchdat) +static int +opLOOP_w(uint32_t fetchdat) { - uint16_t addr, seg; - uint32_t old_pc; - addr = getwordf(); - seg = getword(); if (cpu_state.abrt) return 1; - old_pc = cpu_state.pc; - cpu_state.pc = addr; - loadcsjmp(seg, old_pc); + int8_t offset = (int8_t) getbytef(); + CX--; + CLOCK_CYCLES((is486) ? 7 : 11); + PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0); + if (CX) { + cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); - PREFETCH_RUN(11, 5, -1, 0,0,0,0, 0); PREFETCH_FLUSH(); - return 0; + return 1; + } + return 0; } -static int opJMP_far_a32(uint32_t fetchdat) +static int +opLOOP_l(uint32_t fetchdat) { - uint16_t seg; - uint32_t addr, old_pc; - addr = getlong(); - seg = getword(); if (cpu_state.abrt) return 1; - old_pc = cpu_state.pc; - cpu_state.pc = addr; - loadcsjmp(seg, old_pc); + int8_t offset = (int8_t) getbytef(); + ECX--; + CLOCK_CYCLES((is486) ? 7 : 11); + PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0); + if (ECX) { + cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); - PREFETCH_RUN(11, 7, -1, 0,0,0,0, 0); PREFETCH_FLUSH(); - return 0; + return 1; + } + return 0; } -static int opCALL_r16(uint32_t fetchdat) +static int +opJCXZ(uint32_t fetchdat) { - int16_t addr = (int16_t)getwordf(); - PUSH_W(cpu_state.pc); - cpu_state.pc += addr; + int8_t offset = (int8_t) getbytef(); + CLOCK_CYCLES(5); + if (!CX) { + cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; + CLOCK_CYCLES(4); + CPU_BLOCK_END(); + PREFETCH_RUN(9, 2, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 1; + } + PREFETCH_RUN(5, 2, -1, 0, 0, 0, 0, 0); + return 0; +} +static int +opJECXZ(uint32_t fetchdat) +{ + int8_t offset = (int8_t) getbytef(); + CLOCK_CYCLES(5); + if (!ECX) { + cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; + CLOCK_CYCLES(4); + CPU_BLOCK_END(); + PREFETCH_RUN(9, 2, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 1; + } + PREFETCH_RUN(5, 2, -1, 0, 0, 0, 0, 0); + return 0; +} + +static int +opJMP_r8(uint32_t fetchdat) +{ + int8_t offset = (int8_t) getbytef(); + cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - CLOCK_CYCLES((is486) ? 3 : 7); - PREFETCH_RUN(7, 3, -1, 0,0,1,0, 0); - PREFETCH_FLUSH(); - return 0; + CPU_BLOCK_END(); + CLOCK_CYCLES((is486) ? 3 : 7); + PREFETCH_RUN(7, 2, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } -static int opCALL_r32(uint32_t fetchdat) +static int +opJMP_r16(uint32_t fetchdat) { - int32_t addr = getlong(); if (cpu_state.abrt) return 1; - PUSH_L(cpu_state.pc); - cpu_state.pc += addr; - CPU_BLOCK_END(); - CLOCK_CYCLES((is486) ? 3 : 7); - PREFETCH_RUN(7, 5, -1, 0,0,0,1, 0); - PREFETCH_FLUSH(); - return 0; + int16_t offset = (int16_t) getwordf(); + cpu_state.pc += offset; + cpu_state.pc &= 0xffff; + CPU_BLOCK_END(); + CLOCK_CYCLES((is486) ? 3 : 7); + PREFETCH_RUN(7, 3, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } - -static int opRET_w(uint32_t fetchdat) +static int +opJMP_r32(uint32_t fetchdat) { - uint16_t ret; - - ret = POP_W(); if (cpu_state.abrt) return 1; - cpu_state.pc = ret; - CPU_BLOCK_END(); - - CLOCK_CYCLES((is486) ? 5 : 10); - PREFETCH_RUN(10, 1, -1, 1,0,0,0, 0); - PREFETCH_FLUSH(); - return 0; + int32_t offset = (int32_t) getlong(); + if (cpu_state.abrt) + return 1; + cpu_state.pc += offset; + CPU_BLOCK_END(); + CLOCK_CYCLES((is486) ? 3 : 7); + PREFETCH_RUN(7, 5, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } -static int opRET_l(uint32_t fetchdat) + +static int +opJMP_far_a16(uint32_t fetchdat) { - uint32_t ret; - - ret = POP_L(); if (cpu_state.abrt) return 1; - cpu_state.pc = ret; - CPU_BLOCK_END(); - - CLOCK_CYCLES((is486) ? 5 : 10); - PREFETCH_RUN(10, 1, -1, 0,1,0,0, 0); - PREFETCH_FLUSH(); - return 0; + uint16_t addr, seg; + uint32_t old_pc; + addr = getwordf(); + seg = getword(); + if (cpu_state.abrt) + return 1; + old_pc = cpu_state.pc; + cpu_state.pc = addr; + loadcsjmp(seg, old_pc); + CPU_BLOCK_END(); + PREFETCH_RUN(11, 5, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } - -static int opRET_w_imm(uint32_t fetchdat) +static int +opJMP_far_a32(uint32_t fetchdat) { - uint16_t ret; - uint16_t offset = getwordf(); - - ret = POP_W(); if (cpu_state.abrt) return 1; - if (stack32) ESP += offset; - else SP += offset; - cpu_state.pc = ret; - CPU_BLOCK_END(); - - CLOCK_CYCLES((is486) ? 5 : 10); - PREFETCH_RUN(10, 5, -1, 1,0,0,0, 0); - PREFETCH_FLUSH(); - return 0; + uint16_t seg; + uint32_t addr, old_pc; + addr = getlong(); + seg = getword(); + if (cpu_state.abrt) + return 1; + old_pc = cpu_state.pc; + cpu_state.pc = addr; + loadcsjmp(seg, old_pc); + CPU_BLOCK_END(); + PREFETCH_RUN(11, 7, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } -static int opRET_l_imm(uint32_t fetchdat) + +static int +opCALL_r16(uint32_t fetchdat) { - uint32_t ret; - uint16_t offset = getwordf(); - - ret = POP_L(); if (cpu_state.abrt) return 1; - if (stack32) ESP += offset; - else SP += offset; - cpu_state.pc = ret; - CPU_BLOCK_END(); - - CLOCK_CYCLES((is486) ? 5 : 10); - PREFETCH_RUN(10, 5, -1, 0,1,0,0, 0); - PREFETCH_FLUSH(); - return 0; + int16_t addr = (int16_t) getwordf(); + PUSH_W(cpu_state.pc); + cpu_state.pc += addr; + cpu_state.pc &= 0xffff; + CPU_BLOCK_END(); + CLOCK_CYCLES((is486) ? 3 : 7); + PREFETCH_RUN(7, 3, -1, 0, 0, 1, 0, 0); + PREFETCH_FLUSH(); + return 0; +} +static int +opCALL_r32(uint32_t fetchdat) +{ + int32_t addr = getlong(); + if (cpu_state.abrt) + return 1; + PUSH_L(cpu_state.pc); + cpu_state.pc += addr; + CPU_BLOCK_END(); + CLOCK_CYCLES((is486) ? 3 : 7); + PREFETCH_RUN(7, 5, -1, 0, 0, 0, 1, 0); + PREFETCH_FLUSH(); + return 0; +} + +static int +opRET_w(uint32_t fetchdat) +{ + uint16_t ret; + + ret = POP_W(); + if (cpu_state.abrt) + return 1; + cpu_state.pc = ret; + CPU_BLOCK_END(); + + CLOCK_CYCLES((is486) ? 5 : 10); + PREFETCH_RUN(10, 1, -1, 1, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; +} +static int +opRET_l(uint32_t fetchdat) +{ + uint32_t ret; + + ret = POP_L(); + if (cpu_state.abrt) + return 1; + cpu_state.pc = ret; + CPU_BLOCK_END(); + + CLOCK_CYCLES((is486) ? 5 : 10); + PREFETCH_RUN(10, 1, -1, 0, 1, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; +} + +static int +opRET_w_imm(uint32_t fetchdat) +{ + uint16_t ret; + uint16_t offset = getwordf(); + + ret = POP_W(); + if (cpu_state.abrt) + return 1; + if (stack32) + ESP += offset; + else + SP += offset; + cpu_state.pc = ret; + CPU_BLOCK_END(); + + CLOCK_CYCLES((is486) ? 5 : 10); + PREFETCH_RUN(10, 5, -1, 1, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; +} +static int +opRET_l_imm(uint32_t fetchdat) +{ + uint32_t ret; + uint16_t offset = getwordf(); + + ret = POP_L(); + if (cpu_state.abrt) + return 1; + if (stack32) + ESP += offset; + else + SP += offset; + cpu_state.pc = ret; + CPU_BLOCK_END(); + + CLOCK_CYCLES((is486) ? 5 : 10); + PREFETCH_RUN(10, 5, -1, 0, 1, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index 7fde5dacc..bd1139ba4 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -1,971 +1,1058 @@ -static int opCBW(uint32_t fetchdat) +static int +opCBW(uint32_t fetchdat) { - AH = (AL & 0x80) ? 0xff : 0; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + AH = (AL & 0x80) ? 0xff : 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opCWDE(uint32_t fetchdat) +static int +opCWDE(uint32_t fetchdat) { - EAX = (AX & 0x8000) ? (0xffff0000 | AX) : AX; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + EAX = (AX & 0x8000) ? (0xffff0000 | AX) : AX; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opCWD(uint32_t fetchdat) +static int +opCWD(uint32_t fetchdat) { - DX = (AX & 0x8000) ? 0xFFFF : 0; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; + DX = (AX & 0x8000) ? 0xFFFF : 0; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opCDQ(uint32_t fetchdat) +static int +opCDQ(uint32_t fetchdat) { - EDX = (EAX & 0x80000000) ? 0xffffffff : 0; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; + EDX = (EAX & 0x80000000) ? 0xffffffff : 0; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opNOP(uint32_t fetchdat) +static int +opNOP(uint32_t fetchdat) { - CLOCK_CYCLES((is486) ? 1 : 3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + CLOCK_CYCLES((is486) ? 1 : 3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opSETALC(uint32_t fetchdat) +static int +opSETALC(uint32_t fetchdat) { - AL = (CF_SET()) ? 0xff : 0; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 1, -1, 0,0,0,0, 0); - return 0; + AL = (CF_SET()) ? 0xff : 0; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 1, -1, 0, 0, 0, 0, 0); + return 0; } - - -static int opF6_a16(uint32_t fetchdat) +static int +opF6_a16(uint32_t fetchdat) { - int tempws, tempws2 = 0; - uint16_t tempw, src16; - uint8_t src, dst; - int8_t temps; + int tempws, tempws2 = 0; + uint16_t tempw, src16; + uint8_t src, dst; + int8_t temps; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); - } - dst = geteab(); if (cpu_state.abrt) return 1; - switch (rmdat & 0x38) - { - case 0x00: /*TEST b,#8*/ - case 0x08: - src = readmemb(cs, cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; - setznp8(src & dst); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x10: /*NOT b*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteab(~dst); if (cpu_state.abrt) return 1; - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - break; - case 0x18: /*NEG b*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteab(0 - dst); if (cpu_state.abrt) return 1; - setsub8(0, dst); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - break; - case 0x20: /*MUL AL,b*/ - AX = AL * dst; - flags_rebuild(); - if (AH) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(13); - PREFETCH_RUN(13, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x28: /*IMUL AL,b*/ - tempws = (int)((int8_t)AL) * (int)((int8_t)dst); - AX = tempws & 0xffff; - flags_rebuild(); - if (((int16_t)AX >> 7) != 0 && ((int16_t)AX >> 7) != -1) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x30: /*DIV AL,b*/ - src16 = AX; - if (dst) tempw = src16 / dst; - if (dst && !(tempw & 0xff00)) - { - AH = src16 % dst; - AL = (src16 / dst) &0xff; - if (!cpu_iscyrix) - { - flags_rebuild(); - cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ - cpu_state.flags &= ~1; - } - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 16 : 14); - PREFETCH_RUN((is486 && !cpu_iscyrix) ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x38: /*IDIV AL,b*/ - tempws = (int)(int16_t)AX; - if (dst != 0) tempws2 = tempws / (int)((int8_t)dst); - temps = tempws2 & 0xff; - if (dst && ((int)temps == tempws2)) - { - AH = (tempws % (int)((int8_t)dst)) & 0xff; - AL = tempws2 & 0xff; - if (!cpu_iscyrix) - { - flags_rebuild(); - cpu_state.flags|=0x8D5; /*Not a Cyrix*/ - cpu_state.flags &= ~1; - } - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES(19); - PREFETCH_RUN(19, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - - default: - x86illegal(); - } - return 0; -} -static int opF6_a32(uint32_t fetchdat) -{ - int tempws, tempws2 = 0; - uint16_t tempw, src16; - uint8_t src, dst; - int8_t temps; - - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteab(); if (cpu_state.abrt) return 1; - switch (rmdat & 0x38) - { - case 0x00: /*TEST b,#8*/ - case 0x08: - src = readmemb(cs, cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; - setznp8(src & dst); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x10: /*NOT b*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteab(~dst); if (cpu_state.abrt) return 1; - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - break; - case 0x18: /*NEG b*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteab(0 - dst); if (cpu_state.abrt) return 1; - setsub8(0, dst); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - break; - case 0x20: /*MUL AL,b*/ - AX = AL * dst; - flags_rebuild(); - if (AH) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(13); - PREFETCH_RUN(13, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x28: /*IMUL AL,b*/ - tempws = (int)((int8_t)AL) * (int)((int8_t)dst); - AX = tempws & 0xffff; - flags_rebuild(); - if (((int16_t)AX >> 7) != 0 && ((int16_t)AX >> 7) != -1) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x30: /*DIV AL,b*/ - src16 = AX; - if (dst) tempw = src16 / dst; - if (dst && !(tempw & 0xff00)) - { - AH = src16 % dst; - AL = (src16 / dst) &0xff; - if (!cpu_iscyrix) - { - flags_rebuild(); - cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ - cpu_state.flags &= ~1; - } - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 16 : 14); - PREFETCH_RUN((is486 && !cpu_iscyrix) ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x38: /*IDIV AL,b*/ - tempws = (int)(int16_t)AX; - if (dst != 0) tempws2 = tempws / (int)((int8_t)dst); - temps = tempws2 & 0xff; - if (dst && ((int)temps == tempws2)) - { - AH = (tempws % (int)((int8_t)dst)) & 0xff; - AL = tempws2 & 0xff; - if (!cpu_iscyrix) - { - flags_rebuild(); - cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ - cpu_state.flags &= ~1; - } - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES(19); - PREFETCH_RUN(19, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - - default: - x86illegal(); - } - return 0; -} - - - -static int opF7_w_a16(uint32_t fetchdat) -{ - uint32_t templ, templ2 = 0; - int tempws, tempws2 = 0; - int16_t temps16; - uint16_t src, dst; - - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteaw(); if (cpu_state.abrt) return 1; - switch (rmdat & 0x38) - { - case 0x00: /*TEST w*/ - case 0x08: - src = getword(); if (cpu_state.abrt) return 1; - setznp16(src & dst); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x10: /*NOT w*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(~dst); if (cpu_state.abrt) return 1; - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - break; - case 0x18: /*NEG w*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(0 - dst); if (cpu_state.abrt) return 1; - setsub16(0, dst); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - break; - case 0x20: /*MUL AX,w*/ - templ = AX * dst; - AX = templ & 0xFFFF; - DX = templ >> 16; - flags_rebuild(); - if (DX) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(21); - PREFETCH_RUN(21, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x28: /*IMUL AX,w*/ - templ = (int)((int16_t)AX) * (int)((int16_t)dst); - AX = templ & 0xFFFF; - DX = templ >> 16; - flags_rebuild(); - if (((int32_t)templ >> 15) != 0 && ((int32_t)templ >> 15) != -1) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(22); - PREFETCH_RUN(22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x30: /*DIV AX,w*/ - templ = (DX << 16) | AX; - if (dst) templ2 = templ / dst; - if (dst && !(templ2 & 0xffff0000)) - { - DX = templ % dst; - AX = (templ / dst) & 0xffff; - if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/ - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 24 : 22); - PREFETCH_RUN((is486 && !cpu_iscyrix) ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x38: /*IDIV AX,w*/ - tempws = (int)((DX << 16)|AX); - if (dst) tempws2 = tempws / (int)((int16_t)dst); - temps16 = tempws2 & 0xffff; - if ((dst != 0) && ((int)temps16 == tempws2)) - { - DX = tempws % (int)((int16_t)dst); - AX = tempws2 & 0xffff; - if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/ - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES(27); - PREFETCH_RUN(27, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - - default: - x86illegal(); - } - return 0; -} -static int opF7_w_a32(uint32_t fetchdat) -{ - uint32_t templ, templ2 = 0; - int tempws, tempws2 = 1; - int16_t temps16; - uint16_t src, dst; - - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteaw(); if (cpu_state.abrt) return 1; - switch (rmdat & 0x38) - { - case 0x00: /*TEST w*/ - case 0x08: - src = getword(); if (cpu_state.abrt) return 1; - setznp16(src & dst); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x10: /*NOT w*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(~dst); if (cpu_state.abrt) return 1; - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - break; - case 0x18: /*NEG w*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(0 - dst); if (cpu_state.abrt) return 1; - setsub16(0, dst); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - break; - case 0x20: /*MUL AX,w*/ - templ = AX * dst; - AX = templ & 0xFFFF; - DX = templ >> 16; - flags_rebuild(); - if (DX) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(21); - PREFETCH_RUN(21, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x28: /*IMUL AX,w*/ - templ = (int)((int16_t)AX) * (int)((int16_t)dst); - AX = templ & 0xFFFF; - DX = templ >> 16; - flags_rebuild(); - if (((int32_t)templ >> 15) != 0 && ((int32_t)templ >> 15) != -1) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(22); - PREFETCH_RUN(22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x30: /*DIV AX,w*/ - templ = (DX << 16) | AX; - if (dst) templ2 = templ / dst; - if (dst && !(templ2 & 0xffff0000)) - { - DX = templ % dst; - AX = (templ / dst) & 0xffff; - if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/ - } - else - { -// fatal("DIVw BY 0 %04X:%04X %i\n",cs>>4,pc,ins); - x86_int(0); - return 1; - } - CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 24 : 22); - PREFETCH_RUN((is486 && !cpu_iscyrix) ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x38: /*IDIV AX,w*/ - tempws = (int)((DX << 16)|AX); - if (dst) tempws2 = tempws / (int)((int16_t)dst); - temps16 = tempws2 & 0xffff; - if ((dst != 0) && ((int)temps16 == tempws2)) - { - DX = tempws % (int)((int16_t)dst); - AX = tempws2 & 0xffff; - if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/ - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES(27); - PREFETCH_RUN(27, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - - default: - x86illegal(); - } - return 0; -} - -static int opF7_l_a16(uint32_t fetchdat) -{ - uint64_t temp64; - uint32_t src, dst; - - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteal(); if (cpu_state.abrt) return 1; - - switch (rmdat & 0x38) - { - case 0x00: /*TEST l*/ - case 0x08: - src = getlong(); if (cpu_state.abrt) return 1; - setznp32(src & dst); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - break; - case 0x10: /*NOT l*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(~dst); if (cpu_state.abrt) return 1; - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - break; - case 0x18: /*NEG l*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(0 - dst); if (cpu_state.abrt) return 1; - setsub32(0, dst); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - break; - case 0x20: /*MUL EAX,l*/ - temp64 = (uint64_t)EAX * (uint64_t)dst; - EAX = temp64 & 0xffffffff; - EDX = temp64 >> 32; - flags_rebuild(); - if (EDX) cpu_state.flags |= (C_FLAG|V_FLAG); - else cpu_state.flags &= ~(C_FLAG|V_FLAG); - CLOCK_CYCLES(21); - PREFETCH_RUN(21, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - break; - case 0x28: /*IMUL EAX,l*/ - temp64 = (int64_t)(int32_t)EAX * (int64_t)(int32_t)dst; - EAX = temp64 & 0xffffffff; - EDX = temp64 >> 32; - flags_rebuild(); - if (((int64_t)temp64 >> 31) != 0 && ((int64_t)temp64 >> 31) != -1) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(38); - PREFETCH_RUN(38, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - break; - case 0x30: /*DIV EAX,l*/ - if (divl(dst)) - return 1; - if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ - CLOCK_CYCLES((is486) ? 40 : 38); - PREFETCH_RUN(is486 ? 40:38, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - break; - case 0x38: /*IDIV EAX,l*/ - if (idivl((int32_t)dst)) - return 1; - if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ - CLOCK_CYCLES(43); - PREFETCH_RUN(43, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - break; - - default: - x86illegal(); - } - return 0; -} -static int opF7_l_a32(uint32_t fetchdat) -{ - uint64_t temp64; - uint32_t src, dst; - - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteal(); if (cpu_state.abrt) return 1; - - switch (rmdat & 0x38) - { - case 0x00: /*TEST l*/ - case 0x08: - src = getlong(); if (cpu_state.abrt) return 1; - setznp32(src & dst); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - break; - case 0x10: /*NOT l*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(~dst); if (cpu_state.abrt) return 1; - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - break; - case 0x18: /*NEG l*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(0 - dst); if (cpu_state.abrt) return 1; - setsub32(0, dst); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - break; - case 0x20: /*MUL EAX,l*/ - temp64 = (uint64_t)EAX * (uint64_t)dst; - EAX = temp64 & 0xffffffff; - EDX = temp64 >> 32; - flags_rebuild(); - if (EDX) cpu_state.flags |= (C_FLAG|V_FLAG); - else cpu_state.flags &= ~(C_FLAG|V_FLAG); - CLOCK_CYCLES(21); - PREFETCH_RUN(21, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - break; - case 0x28: /*IMUL EAX,l*/ - temp64 = (int64_t)(int32_t)EAX * (int64_t)(int32_t)dst; - EAX = temp64 & 0xffffffff; - EDX = temp64 >> 32; - flags_rebuild(); - if (((int64_t)temp64 >> 31) != 0 && ((int64_t)temp64 >> 31) != -1) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(38); - PREFETCH_RUN(38, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - break; - case 0x30: /*DIV EAX,l*/ - if (divl(dst)) - return 1; - if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ - CLOCK_CYCLES((is486) ? 40 : 38); - PREFETCH_RUN(is486 ? 40 : 38, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - break; - case 0x38: /*IDIV EAX,l*/ - if (idivl((int32_t)dst)) - return 1; - if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ - CLOCK_CYCLES(43); - PREFETCH_RUN(43, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - break; - - default: - x86illegal(); - } - return 0; -} - - -static int opHLT(uint32_t fetchdat) -{ - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL,0); - return 1; - } - if (smi_line) - enter_smm_check(1); - else if (!((cpu_state.flags & I_FLAG) && pic.int_pending)) - { - CLOCK_CYCLES_ALWAYS(100); - if (!((cpu_state.flags & I_FLAG) && pic.int_pending)) - cpu_state.pc--; - } - else { - CLOCK_CYCLES(5); - } - - CPU_BLOCK_END(); - PREFETCH_RUN(100, 1, -1, 0,0,0,0, 0); - - if (hlt_reset_pending) - softresetx86(); - - return 0; -} - - -static int opLOCK(uint32_t fetchdat) -{ - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 0; - cpu_state.pc++; - - ILLEGAL_ON((fetchdat & 0xff) == 0x90); - - CLOCK_CYCLES(4); - PREFETCH_PREFIX(); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); -} - - - -static int opBOUND_w_a16(uint32_t fetchdat) -{ - int16_t low, high; - - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) { SEG_CHECK_READ(cpu_state.ea_seg); - low = geteaw(); - high = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - - if (((int16_t)cpu_state.regs[cpu_reg].w < low) || ((int16_t)cpu_state.regs[cpu_reg].w > high)) - { - x86_int(5); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); + } + dst = geteab(); + if (cpu_state.abrt) + return 1; + switch (rmdat & 0x38) { + case 0x00: /*TEST b,#8*/ + case 0x08: + src = readmemb(cs, cpu_state.pc); + cpu_state.pc++; + if (cpu_state.abrt) return 1; - } + setznp8(src & dst); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; + case 0x10: /*NOT b*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteab(~dst); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + break; + case 0x18: /*NEG b*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteab(0 - dst); + if (cpu_state.abrt) + return 1; + setsub8(0, dst); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + break; + case 0x20: /*MUL AL,b*/ + AX = AL * dst; + flags_rebuild(); + if (AH) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(13); + PREFETCH_RUN(13, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; + case 0x28: /*IMUL AL,b*/ + tempws = (int) ((int8_t) AL) * (int) ((int8_t) dst); + AX = tempws & 0xffff; + flags_rebuild(); + if (((int16_t) AX >> 7) != 0 && ((int16_t) AX >> 7) != -1) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; + case 0x30: /*DIV AL,b*/ + src16 = AX; + if (dst) + tempw = src16 / dst; + if (dst && !(tempw & 0xff00)) { + AH = src16 % dst; + AL = (src16 / dst) & 0xff; + if (!cpu_iscyrix) { + flags_rebuild(); + cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ + cpu_state.flags &= ~1; + } + } else { + x86_int(0); + return 1; + } + CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 16 : 14); + PREFETCH_RUN((is486 && !cpu_iscyrix) ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; + case 0x38: /*IDIV AL,b*/ + tempws = (int) (int16_t) AX; + if (dst != 0) + tempws2 = tempws / (int) ((int8_t) dst); + temps = tempws2 & 0xff; + if (dst && ((int) temps == tempws2)) { + AH = (tempws % (int) ((int8_t) dst)) & 0xff; + AL = tempws2 & 0xff; + if (!cpu_iscyrix) { + flags_rebuild(); + cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ + cpu_state.flags &= ~1; + } + } else { + x86_int(0); + return 1; + } + CLOCK_CYCLES(19); + PREFETCH_RUN(19, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; - CLOCK_CYCLES(is486 ? 7 : 10); - PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 2,0,0,0, 0); - return 0; + default: + x86illegal(); + } + return 0; } -static int opBOUND_w_a32(uint32_t fetchdat) +static int +opF6_a32(uint32_t fetchdat) { - int16_t low, high; + int tempws, tempws2 = 0; + uint16_t tempw, src16; + uint8_t src, dst; + int8_t temps; - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - low = geteaw(); - high = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - - if (((int16_t)cpu_state.regs[cpu_reg].w < low) || ((int16_t)cpu_state.regs[cpu_reg].w > high)) - { - x86_int(5); + dst = geteab(); + if (cpu_state.abrt) + return 1; + switch (rmdat & 0x38) { + case 0x00: /*TEST b,#8*/ + case 0x08: + src = readmemb(cs, cpu_state.pc); + cpu_state.pc++; + if (cpu_state.abrt) return 1; - } + setznp8(src & dst); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; + case 0x10: /*NOT b*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteab(~dst); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + break; + case 0x18: /*NEG b*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteab(0 - dst); + if (cpu_state.abrt) + return 1; + setsub8(0, dst); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + break; + case 0x20: /*MUL AL,b*/ + AX = AL * dst; + flags_rebuild(); + if (AH) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(13); + PREFETCH_RUN(13, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; + case 0x28: /*IMUL AL,b*/ + tempws = (int) ((int8_t) AL) * (int) ((int8_t) dst); + AX = tempws & 0xffff; + flags_rebuild(); + if (((int16_t) AX >> 7) != 0 && ((int16_t) AX >> 7) != -1) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; + case 0x30: /*DIV AL,b*/ + src16 = AX; + if (dst) + tempw = src16 / dst; + if (dst && !(tempw & 0xff00)) { + AH = src16 % dst; + AL = (src16 / dst) & 0xff; + if (!cpu_iscyrix) { + flags_rebuild(); + cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ + cpu_state.flags &= ~1; + } + } else { + x86_int(0); + return 1; + } + CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 16 : 14); + PREFETCH_RUN((is486 && !cpu_iscyrix) ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; + case 0x38: /*IDIV AL,b*/ + tempws = (int) (int16_t) AX; + if (dst != 0) + tempws2 = tempws / (int) ((int8_t) dst); + temps = tempws2 & 0xff; + if (dst && ((int) temps == tempws2)) { + AH = (tempws % (int) ((int8_t) dst)) & 0xff; + AL = tempws2 & 0xff; + if (!cpu_iscyrix) { + flags_rebuild(); + cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ + cpu_state.flags &= ~1; + } + } else { + x86_int(0); + return 1; + } + CLOCK_CYCLES(19); + PREFETCH_RUN(19, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; - CLOCK_CYCLES(is486 ? 7 : 10); - PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 2,0,0,0, 1); - return 0; + default: + x86illegal(); + } + return 0; } -static int opBOUND_l_a16(uint32_t fetchdat) +static int +opF7_w_a16(uint32_t fetchdat) { - int32_t low, high; + uint32_t templ, templ2 = 0; + int tempws, tempws2 = 0; + int16_t temps16; + uint16_t src, dst; - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - low = geteal(); - high = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - - if (((int32_t)cpu_state.regs[cpu_reg].l < low) || ((int32_t)cpu_state.regs[cpu_reg].l > high)) - { - x86_int(5); + dst = geteaw(); + if (cpu_state.abrt) + return 1; + switch (rmdat & 0x38) { + case 0x00: /*TEST w*/ + case 0x08: + src = getword(); + if (cpu_state.abrt) return 1; - } + setznp16(src & dst); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; + case 0x10: /*NOT w*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(~dst); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + break; + case 0x18: /*NEG w*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(0 - dst); + if (cpu_state.abrt) + return 1; + setsub16(0, dst); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + break; + case 0x20: /*MUL AX,w*/ + templ = AX * dst; + AX = templ & 0xFFFF; + DX = templ >> 16; + flags_rebuild(); + if (DX) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(21); + PREFETCH_RUN(21, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; + case 0x28: /*IMUL AX,w*/ + templ = (int) ((int16_t) AX) * (int) ((int16_t) dst); + AX = templ & 0xFFFF; + DX = templ >> 16; + flags_rebuild(); + if (((int32_t) templ >> 15) != 0 && ((int32_t) templ >> 15) != -1) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(22); + PREFETCH_RUN(22, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; + case 0x30: /*DIV AX,w*/ + templ = (DX << 16) | AX; + if (dst) + templ2 = templ / dst; + if (dst && !(templ2 & 0xffff0000)) { + DX = templ % dst; + AX = (templ / dst) & 0xffff; + if (!cpu_iscyrix) + setznp16(AX); /*Not a Cyrix*/ + } else { + x86_int(0); + return 1; + } + CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 24 : 22); + PREFETCH_RUN((is486 && !cpu_iscyrix) ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; + case 0x38: /*IDIV AX,w*/ + tempws = (int) ((DX << 16) | AX); + if (dst) + tempws2 = tempws / (int) ((int16_t) dst); + temps16 = tempws2 & 0xffff; + if ((dst != 0) && ((int) temps16 == tempws2)) { + DX = tempws % (int) ((int16_t) dst); + AX = tempws2 & 0xffff; + if (!cpu_iscyrix) + setznp16(AX); /*Not a Cyrix*/ + } else { + x86_int(0); + return 1; + } + CLOCK_CYCLES(27); + PREFETCH_RUN(27, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; - CLOCK_CYCLES(is486 ? 7 : 10); - PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 1,1,0,0, 0); - return 0; + default: + x86illegal(); + } + return 0; } -static int opBOUND_l_a32(uint32_t fetchdat) +static int +opF7_w_a32(uint32_t fetchdat) { - int32_t low, high; + uint32_t templ, templ2 = 0; + int tempws, tempws2 = 1; + int16_t temps16; + uint16_t src, dst; - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - low = geteal(); - high = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - - if (((int32_t)cpu_state.regs[cpu_reg].l < low) || ((int32_t)cpu_state.regs[cpu_reg].l > high)) - { - x86_int(5); + dst = geteaw(); + if (cpu_state.abrt) + return 1; + switch (rmdat & 0x38) { + case 0x00: /*TEST w*/ + case 0x08: + src = getword(); + if (cpu_state.abrt) return 1; - } + setznp16(src & dst); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; + case 0x10: /*NOT w*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(~dst); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + break; + case 0x18: /*NEG w*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(0 - dst); + if (cpu_state.abrt) + return 1; + setsub16(0, dst); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + break; + case 0x20: /*MUL AX,w*/ + templ = AX * dst; + AX = templ & 0xFFFF; + DX = templ >> 16; + flags_rebuild(); + if (DX) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(21); + PREFETCH_RUN(21, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; + case 0x28: /*IMUL AX,w*/ + templ = (int) ((int16_t) AX) * (int) ((int16_t) dst); + AX = templ & 0xFFFF; + DX = templ >> 16; + flags_rebuild(); + if (((int32_t) templ >> 15) != 0 && ((int32_t) templ >> 15) != -1) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(22); + PREFETCH_RUN(22, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; + case 0x30: /*DIV AX,w*/ + templ = (DX << 16) | AX; + if (dst) + templ2 = templ / dst; + if (dst && !(templ2 & 0xffff0000)) { + DX = templ % dst; + AX = (templ / dst) & 0xffff; + if (!cpu_iscyrix) + setznp16(AX); /*Not a Cyrix*/ + } else { + // fatal("DIVw BY 0 %04X:%04X %i\n",cs>>4,pc,ins); + x86_int(0); + return 1; + } + CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 24 : 22); + PREFETCH_RUN((is486 && !cpu_iscyrix) ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; + case 0x38: /*IDIV AX,w*/ + tempws = (int) ((DX << 16) | AX); + if (dst) + tempws2 = tempws / (int) ((int16_t) dst); + temps16 = tempws2 & 0xffff; + if ((dst != 0) && ((int) temps16 == tempws2)) { + DX = tempws % (int) ((int16_t) dst); + AX = tempws2 & 0xffff; + if (!cpu_iscyrix) + setznp16(AX); /*Not a Cyrix*/ + } else { + x86_int(0); + return 1; + } + CLOCK_CYCLES(27); + PREFETCH_RUN(27, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; - CLOCK_CYCLES(is486 ? 7 : 10); - PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 1,1,0,0, 1); - return 0; + default: + x86illegal(); + } + return 0; } - -static int opCLTS(uint32_t fetchdat) +static int +opF7_l_a16(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL,0); + uint64_t temp64; + uint32_t src, dst; + + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + dst = geteal(); + if (cpu_state.abrt) + return 1; + + switch (rmdat & 0x38) { + case 0x00: /*TEST l*/ + case 0x08: + src = getlong(); + if (cpu_state.abrt) return 1; - } - cr0 &= ~8; + setznp32(src & dst); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + break; + case 0x10: /*NOT l*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(~dst); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + break; + case 0x18: /*NEG l*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(0 - dst); + if (cpu_state.abrt) + return 1; + setsub32(0, dst); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + break; + case 0x20: /*MUL EAX,l*/ + temp64 = (uint64_t) EAX * (uint64_t) dst; + EAX = temp64 & 0xffffffff; + EDX = temp64 >> 32; + flags_rebuild(); + if (EDX) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(21); + PREFETCH_RUN(21, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + break; + case 0x28: /*IMUL EAX,l*/ + temp64 = (int64_t) (int32_t) EAX * (int64_t) (int32_t) dst; + EAX = temp64 & 0xffffffff; + EDX = temp64 >> 32; + flags_rebuild(); + if (((int64_t) temp64 >> 31) != 0 && ((int64_t) temp64 >> 31) != -1) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(38); + PREFETCH_RUN(38, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + break; + case 0x30: /*DIV EAX,l*/ + if (divl(dst)) + return 1; + if (!cpu_iscyrix) + setznp32(EAX); /*Not a Cyrix*/ + CLOCK_CYCLES((is486) ? 40 : 38); + PREFETCH_RUN(is486 ? 40 : 38, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + break; + case 0x38: /*IDIV EAX,l*/ + if (idivl((int32_t) dst)) + return 1; + if (!cpu_iscyrix) + setznp32(EAX); /*Not a Cyrix*/ + CLOCK_CYCLES(43); + PREFETCH_RUN(43, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + break; + + default: + x86illegal(); + } + return 0; +} +static int +opF7_l_a32(uint32_t fetchdat) +{ + uint64_t temp64; + uint32_t src, dst; + + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + dst = geteal(); + if (cpu_state.abrt) + return 1; + + switch (rmdat & 0x38) { + case 0x00: /*TEST l*/ + case 0x08: + src = getlong(); + if (cpu_state.abrt) + return 1; + setznp32(src & dst); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + break; + case 0x10: /*NOT l*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(~dst); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + break; + case 0x18: /*NEG l*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(0 - dst); + if (cpu_state.abrt) + return 1; + setsub32(0, dst); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + break; + case 0x20: /*MUL EAX,l*/ + temp64 = (uint64_t) EAX * (uint64_t) dst; + EAX = temp64 & 0xffffffff; + EDX = temp64 >> 32; + flags_rebuild(); + if (EDX) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(21); + PREFETCH_RUN(21, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + break; + case 0x28: /*IMUL EAX,l*/ + temp64 = (int64_t) (int32_t) EAX * (int64_t) (int32_t) dst; + EAX = temp64 & 0xffffffff; + EDX = temp64 >> 32; + flags_rebuild(); + if (((int64_t) temp64 >> 31) != 0 && ((int64_t) temp64 >> 31) != -1) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(38); + PREFETCH_RUN(38, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + break; + case 0x30: /*DIV EAX,l*/ + if (divl(dst)) + return 1; + if (!cpu_iscyrix) + setznp32(EAX); /*Not a Cyrix*/ + CLOCK_CYCLES((is486) ? 40 : 38); + PREFETCH_RUN(is486 ? 40 : 38, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + break; + case 0x38: /*IDIV EAX,l*/ + if (idivl((int32_t) dst)) + return 1; + if (!cpu_iscyrix) + setznp32(EAX); /*Not a Cyrix*/ + CLOCK_CYCLES(43); + PREFETCH_RUN(43, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + break; + + default: + x86illegal(); + } + return 0; +} + +static int +opHLT(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + if (smi_line) + enter_smm_check(1); + else if (!((cpu_state.flags & I_FLAG) && pic.int_pending)) { + CLOCK_CYCLES_ALWAYS(100); + if (!((cpu_state.flags & I_FLAG) && pic.int_pending)) + cpu_state.pc--; + } else { CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 0,0,0,0, 0); - return 0; + } + + CPU_BLOCK_END(); + PREFETCH_RUN(100, 1, -1, 0, 0, 0, 0, 0); + + if (hlt_reset_pending) + softresetx86(); + + return 0; } -static int opINVD(uint32_t fetchdat) +static int +opLOCK(uint32_t fetchdat) { - CLOCK_CYCLES(1000); + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 0; + cpu_state.pc++; + + ILLEGAL_ON((fetchdat & 0xff) == 0x90); + + CLOCK_CYCLES(4); + PREFETCH_PREFIX(); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} + +static int +opBOUND_w_a16(uint32_t fetchdat) +{ + int16_t low, high; + + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + low = geteaw(); + high = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + + if (((int16_t) cpu_state.regs[cpu_reg].w < low) || ((int16_t) cpu_state.regs[cpu_reg].w > high)) { + x86_int(5); + return 1; + } + + CLOCK_CYCLES(is486 ? 7 : 10); + PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 2, 0, 0, 0, 0); + return 0; +} +static int +opBOUND_w_a32(uint32_t fetchdat) +{ + int16_t low, high; + + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + low = geteaw(); + high = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + + if (((int16_t) cpu_state.regs[cpu_reg].w < low) || ((int16_t) cpu_state.regs[cpu_reg].w > high)) { + x86_int(5); + return 1; + } + + CLOCK_CYCLES(is486 ? 7 : 10); + PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 2, 0, 0, 0, 1); + return 0; +} + +static int +opBOUND_l_a16(uint32_t fetchdat) +{ + int32_t low, high; + + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + low = geteal(); + high = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + + if (((int32_t) cpu_state.regs[cpu_reg].l < low) || ((int32_t) cpu_state.regs[cpu_reg].l > high)) { + x86_int(5); + return 1; + } + + CLOCK_CYCLES(is486 ? 7 : 10); + PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 1, 1, 0, 0, 0); + return 0; +} +static int +opBOUND_l_a32(uint32_t fetchdat) +{ + int32_t low, high; + + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + low = geteal(); + high = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + + if (((int32_t) cpu_state.regs[cpu_reg].l < low) || ((int32_t) cpu_state.regs[cpu_reg].l > high)) { + x86_int(5); + return 1; + } + + CLOCK_CYCLES(is486 ? 7 : 10); + PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 1, 1, 0, 0, 1); + return 0; +} + +static int +opCLTS(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + cr0 &= ~8; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 0, 0, 0, 0, 0); + return 0; +} + +static int +opINVD(uint32_t fetchdat) +{ + CLOCK_CYCLES(1000); + CPU_BLOCK_END(); + return 0; +} +static int +opWBINVD(uint32_t fetchdat) +{ + CLOCK_CYCLES(10000); + CPU_BLOCK_END(); + return 0; +} + +static int +opLOADALL(uint32_t fetchdat) +{ + if (CPL && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + msw = (msw & 1) | readmemw(0, 0x806); + cpu_state.flags = (readmemw(0, 0x818) & 0xffd5) | 2; + flags_extract(); + tr.seg = readmemw(0, 0x816); + cpu_state.pc = readmemw(0, 0x81A); + ldt.seg = readmemw(0, 0x81C); + DS = readmemw(0, 0x81E); + SS = readmemw(0, 0x820); + CS = readmemw(0, 0x822); + ES = readmemw(0, 0x824); + DI = readmemw(0, 0x826); + SI = readmemw(0, 0x828); + BP = readmemw(0, 0x82A); + SP = readmemw(0, 0x82C); + BX = readmemw(0, 0x82E); + DX = readmemw(0, 0x830); + CX = readmemw(0, 0x832); + AX = readmemw(0, 0x834); + es = readmemw(0, 0x836) | (readmemb(0, 0x838) << 16); + cpu_state.seg_es.access = readmemb(0, 0x839); + cpu_state.seg_es.limit = readmemw(0, 0x83A); + cs = readmemw(0, 0x83C) | (readmemb(0, 0x83E) << 16); + cpu_state.seg_cs.access = readmemb(0, 0x83F); + cpu_state.seg_cs.limit = readmemw(0, 0x840); + ss = readmemw(0, 0x842) | (readmemb(0, 0x844) << 16); + cpu_state.seg_ss.access = readmemb(0, 0x845); + cpu_state.seg_ss.limit = readmemw(0, 0x846); + if (cpu_state.seg_ss.base == 0 && cpu_state.seg_ss.limit_low == 0 && cpu_state.seg_ss.limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATSS; + ds = readmemw(0, 0x848) | (readmemb(0, 0x84A) << 16); + cpu_state.seg_ds.access = readmemb(0, 0x84B); + cpu_state.seg_ds.limit = readmemw(0, 0x84C); + if (cpu_state.seg_ds.base == 0 && cpu_state.seg_ds.limit_low == 0 && cpu_state.seg_ds.limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATDS; + gdt.base = readmemw(0, 0x84E) | (readmemb(0, 0x850) << 16); + gdt.limit = readmemw(0, 0x852); + ldt.base = readmemw(0, 0x854) | (readmemb(0, 0x856) << 16); + ldt.access = readmemb(0, 0x857); + ldt.limit = readmemw(0, 0x858); + idt.base = readmemw(0, 0x85A) | (readmemb(0, 0x85C) << 16); + idt.limit = readmemw(0, 0x85E); + tr.base = readmemw(0, 0x860) | (readmemb(0, 0x862) << 16); + tr.access = readmemb(0, 0x863); + tr.limit = readmemw(0, 0x864); + CLOCK_CYCLES(195); + PREFETCH_RUN(195, 1, -1, 51, 0, 0, 0, 0); + return 0; +} + +static void +set_segment_limit(x86seg *s, uint8_t segdat3) +{ + if ((s->access & 0x18) != 0x10 || !(s->access & (1 << 2))) /*expand-down*/ + { + s->limit_high = s->limit; + s->limit_low = 0; + } else { + s->limit_high = (segdat3 & 0x40) ? 0xffffffff : 0xffff; + s->limit_low = s->limit + 1; + } +} + +static void +loadall_load_segment(uint32_t addr, x86seg *s) +{ + uint32_t attrib = readmeml(0, addr); + uint32_t segdat3 = (attrib >> 16) & 0xff; + s->access = (attrib >> 8) & 0xff; + s->ar_high = segdat3; + s->base = readmeml(0, addr + 4); + s->limit = readmeml(0, addr + 8); + + if (s == &cpu_state.seg_cs) + use32 = (segdat3 & 0x40) ? 0x300 : 0; + if (s == &cpu_state.seg_ss) + stack32 = (segdat3 & 0x40) ? 1 : 0; + + cpu_cur_status &= ~(CPU_STATUS_USE32 | CPU_STATUS_STACK32); + if (use32) + cpu_cur_status |= CPU_STATUS_USE32; + if (stack32) + cpu_cur_status |= CPU_STATUS_STACK32; + + set_segment_limit(s, segdat3); + + if (s == &cpu_state.seg_ds) { + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATDS; + } + if (s == &cpu_state.seg_ss) { + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATSS; + } +} + +static int +opLOADALL386(uint32_t fetchdat) +{ + uint32_t la_addr = es + EDI; + + cr0 = readmeml(0, la_addr); + cpu_state.flags = readmemw(0, la_addr + 4); + cpu_state.eflags = readmemw(0, la_addr + 6); + flags_extract(); + cpu_state.pc = readmeml(0, la_addr + 8); + EDI = readmeml(0, la_addr + 0xC); + ESI = readmeml(0, la_addr + 0x10); + EBP = readmeml(0, la_addr + 0x14); + ESP = readmeml(0, la_addr + 0x18); + EBX = readmeml(0, la_addr + 0x1C); + EDX = readmeml(0, la_addr + 0x20); + ECX = readmeml(0, la_addr + 0x24); + EAX = readmeml(0, la_addr + 0x28); + dr[6] = readmeml(0, la_addr + 0x2C); + dr[7] = readmeml(0, la_addr + 0x30); + tr.seg = readmemw(0, la_addr + 0x34); + ldt.seg = readmemw(0, la_addr + 0x38); + GS = readmemw(0, la_addr + 0x3C); + FS = readmemw(0, la_addr + 0x40); + DS = readmemw(0, la_addr + 0x44); + SS = readmemw(0, la_addr + 0x48); + CS = readmemw(0, la_addr + 0x4C); + ES = readmemw(0, la_addr + 0x50); + + loadall_load_segment(la_addr + 0x54, &tr); + loadall_load_segment(la_addr + 0x60, &idt); + loadall_load_segment(la_addr + 0x6c, &gdt); + loadall_load_segment(la_addr + 0x78, &ldt); + loadall_load_segment(la_addr + 0x84, &cpu_state.seg_gs); + loadall_load_segment(la_addr + 0x90, &cpu_state.seg_fs); + loadall_load_segment(la_addr + 0x9c, &cpu_state.seg_ds); + loadall_load_segment(la_addr + 0xa8, &cpu_state.seg_ss); + loadall_load_segment(la_addr + 0xb4, &cpu_state.seg_cs); + loadall_load_segment(la_addr + 0xc0, &cpu_state.seg_es); + + if (CPL == 3 && oldcpl != 3) + flushmmucache_cr3(); + oldcpl = CPL; + + CLOCK_CYCLES(350); + return 0; +} + +static int +opCPUID(uint32_t fetchdat) +{ + if (CPUID) { + cpu_CPUID(); + CLOCK_CYCLES(9); + return 0; + } + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; +} + +static int +opRDMSR(uint32_t fetchdat) +{ + if (cpu_has_feature(CPU_FEATURE_MSR)) { + cpu_RDMSR(); + CLOCK_CYCLES(9); + return 0; + } + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; +} + +static int +opWRMSR(uint32_t fetchdat) +{ + if (cpu_has_feature(CPU_FEATURE_MSR)) { + cpu_WRMSR(); + CLOCK_CYCLES(9); + return 0; + } + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; +} + +static int +opRSM(uint32_t fetchdat) +{ + if (in_smm) { + leave_smm(); + if (smi_latched) + enter_smm(smm_in_hlt); CPU_BLOCK_END(); return 0; -} -static int opWBINVD(uint32_t fetchdat) -{ - CLOCK_CYCLES(10000); - CPU_BLOCK_END(); - return 0; -} - -static int opLOADALL(uint32_t fetchdat) -{ - if (CPL && (cr0&1)) - { - x86gpf(NULL,0); - return 1; - } - msw = (msw & 1) | readmemw(0, 0x806); - cpu_state.flags = (readmemw(0, 0x818) & 0xffd5) | 2; - flags_extract(); - tr.seg = readmemw(0, 0x816); - cpu_state.pc = readmemw(0, 0x81A); - ldt.seg = readmemw(0, 0x81C); - DS = readmemw(0, 0x81E); - SS = readmemw(0, 0x820); - CS = readmemw(0, 0x822); - ES = readmemw(0, 0x824); - DI = readmemw(0, 0x826); - SI = readmemw(0, 0x828); - BP = readmemw(0, 0x82A); - SP = readmemw(0, 0x82C); - BX = readmemw(0, 0x82E); - DX = readmemw(0, 0x830); - CX = readmemw(0, 0x832); - AX = readmemw(0, 0x834); - es = readmemw(0, 0x836) | (readmemb(0, 0x838) << 16); - cpu_state.seg_es.access = readmemb(0, 0x839); - cpu_state.seg_es.limit = readmemw(0, 0x83A); - cs = readmemw(0, 0x83C) | (readmemb(0, 0x83E) << 16); - cpu_state.seg_cs.access = readmemb(0, 0x83F); - cpu_state.seg_cs.limit = readmemw(0, 0x840); - ss = readmemw(0, 0x842) | (readmemb(0, 0x844) << 16); - cpu_state.seg_ss.access = readmemb(0, 0x845); - cpu_state.seg_ss.limit = readmemw(0, 0x846); - if (cpu_state.seg_ss.base == 0 && cpu_state.seg_ss.limit_low == 0 && cpu_state.seg_ss.limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - ds = readmemw(0, 0x848) | (readmemb(0, 0x84A) << 16); - cpu_state.seg_ds.access = readmemb(0, 0x84B); - cpu_state.seg_ds.limit = readmemw(0, 0x84C); - if (cpu_state.seg_ds.base == 0 && cpu_state.seg_ds.limit_low == 0 && cpu_state.seg_ds.limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; - gdt.base = readmemw(0, 0x84E) | (readmemb(0, 0x850) << 16); - gdt.limit = readmemw(0, 0x852); - ldt.base = readmemw(0, 0x854) | (readmemb(0, 0x856) << 16); - ldt.access = readmemb(0, 0x857); - ldt.limit = readmemw(0, 0x858); - idt.base = readmemw(0, 0x85A) | (readmemb(0, 0x85C) << 16); - idt.limit = readmemw(0, 0x85E); - tr.base = readmemw(0, 0x860) | (readmemb(0, 0x862) << 16); - tr.access = readmemb(0, 0x863); - tr.limit = readmemw(0, 0x864); - CLOCK_CYCLES(195); - PREFETCH_RUN(195, 1, -1, 51,0,0,0, 0); - return 0; -} - -static void set_segment_limit(x86seg *s, uint8_t segdat3) -{ - if ((s->access & 0x18) != 0x10 || !(s->access & (1 << 2))) /*expand-down*/ - { - s->limit_high = s->limit; - s->limit_low = 0; - } - else - { - s->limit_high = (segdat3 & 0x40) ? 0xffffffff : 0xffff; - s->limit_low = s->limit + 1; - } -} - -static void loadall_load_segment(uint32_t addr, x86seg *s) -{ - uint32_t attrib = readmeml(0, addr); - uint32_t segdat3 = (attrib >> 16) & 0xff; - s->access = (attrib >> 8) & 0xff; - s->ar_high = segdat3; - s->base = readmeml(0, addr + 4); - s->limit = readmeml(0, addr + 8); - - if (s == &cpu_state.seg_cs) - use32 = (segdat3 & 0x40) ? 0x300 : 0; - if (s == &cpu_state.seg_ss) - stack32 = (segdat3 & 0x40) ? 1 : 0; - - cpu_cur_status &= ~(CPU_STATUS_USE32 | CPU_STATUS_STACK32); - if (use32) - cpu_cur_status |= CPU_STATUS_USE32; - if (stack32) - cpu_cur_status |= CPU_STATUS_STACK32; - - set_segment_limit(s, segdat3); - - if (s == &cpu_state.seg_ds) - { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; - } - if (s == &cpu_state.seg_ss) - { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - } -} - -static int opLOADALL386(uint32_t fetchdat) -{ - uint32_t la_addr = es + EDI; - - cr0 = readmeml(0, la_addr); - cpu_state.flags = readmemw(0, la_addr + 4); - cpu_state.eflags = readmemw(0, la_addr + 6); - flags_extract(); - cpu_state.pc = readmeml(0, la_addr + 8); - EDI = readmeml(0, la_addr + 0xC); - ESI = readmeml(0, la_addr + 0x10); - EBP = readmeml(0, la_addr + 0x14); - ESP = readmeml(0, la_addr + 0x18); - EBX = readmeml(0, la_addr + 0x1C); - EDX = readmeml(0, la_addr + 0x20); - ECX = readmeml(0, la_addr + 0x24); - EAX = readmeml(0, la_addr + 0x28); - dr[6] = readmeml(0, la_addr + 0x2C); - dr[7] = readmeml(0, la_addr + 0x30); - tr.seg = readmemw(0, la_addr + 0x34); - ldt.seg = readmemw(0, la_addr + 0x38); - GS = readmemw(0, la_addr + 0x3C); - FS = readmemw(0, la_addr + 0x40); - DS = readmemw(0, la_addr + 0x44); - SS = readmemw(0, la_addr + 0x48); - CS = readmemw(0, la_addr + 0x4C); - ES = readmemw(0, la_addr + 0x50); - - loadall_load_segment(la_addr + 0x54, &tr); - loadall_load_segment(la_addr + 0x60, &idt); - loadall_load_segment(la_addr + 0x6c, &gdt); - loadall_load_segment(la_addr + 0x78, &ldt); - loadall_load_segment(la_addr + 0x84, &cpu_state.seg_gs); - loadall_load_segment(la_addr + 0x90, &cpu_state.seg_fs); - loadall_load_segment(la_addr + 0x9c, &cpu_state.seg_ds); - loadall_load_segment(la_addr + 0xa8, &cpu_state.seg_ss); - loadall_load_segment(la_addr + 0xb4, &cpu_state.seg_cs); - loadall_load_segment(la_addr + 0xc0, &cpu_state.seg_es); - - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - oldcpl = CPL; - - CLOCK_CYCLES(350); - return 0; -} - -static int opCPUID(uint32_t fetchdat) -{ - if (CPUID) - { - cpu_CPUID(); - CLOCK_CYCLES(9); - return 0; - } - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; -} - -static int opRDMSR(uint32_t fetchdat) -{ - if (cpu_has_feature(CPU_FEATURE_MSR)) - { - cpu_RDMSR(); - CLOCK_CYCLES(9); - return 0; - } - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; -} - -static int opWRMSR(uint32_t fetchdat) -{ - if (cpu_has_feature(CPU_FEATURE_MSR)) - { - cpu_WRMSR(); - CLOCK_CYCLES(9); - return 0; - } - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; -} - -static int opRSM(uint32_t fetchdat) -{ - if (in_smm) - { - leave_smm(); - if (smi_latched) - enter_smm(smm_in_hlt); - CPU_BLOCK_END(); - return 0; - } - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; + } + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; } diff --git a/src/cpu/x86_ops_mmx.h b/src/cpu/x86_ops_mmx.h index f9a7f9357..d270b728f 100644 --- a/src/cpu/x86_ops_mmx.h +++ b/src/cpu/x86_ops_mmx.h @@ -3,47 +3,43 @@ #define USATB(val) (((val) < 0) ? 0 : (((val) > 255) ? 255 : (val))) #define USATW(val) (((val) < 0) ? 0 : (((val) > 65535) ? 65535 : (val))) -#define MMX_GETSRC() \ - if (cpu_mod == 3) \ - { \ - src = cpu_state.MM[cpu_rm]; \ - CLOCK_CYCLES(1); \ - } \ - else \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - src.q = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; \ - CLOCK_CYCLES(2); \ - } +#define MMX_GETSRC() \ + if (cpu_mod == 3) { \ + src = cpu_state.MM[cpu_rm]; \ + CLOCK_CYCLES(1); \ + } else { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + src.q = readmemq(easeg, cpu_state.eaaddr); \ + if (cpu_state.abrt) \ + return 1; \ + CLOCK_CYCLES(2); \ + } -#define MMX_ENTER() \ - if (!cpu_has_feature(CPU_FEATURE_MMX)) \ - { \ - cpu_state.pc = cpu_state.oldpc; \ - x86illegal(); \ - return 1; \ - } \ - if (cr0 & 0xc) \ - { \ - x86_int(7); \ - return 1; \ - } \ - x87_set_mmx() +#define MMX_ENTER() \ + if (!cpu_has_feature(CPU_FEATURE_MMX)) { \ + cpu_state.pc = cpu_state.oldpc; \ + x86illegal(); \ + return 1; \ + } \ + if (cr0 & 0xc) { \ + x86_int(7); \ + return 1; \ + } \ + x87_set_mmx() -static int opEMMS(uint32_t fetchdat) +static int +opEMMS(uint32_t fetchdat) { - if (!cpu_has_feature(CPU_FEATURE_MMX)) - { - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; - } - if (cr0 & 0xc) - { - x86_int(7); - return 1; - } - x87_emms(); - CLOCK_CYCLES(100); /*Guess*/ - return 0; + if (!cpu_has_feature(CPU_FEATURE_MMX)) { + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; + } + if (cr0 & 0xc) { + x86_int(7); + return 1; + } + x87_emms(); + CLOCK_CYCLES(100); /*Guess*/ + return 0; } diff --git a/src/cpu/x86_ops_mmx_arith.h b/src/cpu/x86_ops_mmx_arith.h index afa8aa383..e473f8ec5 100644 --- a/src/cpu/x86_ops_mmx_arith.h +++ b/src/cpu/x86_ops_mmx_arith.h @@ -1,631 +1,660 @@ -static int opPADDB_a16(uint32_t fetchdat) +static int +opPADDB_a16(uint32_t fetchdat) { + MMX_REG src; + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].b[0] += src.b[0]; + cpu_state.MM[cpu_reg].b[1] += src.b[1]; + cpu_state.MM[cpu_reg].b[2] += src.b[2]; + cpu_state.MM[cpu_reg].b[3] += src.b[3]; + cpu_state.MM[cpu_reg].b[4] += src.b[4]; + cpu_state.MM[cpu_reg].b[5] += src.b[5]; + cpu_state.MM[cpu_reg].b[6] += src.b[6]; + cpu_state.MM[cpu_reg].b[7] += src.b[7]; + + return 0; +} +static int +opPADDB_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].b[0] += src.b[0]; + cpu_state.MM[cpu_reg].b[1] += src.b[1]; + cpu_state.MM[cpu_reg].b[2] += src.b[2]; + cpu_state.MM[cpu_reg].b[3] += src.b[3]; + cpu_state.MM[cpu_reg].b[4] += src.b[4]; + cpu_state.MM[cpu_reg].b[5] += src.b[5]; + cpu_state.MM[cpu_reg].b[6] += src.b[6]; + cpu_state.MM[cpu_reg].b[7] += src.b[7]; + + return 0; +} + +static int +opPADDW_a16(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].w[0] += src.w[0]; + cpu_state.MM[cpu_reg].w[1] += src.w[1]; + cpu_state.MM[cpu_reg].w[2] += src.w[2]; + cpu_state.MM[cpu_reg].w[3] += src.w[3]; + + return 0; +} +static int +opPADDW_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].w[0] += src.w[0]; + cpu_state.MM[cpu_reg].w[1] += src.w[1]; + cpu_state.MM[cpu_reg].w[2] += src.w[2]; + cpu_state.MM[cpu_reg].w[3] += src.w[3]; + + return 0; +} + +static int +opPADDD_a16(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].l[0] += src.l[0]; + cpu_state.MM[cpu_reg].l[1] += src.l[1]; + + return 0; +} +static int +opPADDD_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].l[0] += src.l[0]; + cpu_state.MM[cpu_reg].l[1] += src.l[1]; + + return 0; +} + +static int +opPADDSB_a16(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] + src.sb[0]); + cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] + src.sb[1]); + cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] + src.sb[2]); + cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] + src.sb[3]); + cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] + src.sb[4]); + cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] + src.sb[5]); + cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] + src.sb[6]); + cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] + src.sb[7]); + + return 0; +} +static int +opPADDSB_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] + src.sb[0]); + cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] + src.sb[1]); + cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] + src.sb[2]); + cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] + src.sb[3]); + cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] + src.sb[4]); + cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] + src.sb[5]); + cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] + src.sb[6]); + cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] + src.sb[7]); + + return 0; +} + +static int +opPADDUSB_a16(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] + src.b[0]); + cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] + src.b[1]); + cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] + src.b[2]); + cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] + src.b[3]); + cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] + src.b[4]); + cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] + src.b[5]); + cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] + src.b[6]); + cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] + src.b[7]); + + return 0; +} +static int +opPADDUSB_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] + src.b[0]); + cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] + src.b[1]); + cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] + src.b[2]); + cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] + src.b[3]); + cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] + src.b[4]); + cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] + src.b[5]); + cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] + src.b[6]); + cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] + src.b[7]); + + return 0; +} + +static int +opPADDSW_a16(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] + src.sw[0]); + cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] + src.sw[1]); + cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] + src.sw[2]); + cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] + src.sw[3]); + + return 0; +} +static int +opPADDSW_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] + src.sw[0]); + cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] + src.sw[1]); + cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] + src.sw[2]); + cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] + src.sw[3]); + + return 0; +} + +static int +opPADDUSW_a16(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] + src.w[0]); + cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] + src.w[1]); + cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] + src.w[2]); + cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] + src.w[3]); + + return 0; +} +static int +opPADDUSW_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] + src.w[0]); + cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] + src.w[1]); + cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] + src.w[2]); + cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] + src.w[3]); + + return 0; +} + +static int +opPMADDWD_a16(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSRC(); + + if (cpu_state.MM[cpu_reg].l[0] == 0x80008000 && src.l[0] == 0x80008000) + cpu_state.MM[cpu_reg].l[0] = 0x80000000; + else + cpu_state.MM[cpu_reg].sl[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) + ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]); + + if (cpu_state.MM[cpu_reg].l[1] == 0x80008000 && src.l[1] == 0x80008000) + cpu_state.MM[cpu_reg].l[1] = 0x80000000; + else + cpu_state.MM[cpu_reg].sl[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) + ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]); + + return 0; +} +static int +opPMADDWD_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSRC(); + + if (cpu_state.MM[cpu_reg].l[0] == 0x80008000 && src.l[0] == 0x80008000) + cpu_state.MM[cpu_reg].l[0] = 0x80000000; + else + cpu_state.MM[cpu_reg].sl[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) + ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]); + + if (cpu_state.MM[cpu_reg].l[1] == 0x80008000 && src.l[1] == 0x80008000) + cpu_state.MM[cpu_reg].l[1] = 0x80000000; + else + cpu_state.MM[cpu_reg].sl[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) + ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]); + + return 0; +} + +static int +opPMULLW_a16(uint32_t fetchdat) +{ + MMX_ENTER(); + + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].w[0] *= cpu_state.MM[cpu_rm].w[0]; + cpu_state.MM[cpu_reg].w[1] *= cpu_state.MM[cpu_rm].w[1]; + cpu_state.MM[cpu_reg].w[2] *= cpu_state.MM[cpu_rm].w[2]; + cpu_state.MM[cpu_reg].w[3] *= cpu_state.MM[cpu_rm].w[3]; + CLOCK_CYCLES(1); + } else { MMX_REG src; - MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] += src.b[0]; - cpu_state.MM[cpu_reg].b[1] += src.b[1]; - cpu_state.MM[cpu_reg].b[2] += src.b[2]; - cpu_state.MM[cpu_reg].b[3] += src.b[3]; - cpu_state.MM[cpu_reg].b[4] += src.b[4]; - cpu_state.MM[cpu_reg].b[5] += src.b[5]; - cpu_state.MM[cpu_reg].b[6] += src.b[6]; - cpu_state.MM[cpu_reg].b[7] += src.b[7]; - - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].w[0] *= src.w[0]; + cpu_state.MM[cpu_reg].w[1] *= src.w[1]; + cpu_state.MM[cpu_reg].w[2] *= src.w[2]; + cpu_state.MM[cpu_reg].w[3] *= src.w[3]; + CLOCK_CYCLES(2); + } + return 0; } -static int opPADDB_a32(uint32_t fetchdat) +static int +opPMULLW_a32(uint32_t fetchdat) { + MMX_ENTER(); + + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].w[0] *= cpu_state.MM[cpu_rm].w[0]; + cpu_state.MM[cpu_reg].w[1] *= cpu_state.MM[cpu_rm].w[1]; + cpu_state.MM[cpu_reg].w[2] *= cpu_state.MM[cpu_rm].w[2]; + cpu_state.MM[cpu_reg].w[3] *= cpu_state.MM[cpu_rm].w[3]; + CLOCK_CYCLES(1); + } else { MMX_REG src; - MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] += src.b[0]; - cpu_state.MM[cpu_reg].b[1] += src.b[1]; - cpu_state.MM[cpu_reg].b[2] += src.b[2]; - cpu_state.MM[cpu_reg].b[3] += src.b[3]; - cpu_state.MM[cpu_reg].b[4] += src.b[4]; - cpu_state.MM[cpu_reg].b[5] += src.b[5]; - cpu_state.MM[cpu_reg].b[6] += src.b[6]; - cpu_state.MM[cpu_reg].b[7] += src.b[7]; - - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].w[0] *= src.w[0]; + cpu_state.MM[cpu_reg].w[1] *= src.w[1]; + cpu_state.MM[cpu_reg].w[2] *= src.w[2]; + cpu_state.MM[cpu_reg].w[3] *= src.w[3]; + CLOCK_CYCLES(2); + } + return 0; } -static int opPADDW_a16(uint32_t fetchdat) +static int +opPMULHW_a16(uint32_t fetchdat) { + MMX_ENTER(); + + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) cpu_state.MM[cpu_rm].sw[0]) >> 16; + cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) cpu_state.MM[cpu_rm].sw[1]) >> 16; + cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) cpu_state.MM[cpu_rm].sw[2]) >> 16; + cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) cpu_state.MM[cpu_rm].sw[3]) >> 16; + CLOCK_CYCLES(1); + } else { MMX_REG src; - MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] += src.w[0]; - cpu_state.MM[cpu_reg].w[1] += src.w[1]; - cpu_state.MM[cpu_reg].w[2] += src.w[2]; - cpu_state.MM[cpu_reg].w[3] += src.w[3]; - - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) >> 16; + cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]) >> 16; + cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) >> 16; + cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]) >> 16; + CLOCK_CYCLES(2); + } + return 0; } -static int opPADDW_a32(uint32_t fetchdat) +static int +opPMULHW_a32(uint32_t fetchdat) { + MMX_ENTER(); + + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) cpu_state.MM[cpu_rm].sw[0]) >> 16; + cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) cpu_state.MM[cpu_rm].sw[1]) >> 16; + cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) cpu_state.MM[cpu_rm].sw[2]) >> 16; + cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) cpu_state.MM[cpu_rm].sw[3]) >> 16; + CLOCK_CYCLES(1); + } else { MMX_REG src; - MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] += src.w[0]; - cpu_state.MM[cpu_reg].w[1] += src.w[1]; - cpu_state.MM[cpu_reg].w[2] += src.w[2]; - cpu_state.MM[cpu_reg].w[3] += src.w[3]; - - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) >> 16; + cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]) >> 16; + cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) >> 16; + cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]) >> 16; + CLOCK_CYCLES(2); + } + return 0; } -static int opPADDD_a16(uint32_t fetchdat) +static int +opPSUBB_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] += src.l[0]; - cpu_state.MM[cpu_reg].l[1] += src.l[1]; + cpu_state.MM[cpu_reg].b[0] -= src.b[0]; + cpu_state.MM[cpu_reg].b[1] -= src.b[1]; + cpu_state.MM[cpu_reg].b[2] -= src.b[2]; + cpu_state.MM[cpu_reg].b[3] -= src.b[3]; + cpu_state.MM[cpu_reg].b[4] -= src.b[4]; + cpu_state.MM[cpu_reg].b[5] -= src.b[5]; + cpu_state.MM[cpu_reg].b[6] -= src.b[6]; + cpu_state.MM[cpu_reg].b[7] -= src.b[7]; - return 0; + return 0; } -static int opPADDD_a32(uint32_t fetchdat) +static int +opPSUBB_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] += src.l[0]; - cpu_state.MM[cpu_reg].l[1] += src.l[1]; + cpu_state.MM[cpu_reg].b[0] -= src.b[0]; + cpu_state.MM[cpu_reg].b[1] -= src.b[1]; + cpu_state.MM[cpu_reg].b[2] -= src.b[2]; + cpu_state.MM[cpu_reg].b[3] -= src.b[3]; + cpu_state.MM[cpu_reg].b[4] -= src.b[4]; + cpu_state.MM[cpu_reg].b[5] -= src.b[5]; + cpu_state.MM[cpu_reg].b[6] -= src.b[6]; + cpu_state.MM[cpu_reg].b[7] -= src.b[7]; - return 0; + return 0; } -static int opPADDSB_a16(uint32_t fetchdat) +static int +opPSUBW_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] + src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] + src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] + src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] + src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] + src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] + src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] + src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] + src.sb[7]); + cpu_state.MM[cpu_reg].w[0] -= src.w[0]; + cpu_state.MM[cpu_reg].w[1] -= src.w[1]; + cpu_state.MM[cpu_reg].w[2] -= src.w[2]; + cpu_state.MM[cpu_reg].w[3] -= src.w[3]; - return 0; + return 0; } -static int opPADDSB_a32(uint32_t fetchdat) +static int +opPSUBW_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] + src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] + src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] + src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] + src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] + src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] + src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] + src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] + src.sb[7]); + cpu_state.MM[cpu_reg].w[0] -= src.w[0]; + cpu_state.MM[cpu_reg].w[1] -= src.w[1]; + cpu_state.MM[cpu_reg].w[2] -= src.w[2]; + cpu_state.MM[cpu_reg].w[3] -= src.w[3]; - return 0; + return 0; } -static int opPADDUSB_a16(uint32_t fetchdat) +static int +opPSUBD_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] + src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] + src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] + src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] + src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] + src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] + src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] + src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] + src.b[7]); + cpu_state.MM[cpu_reg].l[0] -= src.l[0]; + cpu_state.MM[cpu_reg].l[1] -= src.l[1]; - return 0; + return 0; } -static int opPADDUSB_a32(uint32_t fetchdat) +static int +opPSUBD_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] + src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] + src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] + src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] + src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] + src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] + src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] + src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] + src.b[7]); + cpu_state.MM[cpu_reg].l[0] -= src.l[0]; + cpu_state.MM[cpu_reg].l[1] -= src.l[1]; - return 0; + return 0; } -static int opPADDSW_a16(uint32_t fetchdat) +static int +opPSUBSB_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + pclog("opPSUBSB_a16(%08X)\n", fetchdat); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] + src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] + src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] + src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] + src.sw[3]); + cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] - src.sb[0]); + cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] - src.sb[1]); + cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] - src.sb[2]); + cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] - src.sb[3]); + cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] - src.sb[4]); + cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] - src.sb[5]); + cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] - src.sb[6]); + cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] - src.sb[7]); - return 0; + return 0; } -static int opPADDSW_a32(uint32_t fetchdat) +static int +opPSUBSB_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + pclog("opPSUBSB_a32(%08X)\n", fetchdat); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] + src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] + src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] + src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] + src.sw[3]); + cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] - src.sb[0]); + cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] - src.sb[1]); + cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] - src.sb[2]); + cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] - src.sb[3]); + cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] - src.sb[4]); + cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] - src.sb[5]); + cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] - src.sb[6]); + cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] - src.sb[7]); - return 0; + return 0; } -static int opPADDUSW_a16(uint32_t fetchdat) +static int +opPSUBUSB_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] + src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] + src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] + src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] + src.w[3]); + cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] - src.b[0]); + cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] - src.b[1]); + cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] - src.b[2]); + cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] - src.b[3]); + cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] - src.b[4]); + cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] - src.b[5]); + cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] - src.b[6]); + cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] - src.b[7]); - return 0; + return 0; } -static int opPADDUSW_a32(uint32_t fetchdat) +static int +opPSUBUSB_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] + src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] + src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] + src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] + src.w[3]); + cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] - src.b[0]); + cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] - src.b[1]); + cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] - src.b[2]); + cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] - src.b[3]); + cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] - src.b[4]); + cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] - src.b[5]); + cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] - src.b[6]); + cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] - src.b[7]); - return 0; + return 0; } -static int opPMADDWD_a16(uint32_t fetchdat) +static int +opPSUBSW_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - if (cpu_state.MM[cpu_reg].l[0] == 0x80008000 && src.l[0] == 0x80008000) - cpu_state.MM[cpu_reg].l[0] = 0x80000000; - else - cpu_state.MM[cpu_reg].sl[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) + ((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]); + cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] - src.sw[0]); + cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] - src.sw[1]); + cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] - src.sw[2]); + cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] - src.sw[3]); - if (cpu_state.MM[cpu_reg].l[1] == 0x80008000 && src.l[1] == 0x80008000) - cpu_state.MM[cpu_reg].l[1] = 0x80000000; - else - cpu_state.MM[cpu_reg].sl[1] = ((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) + ((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]); - - return 0; + return 0; } -static int opPMADDWD_a32(uint32_t fetchdat) +static int +opPSUBSW_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - if (cpu_state.MM[cpu_reg].l[0] == 0x80008000 && src.l[0] == 0x80008000) - cpu_state.MM[cpu_reg].l[0] = 0x80000000; - else - cpu_state.MM[cpu_reg].sl[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) + ((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]); + cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] - src.sw[0]); + cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] - src.sw[1]); + cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] - src.sw[2]); + cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] - src.sw[3]); - if (cpu_state.MM[cpu_reg].l[1] == 0x80008000 && src.l[1] == 0x80008000) - cpu_state.MM[cpu_reg].l[1] = 0x80000000; - else - cpu_state.MM[cpu_reg].sl[1] = ((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) + ((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]); - - return 0; + return 0; } - -static int opPMULLW_a16(uint32_t fetchdat) +static int +opPSUBUSW_a16(uint32_t fetchdat) { - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].w[0] *= cpu_state.MM[cpu_rm].w[0]; - cpu_state.MM[cpu_reg].w[1] *= cpu_state.MM[cpu_rm].w[1]; - cpu_state.MM[cpu_reg].w[2] *= cpu_state.MM[cpu_rm].w[2]; - cpu_state.MM[cpu_reg].w[3] *= cpu_state.MM[cpu_rm].w[3]; - CLOCK_CYCLES(1); - } - else - { - MMX_REG src; + fetch_ea_16(fetchdat); + MMX_GETSRC(); - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].w[0] *= src.w[0]; - cpu_state.MM[cpu_reg].w[1] *= src.w[1]; - cpu_state.MM[cpu_reg].w[2] *= src.w[2]; - cpu_state.MM[cpu_reg].w[3] *= src.w[3]; - CLOCK_CYCLES(2); - } - return 0; + cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] - src.w[0]); + cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] - src.w[1]); + cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] - src.w[2]); + cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] - src.w[3]); + + return 0; } -static int opPMULLW_a32(uint32_t fetchdat) +static int +opPSUBUSW_a32(uint32_t fetchdat) { - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].w[0] *= cpu_state.MM[cpu_rm].w[0]; - cpu_state.MM[cpu_reg].w[1] *= cpu_state.MM[cpu_rm].w[1]; - cpu_state.MM[cpu_reg].w[2] *= cpu_state.MM[cpu_rm].w[2]; - cpu_state.MM[cpu_reg].w[3] *= cpu_state.MM[cpu_rm].w[3]; - CLOCK_CYCLES(1); - } - else - { - MMX_REG src; + fetch_ea_32(fetchdat); + MMX_GETSRC(); - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].w[0] *= src.w[0]; - cpu_state.MM[cpu_reg].w[1] *= src.w[1]; - cpu_state.MM[cpu_reg].w[2] *= src.w[2]; - cpu_state.MM[cpu_reg].w[3] *= src.w[3]; - CLOCK_CYCLES(2); - } - return 0; -} - -static int opPMULHW_a16(uint32_t fetchdat) -{ - MMX_ENTER(); - - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)cpu_state.MM[cpu_rm].sw[0]) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)cpu_state.MM[cpu_rm].sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)cpu_state.MM[cpu_rm].sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)cpu_state.MM[cpu_rm].sw[3]) >> 16; - CLOCK_CYCLES(1); - } - else - { - MMX_REG src; - - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]) >> 16; - CLOCK_CYCLES(2); - } - return 0; -} -static int opPMULHW_a32(uint32_t fetchdat) -{ - MMX_ENTER(); - - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)cpu_state.MM[cpu_rm].sw[0]) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)cpu_state.MM[cpu_rm].sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)cpu_state.MM[cpu_rm].sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)cpu_state.MM[cpu_rm].sw[3]) >> 16; - CLOCK_CYCLES(1); - } - else - { - MMX_REG src; - - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]) >> 16; - CLOCK_CYCLES(2); - } - return 0; -} - -static int opPSUBB_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] -= src.b[0]; - cpu_state.MM[cpu_reg].b[1] -= src.b[1]; - cpu_state.MM[cpu_reg].b[2] -= src.b[2]; - cpu_state.MM[cpu_reg].b[3] -= src.b[3]; - cpu_state.MM[cpu_reg].b[4] -= src.b[4]; - cpu_state.MM[cpu_reg].b[5] -= src.b[5]; - cpu_state.MM[cpu_reg].b[6] -= src.b[6]; - cpu_state.MM[cpu_reg].b[7] -= src.b[7]; - - return 0; -} -static int opPSUBB_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] -= src.b[0]; - cpu_state.MM[cpu_reg].b[1] -= src.b[1]; - cpu_state.MM[cpu_reg].b[2] -= src.b[2]; - cpu_state.MM[cpu_reg].b[3] -= src.b[3]; - cpu_state.MM[cpu_reg].b[4] -= src.b[4]; - cpu_state.MM[cpu_reg].b[5] -= src.b[5]; - cpu_state.MM[cpu_reg].b[6] -= src.b[6]; - cpu_state.MM[cpu_reg].b[7] -= src.b[7]; - - return 0; -} - -static int opPSUBW_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] -= src.w[0]; - cpu_state.MM[cpu_reg].w[1] -= src.w[1]; - cpu_state.MM[cpu_reg].w[2] -= src.w[2]; - cpu_state.MM[cpu_reg].w[3] -= src.w[3]; - - return 0; -} -static int opPSUBW_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] -= src.w[0]; - cpu_state.MM[cpu_reg].w[1] -= src.w[1]; - cpu_state.MM[cpu_reg].w[2] -= src.w[2]; - cpu_state.MM[cpu_reg].w[3] -= src.w[3]; - - return 0; -} - -static int opPSUBD_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] -= src.l[0]; - cpu_state.MM[cpu_reg].l[1] -= src.l[1]; - - return 0; -} -static int opPSUBD_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] -= src.l[0]; - cpu_state.MM[cpu_reg].l[1] -= src.l[1]; - - return 0; -} - -static int opPSUBSB_a16(uint32_t fetchdat) -{ - MMX_REG src; - pclog("opPSUBSB_a16(%08X)\n", fetchdat); - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] - src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] - src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] - src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] - src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] - src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] - src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] - src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] - src.sb[7]); - - return 0; -} -static int opPSUBSB_a32(uint32_t fetchdat) -{ - MMX_REG src; - pclog("opPSUBSB_a32(%08X)\n", fetchdat); - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] - src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] - src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] - src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] - src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] - src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] - src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] - src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] - src.sb[7]); - - return 0; -} - -static int opPSUBUSB_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] - src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] - src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] - src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] - src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] - src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] - src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] - src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] - src.b[7]); - - return 0; -} -static int opPSUBUSB_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] - src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] - src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] - src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] - src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] - src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] - src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] - src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] - src.b[7]); - - return 0; -} - -static int opPSUBSW_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] - src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] - src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] - src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] - src.sw[3]); - - return 0; -} -static int opPSUBSW_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] - src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] - src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] - src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] - src.sw[3]); - - return 0; -} - -static int opPSUBUSW_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] - src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] - src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] - src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] - src.w[3]); - - return 0; -} -static int opPSUBUSW_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] - src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] - src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] - src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] - src.w[3]); - - return 0; + cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] - src.w[0]); + cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] - src.w[1]); + cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] - src.w[2]); + cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] - src.w[3]); + + return 0; } diff --git a/src/cpu/x86_ops_mmx_cmp.h b/src/cpu/x86_ops_mmx_cmp.h index a07d8d0a8..40ae66a9c 100644 --- a/src/cpu/x86_ops_mmx_cmp.h +++ b/src/cpu/x86_ops_mmx_cmp.h @@ -1,205 +1,217 @@ -static int opPCMPEQB_a16(uint32_t fetchdat) +static int +opPCMPEQB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0; - return 0; + return 0; } -static int opPCMPEQB_a32(uint32_t fetchdat) +static int +opPCMPEQB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0; - return 0; + return 0; } -static int opPCMPGTB_a16(uint32_t fetchdat) +static int +opPCMPGTB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0; - return 0; + return 0; } -static int opPCMPGTB_a32(uint32_t fetchdat) +static int +opPCMPGTB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0; - return 0; + return 0; } -static int opPCMPEQW_a16(uint32_t fetchdat) +static int +opPCMPEQW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0; - return 0; + return 0; } -static int opPCMPEQW_a32(uint32_t fetchdat) +static int +opPCMPEQW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0; - return 0; + return 0; } -static int opPCMPGTW_a16(uint32_t fetchdat) +static int +opPCMPGTW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0; - return 0; + return 0; } -static int opPCMPGTW_a32(uint32_t fetchdat) +static int +opPCMPGTW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0; - return 0; + return 0; } -static int opPCMPEQD_a16(uint32_t fetchdat) +static int +opPCMPEQD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0; - return 0; + return 0; } -static int opPCMPEQD_a32(uint32_t fetchdat) +static int +opPCMPEQD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0; - return 0; + return 0; } -static int opPCMPGTD_a16(uint32_t fetchdat) +static int +opPCMPGTD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0; - return 0; + return 0; } -static int opPCMPGTD_a32(uint32_t fetchdat) +static int +opPCMPGTD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0; - return 0; + return 0; } diff --git a/src/cpu/x86_ops_mmx_logic.h b/src/cpu/x86_ops_mmx_logic.h index e3f1d9145..c22c820c1 100644 --- a/src/cpu/x86_ops_mmx_logic.h +++ b/src/cpu/x86_ops_mmx_logic.h @@ -1,91 +1,99 @@ -static int opPAND_a16(uint32_t fetchdat) +static int +opPAND_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q &= src.q; - return 0; + cpu_state.MM[cpu_reg].q &= src.q; + return 0; } -static int opPAND_a32(uint32_t fetchdat) +static int +opPAND_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q &= src.q; - return 0; + cpu_state.MM[cpu_reg].q &= src.q; + return 0; } -static int opPANDN_a16(uint32_t fetchdat) +static int +opPANDN_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q; - return 0; + cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q; + return 0; } -static int opPANDN_a32(uint32_t fetchdat) +static int +opPANDN_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q; - return 0; + cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q; + return 0; } -static int opPOR_a16(uint32_t fetchdat) +static int +opPOR_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q |= src.q; - return 0; + cpu_state.MM[cpu_reg].q |= src.q; + return 0; } -static int opPOR_a32(uint32_t fetchdat) +static int +opPOR_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q |= src.q; - return 0; + cpu_state.MM[cpu_reg].q |= src.q; + return 0; } -static int opPXOR_a16(uint32_t fetchdat) +static int +opPXOR_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q ^= src.q; - return 0; + cpu_state.MM[cpu_reg].q ^= src.q; + return 0; } -static int opPXOR_a32(uint32_t fetchdat) +static int +opPXOR_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q ^= src.q; - return 0; + cpu_state.MM[cpu_reg].q ^= src.q; + return 0; } diff --git a/src/cpu/x86_ops_mmx_mov.h b/src/cpu/x86_ops_mmx_mov.h index fe06525b7..bb51573e6 100644 --- a/src/cpu/x86_ops_mmx_mov.h +++ b/src/cpu/x86_ops_mmx_mov.h @@ -1,217 +1,217 @@ -static int opMOVD_l_mm_a16(uint32_t fetchdat) +static int +opMOVD_l_mm_a16(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l; - cpu_state.MM[cpu_reg].l[1] = 0; - CLOCK_CYCLES(1); - } - else - { - uint32_t dst; + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l; + cpu_state.MM[cpu_reg].l[1] = 0; + CLOCK_CYCLES(1); + } else { + uint32_t dst; - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; - cpu_state.MM[cpu_reg].l[0] = dst; - cpu_state.MM[cpu_reg].l[1] = 0; + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + cpu_state.MM[cpu_reg].l[0] = dst; + cpu_state.MM[cpu_reg].l[1] = 0; - CLOCK_CYCLES(2); - } - return 0; + CLOCK_CYCLES(2); + } + return 0; } -static int opMOVD_l_mm_a32(uint32_t fetchdat) +static int +opMOVD_l_mm_a32(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l; - cpu_state.MM[cpu_reg].l[1] = 0; - CLOCK_CYCLES(1); - } - else - { - uint32_t dst; + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l; + cpu_state.MM[cpu_reg].l[1] = 0; + CLOCK_CYCLES(1); + } else { + uint32_t dst; - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; - cpu_state.MM[cpu_reg].l[0] = dst; - cpu_state.MM[cpu_reg].l[1] = 0; + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + cpu_state.MM[cpu_reg].l[0] = dst; + cpu_state.MM[cpu_reg].l[1] = 0; - CLOCK_CYCLES(2); - } - return 0; + CLOCK_CYCLES(2); + } + return 0; } -static int opMOVD_mm_l_a16(uint32_t fetchdat) +static int +opMOVD_mm_l_a16(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; - CLOCK_CYCLES(1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; - CLOCK_CYCLES(2); - } - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } + return 0; } -static int opMOVD_mm_l_a32(uint32_t fetchdat) +static int +opMOVD_mm_l_a32(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; - CLOCK_CYCLES(1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; - CLOCK_CYCLES(2); - } - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } + return 0; } #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) /*Cyrix maps both MOVD and SMINT to the same opcode*/ -static int opMOVD_mm_l_a16_cx(uint32_t fetchdat) +static int +opMOVD_mm_l_a16_cx(uint32_t fetchdat) { - if (in_smm) - return opSMINT(fetchdat); + if (in_smm) + return opSMINT(fetchdat); - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; - CLOCK_CYCLES(1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; - CLOCK_CYCLES(2); - } - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } + return 0; } -static int opMOVD_mm_l_a32_cx(uint32_t fetchdat) +static int +opMOVD_mm_l_a32_cx(uint32_t fetchdat) { - if (in_smm) - return opSMINT(fetchdat); + if (in_smm) + return opSMINT(fetchdat); - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; - CLOCK_CYCLES(1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; - CLOCK_CYCLES(2); - } - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } + return 0; } #endif -static int opMOVQ_q_mm_a16(uint32_t fetchdat) +static int +opMOVQ_q_mm_a16(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q; - CLOCK_CYCLES(1); - } - else - { - uint64_t dst; + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q; + CLOCK_CYCLES(1); + } else { + uint64_t dst; - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; - cpu_state.MM[cpu_reg].q = dst; - CLOCK_CYCLES(2); - } - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmemq(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + cpu_state.MM[cpu_reg].q = dst; + CLOCK_CYCLES(2); + } + return 0; } -static int opMOVQ_q_mm_a32(uint32_t fetchdat) +static int +opMOVQ_q_mm_a32(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q; - CLOCK_CYCLES(1); - } - else - { - uint64_t dst; + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q; + CLOCK_CYCLES(1); + } else { + uint64_t dst; - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; - cpu_state.MM[cpu_reg].q = dst; - CLOCK_CYCLES(2); - } - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmemq(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + cpu_state.MM[cpu_reg].q = dst; + CLOCK_CYCLES(2); + } + return 0; } -static int opMOVQ_mm_q_a16(uint32_t fetchdat) +static int +opMOVQ_mm_q_a16(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q; - CLOCK_CYCLES(1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); - writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); if (cpu_state.abrt) return 1; - CLOCK_CYCLES(2); - } - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); + writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } + return 0; } -static int opMOVQ_mm_q_a32(uint32_t fetchdat) +static int +opMOVQ_mm_q_a32(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q; - CLOCK_CYCLES(1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); - writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); if (cpu_state.abrt) return 1; - CLOCK_CYCLES(2); - } - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); + writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } + return 0; } diff --git a/src/cpu/x86_ops_mmx_pack.h b/src/cpu/x86_ops_mmx_pack.h index e12d1b448..f0180db91 100644 --- a/src/cpu/x86_ops_mmx_pack.h +++ b/src/cpu/x86_ops_mmx_pack.h @@ -1,326 +1,342 @@ -static int opPUNPCKLDQ_a16(uint32_t fetchdat) +static int +opPUNPCKLDQ_a16(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0]; - CLOCK_CYCLES(1); - } - else - { - uint32_t src; + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0]; + CLOCK_CYCLES(1); + } else { + uint32_t src; - SEG_CHECK_READ(cpu_state.ea_seg); - src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].l[1] = src; + SEG_CHECK_READ(cpu_state.ea_seg); + src = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].l[1] = src; - CLOCK_CYCLES(2); - } - return 0; + CLOCK_CYCLES(2); + } + return 0; } -static int opPUNPCKLDQ_a32(uint32_t fetchdat) +static int +opPUNPCKLDQ_a32(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0]; - CLOCK_CYCLES(1); - } - else - { - uint32_t src; + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0]; + CLOCK_CYCLES(1); + } else { + uint32_t src; - SEG_CHECK_READ(cpu_state.ea_seg); - src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].l[1] = src; + SEG_CHECK_READ(cpu_state.ea_seg); + src = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].l[1] = src; - CLOCK_CYCLES(2); - } - return 0; + CLOCK_CYCLES(2); + } + return 0; } -static int opPUNPCKHDQ_a16(uint32_t fetchdat) +static int +opPUNPCKHDQ_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1]; - cpu_state.MM[cpu_reg].l[1] = src.l[1]; + cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1]; + cpu_state.MM[cpu_reg].l[1] = src.l[1]; - return 0; + return 0; } -static int opPUNPCKHDQ_a32(uint32_t fetchdat) +static int +opPUNPCKHDQ_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1]; - cpu_state.MM[cpu_reg].l[1] = src.l[1]; + cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1]; + cpu_state.MM[cpu_reg].l[1] = src.l[1]; - return 0; + return 0; } -static int opPUNPCKLBW_a16(uint32_t fetchdat) +static int +opPUNPCKLBW_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[7] = src.b[3]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3]; - cpu_state.MM[cpu_reg].b[5] = src.b[2]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2]; - cpu_state.MM[cpu_reg].b[3] = src.b[1]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1]; - cpu_state.MM[cpu_reg].b[1] = src.b[0]; - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0]; + cpu_state.MM[cpu_reg].b[7] = src.b[3]; + cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3]; + cpu_state.MM[cpu_reg].b[5] = src.b[2]; + cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2]; + cpu_state.MM[cpu_reg].b[3] = src.b[1]; + cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1]; + cpu_state.MM[cpu_reg].b[1] = src.b[0]; + cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0]; - return 0; + return 0; } -static int opPUNPCKLBW_a32(uint32_t fetchdat) +static int +opPUNPCKLBW_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[7] = src.b[3]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3]; - cpu_state.MM[cpu_reg].b[5] = src.b[2]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2]; - cpu_state.MM[cpu_reg].b[3] = src.b[1]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1]; - cpu_state.MM[cpu_reg].b[1] = src.b[0]; - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0]; + cpu_state.MM[cpu_reg].b[7] = src.b[3]; + cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3]; + cpu_state.MM[cpu_reg].b[5] = src.b[2]; + cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2]; + cpu_state.MM[cpu_reg].b[3] = src.b[1]; + cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1]; + cpu_state.MM[cpu_reg].b[1] = src.b[0]; + cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0]; - return 0; + return 0; } -static int opPUNPCKHBW_a16(uint32_t fetchdat) +static int +opPUNPCKHBW_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4]; - cpu_state.MM[cpu_reg].b[1] = src.b[4]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5]; - cpu_state.MM[cpu_reg].b[3] = src.b[5]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6]; - cpu_state.MM[cpu_reg].b[5] = src.b[6]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7]; - cpu_state.MM[cpu_reg].b[7] = src.b[7]; + cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4]; + cpu_state.MM[cpu_reg].b[1] = src.b[4]; + cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5]; + cpu_state.MM[cpu_reg].b[3] = src.b[5]; + cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6]; + cpu_state.MM[cpu_reg].b[5] = src.b[6]; + cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7]; + cpu_state.MM[cpu_reg].b[7] = src.b[7]; - return 0; + return 0; } -static int opPUNPCKHBW_a32(uint32_t fetchdat) +static int +opPUNPCKHBW_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4]; - cpu_state.MM[cpu_reg].b[1] = src.b[4]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5]; - cpu_state.MM[cpu_reg].b[3] = src.b[5]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6]; - cpu_state.MM[cpu_reg].b[5] = src.b[6]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7]; - cpu_state.MM[cpu_reg].b[7] = src.b[7]; + cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4]; + cpu_state.MM[cpu_reg].b[1] = src.b[4]; + cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5]; + cpu_state.MM[cpu_reg].b[3] = src.b[5]; + cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6]; + cpu_state.MM[cpu_reg].b[5] = src.b[6]; + cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7]; + cpu_state.MM[cpu_reg].b[7] = src.b[7]; - return 0; + return 0; } -static int opPUNPCKLWD_a16(uint32_t fetchdat) +static int +opPUNPCKLWD_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[3] = src.w[1]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1]; - cpu_state.MM[cpu_reg].w[1] = src.w[0]; - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0]; + cpu_state.MM[cpu_reg].w[3] = src.w[1]; + cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1]; + cpu_state.MM[cpu_reg].w[1] = src.w[0]; + cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0]; - return 0; + return 0; } -static int opPUNPCKLWD_a32(uint32_t fetchdat) +static int +opPUNPCKLWD_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[3] = src.w[1]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1]; - cpu_state.MM[cpu_reg].w[1] = src.w[0]; - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0]; + cpu_state.MM[cpu_reg].w[3] = src.w[1]; + cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1]; + cpu_state.MM[cpu_reg].w[1] = src.w[0]; + cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0]; - return 0; + return 0; } -static int opPUNPCKHWD_a16(uint32_t fetchdat) +static int +opPUNPCKHWD_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2]; - cpu_state.MM[cpu_reg].w[1] = src.w[2]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3]; - cpu_state.MM[cpu_reg].w[3] = src.w[3]; + cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2]; + cpu_state.MM[cpu_reg].w[1] = src.w[2]; + cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3]; + cpu_state.MM[cpu_reg].w[3] = src.w[3]; - return 0; + return 0; } -static int opPUNPCKHWD_a32(uint32_t fetchdat) +static int +opPUNPCKHWD_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2]; - cpu_state.MM[cpu_reg].w[1] = src.w[2]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3]; - cpu_state.MM[cpu_reg].w[3] = src.w[3]; + cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2]; + cpu_state.MM[cpu_reg].w[1] = src.w[2]; + cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3]; + cpu_state.MM[cpu_reg].w[3] = src.w[3]; - return 0; + return 0; } -static int opPACKSSWB_a16(uint32_t fetchdat) +static int +opPACKSSWB_a16(uint32_t fetchdat) { - MMX_REG src, dst; - MMX_ENTER(); + MMX_REG src, dst; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; + fetch_ea_16(fetchdat); + MMX_GETSRC(); + dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]); + cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]); + cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]); + cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]); + cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]); + cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]); + cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]); + cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]); + cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]); - return 0; + return 0; } -static int opPACKSSWB_a32(uint32_t fetchdat) +static int +opPACKSSWB_a32(uint32_t fetchdat) { - MMX_REG src, dst; - MMX_ENTER(); + MMX_REG src, dst; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; + fetch_ea_32(fetchdat); + MMX_GETSRC(); + dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]); + cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]); + cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]); + cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]); + cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]); + cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]); + cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]); + cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]); + cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]); - return 0; + return 0; } -static int opPACKUSWB_a16(uint32_t fetchdat) +static int +opPACKUSWB_a16(uint32_t fetchdat) { - MMX_REG src, dst; - MMX_ENTER(); + MMX_REG src, dst; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; + fetch_ea_16(fetchdat); + MMX_GETSRC(); + dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]); - cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]); - cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]); - cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]); + cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]); + cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]); + cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]); + cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]); + cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]); + cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]); + cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]); + cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]); - return 0; + return 0; } -static int opPACKUSWB_a32(uint32_t fetchdat) +static int +opPACKUSWB_a32(uint32_t fetchdat) { - MMX_REG src, dst; - MMX_ENTER(); + MMX_REG src, dst; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; + fetch_ea_32(fetchdat); + MMX_GETSRC(); + dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]); - cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]); - cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]); - cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]); + cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]); + cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]); + cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]); + cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]); + cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]); + cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]); + cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]); + cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]); - return 0; + return 0; } -static int opPACKSSDW_a16(uint32_t fetchdat) +static int +opPACKSSDW_a16(uint32_t fetchdat) { - MMX_REG src, dst; - MMX_ENTER(); + MMX_REG src, dst; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; + fetch_ea_16(fetchdat); + MMX_GETSRC(); + dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]); + cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]); + cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]); + cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]); + cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]); - return 0; + return 0; } -static int opPACKSSDW_a32(uint32_t fetchdat) +static int +opPACKSSDW_a32(uint32_t fetchdat) { - MMX_REG src, dst; - MMX_ENTER(); + MMX_REG src, dst; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; + fetch_ea_32(fetchdat); + MMX_GETSRC(); + dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]); + cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]); + cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]); + cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]); + cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]); - return 0; + return 0; } diff --git a/src/cpu/x86_ops_mmx_shift.h b/src/cpu/x86_ops_mmx_shift.h index df8d75cf8..c9ddc9b93 100644 --- a/src/cpu/x86_ops_mmx_shift.h +++ b/src/cpu/x86_ops_mmx_shift.h @@ -1,450 +1,453 @@ -#define MMX_GETSHIFT() \ - if (cpu_mod == 3) \ - { \ - shift = cpu_state.MM[cpu_rm].b[0]; \ - CLOCK_CYCLES(1); \ - } \ - else \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - shift = readmemb(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; \ - CLOCK_CYCLES(2); \ - } +#define MMX_GETSHIFT() \ + if (cpu_mod == 3) { \ + shift = cpu_state.MM[cpu_rm].b[0]; \ + CLOCK_CYCLES(1); \ + } else { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + shift = readmemb(easeg, cpu_state.eaaddr); \ + if (cpu_state.abrt) \ + return 0; \ + CLOCK_CYCLES(2); \ + } -static int opPSxxW_imm(uint32_t fetchdat) +static int +opPSxxW_imm(uint32_t fetchdat) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = (fetchdat >> 8) & 0xff; + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = (fetchdat >> 8) & 0xff; - cpu_state.pc += 2; - MMX_ENTER(); + cpu_state.pc += 2; + MMX_ENTER(); - switch (op) - { - case 0x10: /*PSRLW*/ - if (shift > 15) - cpu_state.MM[reg].q = 0; - else - { - cpu_state.MM[reg].w[0] >>= shift; - cpu_state.MM[reg].w[1] >>= shift; - cpu_state.MM[reg].w[2] >>= shift; - cpu_state.MM[reg].w[3] >>= shift; - } - break; - case 0x20: /*PSRAW*/ - if (shift > 15) - shift = 15; - cpu_state.MM[reg].sw[0] >>= shift; - cpu_state.MM[reg].sw[1] >>= shift; - cpu_state.MM[reg].sw[2] >>= shift; - cpu_state.MM[reg].sw[3] >>= shift; - break; - case 0x30: /*PSLLW*/ - if (shift > 15) - cpu_state.MM[reg].q = 0; - else - { - cpu_state.MM[reg].w[0] <<= shift; - cpu_state.MM[reg].w[1] <<= shift; - cpu_state.MM[reg].w[2] <<= shift; - cpu_state.MM[reg].w[3] <<= shift; - } - break; - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 0; - } - - CLOCK_CYCLES(1); - return 0; -} - -static int opPSLLW_a16(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); - - if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].w[0] <<= shift; - cpu_state.MM[cpu_reg].w[1] <<= shift; - cpu_state.MM[cpu_reg].w[2] <<= shift; - cpu_state.MM[cpu_reg].w[3] <<= shift; - } - - return 0; -} -static int opPSLLW_a32(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); - - if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].w[0] <<= shift; - cpu_state.MM[cpu_reg].w[1] <<= shift; - cpu_state.MM[cpu_reg].w[2] <<= shift; - cpu_state.MM[cpu_reg].w[3] <<= shift; - } - - return 0; -} - -static int opPSRLW_a16(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); - - if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].w[0] >>= shift; - cpu_state.MM[cpu_reg].w[1] >>= shift; - cpu_state.MM[cpu_reg].w[2] >>= shift; - cpu_state.MM[cpu_reg].w[3] >>= shift; - } - - return 0; -} -static int opPSRLW_a32(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); - - if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].w[0] >>= shift; - cpu_state.MM[cpu_reg].w[1] >>= shift; - cpu_state.MM[cpu_reg].w[2] >>= shift; - cpu_state.MM[cpu_reg].w[3] >>= shift; - } - - return 0; -} - -static int opPSRAW_a16(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); - - if (shift > 15) + switch (op) { + case 0x10: /*PSRLW*/ + if (shift > 15) + cpu_state.MM[reg].q = 0; + else { + cpu_state.MM[reg].w[0] >>= shift; + cpu_state.MM[reg].w[1] >>= shift; + cpu_state.MM[reg].w[2] >>= shift; + cpu_state.MM[reg].w[3] >>= shift; + } + break; + case 0x20: /*PSRAW*/ + if (shift > 15) shift = 15; + cpu_state.MM[reg].sw[0] >>= shift; + cpu_state.MM[reg].sw[1] >>= shift; + cpu_state.MM[reg].sw[2] >>= shift; + cpu_state.MM[reg].sw[3] >>= shift; + break; + case 0x30: /*PSLLW*/ + if (shift > 15) + cpu_state.MM[reg].q = 0; + else { + cpu_state.MM[reg].w[0] <<= shift; + cpu_state.MM[reg].w[1] <<= shift; + cpu_state.MM[reg].w[2] <<= shift; + cpu_state.MM[reg].w[3] <<= shift; + } + break; + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 0; + } - cpu_state.MM[cpu_reg].sw[0] >>= shift; - cpu_state.MM[cpu_reg].sw[1] >>= shift; - cpu_state.MM[cpu_reg].sw[2] >>= shift; - cpu_state.MM[cpu_reg].sw[3] >>= shift; - - return 0; -} -static int opPSRAW_a32(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); - - if (shift > 15) - shift = 15; - - cpu_state.MM[cpu_reg].sw[0] >>= shift; - cpu_state.MM[cpu_reg].sw[1] >>= shift; - cpu_state.MM[cpu_reg].sw[2] >>= shift; - cpu_state.MM[cpu_reg].sw[3] >>= shift; - - return 0; + CLOCK_CYCLES(1); + return 0; } -static int opPSxxD_imm(uint32_t fetchdat) +static int +opPSLLW_a16(uint32_t fetchdat) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = (fetchdat >> 8) & 0xff; + int shift; - cpu_state.pc += 2; - MMX_ENTER(); + MMX_ENTER(); - switch (op) - { - case 0x10: /*PSRLD*/ - if (shift > 31) - cpu_state.MM[reg].q = 0; - else - { - cpu_state.MM[reg].l[0] >>= shift; - cpu_state.MM[reg].l[1] >>= shift; - } - break; - case 0x20: /*PSRAD*/ - if (shift > 31) - shift = 31; - cpu_state.MM[reg].sl[0] >>= shift; - cpu_state.MM[reg].sl[1] >>= shift; - break; - case 0x30: /*PSLLD*/ - if (shift > 31) - cpu_state.MM[reg].q = 0; - else - { - cpu_state.MM[reg].l[0] <<= shift; - cpu_state.MM[reg].l[1] <<= shift; - } - break; - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 0; - } + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); - CLOCK_CYCLES(1); - return 0; + if (shift > 15) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].w[0] <<= shift; + cpu_state.MM[cpu_reg].w[1] <<= shift; + cpu_state.MM[cpu_reg].w[2] <<= shift; + cpu_state.MM[cpu_reg].w[3] <<= shift; + } + + return 0; +} +static int +opPSLLW_a32(uint32_t fetchdat) +{ + int shift; + + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); + + if (shift > 15) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].w[0] <<= shift; + cpu_state.MM[cpu_reg].w[1] <<= shift; + cpu_state.MM[cpu_reg].w[2] <<= shift; + cpu_state.MM[cpu_reg].w[3] <<= shift; + } + + return 0; } -static int opPSLLD_a16(uint32_t fetchdat) +static int +opPSRLW_a16(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); - if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].l[0] <<= shift; - cpu_state.MM[cpu_reg].l[1] <<= shift; - } + if (shift > 15) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].w[0] >>= shift; + cpu_state.MM[cpu_reg].w[1] >>= shift; + cpu_state.MM[cpu_reg].w[2] >>= shift; + cpu_state.MM[cpu_reg].w[3] >>= shift; + } - return 0; + return 0; } -static int opPSLLD_a32(uint32_t fetchdat) +static int +opPSRLW_a32(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); - if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].l[0] <<= shift; - cpu_state.MM[cpu_reg].l[1] <<= shift; - } + if (shift > 15) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].w[0] >>= shift; + cpu_state.MM[cpu_reg].w[1] >>= shift; + cpu_state.MM[cpu_reg].w[2] >>= shift; + cpu_state.MM[cpu_reg].w[3] >>= shift; + } - return 0; + return 0; } -static int opPSRLD_a16(uint32_t fetchdat) +static int +opPSRAW_a16(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); - if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].l[0] >>= shift; - cpu_state.MM[cpu_reg].l[1] >>= shift; - } + if (shift > 15) + shift = 15; - return 0; + cpu_state.MM[cpu_reg].sw[0] >>= shift; + cpu_state.MM[cpu_reg].sw[1] >>= shift; + cpu_state.MM[cpu_reg].sw[2] >>= shift; + cpu_state.MM[cpu_reg].sw[3] >>= shift; + + return 0; } -static int opPSRLD_a32(uint32_t fetchdat) +static int +opPSRAW_a32(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); - if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].l[0] >>= shift; - cpu_state.MM[cpu_reg].l[1] >>= shift; - } + if (shift > 15) + shift = 15; - return 0; + cpu_state.MM[cpu_reg].sw[0] >>= shift; + cpu_state.MM[cpu_reg].sw[1] >>= shift; + cpu_state.MM[cpu_reg].sw[2] >>= shift; + cpu_state.MM[cpu_reg].sw[3] >>= shift; + + return 0; } -static int opPSRAD_a16(uint32_t fetchdat) +static int +opPSxxD_imm(uint32_t fetchdat) { - int shift; + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = (fetchdat >> 8) & 0xff; - MMX_ENTER(); + cpu_state.pc += 2; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); - - if (shift > 31) + switch (op) { + case 0x10: /*PSRLD*/ + if (shift > 31) + cpu_state.MM[reg].q = 0; + else { + cpu_state.MM[reg].l[0] >>= shift; + cpu_state.MM[reg].l[1] >>= shift; + } + break; + case 0x20: /*PSRAD*/ + if (shift > 31) shift = 31; + cpu_state.MM[reg].sl[0] >>= shift; + cpu_state.MM[reg].sl[1] >>= shift; + break; + case 0x30: /*PSLLD*/ + if (shift > 31) + cpu_state.MM[reg].q = 0; + else { + cpu_state.MM[reg].l[0] <<= shift; + cpu_state.MM[reg].l[1] <<= shift; + } + break; + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 0; + } - cpu_state.MM[cpu_reg].sl[0] >>= shift; - cpu_state.MM[cpu_reg].sl[1] >>= shift; - - return 0; + CLOCK_CYCLES(1); + return 0; } -static int opPSRAD_a32(uint32_t fetchdat) + +static int +opPSLLD_a16(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); - if (shift > 31) - shift = 31; + if (shift > 31) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].l[0] <<= shift; + cpu_state.MM[cpu_reg].l[1] <<= shift; + } - cpu_state.MM[cpu_reg].sl[0] >>= shift; - cpu_state.MM[cpu_reg].sl[1] >>= shift; - - return 0; + return 0; } - -static int opPSxxQ_imm(uint32_t fetchdat) +static int +opPSLLD_a32(uint32_t fetchdat) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = (fetchdat >> 8) & 0xff; + int shift; - cpu_state.pc += 2; - MMX_ENTER(); + MMX_ENTER(); - switch (op) - { - case 0x10: /*PSRLW*/ - if (shift > 63) - cpu_state.MM[reg].q = 0; - else - cpu_state.MM[reg].q >>= shift; - break; - case 0x20: /*PSRAW*/ - if (shift > 63) - shift = 63; - cpu_state.MM[reg].sq >>= shift; - break; - case 0x30: /*PSLLW*/ - if (shift > 63) - cpu_state.MM[reg].q = 0; - else - cpu_state.MM[reg].q <<= shift; - break; - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 0; - } + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); - CLOCK_CYCLES(1); - return 0; + if (shift > 31) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].l[0] <<= shift; + cpu_state.MM[cpu_reg].l[1] <<= shift; + } + + return 0; } -static int opPSLLQ_a16(uint32_t fetchdat) +static int +opPSRLD_a16(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q <<= shift; + if (shift > 31) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].l[0] >>= shift; + cpu_state.MM[cpu_reg].l[1] >>= shift; + } - return 0; + return 0; } -static int opPSLLQ_a32(uint32_t fetchdat) +static int +opPSRLD_a32(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q <<= shift; + if (shift > 31) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].l[0] >>= shift; + cpu_state.MM[cpu_reg].l[1] >>= shift; + } - return 0; + return 0; } -static int opPSRLQ_a16(uint32_t fetchdat) +static int +opPSRAD_a16(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q >>= shift; + if (shift > 31) + shift = 31; - return 0; + cpu_state.MM[cpu_reg].sl[0] >>= shift; + cpu_state.MM[cpu_reg].sl[1] >>= shift; + + return 0; } -static int opPSRLQ_a32(uint32_t fetchdat) +static int +opPSRAD_a32(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q >>= shift; + if (shift > 31) + shift = 31; - return 0; + cpu_state.MM[cpu_reg].sl[0] >>= shift; + cpu_state.MM[cpu_reg].sl[1] >>= shift; + + return 0; +} + +static int +opPSxxQ_imm(uint32_t fetchdat) +{ + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = (fetchdat >> 8) & 0xff; + + cpu_state.pc += 2; + MMX_ENTER(); + + switch (op) { + case 0x10: /*PSRLW*/ + if (shift > 63) + cpu_state.MM[reg].q = 0; + else + cpu_state.MM[reg].q >>= shift; + break; + case 0x20: /*PSRAW*/ + if (shift > 63) + shift = 63; + cpu_state.MM[reg].sq >>= shift; + break; + case 0x30: /*PSLLW*/ + if (shift > 63) + cpu_state.MM[reg].q = 0; + else + cpu_state.MM[reg].q <<= shift; + break; + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 0; + } + + CLOCK_CYCLES(1); + return 0; +} + +static int +opPSLLQ_a16(uint32_t fetchdat) +{ + int shift; + + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); + + if (shift > 63) + cpu_state.MM[cpu_reg].q = 0; + else + cpu_state.MM[cpu_reg].q <<= shift; + + return 0; +} +static int +opPSLLQ_a32(uint32_t fetchdat) +{ + int shift; + + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); + + if (shift > 63) + cpu_state.MM[cpu_reg].q = 0; + else + cpu_state.MM[cpu_reg].q <<= shift; + + return 0; +} + +static int +opPSRLQ_a16(uint32_t fetchdat) +{ + int shift; + + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); + + if (shift > 63) + cpu_state.MM[cpu_reg].q = 0; + else + cpu_state.MM[cpu_reg].q >>= shift; + + return 0; +} +static int +opPSRLQ_a32(uint32_t fetchdat) +{ + int shift; + + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); + + if (shift > 63) + cpu_state.MM[cpu_reg].q = 0; + else + cpu_state.MM[cpu_reg].q >>= shift; + + return 0; } diff --git a/src/cpu/x86_ops_mov.h b/src/cpu/x86_ops_mov.h index e7d5247d1..33a8a44c0 100644 --- a/src/cpu/x86_ops_mov.h +++ b/src/cpu/x86_ops_mov.h @@ -1,770 +1,851 @@ -static int opMOV_AL_imm(uint32_t fetchdat) +static int +opMOV_AL_imm(uint32_t fetchdat) { - AL = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + AL = getbytef(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_AH_imm(uint32_t fetchdat) +static int +opMOV_AH_imm(uint32_t fetchdat) { - AH = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + AH = getbytef(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_BL_imm(uint32_t fetchdat) +static int +opMOV_BL_imm(uint32_t fetchdat) { - BL = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + BL = getbytef(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_BH_imm(uint32_t fetchdat) +static int +opMOV_BH_imm(uint32_t fetchdat) { - BH = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + BH = getbytef(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_CL_imm(uint32_t fetchdat) +static int +opMOV_CL_imm(uint32_t fetchdat) { - CL = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + CL = getbytef(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_CH_imm(uint32_t fetchdat) +static int +opMOV_CH_imm(uint32_t fetchdat) { - CH = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + CH = getbytef(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_DL_imm(uint32_t fetchdat) +static int +opMOV_DL_imm(uint32_t fetchdat) { - DL = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + DL = getbytef(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_DH_imm(uint32_t fetchdat) +static int +opMOV_DH_imm(uint32_t fetchdat) { - DH = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + DH = getbytef(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_AX_imm(uint32_t fetchdat) +static int +opMOV_AX_imm(uint32_t fetchdat) { - AX = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + AX = getwordf(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_BX_imm(uint32_t fetchdat) +static int +opMOV_BX_imm(uint32_t fetchdat) { - BX = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + BX = getwordf(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_CX_imm(uint32_t fetchdat) +static int +opMOV_CX_imm(uint32_t fetchdat) { - CX = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + CX = getwordf(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_DX_imm(uint32_t fetchdat) +static int +opMOV_DX_imm(uint32_t fetchdat) { - DX = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + DX = getwordf(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_SI_imm(uint32_t fetchdat) +static int +opMOV_SI_imm(uint32_t fetchdat) { - SI = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + SI = getwordf(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_DI_imm(uint32_t fetchdat) +static int +opMOV_DI_imm(uint32_t fetchdat) { - DI = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + DI = getwordf(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_BP_imm(uint32_t fetchdat) +static int +opMOV_BP_imm(uint32_t fetchdat) { - BP = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + BP = getwordf(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_SP_imm(uint32_t fetchdat) +static int +opMOV_SP_imm(uint32_t fetchdat) { - SP = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + SP = getwordf(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_EAX_imm(uint32_t fetchdat) +static int +opMOV_EAX_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - EAX = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t templ = getlong(); + if (cpu_state.abrt) + return 1; + EAX = templ; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_EBX_imm(uint32_t fetchdat) +static int +opMOV_EBX_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - EBX = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t templ = getlong(); + if (cpu_state.abrt) + return 1; + EBX = templ; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_ECX_imm(uint32_t fetchdat) +static int +opMOV_ECX_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - ECX = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t templ = getlong(); + if (cpu_state.abrt) + return 1; + ECX = templ; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_EDX_imm(uint32_t fetchdat) +static int +opMOV_EDX_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - EDX = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t templ = getlong(); + if (cpu_state.abrt) + return 1; + EDX = templ; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_ESI_imm(uint32_t fetchdat) +static int +opMOV_ESI_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - ESI = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t templ = getlong(); + if (cpu_state.abrt) + return 1; + ESI = templ; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_EDI_imm(uint32_t fetchdat) +static int +opMOV_EDI_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - EDI = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t templ = getlong(); + if (cpu_state.abrt) + return 1; + EDI = templ; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_EBP_imm(uint32_t fetchdat) +static int +opMOV_EBP_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - EBP = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t templ = getlong(); + if (cpu_state.abrt) + return 1; + EBP = templ; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_ESP_imm(uint32_t fetchdat) +static int +opMOV_ESP_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - ESP = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t templ = getlong(); + if (cpu_state.abrt) + return 1; + ESP = templ; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_b_imm_a16(uint32_t fetchdat) +static int +opMOV_b_imm_a16(uint32_t fetchdat) { - uint8_t temp; - fetch_ea_16(fetchdat); - ILLEGAL_ON((rmdat & 0x38) != 0); + uint8_t temp; + fetch_ea_16(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = readmemb(cs, cpu_state.pc); + cpu_state.pc++; + if (cpu_state.abrt) + return 1; + seteab(temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, rmdat, 0, 0, (cpu_mod == 3) ? 1 : 0, 0, 0); + return cpu_state.abrt; +} +static int +opMOV_b_imm_a32(uint32_t fetchdat) +{ + uint8_t temp; + fetch_ea_32(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = getbyte(); + if (cpu_state.abrt) + return 1; + seteab(temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, rmdat, 0, 0, (cpu_mod == 3) ? 1 : 0, 0, 1); + return cpu_state.abrt; +} + +static int +opMOV_w_imm_a16(uint32_t fetchdat) +{ + uint16_t temp; + fetch_ea_16(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = getword(); + if (cpu_state.abrt) + return 1; + seteaw(temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 4, rmdat, 0, 0, (cpu_mod == 3) ? 1 : 0, 0, 0); + return cpu_state.abrt; +} +static int +opMOV_w_imm_a32(uint32_t fetchdat) +{ + uint16_t temp; + fetch_ea_32(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = getword(); + if (cpu_state.abrt) + return 1; + seteaw(temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 4, rmdat, 0, 0, (cpu_mod == 3) ? 1 : 0, 0, 1); + return cpu_state.abrt; +} +static int +opMOV_l_imm_a16(uint32_t fetchdat) +{ + uint32_t temp; + fetch_ea_16(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = getlong(); + if (cpu_state.abrt) + return 1; + seteal(temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 6, rmdat, 0, 0, 0, (cpu_mod == 3) ? 1 : 0, 0); + return cpu_state.abrt; +} +static int +opMOV_l_imm_a32(uint32_t fetchdat) +{ + uint32_t temp; + fetch_ea_32(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = getlong(); + if (cpu_state.abrt) + return 1; + seteal(temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 6, rmdat, 0, 0, 0, (cpu_mod == 3) ? 1 : 0, 1); + return cpu_state.abrt; +} + +static int +opMOV_AL_a16(uint32_t fetchdat) +{ + uint8_t temp; + uint16_t addr = getwordf(); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, addr, addr); + temp = readmemb(cpu_state.ea_seg->base, addr); + if (cpu_state.abrt) + return 1; + AL = temp; + CLOCK_CYCLES((is486) ? 1 : 4); + PREFETCH_RUN(4, 3, -1, 1, 0, 0, 0, 0); + return 0; +} +static int +opMOV_AL_a32(uint32_t fetchdat) +{ + uint8_t temp; + uint32_t addr = getlong(); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, addr, addr); + temp = readmemb(cpu_state.ea_seg->base, addr); + if (cpu_state.abrt) + return 1; + AL = temp; + CLOCK_CYCLES((is486) ? 1 : 4); + PREFETCH_RUN(4, 5, -1, 1, 0, 0, 0, 1); + return 0; +} +static int +opMOV_AX_a16(uint32_t fetchdat) +{ + uint16_t temp; + uint16_t addr = getwordf(); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, addr, addr + 1UL); + temp = readmemw(cpu_state.ea_seg->base, addr); + if (cpu_state.abrt) + return 1; + AX = temp; + CLOCK_CYCLES((is486) ? 1 : 4); + PREFETCH_RUN(4, 3, -1, 1, 0, 0, 0, 0); + return 0; +} +static int +opMOV_AX_a32(uint32_t fetchdat) +{ + uint16_t temp; + uint32_t addr = getlong(); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, addr, addr + 1); + temp = readmemw(cpu_state.ea_seg->base, addr); + if (cpu_state.abrt) + return 1; + AX = temp; + CLOCK_CYCLES((is486) ? 1 : 4); + PREFETCH_RUN(4, 5, -1, 1, 0, 0, 0, 1); + return 0; +} +static int +opMOV_EAX_a16(uint32_t fetchdat) +{ + uint32_t temp; + uint16_t addr = getwordf(); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, addr, addr + 3UL); + temp = readmeml(cpu_state.ea_seg->base, addr); + if (cpu_state.abrt) + return 1; + EAX = temp; + CLOCK_CYCLES((is486) ? 1 : 4); + PREFETCH_RUN(4, 3, -1, 0, 1, 0, 0, 0); + return 0; +} +static int +opMOV_EAX_a32(uint32_t fetchdat) +{ + uint32_t temp; + uint32_t addr = getlong(); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, addr, addr + 3); + temp = readmeml(cpu_state.ea_seg->base, addr); + if (cpu_state.abrt) + return 1; + EAX = temp; + CLOCK_CYCLES((is486) ? 1 : 4); + PREFETCH_RUN(4, 5, -1, 0, 1, 0, 0, 1); + return 0; +} + +static int +opMOV_a16_AL(uint32_t fetchdat) +{ + uint16_t addr = getwordf(); + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr); + writememb(cpu_state.ea_seg->base, addr, AL); + CLOCK_CYCLES((is486) ? 1 : 2); + PREFETCH_RUN(2, 3, -1, 0, 0, 1, 0, 0); + return cpu_state.abrt; +} +static int +opMOV_a32_AL(uint32_t fetchdat) +{ + uint32_t addr = getlong(); + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr); + writememb(cpu_state.ea_seg->base, addr, AL); + CLOCK_CYCLES((is486) ? 1 : 2); + PREFETCH_RUN(2, 5, -1, 0, 0, 1, 0, 1); + return cpu_state.abrt; +} +static int +opMOV_a16_AX(uint32_t fetchdat) +{ + uint16_t addr = getwordf(); + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 1UL); + writememw(cpu_state.ea_seg->base, addr, AX); + CLOCK_CYCLES((is486) ? 1 : 2); + PREFETCH_RUN(2, 3, -1, 0, 0, 1, 0, 0); + return cpu_state.abrt; +} +static int +opMOV_a32_AX(uint32_t fetchdat) +{ + uint32_t addr = getlong(); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 1); + writememw(cpu_state.ea_seg->base, addr, AX); + CLOCK_CYCLES((is486) ? 1 : 2); + PREFETCH_RUN(2, 5, -1, 0, 0, 1, 0, 1); + return cpu_state.abrt; +} +static int +opMOV_a16_EAX(uint32_t fetchdat) +{ + uint16_t addr = getwordf(); + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 3UL); + writememl(cpu_state.ea_seg->base, addr, EAX); + CLOCK_CYCLES((is486) ? 1 : 2); + PREFETCH_RUN(2, 3, -1, 0, 0, 0, 1, 0); + return cpu_state.abrt; +} +static int +opMOV_a32_EAX(uint32_t fetchdat) +{ + uint32_t addr = getlong(); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 3); + writememl(cpu_state.ea_seg->base, addr, EAX); + CLOCK_CYCLES((is486) ? 1 : 2); + PREFETCH_RUN(2, 5, -1, 0, 0, 0, 1, 1); + return cpu_state.abrt; +} + +static int +opLEA_w_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + cpu_state.regs[cpu_reg].w = cpu_state.eaaddr; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opLEA_w_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + cpu_state.regs[cpu_reg].w = cpu_state.eaaddr; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static int +opLEA_l_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + cpu_state.regs[cpu_reg].l = cpu_state.eaaddr & 0xffff; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opLEA_l_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + cpu_state.regs[cpu_reg].l = cpu_state.eaaddr; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static int +opXLAT_a16(uint32_t fetchdat) +{ + uint32_t addr = (BX + AL) & 0xFFFF; + uint8_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmemb(cpu_state.ea_seg->base, addr); + if (cpu_state.abrt) + return 1; + AL = temp; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + return 0; +} +static int +opXLAT_a32(uint32_t fetchdat) +{ + uint32_t addr = EBX + AL; + uint8_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmemb(cpu_state.ea_seg->base, addr); + if (cpu_state.abrt) + return 1; + AL = temp; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 1); + return 0; +} + +static int +opMOV_b_r_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + setr8(cpu_rm, getr8(cpu_reg)); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + } else { SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = readmemb(cs,cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; - seteab(temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 0); - return cpu_state.abrt; + seteab(getr8(cpu_reg)); + CLOCK_CYCLES(is486 ? 1 : 2); + PREFETCH_RUN(2, 2, rmdat, 0, 0, 1, 0, 0); + } + return cpu_state.abrt; } -static int opMOV_b_imm_a32(uint32_t fetchdat) +static int +opMOV_b_r_a32(uint32_t fetchdat) { - uint8_t temp; - fetch_ea_32(fetchdat); - ILLEGAL_ON((rmdat & 0x38) != 0); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = getbyte(); if (cpu_state.abrt) return 1; - seteab(temp); + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + setr8(cpu_rm, getr8(cpu_reg)); CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 1); - return cpu_state.abrt; + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteab(getr8(cpu_reg)); + CLOCK_CYCLES(is486 ? 1 : 2); + PREFETCH_RUN(2, 2, rmdat, 0, 0, 1, 0, 1); + } + return cpu_state.abrt; +} +static int +opMOV_w_r_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].w = cpu_state.regs[cpu_reg].w; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(cpu_state.regs[cpu_reg].w); + CLOCK_CYCLES(is486 ? 1 : 2); + PREFETCH_RUN(2, 2, rmdat, 0, 0, 1, 0, 0); + } + return cpu_state.abrt; +} +static int +opMOV_w_r_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].w = cpu_state.regs[cpu_reg].w; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(cpu_state.regs[cpu_reg].w); + CLOCK_CYCLES(is486 ? 1 : 2); + PREFETCH_RUN(2, 2, rmdat, 0, 0, 1, 0, 1); + } + return cpu_state.abrt; +} +static int +opMOV_l_r_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].l = cpu_state.regs[cpu_reg].l; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(cpu_state.regs[cpu_reg].l); + CLOCK_CYCLES(is486 ? 1 : 2); + PREFETCH_RUN(2, 2, rmdat, 0, 0, 0, 1, 0); + } + return cpu_state.abrt; +} +static int +opMOV_l_r_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].l = cpu_state.regs[cpu_reg].l; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(cpu_state.regs[cpu_reg].l); + CLOCK_CYCLES(is486 ? 1 : 2); + PREFETCH_RUN(2, 2, rmdat, 0, 0, 0, 1, 1); + } + return cpu_state.abrt; } -static int opMOV_w_imm_a16(uint32_t fetchdat) +static int +opMOV_r_b_a16(uint32_t fetchdat) { + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + setr8(cpu_reg, getr8(cpu_rm)); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + } else { + uint8_t temp; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); + temp = geteab(); + if (cpu_state.abrt) + return 1; + setr8(cpu_reg, temp); + CLOCK_CYCLES(is486 ? 1 : 4); + PREFETCH_RUN(4, 2, rmdat, 1, 0, 0, 0, 0); + } + return 0; +} +static int +opMOV_r_b_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + setr8(cpu_reg, getr8(cpu_rm)); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); + } else { + uint8_t temp; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); + temp = geteab(); + if (cpu_state.abrt) + return 1; + setr8(cpu_reg, temp); + CLOCK_CYCLES(is486 ? 1 : 4); + PREFETCH_RUN(4, 2, rmdat, 1, 0, 0, 0, 1); + } + return 0; +} +static int +opMOV_r_w_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + } else { uint16_t temp; - fetch_ea_16(fetchdat); - ILLEGAL_ON((rmdat & 0x38) != 0); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = getword(); if (cpu_state.abrt) return 1; - seteaw(temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 4, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 0); - return cpu_state.abrt; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = temp; + CLOCK_CYCLES((is486) ? 1 : 4); + PREFETCH_RUN(4, 2, rmdat, 1, 0, 0, 0, 0); + } + return 0; } -static int opMOV_w_imm_a32(uint32_t fetchdat) +static int +opMOV_r_w_a32(uint32_t fetchdat) { + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); + } else { uint16_t temp; - fetch_ea_32(fetchdat); - ILLEGAL_ON((rmdat & 0x38) != 0); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = getword(); if (cpu_state.abrt) return 1; - seteaw(temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 4, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 1); - return cpu_state.abrt; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = temp; + CLOCK_CYCLES((is486) ? 1 : 4); + PREFETCH_RUN(4, 2, rmdat, 1, 0, 0, 0, 1); + } + return 0; } -static int opMOV_l_imm_a16(uint32_t fetchdat) +static int +opMOV_r_l_a16(uint32_t fetchdat) { + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + } else { uint32_t temp; - fetch_ea_16(fetchdat); - ILLEGAL_ON((rmdat & 0x38) != 0); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = getlong(); if (cpu_state.abrt) return 1; - seteal(temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 6, rmdat, 0,0,0,(cpu_mod == 3) ? 1:0, 0); - return cpu_state.abrt; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + temp = geteal(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = temp; + CLOCK_CYCLES(is486 ? 1 : 4); + PREFETCH_RUN(4, 2, rmdat, 0, 1, 0, 0, 0); + } + return 0; } -static int opMOV_l_imm_a32(uint32_t fetchdat) +static int +opMOV_r_l_a32(uint32_t fetchdat) { + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); + } else { uint32_t temp; - fetch_ea_32(fetchdat); - ILLEGAL_ON((rmdat & 0x38) != 0); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = getlong(); if (cpu_state.abrt) return 1; - seteal(temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 6, rmdat, 0,0,0,(cpu_mod == 3) ? 1:0, 1); - return cpu_state.abrt; -} - - -static int opMOV_AL_a16(uint32_t fetchdat) -{ - uint8_t temp; - uint16_t addr = getwordf(); SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, addr, addr); - temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - AL = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 3, -1, 1,0,0,0, 0); - return 0; -} -static int opMOV_AL_a32(uint32_t fetchdat) -{ - uint8_t temp; - uint32_t addr = getlong(); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, addr, addr); - temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - AL = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 5, -1, 1,0,0,0, 1); - return 0; -} -static int opMOV_AX_a16(uint32_t fetchdat) -{ - uint16_t temp; - uint16_t addr = getwordf(); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, addr, addr + 1UL); - temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - AX = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 3, -1, 1,0,0,0, 0); - return 0; -} -static int opMOV_AX_a32(uint32_t fetchdat) -{ - uint16_t temp; - uint32_t addr = getlong(); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, addr, addr+1); - temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - AX = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 5, -1, 1,0,0,0, 1); - return 0; -} -static int opMOV_EAX_a16(uint32_t fetchdat) -{ - uint32_t temp; - uint16_t addr = getwordf(); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, addr, addr + 3UL); - temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - EAX = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 3, -1, 0,1,0,0, 0); - return 0; -} -static int opMOV_EAX_a32(uint32_t fetchdat) -{ - uint32_t temp; - uint32_t addr = getlong(); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, addr, addr+3); - temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - EAX = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 5, -1, 0,1,0,0, 1); - return 0; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + temp = geteal(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = temp; + CLOCK_CYCLES(is486 ? 1 : 4); + PREFETCH_RUN(4, 2, rmdat, 0, 1, 0, 0, 1); + } + return 0; } -static int opMOV_a16_AL(uint32_t fetchdat) -{ - uint16_t addr = getwordf(); - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr); - writememb(cpu_state.ea_seg->base, addr, AL); - CLOCK_CYCLES((is486) ? 1 : 2); - PREFETCH_RUN(2, 3, -1, 0,0,1,0, 0); - return cpu_state.abrt; -} -static int opMOV_a32_AL(uint32_t fetchdat) -{ - uint32_t addr = getlong(); - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr); - writememb(cpu_state.ea_seg->base, addr, AL); - CLOCK_CYCLES((is486) ? 1 : 2); - PREFETCH_RUN(2, 5, -1, 0,0,1,0, 1); - return cpu_state.abrt; -} -static int opMOV_a16_AX(uint32_t fetchdat) -{ - uint16_t addr = getwordf(); - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 1UL); - writememw(cpu_state.ea_seg->base, addr, AX); - CLOCK_CYCLES((is486) ? 1 : 2); - PREFETCH_RUN(2, 3, -1, 0,0,1,0, 0); - return cpu_state.abrt; -} -static int opMOV_a32_AX(uint32_t fetchdat) -{ - uint32_t addr = getlong(); if (cpu_state.abrt) return 1; - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 1); - writememw(cpu_state.ea_seg->base, addr, AX); - CLOCK_CYCLES((is486) ? 1 : 2); - PREFETCH_RUN(2, 5, -1, 0,0,1,0, 1); - return cpu_state.abrt; -} -static int opMOV_a16_EAX(uint32_t fetchdat) -{ - uint16_t addr = getwordf(); - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 3UL); - writememl(cpu_state.ea_seg->base, addr, EAX); - CLOCK_CYCLES((is486) ? 1 : 2); - PREFETCH_RUN(2, 3, -1, 0,0,0,1, 0); - return cpu_state.abrt; -} -static int opMOV_a32_EAX(uint32_t fetchdat) -{ - uint32_t addr = getlong(); if (cpu_state.abrt) return 1; - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 3); - writememl(cpu_state.ea_seg->base, addr, EAX); - CLOCK_CYCLES((is486) ? 1 : 2); - PREFETCH_RUN(2, 5, -1, 0,0,0,1, 1); - return cpu_state.abrt; -} - - -static int opLEA_w_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - cpu_state.regs[cpu_reg].w = cpu_state.eaaddr; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opLEA_w_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - cpu_state.regs[cpu_reg].w = cpu_state.eaaddr; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - return 0; -} - -static int opLEA_l_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - cpu_state.regs[cpu_reg].l = cpu_state.eaaddr & 0xffff; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opLEA_l_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - cpu_state.regs[cpu_reg].l = cpu_state.eaaddr; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - return 0; -} - - - -static int opXLAT_a16(uint32_t fetchdat) -{ - uint32_t addr = (BX + AL)&0xFFFF; - uint8_t temp; - - SEG_CHECK_READ(cpu_state.ea_seg); - temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - AL = temp; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); - return 0; -} -static int opXLAT_a32(uint32_t fetchdat) -{ - uint32_t addr = EBX + AL; - uint8_t temp; - - SEG_CHECK_READ(cpu_state.ea_seg); - temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - AL = temp; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1); - return 0; -} - -static int opMOV_b_r_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - setr8(cpu_rm, getr8(cpu_reg)); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteab(getr8(cpu_reg)); - CLOCK_CYCLES(is486 ? 1 : 2); - PREFETCH_RUN(2, 2, rmdat, 0,0,1,0, 0); - } - return cpu_state.abrt; -} -static int opMOV_b_r_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - setr8(cpu_rm, getr8(cpu_reg)); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteab(getr8(cpu_reg)); - CLOCK_CYCLES(is486 ? 1 : 2); - PREFETCH_RUN(2, 2, rmdat, 0,0,1,0, 1); - } - return cpu_state.abrt; -} -static int opMOV_w_r_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].w = cpu_state.regs[cpu_reg].w; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(cpu_state.regs[cpu_reg].w); - CLOCK_CYCLES(is486 ? 1 : 2); - PREFETCH_RUN(2, 2, rmdat, 0,0,1,0, 0); - } - return cpu_state.abrt; -} -static int opMOV_w_r_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].w = cpu_state.regs[cpu_reg].w; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(cpu_state.regs[cpu_reg].w); - CLOCK_CYCLES(is486 ? 1 : 2); - PREFETCH_RUN(2, 2, rmdat, 0,0,1,0, 1); - } - return cpu_state.abrt; -} -static int opMOV_l_r_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].l = cpu_state.regs[cpu_reg].l; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(cpu_state.regs[cpu_reg].l); - CLOCK_CYCLES(is486 ? 1 : 2); - PREFETCH_RUN(2, 2, rmdat, 0,0,0,1, 0); - } - return cpu_state.abrt; -} -static int opMOV_l_r_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].l = cpu_state.regs[cpu_reg].l; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(cpu_state.regs[cpu_reg].l); - CLOCK_CYCLES(is486 ? 1 : 2); - PREFETCH_RUN(2, 2, rmdat, 0,0,0,1, 1); - } - return cpu_state.abrt; -} - -static int opMOV_r_b_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - setr8(cpu_reg, getr8(cpu_rm)); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - } - else - { - uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); - temp = geteab(); if (cpu_state.abrt) return 1; - setr8(cpu_reg, temp); - CLOCK_CYCLES(is486 ? 1 : 4); - PREFETCH_RUN(4, 2, rmdat, 1,0,0,0, 0); - } - return 0; -} -static int opMOV_r_b_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - setr8(cpu_reg, getr8(cpu_rm)); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - } - else - { - uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); - temp = geteab(); if (cpu_state.abrt) return 1; - setr8(cpu_reg, temp); - CLOCK_CYCLES(is486 ? 1 : 4); - PREFETCH_RUN(4, 2, rmdat, 1,0,0,0, 1); - } - return 0; -} -static int opMOV_r_w_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - } - else - { - uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 2, rmdat, 1,0,0,0, 0); - } - return 0; -} -static int opMOV_r_w_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - } - else - { - uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 2, rmdat, 1,0,0,0, 1); - } - return 0; -} -static int opMOV_r_l_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - } - else - { - uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); - temp = geteal(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = temp; - CLOCK_CYCLES(is486 ? 1 : 4); - PREFETCH_RUN(4, 2, rmdat, 0,1,0,0, 0); - } - return 0; -} -static int opMOV_r_l_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - } - else - { - uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); - temp = geteal(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = temp; - CLOCK_CYCLES(is486 ? 1 : 4); - PREFETCH_RUN(4, 2, rmdat, 0,1,0,0, 1); - } - return 0; -} - -#define opCMOV(condition) \ - static int opCMOV ## condition ## _w_a16(uint32_t fetchdat) \ - { \ - fetch_ea_16(fetchdat); \ - if (cond_ ## condition) \ - { \ - if (cpu_mod == 3) \ - cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \ - else \ - { \ - uint16_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); \ - temp = geteaw(); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].w = temp; \ - } \ - } \ - CLOCK_CYCLES(1); \ - return 0; \ - } \ - static int opCMOV ## condition ## _w_a32(uint32_t fetchdat) \ - { \ - fetch_ea_32(fetchdat); \ - if (cond_ ## condition) \ - { \ - if (cpu_mod == 3) \ - cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \ - else \ - { \ - uint16_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); \ - temp = geteaw(); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].w = temp; \ - } \ - } \ - CLOCK_CYCLES(1); \ - return 0; \ - } \ - static int opCMOV ## condition ## _l_a16(uint32_t fetchdat) \ - { \ - fetch_ea_16(fetchdat); \ - if (cond_ ## condition) \ - { \ - if (cpu_mod == 3) \ - cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \ - else \ - { \ - uint32_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); \ - temp = geteal(); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].l = temp; \ - } \ - } \ - CLOCK_CYCLES(1); \ - return 0; \ - } \ - static int opCMOV ## condition ## _l_a32(uint32_t fetchdat) \ - { \ - fetch_ea_32(fetchdat); \ - if (cond_ ## condition) \ - { \ - if (cpu_mod == 3) \ - cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \ - else \ - { \ - uint32_t temp; \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - temp = geteal(); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].l = temp; \ - } \ - } \ - CLOCK_CYCLES(1); \ - return 0; \ - } +#define opCMOV(condition) \ + static int opCMOV##condition##_w_a16(uint32_t fetchdat) \ + { \ + fetch_ea_16(fetchdat); \ + if (cond_##condition) { \ + if (cpu_mod == 3) \ + cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \ + else { \ + uint16_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \ + temp = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].w = temp; \ + } \ + } \ + CLOCK_CYCLES(1); \ + return 0; \ + } \ + static int opCMOV##condition##_w_a32(uint32_t fetchdat) \ + { \ + fetch_ea_32(fetchdat); \ + if (cond_##condition) { \ + if (cpu_mod == 3) \ + cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \ + else { \ + uint16_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \ + temp = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].w = temp; \ + } \ + } \ + CLOCK_CYCLES(1); \ + return 0; \ + } \ + static int opCMOV##condition##_l_a16(uint32_t fetchdat) \ + { \ + fetch_ea_16(fetchdat); \ + if (cond_##condition) { \ + if (cpu_mod == 3) \ + cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \ + else { \ + uint32_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ + temp = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].l = temp; \ + } \ + } \ + CLOCK_CYCLES(1); \ + return 0; \ + } \ + static int opCMOV##condition##_l_a32(uint32_t fetchdat) \ + { \ + fetch_ea_32(fetchdat); \ + if (cond_##condition) { \ + if (cpu_mod == 3) \ + cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \ + else { \ + uint32_t temp; \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + temp = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].l = temp; \ + } \ + } \ + CLOCK_CYCLES(1); \ + return 0; \ + } opCMOV(O) opCMOV(NO) diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu/x86_ops_mov_ctrl.h index 0d973338e..0cfa38095 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu/x86_ops_mov_ctrl.h @@ -1,368 +1,362 @@ -static int opMOV_r_CRx_a16(uint32_t fetchdat) +static int +opMOV_r_CRx_a16(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - switch (cpu_reg) - { - case 0: - cpu_state.regs[cpu_rm].l = cr0; - if (is486 || isibm486) - cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/ - else { - if (is386) - cpu_state.regs[cpu_rm].l |=0x7fffffe0; - else - cpu_state.regs[cpu_rm].l |=0x7ffffff0; - } - break; - case 2: - cpu_state.regs[cpu_rm].l = cr2; - break; - case 3: - cpu_state.regs[cpu_rm].l = cr3; - break; - case 4: - if (cpu_has_feature(CPU_FEATURE_CR4)) - { - cpu_state.regs[cpu_rm].l = cr4; - break; - } - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opMOV_r_CRx_a32(uint32_t fetchdat) -{ - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_32(fetchdat); - switch (cpu_reg) - { - case 0: - cpu_state.regs[cpu_rm].l = cr0; - if (is486 || isibm486) - cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/ - else { - if (is386) - cpu_state.regs[cpu_rm].l |=0x7fffffe0; - else - cpu_state.regs[cpu_rm].l |=0x7ffffff0; - } - break; - case 2: - cpu_state.regs[cpu_rm].l = cr2; - break; - case 3: - cpu_state.regs[cpu_rm].l = cr3; - break; - case 4: - if (cpu_has_feature(CPU_FEATURE_CR4)) - { - cpu_state.regs[cpu_rm].l = cr4; - break; - } - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1); - return 0; -} - -static int opMOV_r_DRx_a16(uint32_t fetchdat) -{ - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opMOV_r_DRx_a32(uint32_t fetchdat) -{ - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_32(fetchdat); - cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1); - return 0; -} - -static int opMOV_CRx_r_a16(uint32_t fetchdat) -{ - uint32_t old_cr0 = cr0; - - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL,0); - return 1; - } - fetch_ea_16(fetchdat); - switch (cpu_reg) - { - case 0: - if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001) - flushmmucache(); - /* Make sure CPL = 0 when switching from real mode to protected mode. */ - if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) - cpu_state.seg_cs.access &= 0x9f; - cr0 = cpu_state.regs[cpu_rm].l; - if (cpu_16bitbus) - cr0 |= 0x10; - if (!(cr0 & 0x80000000)) - mmu_perm=4; - if (hascache && !(cr0 & (1 << 30))) - cpu_cache_int_enabled = 1; - else - cpu_cache_int_enabled = 0; - if (hascache && ((cr0 ^ old_cr0) & (1 << 30))) - cpu_update_waitstates(); - if (cr0 & 1) - cpu_cur_status |= CPU_STATUS_PMODE; + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + switch (cpu_reg) { + case 0: + cpu_state.regs[cpu_rm].l = cr0; + if (is486 || isibm486) + cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/ + else { + if (is386) + cpu_state.regs[cpu_rm].l |= 0x7fffffe0; else - cpu_cur_status &= ~CPU_STATUS_PMODE; + cpu_state.regs[cpu_rm].l |= 0x7ffffff0; + } + break; + case 2: + cpu_state.regs[cpu_rm].l = cr2; + break; + case 3: + cpu_state.regs[cpu_rm].l = cr3; + break; + case 4: + if (cpu_has_feature(CPU_FEATURE_CR4)) { + cpu_state.regs[cpu_rm].l = cr4; break; - case 2: - cr2 = cpu_state.regs[cpu_rm].l; + } + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opMOV_r_CRx_a32(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_32(fetchdat); + switch (cpu_reg) { + case 0: + cpu_state.regs[cpu_rm].l = cr0; + if (is486 || isibm486) + cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/ + else { + if (is386) + cpu_state.regs[cpu_rm].l |= 0x7fffffe0; + else + cpu_state.regs[cpu_rm].l |= 0x7ffffff0; + } + break; + case 2: + cpu_state.regs[cpu_rm].l = cr2; + break; + case 3: + cpu_state.regs[cpu_rm].l = cr3; + break; + case 4: + if (cpu_has_feature(CPU_FEATURE_CR4)) { + cpu_state.regs[cpu_rm].l = cr4; break; - case 3: - cr3 = cpu_state.regs[cpu_rm].l; + } + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static int +opMOV_r_DRx_a16(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opMOV_r_DRx_a32(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_32(fetchdat); + cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static int +opMOV_CRx_r_a16(uint32_t fetchdat) +{ + uint32_t old_cr0 = cr0; + + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + switch (cpu_reg) { + case 0: + if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001) flushmmucache(); + /* Make sure CPL = 0 when switching from real mode to protected mode. */ + if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) + cpu_state.seg_cs.access &= 0x9f; + cr0 = cpu_state.regs[cpu_rm].l; + if (cpu_16bitbus) + cr0 |= 0x10; + if (!(cr0 & 0x80000000)) + mmu_perm = 4; + if (hascache && !(cr0 & (1 << 30))) + cpu_cache_int_enabled = 1; + else + cpu_cache_int_enabled = 0; + if (hascache && ((cr0 ^ old_cr0) & (1 << 30))) + cpu_update_waitstates(); + if (cr0 & 1) + cpu_cur_status |= CPU_STATUS_PMODE; + else + cpu_cur_status &= ~CPU_STATUS_PMODE; + break; + case 2: + cr2 = cpu_state.regs[cpu_rm].l; + break; + case 3: + cr3 = cpu_state.regs[cpu_rm].l; + flushmmucache(); + break; + case 4: + if (cpu_has_feature(CPU_FEATURE_CR4)) { + if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & CR4_PAE) + flushmmucache(); + cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; break; - case 4: - if (cpu_has_feature(CPU_FEATURE_CR4)) - { - if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & CR4_PAE) - flushmmucache(); - cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; - break; - } + } - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - CLOCK_CYCLES(10); - PREFETCH_RUN(10, 2, rmdat, 0,0,0,0, 0); - return 0; + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + CLOCK_CYCLES(10); + PREFETCH_RUN(10, 2, rmdat, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_CRx_r_a32(uint32_t fetchdat) +static int +opMOV_CRx_r_a32(uint32_t fetchdat) { - uint32_t old_cr0 = cr0; + uint32_t old_cr0 = cr0; - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL,0); - return 1; - } - fetch_ea_32(fetchdat); - switch (cpu_reg) - { - case 0: - if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001) - flushmmucache(); - /* Make sure CPL = 0 when switching from real mode to protected mode. */ - if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) - cpu_state.seg_cs.access &= 0x9f; - cr0 = cpu_state.regs[cpu_rm].l; - if (cpu_16bitbus) - cr0 |= 0x10; - if (!(cr0 & 0x80000000)) - mmu_perm=4; - if (hascache && !(cr0 & (1 << 30))) - cpu_cache_int_enabled = 1; - else - cpu_cache_int_enabled = 0; - if (hascache && ((cr0 ^ old_cr0) & (1 << 30))) - cpu_update_waitstates(); - if (cr0 & 1) - cpu_cur_status |= CPU_STATUS_PMODE; - else - cpu_cur_status &= ~CPU_STATUS_PMODE; - break; - case 2: - cr2 = cpu_state.regs[cpu_rm].l; - break; - case 3: - cr3 = cpu_state.regs[cpu_rm].l; + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_32(fetchdat); + switch (cpu_reg) { + case 0: + if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001) flushmmucache(); + /* Make sure CPL = 0 when switching from real mode to protected mode. */ + if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) + cpu_state.seg_cs.access &= 0x9f; + cr0 = cpu_state.regs[cpu_rm].l; + if (cpu_16bitbus) + cr0 |= 0x10; + if (!(cr0 & 0x80000000)) + mmu_perm = 4; + if (hascache && !(cr0 & (1 << 30))) + cpu_cache_int_enabled = 1; + else + cpu_cache_int_enabled = 0; + if (hascache && ((cr0 ^ old_cr0) & (1 << 30))) + cpu_update_waitstates(); + if (cr0 & 1) + cpu_cur_status |= CPU_STATUS_PMODE; + else + cpu_cur_status &= ~CPU_STATUS_PMODE; + break; + case 2: + cr2 = cpu_state.regs[cpu_rm].l; + break; + case 3: + cr3 = cpu_state.regs[cpu_rm].l; + flushmmucache(); + break; + case 4: + if (cpu_has_feature(CPU_FEATURE_CR4)) { + if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & CR4_PAE) + flushmmucache(); + cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; break; - case 4: - if (cpu_has_feature(CPU_FEATURE_CR4)) - { - if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & CR4_PAE) - flushmmucache(); - cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; + } + + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + CLOCK_CYCLES(10); + PREFETCH_RUN(10, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static int +opMOV_DRx_r_a16(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + dr[cpu_reg] = cpu_state.regs[cpu_rm].l; + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opMOV_DRx_r_a32(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + dr[cpu_reg] = cpu_state.regs[cpu_rm].l; + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static void +opMOV_r_TRx(void) +{ + uint32_t base; + + base = _tr[4] & 0xfffff800; + switch (cpu_reg) { + case 3: + pclog("[R] %08X cache = %08X\n", base + cache_index, _tr[3]); + _tr[3] = *(uint32_t *) &(_cache[cache_index]); + cache_index = (cache_index + 4) & 0xf; + break; + } + cpu_state.regs[cpu_rm].l = _tr[cpu_reg]; + CLOCK_CYCLES(6); +} +static int +opMOV_r_TRx_a16(uint32_t fetchdat) +{ + if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + opMOV_r_TRx(); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opMOV_r_TRx_a32(uint32_t fetchdat) +{ + if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_32(fetchdat); + opMOV_r_TRx(); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static void +opMOV_TRx_r(void) +{ + uint32_t base; + int i, ctl; + + _tr[cpu_reg] = cpu_state.regs[cpu_rm].l; + base = _tr[4] & 0xfffff800; + ctl = _tr[5] & 3; + switch (cpu_reg) { + case 3: + pclog("[W] %08X cache = %08X\n", base + cache_index, _tr[3]); + *(uint32_t *) &(_cache[cache_index]) = _tr[3]; + cache_index = (cache_index + 4) & 0xf; + break; + case 4: + if (!(cr0 & 1) && !(_tr[5] & (1 << 19))) + pclog("TAG = %08X, DEST = %08X\n", base, base + cache_index - 16); + break; + case 5: + pclog("[16] EXT = %i (%i), SET = %04X\n", !!(_tr[5] & (1 << 19)), _tr[5] & 0x03, _tr[5] & 0x7f0); + if (!(_tr[5] & (1 << 19))) { + switch (ctl) { + case 0: + pclog(" Cache fill or read...\n", base); + break; + case 1: + base += (_tr[5] & 0x7f0); + pclog(" Writing 16 bytes to %08X...\n", base); + for (i = 0; i < 16; i += 4) + mem_writel_phys(base + i, *(uint32_t *) &(_cache[i])); + break; + case 2: + base += (_tr[5] & 0x7f0); + pclog(" Reading 16 bytes from %08X...\n", base); + for (i = 0; i < 16; i += 4) + *(uint32_t *) &(_cache[i]) = mem_readl_phys(base + i); + break; + case 3: + pclog(" Cache invalidate/flush...\n", base); break; } - - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - CLOCK_CYCLES(10); - PREFETCH_RUN(10, 2, rmdat, 0,0,0,0, 1); - return 0; + } + break; + } + CLOCK_CYCLES(6); } - -static int opMOV_DRx_r_a16(uint32_t fetchdat) +static int +opMOV_TRx_r_a16(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - dr[cpu_reg] = cpu_state.regs[cpu_rm].l; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0); - return 0; + if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + opMOV_TRx_r(); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_DRx_r_a32(uint32_t fetchdat) +static int +opMOV_TRx_r_a32(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - dr[cpu_reg] = cpu_state.regs[cpu_rm].l; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1); - return 0; -} - -static void opMOV_r_TRx(void) -{ - uint32_t base; - - base = _tr[4] & 0xfffff800; - switch (cpu_reg) { - case 3: - pclog("[R] %08X cache = %08X\n", base + cache_index, _tr[3]); - _tr[3] = *(uint32_t *) &(_cache[cache_index]); - cache_index = (cache_index + 4) & 0xf; - break; - } - cpu_state.regs[cpu_rm].l = _tr[cpu_reg]; - CLOCK_CYCLES(6); -} -static int opMOV_r_TRx_a16(uint32_t fetchdat) -{ - if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - opMOV_r_TRx(); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opMOV_r_TRx_a32(uint32_t fetchdat) -{ - if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_32(fetchdat); - opMOV_r_TRx(); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1); - return 0; -} - -static void opMOV_TRx_r(void) -{ - uint32_t base; - int i, ctl; - - _tr[cpu_reg] = cpu_state.regs[cpu_rm].l; - base = _tr[4] & 0xfffff800; - ctl = _tr[5] & 3; - switch (cpu_reg) { - case 3: - pclog("[W] %08X cache = %08X\n", base + cache_index, _tr[3]); - *(uint32_t *) &(_cache[cache_index]) = _tr[3]; - cache_index = (cache_index + 4) & 0xf; - break; - case 4: - if (!(cr0 & 1) && !(_tr[5] & (1 << 19))) - pclog("TAG = %08X, DEST = %08X\n", base, base + cache_index - 16); - break; - case 5: - pclog("[16] EXT = %i (%i), SET = %04X\n", !!(_tr[5] & (1 << 19)), _tr[5] & 0x03, _tr[5] & 0x7f0); - if (!(_tr[5] & (1 << 19))) { - switch(ctl) { - case 0: - pclog(" Cache fill or read...\n", base); - break; - case 1: - base += (_tr[5] & 0x7f0); - pclog(" Writing 16 bytes to %08X...\n", base); - for (i = 0; i < 16; i += 4) - mem_writel_phys(base + i, *(uint32_t *) &(_cache[i])); - break; - case 2: - base += (_tr[5] & 0x7f0); - pclog(" Reading 16 bytes from %08X...\n", base); - for (i = 0; i < 16; i += 4) - *(uint32_t *) &(_cache[i]) = mem_readl_phys(base + i); - break; - case 3: - pclog(" Cache invalidate/flush...\n", base); - break; - } - } - break; - } - CLOCK_CYCLES(6); -} -static int opMOV_TRx_r_a16(uint32_t fetchdat) -{ - if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - opMOV_TRx_r(); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opMOV_TRx_r_a32(uint32_t fetchdat) -{ - if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_32(fetchdat); - opMOV_TRx_r(); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1); - return 0; + if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_32(fetchdat); + opMOV_TRx_r(); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + return 0; } diff --git a/src/cpu/x86_ops_mov_seg.h b/src/cpu/x86_ops_mov_seg.h index 02e2d50de..be8acb618 100644 --- a/src/cpu/x86_ops_mov_seg.h +++ b/src/cpu/x86_ops_mov_seg.h @@ -1,445 +1,532 @@ -static int opMOV_w_seg_a16(uint32_t fetchdat) +static int +opMOV_w_seg_a16(uint32_t fetchdat) { - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + seteaw(ES); + break; + case 0x08: /*CS*/ + seteaw(CS); + break; + case 0x18: /*DS*/ + seteaw(DS); + break; + case 0x10: /*SS*/ + seteaw(SS); + break; + case 0x20: /*FS*/ + seteaw(FS); + break; + case 0x28: /*GS*/ + seteaw(GS); + break; + } + + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + return cpu_state.abrt; +} +static int +opMOV_w_seg_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + seteaw(ES); + break; + case 0x08: /*CS*/ + seteaw(CS); + break; + case 0x18: /*DS*/ + seteaw(DS); + break; + case 0x10: /*SS*/ + seteaw(SS); + break; + case 0x20: /*FS*/ + seteaw(FS); + break; + case 0x28: /*GS*/ + seteaw(GS); + break; + } + + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + return cpu_state.abrt; +} + +static int +opMOV_l_seg_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = ES; + else seteaw(ES); - break; - case 0x08: /*CS*/ + break; + case 0x08: /*CS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = CS; + else seteaw(CS); - break; - case 0x18: /*DS*/ + break; + case 0x18: /*DS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = DS; + else seteaw(DS); - break; - case 0x10: /*SS*/ + break; + case 0x10: /*SS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = SS; + else seteaw(SS); - break; - case 0x20: /*FS*/ + break; + case 0x20: /*FS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = FS; + else seteaw(FS); - break; - case 0x28: /*GS*/ + break; + case 0x28: /*GS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = GS; + else seteaw(GS); - break; - } + break; + } - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - return cpu_state.abrt; + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + return cpu_state.abrt; } -static int opMOV_w_seg_a32(uint32_t fetchdat) +static int +opMOV_l_seg_a32(uint32_t fetchdat) { - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = ES; + else seteaw(ES); - break; - case 0x08: /*CS*/ + break; + case 0x08: /*CS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = CS; + else seteaw(CS); - break; - case 0x18: /*DS*/ + break; + case 0x18: /*DS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = DS; + else seteaw(DS); - break; - case 0x10: /*SS*/ + break; + case 0x10: /*SS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = SS; + else seteaw(SS); - break; - case 0x20: /*FS*/ + break; + case 0x20: /*FS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = FS; + else seteaw(FS); - break; - case 0x28: /*GS*/ + break; + case 0x28: /*GS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = GS; + else seteaw(GS); - break; - } + break; + } - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - return cpu_state.abrt; + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + return cpu_state.abrt; } -static int opMOV_l_seg_a16(uint32_t fetchdat) +static int +opMOV_seg_w_a16(uint32_t fetchdat) { - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + uint16_t new_seg; - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = ES; - else seteaw(ES); - break; - case 0x08: /*CS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = CS; - else seteaw(CS); - break; - case 0x18: /*DS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = DS; - else seteaw(DS); - break; - case 0x10: /*SS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = SS; - else seteaw(SS); - break; - case 0x20: /*FS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = FS; - else seteaw(FS); - break; - case 0x28: /*GS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = GS; - else seteaw(GS); - break; - } + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + new_seg = geteaw(); + if (cpu_state.abrt) + return 1; - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - return cpu_state.abrt; -} -static int opMOV_l_seg_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = ES; - else seteaw(ES); - break; - case 0x08: /*CS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = CS; - else seteaw(CS); - break; - case 0x18: /*DS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = DS; - else seteaw(DS); - break; - case 0x10: /*SS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = SS; - else seteaw(SS); - break; - case 0x20: /*FS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = FS; - else seteaw(FS); - break; - case 0x28: /*GS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = GS; - else seteaw(GS); - break; - } - - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - return cpu_state.abrt; -} - -static int opMOV_seg_w_a16(uint32_t fetchdat) -{ - uint16_t new_seg; - - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - new_seg=geteaw(); if (cpu_state.abrt) return 1; - - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ - loadseg(new_seg, &cpu_state.seg_es); - break; - case 0x18: /*DS*/ - loadseg(new_seg, &cpu_state.seg_ds); - break; - case 0x10: /*SS*/ - loadseg(new_seg, &cpu_state.seg_ss); - if (cpu_state.abrt) return 1; - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; - cpu_state.ssegs = 0; - cpu_state.ea_seg = &cpu_state.seg_ds; - fetchdat = fastreadl(cs + cpu_state.pc); - cpu_state.pc++; - if (cpu_state.abrt) return 1; - x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + loadseg(new_seg, &cpu_state.seg_es); + break; + case 0x18: /*DS*/ + loadseg(new_seg, &cpu_state.seg_ds); + break; + case 0x10: /*SS*/ + loadseg(new_seg, &cpu_state.seg_ss); + if (cpu_state.abrt) return 1; - case 0x20: /*FS*/ - loadseg(new_seg, &cpu_state.seg_fs); - break; - case 0x28: /*GS*/ - loadseg(new_seg, &cpu_state.seg_gs); - break; - } - - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - return cpu_state.abrt; -} -static int opMOV_seg_w_a32(uint32_t fetchdat) -{ - uint16_t new_seg; - - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - new_seg=geteaw(); if (cpu_state.abrt) return 1; - - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ - loadseg(new_seg, &cpu_state.seg_es); - break; - case 0x18: /*DS*/ - loadseg(new_seg, &cpu_state.seg_ds); - break; - case 0x10: /*SS*/ - loadseg(new_seg, &cpu_state.seg_ss); - if (cpu_state.abrt) return 1; - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; - cpu_state.ssegs = 0; - cpu_state.ea_seg = &cpu_state.seg_ds; - fetchdat = fastreadl(cs + cpu_state.pc); - cpu_state.pc++; - if (cpu_state.abrt) return 1; - x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + fetchdat = fastreadl(cs + cpu_state.pc); + cpu_state.pc++; + if (cpu_state.abrt) return 1; - case 0x20: /*FS*/ - loadseg(new_seg, &cpu_state.seg_fs); - break; - case 0x28: /*GS*/ - loadseg(new_seg, &cpu_state.seg_gs); - break; - } + x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return 1; + case 0x20: /*FS*/ + loadseg(new_seg, &cpu_state.seg_fs); + break; + case 0x28: /*GS*/ + loadseg(new_seg, &cpu_state.seg_gs); + break; + } - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - return cpu_state.abrt; + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + return cpu_state.abrt; } - - -static int opLDS_w_a16(uint32_t fetchdat) +static int +opMOV_seg_w_a32(uint32_t fetchdat) { - uint16_t addr, seg; + uint16_t new_seg; - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state. eaaddr + 3); - addr = readmemw(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 0); - return 0; -} -static int opLDS_w_a32(uint32_t fetchdat) -{ - uint16_t addr, seg; - - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state. eaaddr + 3); - addr = readmemw(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 1); - return 0; -} -static int opLDS_l_a16(uint32_t fetchdat) -{ - uint32_t addr; - uint16_t seg; - - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state. eaaddr + 5); - addr = readmeml(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 1,1,0,0, 0); - return 0; -} -static int opLDS_l_a32(uint32_t fetchdat) -{ - uint32_t addr; - uint16_t seg; - - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state. eaaddr + 5); - addr = readmeml(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 1,1,0,0, 1); - return 0; -} - -static int opLSS_w_a16(uint32_t fetchdat) -{ - uint16_t addr, seg; - - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - addr = readmemw(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 0); + new_seg = geteaw(); + if (cpu_state.abrt) return 1; + + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + loadseg(new_seg, &cpu_state.seg_es); + break; + case 0x18: /*DS*/ + loadseg(new_seg, &cpu_state.seg_ds); + break; + case 0x10: /*SS*/ + loadseg(new_seg, &cpu_state.seg_ss); + if (cpu_state.abrt) + return 1; + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + fetchdat = fastreadl(cs + cpu_state.pc); + cpu_state.pc++; + if (cpu_state.abrt) + return 1; + x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return 1; + case 0x20: /*FS*/ + loadseg(new_seg, &cpu_state.seg_fs); + break; + case 0x28: /*GS*/ + loadseg(new_seg, &cpu_state.seg_gs); + break; + } + + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + return cpu_state.abrt; } -static int opLSS_w_a32(uint32_t fetchdat) + +static int +opLDS_w_a16(uint32_t fetchdat) { - uint16_t addr, seg; + uint16_t addr, seg; - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - addr = readmemw(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 1); + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + addr = readmemw(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) return 1; + loadseg(seg, &cpu_state.seg_ds); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = addr; + + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 0); + return 0; } -static int opLSS_l_a16(uint32_t fetchdat) +static int +opLDS_w_a32(uint32_t fetchdat) { - uint32_t addr; - uint16_t seg; + uint16_t addr, seg; - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); - addr = readmeml(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 0); + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + addr = readmemw(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) return 1; + loadseg(seg, &cpu_state.seg_ds); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = addr; + + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 1); + return 0; } -static int opLSS_l_a32(uint32_t fetchdat) +static int +opLDS_l_a16(uint32_t fetchdat) { - uint32_t addr; - uint16_t seg; + uint32_t addr; + uint16_t seg; - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); - addr = readmeml(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 1); + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); + addr = readmeml(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) return 1; + loadseg(seg, &cpu_state.seg_ds); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = addr; + + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 1, 1, 0, 0, 0); + return 0; +} +static int +opLDS_l_a32(uint32_t fetchdat) +{ + uint32_t addr; + uint16_t seg; + + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); + addr = readmeml(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + loadseg(seg, &cpu_state.seg_ds); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = addr; + + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 1, 1, 0, 0, 1); + return 0; } -#define opLsel(name, sel) \ - static int opL ## name ## _w_a16(uint32_t fetchdat) \ - { \ - uint16_t addr, seg; \ - \ - fetch_ea_16(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - ILLEGAL_ON(cpu_mod == 3); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ - addr = readmemw(easeg, cpu_state.eaaddr); \ - seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; \ - loadseg(seg, &sel); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].w = addr; \ - \ - CLOCK_CYCLES(7); \ - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 0); \ - return 0; \ - } \ - \ - static int opL ## name ## _w_a32(uint32_t fetchdat) \ - { \ - uint16_t addr, seg; \ - \ - fetch_ea_32(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - ILLEGAL_ON(cpu_mod == 3); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ - addr = readmemw(easeg, cpu_state.eaaddr); \ - seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; \ - loadseg(seg, &sel); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].w = addr; \ - \ - CLOCK_CYCLES(7); \ - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 1); \ - return 0; \ - } \ - \ - static int opL ## name ## _l_a16(uint32_t fetchdat) \ - { \ - uint32_t addr; \ - uint16_t seg; \ - \ - fetch_ea_16(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - ILLEGAL_ON(cpu_mod == 3); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); \ - addr = readmeml(easeg, cpu_state.eaaddr); \ - seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; \ - loadseg(seg, &sel); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].l = addr; \ - \ - CLOCK_CYCLES(7); \ - PREFETCH_RUN(7, 2, rmdat, 1,1,0,0, 0); \ - return 0; \ - } \ - \ - static int opL ## name ## _l_a32(uint32_t fetchdat) \ - { \ - uint32_t addr; \ - uint16_t seg; \ - \ - fetch_ea_32(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - ILLEGAL_ON(cpu_mod == 3); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); \ - addr = readmeml(easeg, cpu_state.eaaddr); \ - seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; \ - loadseg(seg, &sel); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].l = addr; \ - \ - CLOCK_CYCLES(7); \ - PREFETCH_RUN(7, 2, rmdat, 1,1,0,0, 1); \ - return 0; \ - } +static int +opLSS_w_a16(uint32_t fetchdat) +{ + uint16_t addr, seg; + + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + addr = readmemw(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + loadseg(seg, &cpu_state.seg_ss); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = addr; + + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 0); + return 1; +} +static int +opLSS_w_a32(uint32_t fetchdat) +{ + uint16_t addr, seg; + + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + addr = readmemw(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + loadseg(seg, &cpu_state.seg_ss); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = addr; + + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 1); + return 1; +} +static int +opLSS_l_a16(uint32_t fetchdat) +{ + uint32_t addr; + uint16_t seg; + + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); + addr = readmeml(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + loadseg(seg, &cpu_state.seg_ss); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = addr; + + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 0); + return 1; +} +static int +opLSS_l_a32(uint32_t fetchdat) +{ + uint32_t addr; + uint16_t seg; + + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); + addr = readmeml(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + loadseg(seg, &cpu_state.seg_ss); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = addr; + + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 1); + return 1; +} + +#define opLsel(name, sel) \ + static int opL##name##_w_a16(uint32_t fetchdat) \ + { \ + uint16_t addr, seg; \ + \ + fetch_ea_16(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + ILLEGAL_ON(cpu_mod == 3); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ + addr = readmemw(easeg, cpu_state.eaaddr); \ + seg = readmemw(easeg, cpu_state.eaaddr + 2); \ + if (cpu_state.abrt) \ + return 1; \ + loadseg(seg, &sel); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].w = addr; \ + \ + CLOCK_CYCLES(7); \ + PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 0); \ + return 0; \ + } \ + \ + static int opL##name##_w_a32(uint32_t fetchdat) \ + { \ + uint16_t addr, seg; \ + \ + fetch_ea_32(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + ILLEGAL_ON(cpu_mod == 3); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ + addr = readmemw(easeg, cpu_state.eaaddr); \ + seg = readmemw(easeg, cpu_state.eaaddr + 2); \ + if (cpu_state.abrt) \ + return 1; \ + loadseg(seg, &sel); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].w = addr; \ + \ + CLOCK_CYCLES(7); \ + PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 1); \ + return 0; \ + } \ + \ + static int opL##name##_l_a16(uint32_t fetchdat) \ + { \ + uint32_t addr; \ + uint16_t seg; \ + \ + fetch_ea_16(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + ILLEGAL_ON(cpu_mod == 3); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); \ + addr = readmeml(easeg, cpu_state.eaaddr); \ + seg = readmemw(easeg, cpu_state.eaaddr + 4); \ + if (cpu_state.abrt) \ + return 1; \ + loadseg(seg, &sel); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].l = addr; \ + \ + CLOCK_CYCLES(7); \ + PREFETCH_RUN(7, 2, rmdat, 1, 1, 0, 0, 0); \ + return 0; \ + } \ + \ + static int opL##name##_l_a32(uint32_t fetchdat) \ + { \ + uint32_t addr; \ + uint16_t seg; \ + \ + fetch_ea_32(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + ILLEGAL_ON(cpu_mod == 3); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); \ + addr = readmeml(easeg, cpu_state.eaaddr); \ + seg = readmemw(easeg, cpu_state.eaaddr + 4); \ + if (cpu_state.abrt) \ + return 1; \ + loadseg(seg, &sel); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].l = addr; \ + \ + CLOCK_CYCLES(7); \ + PREFETCH_RUN(7, 2, rmdat, 1, 1, 0, 0, 1); \ + return 0; \ + } opLsel(ES, cpu_state.seg_es) opLsel(FS, cpu_state.seg_fs) diff --git a/src/cpu/x86_ops_movx.h b/src/cpu/x86_ops_movx.h index 3ad89b7f0..1b607fb8b 100644 --- a/src/cpu/x86_ops_movx.h +++ b/src/cpu/x86_ops_movx.h @@ -1,209 +1,251 @@ -static int opMOVZX_w_b_a16(uint32_t fetchdat) +static int +opMOVZX_w_b_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = (uint16_t)temp; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = (uint16_t) temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opMOVZX_w_b_a32(uint32_t fetchdat) +static int +opMOVZX_w_b_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = (uint16_t)temp; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = (uint16_t) temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opMOVZX_l_b_a16(uint32_t fetchdat) +static int +opMOVZX_l_b_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = (uint32_t) temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opMOVZX_l_b_a32(uint32_t fetchdat) +static int +opMOVZX_l_b_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = (uint32_t) temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opMOVZX_w_w_a16(uint32_t fetchdat) +static int +opMOVZX_w_w_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = temp; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opMOVZX_w_w_a32(uint32_t fetchdat) +static int +opMOVZX_w_w_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = temp; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opMOVZX_l_w_a16(uint32_t fetchdat) +static int +opMOVZX_l_w_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = (uint32_t) temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opMOVZX_l_w_a32(uint32_t fetchdat) +static int +opMOVZX_l_w_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = (uint32_t) temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opMOVSX_w_b_a16(uint32_t fetchdat) +static int +opMOVSX_w_b_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = (uint16_t)temp; - if (temp & 0x80) - cpu_state.regs[cpu_reg].w |= 0xff00; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = (uint16_t) temp; + if (temp & 0x80) + cpu_state.regs[cpu_reg].w |= 0xff00; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opMOVSX_w_b_a32(uint32_t fetchdat) +static int +opMOVSX_w_b_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = (uint16_t)temp; - if (temp & 0x80) - cpu_state.regs[cpu_reg].w |= 0xff00; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = (uint16_t) temp; + if (temp & 0x80) + cpu_state.regs[cpu_reg].w |= 0xff00; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opMOVSX_l_b_a16(uint32_t fetchdat) +static int +opMOVSX_l_b_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; - if (temp & 0x80) - cpu_state.regs[cpu_reg].l |= 0xffffff00; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = (uint32_t) temp; + if (temp & 0x80) + cpu_state.regs[cpu_reg].l |= 0xffffff00; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opMOVSX_l_b_a32(uint32_t fetchdat) +static int +opMOVSX_l_b_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; - if (temp & 0x80) - cpu_state.regs[cpu_reg].l |= 0xffffff00; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = (uint32_t) temp; + if (temp & 0x80) + cpu_state.regs[cpu_reg].l |= 0xffffff00; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opMOVSX_l_w_a16(uint32_t fetchdat) +static int +opMOVSX_l_w_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; - if (temp & 0x8000) - cpu_state.regs[cpu_reg].l |= 0xffff0000; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = (uint32_t) temp; + if (temp & 0x8000) + cpu_state.regs[cpu_reg].l |= 0xffff0000; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opMOVSX_l_w_a32(uint32_t fetchdat) +static int +opMOVSX_l_w_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; - if (temp & 0x8000) - cpu_state.regs[cpu_reg].l |= 0xffff0000; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = (uint32_t) temp; + if (temp & 0x8000) + cpu_state.regs[cpu_reg].l |= 0xffff0000; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } diff --git a/src/cpu/x86_ops_msr.h b/src/cpu/x86_ops_msr.h index cdf9d8612..daae01d84 100644 --- a/src/cpu/x86_ops_msr.h +++ b/src/cpu/x86_ops_msr.h @@ -1,34 +1,33 @@ -static int opRDTSC(uint32_t fetchdat) +static int +opRDTSC(uint32_t fetchdat) { - if (!cpu_has_feature(CPU_FEATURE_RDTSC)) - { - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; - } - if ((cr4 & CR4_TSD) && CPL) - { - x86gpf("RDTSC when TSD set and CPL != 0", 0); - return 1; - } - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - CLOCK_CYCLES(1); + if (!cpu_has_feature(CPU_FEATURE_RDTSC)) { + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; + } + if ((cr4 & CR4_TSD) && CPL) { + x86gpf("RDTSC when TSD set and CPL != 0", 0); + return 1; + } + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + CLOCK_CYCLES(1); #ifdef USE_DYNAREC if (cpu_use_dynarec) update_tsc(); #endif - return 0; + return 0; } -static int opRDPMC(uint32_t fetchdat) +static int +opRDPMC(uint32_t fetchdat) { - if (ECX > 1 || (!(cr4 & CR4_PCE) && (cr0 & 1) && CPL)) - { - x86gpf("RDPMC not allowed", 0); - return 1; - } - EAX = EDX = 0; - CLOCK_CYCLES(1); - return 0; + if (ECX > 1 || (!(cr4 & CR4_PCE) && (cr0 & 1) && CPL)) { + x86gpf("RDPMC not allowed", 0); + return 1; + } + EAX = EDX = 0; + CLOCK_CYCLES(1); + return 0; } diff --git a/src/cpu/x86_ops_mul.h b/src/cpu/x86_ops_mul.h index ca12a9add..552a9973a 100644 --- a/src/cpu/x86_ops_mul.h +++ b/src/cpu/x86_ops_mul.h @@ -1,263 +1,337 @@ -static int opIMUL_w_iw_a16(uint32_t fetchdat) +static int +opIMUL_w_iw_a16(uint32_t fetchdat) { - int32_t templ; - int16_t tempw, tempw2; + int32_t templ; + int16_t tempw, tempw2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); if (cpu_state.abrt) return 1; - tempw2 = getword(); if (cpu_state.abrt) return 1; + tempw = geteaw(); + if (cpu_state.abrt) + return 1; + tempw2 = getword(); + if (cpu_state.abrt) + return 1; - templ = ((int)tempw) * ((int)tempw2); - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].w = templ & 0xffff; + templ = ((int) tempw) * ((int) tempw2); + flags_rebuild(); + if ((templ >> 15) != 0 && (templ >> 15) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cpu_state.regs[cpu_reg].w = templ & 0xffff; - CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); - PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 4, rmdat, 1,0,0,0, 0); - return 0; + CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); + PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 4, rmdat, 1, 0, 0, 0, 0); + return 0; } -static int opIMUL_w_iw_a32(uint32_t fetchdat) +static int +opIMUL_w_iw_a32(uint32_t fetchdat) { - int32_t templ; - int16_t tempw, tempw2; + int32_t templ; + int16_t tempw, tempw2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); if (cpu_state.abrt) return 1; - tempw2 = getword(); if (cpu_state.abrt) return 1; + tempw = geteaw(); + if (cpu_state.abrt) + return 1; + tempw2 = getword(); + if (cpu_state.abrt) + return 1; - templ = ((int)tempw) * ((int)tempw2); - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].w = templ & 0xffff; + templ = ((int) tempw) * ((int) tempw2); + flags_rebuild(); + if ((templ >> 15) != 0 && (templ >> 15) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cpu_state.regs[cpu_reg].w = templ & 0xffff; - CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); - PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 4, rmdat, 1,0,0,0, 1); - return 0; + CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); + PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 4, rmdat, 1, 0, 0, 0, 1); + return 0; } -static int opIMUL_l_il_a16(uint32_t fetchdat) +static int +opIMUL_l_il_a16(uint32_t fetchdat) { - int64_t temp64; - int32_t templ, templ2; + int64_t temp64; + int32_t templ, templ2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - templ = geteal(); if (cpu_state.abrt) return 1; - templ2 = getlong(); if (cpu_state.abrt) return 1; + templ = geteal(); + if (cpu_state.abrt) + return 1; + templ2 = getlong(); + if (cpu_state.abrt) + return 1; - temp64 = ((int64_t)templ) * ((int64_t)templ2); - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; + temp64 = ((int64_t) templ) * ((int64_t) templ2); + flags_rebuild(); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; - CLOCK_CYCLES(25); - PREFETCH_RUN(25, 6, rmdat, 0,1,0,0, 0); - return 0; + CLOCK_CYCLES(25); + PREFETCH_RUN(25, 6, rmdat, 0, 1, 0, 0, 0); + return 0; } -static int opIMUL_l_il_a32(uint32_t fetchdat) +static int +opIMUL_l_il_a32(uint32_t fetchdat) { - int64_t temp64; - int32_t templ, templ2; + int64_t temp64; + int32_t templ, templ2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - templ = geteal(); if (cpu_state.abrt) return 1; - templ2 = getlong(); if (cpu_state.abrt) return 1; + templ = geteal(); + if (cpu_state.abrt) + return 1; + templ2 = getlong(); + if (cpu_state.abrt) + return 1; - temp64 = ((int64_t)templ) * ((int64_t)templ2); - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; + temp64 = ((int64_t) templ) * ((int64_t) templ2); + flags_rebuild(); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; - CLOCK_CYCLES(25); - PREFETCH_RUN(25, 6, rmdat, 0,1,0,0, 1); - return 0; + CLOCK_CYCLES(25); + PREFETCH_RUN(25, 6, rmdat, 0, 1, 0, 0, 1); + return 0; } -static int opIMUL_w_ib_a16(uint32_t fetchdat) +static int +opIMUL_w_ib_a16(uint32_t fetchdat) { - int32_t templ; - int16_t tempw, tempw2; + int32_t templ; + int16_t tempw, tempw2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); if (cpu_state.abrt) return 1; - tempw2 = getbyte(); if (cpu_state.abrt) return 1; - if (tempw2 & 0x80) tempw2 |= 0xff00; + tempw = geteaw(); + if (cpu_state.abrt) + return 1; + tempw2 = getbyte(); + if (cpu_state.abrt) + return 1; + if (tempw2 & 0x80) + tempw2 |= 0xff00; - templ = ((int)tempw) * ((int)tempw2); - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].w = templ & 0xffff; + templ = ((int) tempw) * ((int) tempw2); + flags_rebuild(); + if ((templ >> 15) != 0 && (templ >> 15) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cpu_state.regs[cpu_reg].w = templ & 0xffff; - CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); - PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 3, rmdat, 1,0,0,0, 0); - return 0; + CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); + PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 3, rmdat, 1, 0, 0, 0, 0); + return 0; } -static int opIMUL_w_ib_a32(uint32_t fetchdat) +static int +opIMUL_w_ib_a32(uint32_t fetchdat) { - int32_t templ; - int16_t tempw, tempw2; + int32_t templ; + int16_t tempw, tempw2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); if (cpu_state.abrt) return 1; - tempw2 = getbyte(); if (cpu_state.abrt) return 1; - if (tempw2 & 0x80) tempw2 |= 0xff00; + tempw = geteaw(); + if (cpu_state.abrt) + return 1; + tempw2 = getbyte(); + if (cpu_state.abrt) + return 1; + if (tempw2 & 0x80) + tempw2 |= 0xff00; - templ = ((int)tempw) * ((int)tempw2); - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].w = templ & 0xffff; + templ = ((int) tempw) * ((int) tempw2); + flags_rebuild(); + if ((templ >> 15) != 0 && (templ >> 15) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cpu_state.regs[cpu_reg].w = templ & 0xffff; - CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); - PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 3, rmdat, 1,0,0,0, 1); - return 0; + CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); + PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 3, rmdat, 1, 0, 0, 0, 1); + return 0; } -static int opIMUL_l_ib_a16(uint32_t fetchdat) +static int +opIMUL_l_ib_a16(uint32_t fetchdat) { - int64_t temp64; - int32_t templ, templ2; + int64_t temp64; + int32_t templ, templ2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - templ = geteal(); if (cpu_state.abrt) return 1; - templ2 = getbyte(); if (cpu_state.abrt) return 1; - if (templ2 & 0x80) templ2 |= 0xffffff00; + templ = geteal(); + if (cpu_state.abrt) + return 1; + templ2 = getbyte(); + if (cpu_state.abrt) + return 1; + if (templ2 & 0x80) + templ2 |= 0xffffff00; - temp64 = ((int64_t)templ)*((int64_t)templ2); - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; + temp64 = ((int64_t) templ) * ((int64_t) templ2); + flags_rebuild(); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 3, rmdat, 0,1,0,0, 0); - return 0; + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 3, rmdat, 0, 1, 0, 0, 0); + return 0; } -static int opIMUL_l_ib_a32(uint32_t fetchdat) +static int +opIMUL_l_ib_a32(uint32_t fetchdat) { - int64_t temp64; - int32_t templ, templ2; + int64_t temp64; + int32_t templ, templ2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - templ = geteal(); if (cpu_state.abrt) return 1; - templ2 = getbyte(); if (cpu_state.abrt) return 1; - if (templ2 & 0x80) templ2 |= 0xffffff00; + templ = geteal(); + if (cpu_state.abrt) + return 1; + templ2 = getbyte(); + if (cpu_state.abrt) + return 1; + if (templ2 & 0x80) + templ2 |= 0xffffff00; - temp64 = ((int64_t)templ)*((int64_t)templ2); - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; + temp64 = ((int64_t) templ) * ((int64_t) templ2); + flags_rebuild(); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 3, rmdat, 0,1,0,0, 1); - return 0; + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 3, rmdat, 0, 1, 0, 0, 1); + return 0; } - - -static int opIMUL_w_w_a16(uint32_t fetchdat) +static int +opIMUL_w_w_a16(uint32_t fetchdat) { - int32_t templ; + int32_t templ; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw(); - if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = templ & 0xFFFF; - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); + templ = (int32_t) (int16_t) cpu_state.regs[cpu_reg].w * (int32_t) (int16_t) geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = templ & 0xFFFF; + flags_rebuild(); + if ((templ >> 15) != 0 && (templ >> 15) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(18); - PREFETCH_RUN(18, 2, rmdat, 1,0,0,0, 0); - return 0; + CLOCK_CYCLES(18); + PREFETCH_RUN(18, 2, rmdat, 1, 0, 0, 0, 0); + return 0; } -static int opIMUL_w_w_a32(uint32_t fetchdat) +static int +opIMUL_w_w_a32(uint32_t fetchdat) { - int32_t templ; + int32_t templ; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw(); - if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = templ & 0xFFFF; - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); + templ = (int32_t) (int16_t) cpu_state.regs[cpu_reg].w * (int32_t) (int16_t) geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = templ & 0xFFFF; + flags_rebuild(); + if ((templ >> 15) != 0 && (templ >> 15) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(18); - PREFETCH_RUN(18, 2, rmdat, 1,0,0,0, 1); - return 0; + CLOCK_CYCLES(18); + PREFETCH_RUN(18, 2, rmdat, 1, 0, 0, 0, 1); + return 0; } -static int opIMUL_l_l_a16(uint32_t fetchdat) +static int +opIMUL_l_l_a16(uint32_t fetchdat) { - int64_t temp64; + int64_t temp64; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal(); - if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF; - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); + temp64 = (int64_t) (int32_t) cpu_state.regs[cpu_reg].l * (int64_t) (int32_t) geteal(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF; + flags_rebuild(); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(30); - PREFETCH_RUN(30, 2, rmdat, 0,1,0,0, 0); - return 0; + CLOCK_CYCLES(30); + PREFETCH_RUN(30, 2, rmdat, 0, 1, 0, 0, 0); + return 0; } -static int opIMUL_l_l_a32(uint32_t fetchdat) +static int +opIMUL_l_l_a32(uint32_t fetchdat) { - int64_t temp64; + int64_t temp64; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal(); - if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF; - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); + temp64 = (int64_t) (int32_t) cpu_state.regs[cpu_reg].l * (int64_t) (int32_t) geteal(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF; + flags_rebuild(); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(30); - PREFETCH_RUN(30, 2, rmdat, 0,1,0,0, 1); - return 0; + CLOCK_CYCLES(30); + PREFETCH_RUN(30, 2, rmdat, 0, 1, 0, 0, 1); + return 0; } diff --git a/src/cpu/x86_ops_pmode.h b/src/cpu/x86_ops_pmode.h index 698cfc838..4fee881ea 100644 --- a/src/cpu/x86_ops_pmode.h +++ b/src/cpu/x86_ops_pmode.h @@ -1,460 +1,513 @@ -static int opARPL_a16(uint32_t fetchdat) +static int +opARPL_a16(uint32_t fetchdat) { - uint16_t temp_seg; + uint16_t temp_seg; - NOTRM - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp_seg = geteaw(); if (cpu_state.abrt) return 1; + NOTRM + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp_seg = geteaw(); + if (cpu_state.abrt) + return 1; - flags_rebuild(); - if ((temp_seg & 3) < (cpu_state.regs[cpu_reg].w & 3)) - { - temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3); - seteaw(temp_seg); if (cpu_state.abrt) return 1; - cpu_state.flags |= Z_FLAG; - } - else - cpu_state.flags &= ~Z_FLAG; + flags_rebuild(); + if ((temp_seg & 3) < (cpu_state.regs[cpu_reg].w & 3)) { + temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3); + seteaw(temp_seg); + if (cpu_state.abrt) + return 1; + cpu_state.flags |= Z_FLAG; + } else + cpu_state.flags &= ~Z_FLAG; - CLOCK_CYCLES(is486 ? 9 : 20); - PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1,0,1,0, 0); - return 0; + CLOCK_CYCLES(is486 ? 9 : 20); + PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1, 0, 1, 0, 0); + return 0; } -static int opARPL_a32(uint32_t fetchdat) +static int +opARPL_a32(uint32_t fetchdat) { - uint16_t temp_seg; + uint16_t temp_seg; - NOTRM - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp_seg = geteaw(); if (cpu_state.abrt) return 1; + NOTRM + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp_seg = geteaw(); + if (cpu_state.abrt) + return 1; - flags_rebuild(); - if ((temp_seg & 3) < (cpu_state.regs[cpu_reg].w & 3)) - { - temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3); - seteaw(temp_seg); if (cpu_state.abrt) return 1; - cpu_state.flags |= Z_FLAG; - } - else - cpu_state.flags &= ~Z_FLAG; + flags_rebuild(); + if ((temp_seg & 3) < (cpu_state.regs[cpu_reg].w & 3)) { + temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3); + seteaw(temp_seg); + if (cpu_state.abrt) + return 1; + cpu_state.flags |= Z_FLAG; + } else + cpu_state.flags &= ~Z_FLAG; - CLOCK_CYCLES(is486 ? 9 : 20); - PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1,0,1,0, 1); - return 0; + CLOCK_CYCLES(is486 ? 9 : 20); + PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1, 0, 1, 0, 1); + return 0; } -#define opLAR(name, fetch_ea, is32, ea32) \ - static int opLAR_ ## name(uint32_t fetchdat) \ - { \ - int valid; \ - uint16_t sel, desc = 0; \ - \ - NOTRM \ - fetch_ea(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - \ - sel = geteaw(); if (cpu_state.abrt) return 1; \ - \ - flags_rebuild(); \ - if (!(sel & 0xfffc)) { cpu_state.flags &= ~Z_FLAG; return 0; } /*Null selector*/ \ - valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \ - if (valid) \ - { \ - cpl_override = 1; \ - desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \ - cpl_override = 0; if (cpu_state.abrt) return 1; \ - } \ - cpu_state.flags &= ~Z_FLAG; \ - if ((desc & 0x1f00) == 0x000) valid = 0; \ - if ((desc & 0x1f00) == 0x800) valid = 0; \ - if ((desc & 0x1f00) == 0xa00) valid = 0; \ - if ((desc & 0x1f00) == 0xd00) valid = 0; \ - if ((desc & 0x1c00) < 0x1c00) /*Exclude conforming code segments*/ \ - { \ - int dpl = (desc >> 13) & 3; \ - if (dpl < CPL || dpl < (sel & 3)) valid = 0; \ - } \ - if (valid) \ - { \ - cpu_state.flags |= Z_FLAG; \ - cpl_override = 1; \ - if (is32) \ - cpu_state.regs[cpu_reg].l = readmeml(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xffff00; \ - else \ - cpu_state.regs[cpu_reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xff00; \ - cpl_override = 0; \ - } \ - CLOCK_CYCLES(11); \ - PREFETCH_RUN(11, 2, rmdat, 2,0,0,0, ea32); \ - return cpu_state.abrt; \ - } +#define opLAR(name, fetch_ea, is32, ea32) \ + static int opLAR_##name(uint32_t fetchdat) \ + { \ + int valid; \ + uint16_t sel, desc = 0; \ + \ + NOTRM \ + fetch_ea(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + \ + sel = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + \ + flags_rebuild(); \ + if (!(sel & 0xfffc)) { \ + cpu_state.flags &= ~Z_FLAG; \ + return 0; \ + } /*Null selector*/ \ + valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \ + if (valid) { \ + cpl_override = 1; \ + desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \ + cpl_override = 0; \ + if (cpu_state.abrt) \ + return 1; \ + } \ + cpu_state.flags &= ~Z_FLAG; \ + if ((desc & 0x1f00) == 0x000) \ + valid = 0; \ + if ((desc & 0x1f00) == 0x800) \ + valid = 0; \ + if ((desc & 0x1f00) == 0xa00) \ + valid = 0; \ + if ((desc & 0x1f00) == 0xd00) \ + valid = 0; \ + if ((desc & 0x1c00) < 0x1c00) /*Exclude conforming code segments*/ \ + { \ + int dpl = (desc >> 13) & 3; \ + if (dpl < CPL || dpl < (sel & 3)) \ + valid = 0; \ + } \ + if (valid) { \ + cpu_state.flags |= Z_FLAG; \ + cpl_override = 1; \ + if (is32) \ + cpu_state.regs[cpu_reg].l = readmeml(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xffff00; \ + else \ + cpu_state.regs[cpu_reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xff00; \ + cpl_override = 0; \ + } \ + CLOCK_CYCLES(11); \ + PREFETCH_RUN(11, 2, rmdat, 2, 0, 0, 0, ea32); \ + return cpu_state.abrt; \ + } opLAR(w_a16, fetch_ea_16, 0, 0) -opLAR(w_a32, fetch_ea_32, 0, 1) -opLAR(l_a16, fetch_ea_16, 1, 0) -opLAR(l_a32, fetch_ea_32, 1, 1) + opLAR(w_a32, fetch_ea_32, 0, 1) + opLAR(l_a16, fetch_ea_16, 1, 0) + opLAR(l_a32, fetch_ea_32, 1, 1) -#define opLSL(name, fetch_ea, is32, ea32) \ - static int opLSL_ ## name(uint32_t fetchdat) \ - { \ - int valid; \ - uint16_t sel, desc = 0; \ - \ - NOTRM \ - fetch_ea(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - \ - sel = geteaw(); if (cpu_state.abrt) return 1; \ - flags_rebuild(); \ - cpu_state.flags &= ~Z_FLAG; \ - if (!(sel & 0xfffc)) return 0; /*Null selector*/ \ - valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \ - if (valid) \ - { \ - cpl_override = 1; \ - desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \ - cpl_override = 0; if (cpu_state.abrt) return 1; \ - } \ - if ((desc & 0x1400) == 0x400) valid = 0; /*Interrupt or trap or call gate*/ \ - if ((desc & 0x1f00) == 0x000) valid = 0; /*Invalid*/ \ - if ((desc & 0x1f00) == 0xa00) valid = 0; /*Invalid*/ \ - if ((desc & 0x1c00) != 0x1c00) /*Exclude conforming code segments*/ \ - { \ - int rpl = (desc >> 13) & 3; \ - if (rpl < CPL || rpl < (sel & 3)) valid = 0; \ - } \ - if (valid) \ - { \ - cpu_state.flags |= Z_FLAG; \ - cpl_override = 1; \ - if (is32) \ - { \ - cpu_state.regs[cpu_reg].l = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7)); \ - cpu_state.regs[cpu_reg].l |= (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0xF) << 16; \ - if (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0x80) \ - { \ - cpu_state.regs[cpu_reg].l <<= 12; \ - cpu_state.regs[cpu_reg].l |= 0xFFF; \ - } \ - } \ - else \ - cpu_state.regs[cpu_reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7)); \ - cpl_override = 0; \ - } \ - CLOCK_CYCLES(10); \ - PREFETCH_RUN(10, 2, rmdat, 4,0,0,0, ea32); \ - return cpu_state.abrt; \ - } +#define opLSL(name, fetch_ea, is32, ea32) \ + static int opLSL_##name(uint32_t fetchdat) \ + { \ + int valid; \ + uint16_t sel, desc = 0; \ + \ + NOTRM \ + fetch_ea(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + \ + sel = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + flags_rebuild(); \ + cpu_state.flags &= ~Z_FLAG; \ + if (!(sel & 0xfffc)) \ + return 0; /*Null selector*/ \ + valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \ + if (valid) { \ + cpl_override = 1; \ + desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \ + cpl_override = 0; \ + if (cpu_state.abrt) \ + return 1; \ + } \ + if ((desc & 0x1400) == 0x400) \ + valid = 0; /*Interrupt or trap or call gate*/ \ + if ((desc & 0x1f00) == 0x000) \ + valid = 0; /*Invalid*/ \ + if ((desc & 0x1f00) == 0xa00) \ + valid = 0; /*Invalid*/ \ + if ((desc & 0x1c00) != 0x1c00) /*Exclude conforming code segments*/ \ + { \ + int rpl = (desc >> 13) & 3; \ + if (rpl < CPL || rpl < (sel & 3)) \ + valid = 0; \ + } \ + if (valid) { \ + cpu_state.flags |= Z_FLAG; \ + cpl_override = 1; \ + if (is32) { \ + cpu_state.regs[cpu_reg].l = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7)); \ + cpu_state.regs[cpu_reg].l |= (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0xF) << 16; \ + if (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0x80) { \ + cpu_state.regs[cpu_reg].l <<= 12; \ + cpu_state.regs[cpu_reg].l |= 0xFFF; \ + } \ + } else \ + cpu_state.regs[cpu_reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7)); \ + cpl_override = 0; \ + } \ + CLOCK_CYCLES(10); \ + PREFETCH_RUN(10, 2, rmdat, 4, 0, 0, 0, ea32); \ + return cpu_state.abrt; \ + } -opLSL(w_a16, fetch_ea_16, 0, 0) -opLSL(w_a32, fetch_ea_32, 0, 1) -opLSL(l_a16, fetch_ea_16, 1, 0) -opLSL(l_a32, fetch_ea_32, 1, 1) + opLSL(w_a16, fetch_ea_16, 0, 0) + opLSL(w_a32, fetch_ea_32, 0, 1) + opLSL(l_a16, fetch_ea_16, 1, 0) + opLSL(l_a32, fetch_ea_32, 1, 1) - -static int op0F00_common(uint32_t fetchdat, int ea32) + static int op0F00_common(uint32_t fetchdat, int ea32) { - int dpl, valid, granularity; - uint32_t addr, base, limit; - uint16_t desc, sel; - uint8_t access, ar_high; + int dpl, valid, granularity; + uint32_t addr, base, limit; + uint16_t desc, sel; + uint8_t access, ar_high; - switch (rmdat & 0x38) - { - case 0x00: /*SLDT*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(ldt.seg); - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); + switch (rmdat & 0x38) { + case 0x00: /*SLDT*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(ldt.seg); + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); + break; + case 0x08: /*STR*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(tr.seg); + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); + break; + case 0x10: /*LLDT*/ + if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + sel = geteaw(); + if (cpu_state.abrt) + return 1; + addr = (sel & ~7) + gdt.base; + limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16); + base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24); + access = readmemb(0, addr + 5); + ar_high = readmemb(0, addr + 6); + granularity = readmemb(0, addr + 6) & 0x80; + if (cpu_state.abrt) + return 1; + ldt.limit = limit; + ldt.access = access; + ldt.ar_high = ar_high; + if (granularity) { + ldt.limit <<= 12; + ldt.limit |= 0xfff; + } + ldt.base = base; + ldt.seg = sel; + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 2, 0, 0, ea32); + break; + case 0x18: /*LTR*/ + if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { + x86gpf(NULL, 0); break; - case 0x08: /*STR*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(tr.seg); - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); - break; - case 0x10: /*LLDT*/ - if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) - { - x86gpf(NULL,0); - return 1; - } - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - sel = geteaw(); if (cpu_state.abrt) return 1; - addr = (sel & ~7) + gdt.base; - limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16); - base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24); - access = readmemb(0, addr + 5); - ar_high = readmemb(0, addr + 6); - granularity = readmemb(0, addr + 6) & 0x80; - if (cpu_state.abrt) return 1; - ldt.limit = limit; - ldt.access = access; - ldt.ar_high = ar_high; - if (granularity) - { - ldt.limit <<= 12; - ldt.limit |= 0xfff; - } - ldt.base = base; - ldt.seg = sel; - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0:1,2,0,0, ea32); - break; - case 0x18: /*LTR*/ - if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) - { - x86gpf(NULL,0); - break; - } - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - sel = geteaw(); if (cpu_state.abrt) return 1; - addr = (sel & ~7) + gdt.base; - limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16); - base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24); - access = readmemb(0, addr + 5); - ar_high = readmemb(0, addr + 6); - granularity = readmemb(0, addr + 6) & 0x80; - if (cpu_state.abrt) return 1; - access |= 2; - writememb(0, addr + 5, access); - if (cpu_state.abrt) return 1; - tr.seg = sel; - tr.limit = limit; - tr.access = access; - tr.ar_high = ar_high; - if (granularity) - { - tr.limit <<= 12; - tr.limit |= 0xFFF; - } - tr.base = base; - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0:1,2,0,0, ea32); - break; - case 0x20: /*VERR*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - sel = geteaw(); if (cpu_state.abrt) return 1; - flags_rebuild(); - cpu_state.flags &= ~Z_FLAG; - if (!(sel & 0xfffc)) return 0; /*Null selector*/ - cpl_override = 1; - valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); - desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); - cpl_override = 0; if (cpu_state.abrt) return 1; - if (!(desc & 0x1000)) valid = 0; - if ((desc & 0xC00) != 0xC00) /*Exclude conforming code segments*/ - { - dpl = (desc >> 13) & 3; /*Check permissions*/ - if (dpl < CPL || dpl < (sel & 3)) valid = 0; - } - if ((desc & 0x0800) && !(desc & 0x0200)) valid = 0; /*Non-readable code*/ - if (valid) cpu_state.flags |= Z_FLAG; - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1:2,0,0,0, ea32); - break; - case 0x28: /*VERW*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - sel = geteaw(); if (cpu_state.abrt) return 1; - flags_rebuild(); - cpu_state.flags &= ~Z_FLAG; - if (!(sel & 0xfffc)) return 0; /*Null selector*/ - cpl_override = 1; - valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); - desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); - cpl_override = 0; if (cpu_state.abrt) return 1; - if (!(desc & 0x1000)) valid = 0; + } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + sel = geteaw(); + if (cpu_state.abrt) + return 1; + addr = (sel & ~7) + gdt.base; + limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16); + base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24); + access = readmemb(0, addr + 5); + ar_high = readmemb(0, addr + 6); + granularity = readmemb(0, addr + 6) & 0x80; + if (cpu_state.abrt) + return 1; + access |= 2; + writememb(0, addr + 5, access); + if (cpu_state.abrt) + return 1; + tr.seg = sel; + tr.limit = limit; + tr.access = access; + tr.ar_high = ar_high; + if (granularity) { + tr.limit <<= 12; + tr.limit |= 0xFFF; + } + tr.base = base; + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 2, 0, 0, ea32); + break; + case 0x20: /*VERR*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + sel = geteaw(); + if (cpu_state.abrt) + return 1; + flags_rebuild(); + cpu_state.flags &= ~Z_FLAG; + if (!(sel & 0xfffc)) + return 0; /*Null selector*/ + cpl_override = 1; + valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); + desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); + cpl_override = 0; + if (cpu_state.abrt) + return 1; + if (!(desc & 0x1000)) + valid = 0; + if ((desc & 0xC00) != 0xC00) /*Exclude conforming code segments*/ + { dpl = (desc >> 13) & 3; /*Check permissions*/ - if (dpl < CPL || dpl < (sel & 3)) valid = 0; - if (desc & 0x0800) valid = 0; /*Code*/ - if (!(desc & 0x0200)) valid = 0; /*Read-only data*/ - if (valid) cpu_state.flags |= Z_FLAG; - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1:2,0,0,0, ea32); - break; + if (dpl < CPL || dpl < (sel & 3)) + valid = 0; + } + if ((desc & 0x0800) && !(desc & 0x0200)) + valid = 0; /*Non-readable code*/ + if (valid) + cpu_state.flags |= Z_FLAG; + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1 : 2, 0, 0, 0, ea32); + break; + case 0x28: /*VERW*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + sel = geteaw(); + if (cpu_state.abrt) + return 1; + flags_rebuild(); + cpu_state.flags &= ~Z_FLAG; + if (!(sel & 0xfffc)) + return 0; /*Null selector*/ + cpl_override = 1; + valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); + desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); + cpl_override = 0; + if (cpu_state.abrt) + return 1; + if (!(desc & 0x1000)) + valid = 0; + dpl = (desc >> 13) & 3; /*Check permissions*/ + if (dpl < CPL || dpl < (sel & 3)) + valid = 0; + if (desc & 0x0800) + valid = 0; /*Code*/ + if (!(desc & 0x0200)) + valid = 0; /*Read-only data*/ + if (valid) + cpu_state.flags |= Z_FLAG; + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1 : 2, 0, 0, 0, ea32); + break; - default: - cpu_state.pc -= 3; - x86illegal(); - break; - } - return cpu_state.abrt; + default: + cpu_state.pc -= 3; + x86illegal(); + break; + } + return cpu_state.abrt; } -static int op0F00_a16(uint32_t fetchdat) +static int +op0F00_a16(uint32_t fetchdat) { - NOTRM + NOTRM - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); - return op0F00_common(fetchdat, 0); + return op0F00_common(fetchdat, 0); } -static int op0F00_a32(uint32_t fetchdat) +static int +op0F00_a32(uint32_t fetchdat) { - NOTRM + NOTRM - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); - return op0F00_common(fetchdat, 1); + return op0F00_common(fetchdat, 1); } -static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) +static int +op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) { - uint32_t base; - uint16_t limit, tempw; - switch (rmdat & 0x38) - { - case 0x00: /*SGDT*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(gdt.limit); - base = gdt.base; //is32 ? gdt.base : (gdt.base & 0xffffff); - if (is286) - base |= 0xff000000; - writememl(easeg, cpu_state.eaaddr + 2, base); - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 0,0,1,1, ea32); + uint32_t base; + uint16_t limit, tempw; + switch (rmdat & 0x38) { + case 0x00: /*SGDT*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(gdt.limit); + base = gdt.base; // is32 ? gdt.base : (gdt.base & 0xffffff); + if (is286) + base |= 0xff000000; + writememl(easeg, cpu_state.eaaddr + 2, base); + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 0, 0, 1, 1, ea32); + break; + case 0x08: /*SIDT*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(idt.limit); + base = idt.base; + if (is286) + base |= 0xff000000; + writememl(easeg, cpu_state.eaaddr + 2, base); + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 0, 0, 1, 1, ea32); + break; + case 0x10: /*LGDT*/ + if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { + x86gpf(NULL, 0); break; - case 0x08: /*SIDT*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(idt.limit); - base = idt.base; - if (is286) - base |= 0xff000000; - writememl(easeg, cpu_state.eaaddr + 2, base); - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 0,0,1,1, ea32); + } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + limit = geteaw(); + base = readmeml(0, easeg + cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + gdt.limit = limit; + gdt.base = base; + if (!is32) + gdt.base &= 0xffffff; + CLOCK_CYCLES(11); + PREFETCH_RUN(11, 2, rmdat, 1, 1, 0, 0, ea32); + break; + case 0x18: /*LIDT*/ + if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { + x86gpf(NULL, 0); break; - case 0x10: /*LGDT*/ - if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) - { - x86gpf(NULL,0); - break; + } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + limit = geteaw(); + base = readmeml(0, easeg + cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + idt.limit = limit; + idt.base = base; + if (!is32) + idt.base &= 0xffffff; + CLOCK_CYCLES(11); + PREFETCH_RUN(11, 2, rmdat, 1, 1, 0, 0, ea32); + break; + + case 0x20: /*SMSW*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (is486 || isibm486) + seteaw(msw); + else if (is386) + seteaw(msw | /* 0xFF00 */ 0xFFE0); + else + seteaw(msw | 0xFFF0); + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); + break; + case 0x30: /*LMSW*/ + if ((CPL || cpu_state.eflags & VM_FLAG) && (msw & 1)) { + x86gpf(NULL, 0); + break; + } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + tempw = geteaw(); + if (cpu_state.abrt) + return 1; + if (msw & 1) + tempw |= 1; + if (is386) { + tempw &= ~0x10; + tempw |= (msw & 0x10); + } else + tempw &= 0xF; + msw = tempw; + if (msw & 1) + cpu_cur_status |= CPU_STATUS_PMODE; + else + cpu_cur_status &= ~CPU_STATUS_PMODE; + PREFETCH_RUN(2, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); + break; + + case 0x38: /*INVLPG*/ + if (is486 || isibm486) { + if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { + x86gpf(NULL, 0); + break; } - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - limit = geteaw(); - base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - gdt.limit = limit; - gdt.base = base; - if (!is32) gdt.base &= 0xffffff; - CLOCK_CYCLES(11); - PREFETCH_RUN(11, 2, rmdat, 1,1,0,0, ea32); - break; - case 0x18: /*LIDT*/ - if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) - { - x86gpf(NULL,0); - break; - } - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - limit = geteaw(); - base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - idt.limit = limit; - idt.base = base; - if (!is32) idt.base &= 0xffffff; - CLOCK_CYCLES(11); - PREFETCH_RUN(11, 2, rmdat, 1,1,0,0, ea32); + SEG_CHECK_READ(cpu_state.ea_seg); + mmu_invalidate(ds + cpu_state.eaaddr); + CLOCK_CYCLES(12); + PREFETCH_RUN(12, 2, rmdat, 0, 0, 0, 0, ea32); break; + } - case 0x20: /*SMSW*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - if (is486 || isibm486) seteaw(msw); - else if (is386) seteaw(msw | /* 0xFF00 */ 0xFFE0); - else seteaw(msw | 0xFFF0); - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); - break; - case 0x30: /*LMSW*/ - if ((CPL || cpu_state.eflags&VM_FLAG) && (msw&1)) - { - x86gpf(NULL, 0); - break; - } - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); if (cpu_state.abrt) return 1; - if (msw & 1) tempw |= 1; - if (is386) - { - tempw &= ~0x10; - tempw |= (msw & 0x10); - } - else tempw &= 0xF; - msw = tempw; - if (msw & 1) - cpu_cur_status |= CPU_STATUS_PMODE; - else - cpu_cur_status &= ~CPU_STATUS_PMODE; - PREFETCH_RUN(2, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); - break; - - case 0x38: /*INVLPG*/ - if (is486 || isibm486) - { - if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) - { - x86gpf(NULL, 0); - break; - } - SEG_CHECK_READ(cpu_state.ea_seg); - mmu_invalidate(ds + cpu_state.eaaddr); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 2, rmdat, 0,0,0,0, ea32); - break; - } - - default: - cpu_state.pc -= 3; - x86illegal(); - break; - } - return cpu_state.abrt; + default: + cpu_state.pc -= 3; + x86illegal(); + break; + } + return cpu_state.abrt; } -static int op0F01_w_a16(uint32_t fetchdat) +static int +op0F01_w_a16(uint32_t fetchdat) { - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); - return op0F01_common(fetchdat, 0, 0, 0); + return op0F01_common(fetchdat, 0, 0, 0); } -static int op0F01_w_a32(uint32_t fetchdat) +static int +op0F01_w_a32(uint32_t fetchdat) { - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); - return op0F01_common(fetchdat, 0, 0, 1); + return op0F01_common(fetchdat, 0, 0, 1); } -static int op0F01_l_a16(uint32_t fetchdat) +static int +op0F01_l_a16(uint32_t fetchdat) { - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); - return op0F01_common(fetchdat, 1, 0, 0); + return op0F01_common(fetchdat, 1, 0, 0); } -static int op0F01_l_a32(uint32_t fetchdat) +static int +op0F01_l_a32(uint32_t fetchdat) { - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); - return op0F01_common(fetchdat, 1, 0, 1); + return op0F01_common(fetchdat, 1, 0, 1); } -static int op0F01_286(uint32_t fetchdat) +static int +op0F01_286(uint32_t fetchdat) { - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); - return op0F01_common(fetchdat, 0, 1, 0); + return op0F01_common(fetchdat, 0, 1, 0); } diff --git a/src/cpu/x86_ops_prefix.h b/src/cpu/x86_ops_prefix.h index 3029da30a..4d4adb77d 100644 --- a/src/cpu/x86_ops_prefix.h +++ b/src/cpu/x86_ops_prefix.h @@ -1,67 +1,71 @@ -#define op_seg(name, seg, opcode_table, normal_opcode_table) \ -static int op ## name ## _w_a16(uint32_t fetchdat) \ -{ \ - fetchdat = fastreadl(cs + cpu_state.pc); \ - if (cpu_state.abrt) return 1; \ - cpu_state.pc++; \ - \ - cpu_state.ea_seg = &seg; \ - cpu_state.ssegs = 1; \ - CLOCK_CYCLES(4); \ - PREFETCH_PREFIX(); \ - \ - if (opcode_table[fetchdat & 0xff]) \ - return opcode_table[fetchdat & 0xff](fetchdat >> 8); \ - return normal_opcode_table[fetchdat & 0xff](fetchdat >> 8); \ -} \ - \ -static int op ## name ## _l_a16(uint32_t fetchdat) \ -{ \ - fetchdat = fastreadl(cs + cpu_state.pc); \ - if (cpu_state.abrt) return 1; \ - cpu_state.pc++; \ - \ - cpu_state.ea_seg = &seg; \ - cpu_state.ssegs = 1; \ - CLOCK_CYCLES(4); \ - PREFETCH_PREFIX(); \ - \ - if (opcode_table[(fetchdat & 0xff) | 0x100]) \ - return opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ +#define op_seg(name, seg, opcode_table, normal_opcode_table) \ + static int op##name##_w_a16(uint32_t fetchdat) \ + { \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[fetchdat & 0xff]) \ + return opcode_table[fetchdat & 0xff](fetchdat >> 8); \ + return normal_opcode_table[fetchdat & 0xff](fetchdat >> 8); \ + } \ + \ + static int op##name##_l_a16(uint32_t fetchdat) \ + { \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x100]) \ + return opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ return normal_opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ -} \ - \ -static int op ## name ## _w_a32(uint32_t fetchdat) \ -{ \ - fetchdat = fastreadl(cs + cpu_state.pc); \ - if (cpu_state.abrt) return 1; \ - cpu_state.pc++; \ - \ - cpu_state.ea_seg = &seg; \ - cpu_state.ssegs = 1; \ - CLOCK_CYCLES(4); \ - PREFETCH_PREFIX(); \ - \ - if (opcode_table[(fetchdat & 0xff) | 0x200]) \ - return opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ + } \ + \ + static int op##name##_w_a32(uint32_t fetchdat) \ + { \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x200]) \ + return opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ return normal_opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ -} \ - \ -static int op ## name ## _l_a32(uint32_t fetchdat) \ -{ \ - fetchdat = fastreadl(cs + cpu_state.pc); \ - if (cpu_state.abrt) return 1; \ - cpu_state.pc++; \ - \ - cpu_state.ea_seg = &seg; \ - cpu_state.ssegs = 1; \ - CLOCK_CYCLES(4); \ - PREFETCH_PREFIX(); \ - \ - if (opcode_table[(fetchdat & 0xff) | 0x300]) \ - return opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ + } \ + \ + static int op##name##_l_a32(uint32_t fetchdat) \ + { \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x300]) \ + return opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ return normal_opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ -} + } op_seg(CS, cpu_state.seg_cs, x86_opcodes, x86_opcodes) op_seg(DS, cpu_state.seg_ds, x86_opcodes, x86_opcodes) @@ -84,78 +88,89 @@ op_seg(FS_REPNE, cpu_state.seg_fs, x86_opcodes_REPNE, x86_opcodes) op_seg(GS_REPNE, cpu_state.seg_gs, x86_opcodes_REPNE, x86_opcodes) op_seg(SS_REPNE, cpu_state.seg_ss, x86_opcodes_REPNE, x86_opcodes) -static int op_66(uint32_t fetchdat) /*Data size select*/ + static int op_66(uint32_t fetchdat) /*Data size select*/ { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } -static int op_67(uint32_t fetchdat) /*Address size select*/ +static int +op_67(uint32_t fetchdat) /*Address size select*/ { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } -static int op_66_REPE(uint32_t fetchdat) /*Data size select*/ +static int +op_66_REPE(uint32_t fetchdat) /*Data size select*/ { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } -static int op_67_REPE(uint32_t fetchdat) /*Address size select*/ +static int +op_67_REPE(uint32_t fetchdat) /*Address size select*/ { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } -static int op_66_REPNE(uint32_t fetchdat) /*Data size select*/ +static int +op_66_REPNE(uint32_t fetchdat) /*Data size select*/ { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } -static int op_67_REPNE(uint32_t fetchdat) /*Address size select*/ +static int +op_67_REPNE(uint32_t fetchdat) /*Address size select*/ { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } diff --git a/src/cpu/x86_ops_rep.h b/src/cpu/x86_ops_rep.h index ffae30e09..67bd8433d 100644 --- a/src/cpu/x86_ops_rep.h +++ b/src/cpu/x86_ops_rep.h @@ -1,768 +1,883 @@ -#define REP_OPS(size, CNT_REG, SRC_REG, DEST_REG) \ -static int opREP_INSB_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - \ - addr64 = 0x00000000; \ - \ - if (CNT_REG > 0) \ - { \ - uint8_t temp; \ - \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ - CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - high_page = 0; \ - do_mmut_wb(es, DEST_REG, &addr64); \ - if (cpu_state.abrt) return 1; \ - temp = inb(DX); \ - writememb_n(es, DEST_REG, addr64, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) DEST_REG--; \ - else DEST_REG++; \ - CNT_REG--; \ - cycles -= 15; \ - reads++; writes++; total_cycles += 15; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_INSW_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - \ - addr64a[0] = addr64a[1] = 0x00000000; \ - \ - if (CNT_REG > 0) \ - { \ - uint16_t temp; \ - \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - high_page = 0; \ - do_mmut_ww(es, DEST_REG, addr64a); \ - if (cpu_state.abrt) return 1; \ - temp = inw(DX); \ - writememw_n(es, DEST_REG, addr64a, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ - else DEST_REG += 2; \ - CNT_REG--; \ - cycles -= 15; \ - reads++; writes++; total_cycles += 15; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_INSL_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - \ - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ - \ - if (CNT_REG > 0) \ - { \ - uint32_t temp; \ - \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - check_io_perm(DX+2); \ - check_io_perm(DX+3); \ - CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - high_page = 0; \ - do_mmut_wl(es, DEST_REG, addr64a); \ - if (cpu_state.abrt) return 1; \ - temp = inl(DX); \ - writememl_n(es, DEST_REG, addr64a, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ - else DEST_REG += 4; \ - CNT_REG--; \ - cycles -= 15; \ - reads++; writes++; total_cycles += 15; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, writes, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_OUTSB_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - \ - if (CNT_REG > 0) \ - { \ - uint8_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - check_io_perm(DX); \ - outb(DX, temp); \ - if (cpu_state.flags & D_FLAG) SRC_REG--; \ - else SRC_REG++; \ - CNT_REG--; \ - cycles -= 14; \ - reads++; writes++; total_cycles += 14; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_OUTSW_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - \ - if (CNT_REG > 0) \ - { \ - uint16_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - outw(DX, temp); \ - if (cpu_state.flags & D_FLAG) SRC_REG -= 2; \ - else SRC_REG += 2; \ - CNT_REG--; \ - cycles -= 14; \ - reads++; writes++; total_cycles += 14; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_OUTSL_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - \ - if (CNT_REG > 0) \ - { \ - uint32_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - check_io_perm(DX+2); \ - check_io_perm(DX+3); \ - outl(DX, temp); \ - if (cpu_state.flags & D_FLAG) SRC_REG -= 4; \ - else SRC_REG += 4; \ - CNT_REG--; \ - cycles -= 14; \ - reads++; writes++; total_cycles += 14; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, writes, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_MOVSB_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - addr64 = addr64_2 = 0x00000000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ - while (CNT_REG > 0) \ - { \ - uint8_t temp; \ - \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - high_page = 0; \ - do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64) ; \ - if (cpu_state.abrt) break; \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - do_mmut_wb(es, DEST_REG, &addr64_2); \ - if (cpu_state.abrt) break; \ - temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); if (cpu_state.abrt) return 1; \ - writememb_n(es, DEST_REG, addr64_2, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ - else { DEST_REG++; SRC_REG++; } \ - CNT_REG--; \ - cycles -= is486 ? 3 : 4; \ - reads++; writes++; total_cycles += is486 ? 3 : 4; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_MOVSW_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - addr64a[0] = addr64a[1] = 0x00000000; \ - addr64a_2[0] = addr64a_2[1] = 0x00000000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ - while (CNT_REG > 0) \ - { \ - uint16_t temp; \ - \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - high_page = 0; \ - do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ - if (cpu_state.abrt) break; \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - do_mmut_ww(es, DEST_REG, addr64a_2); \ - if (cpu_state.abrt) break; \ - temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ - writememw_n(es, DEST_REG, addr64a_2, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ - else { DEST_REG += 2; SRC_REG += 2; } \ - CNT_REG--; \ - cycles -= is486 ? 3 : 4; \ - reads++; writes++; total_cycles += is486 ? 3 : 4; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_MOVSL_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ - addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ - while (CNT_REG > 0) \ - { \ - uint32_t temp; \ - \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - high_page = 0; \ - do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ - if (cpu_state.abrt) break; \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - do_mmut_wl(es, DEST_REG, addr64a_2); \ - if (cpu_state.abrt) break; \ - temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ - writememl_n(es, DEST_REG, addr64a_2, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ - else { DEST_REG += 4; SRC_REG += 4; } \ - CNT_REG--; \ - cycles -= is486 ? 3 : 4; \ - reads++; writes++; total_cycles += is486 ? 3 : 4; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ - \ -static int opREP_STOSB_ ## size(uint32_t fetchdat) \ -{ \ - int writes = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - while (CNT_REG > 0) \ - { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - writememb(es, DEST_REG, AL); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) DEST_REG--; \ - else DEST_REG++; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - writes++; total_cycles += is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_STOSW_ ## size(uint32_t fetchdat) \ -{ \ - int writes = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - while (CNT_REG > 0) \ - { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - writememw(es, DEST_REG, AX); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ - else DEST_REG += 2; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - writes++; total_cycles += is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_STOSL_ ## size(uint32_t fetchdat) \ -{ \ - int writes = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - while (CNT_REG > 0) \ - { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - writememl(es, DEST_REG, EAX); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ - else DEST_REG += 4; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - writes++; total_cycles += is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, 0, 0, writes, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_LODSB_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - while (CNT_REG > 0) \ - { \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - AL = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) SRC_REG--; \ - else SRC_REG++; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - reads++; total_cycles += is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_LODSW_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - while (CNT_REG > 0) \ - { \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - AX = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) SRC_REG -= 2; \ - else SRC_REG += 2; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - reads++; total_cycles += is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_LODSL_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - while (CNT_REG > 0) \ - { \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) SRC_REG -= 4; \ - else SRC_REG += 4; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - reads++; total_cycles += is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - +#define REP_OPS(size, CNT_REG, SRC_REG, DEST_REG) \ + static int opREP_INSB_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + addr64 = 0x00000000; \ + \ + if (CNT_REG > 0) { \ + uint8_t temp; \ + \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + check_io_perm(DX); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + high_page = 0; \ + do_mmut_wb(es, DEST_REG, &addr64); \ + if (cpu_state.abrt) \ + return 1; \ + temp = inb(DX); \ + writememb_n(es, DEST_REG, addr64, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG--; \ + else \ + DEST_REG++; \ + CNT_REG--; \ + cycles -= 15; \ + reads++; \ + writes++; \ + total_cycles += 15; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_INSW_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + addr64a[0] = addr64a[1] = 0x00000000; \ + \ + if (CNT_REG > 0) { \ + uint16_t temp; \ + \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + high_page = 0; \ + do_mmut_ww(es, DEST_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + temp = inw(DX); \ + writememw_n(es, DEST_REG, addr64a, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 2; \ + else \ + DEST_REG += 2; \ + CNT_REG--; \ + cycles -= 15; \ + reads++; \ + writes++; \ + total_cycles += 15; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_INSL_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + \ + if (CNT_REG > 0) { \ + uint32_t temp; \ + \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + check_io_perm(DX + 2); \ + check_io_perm(DX + 3); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + high_page = 0; \ + do_mmut_wl(es, DEST_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + temp = inl(DX); \ + writememl_n(es, DEST_REG, addr64a, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 4; \ + else \ + DEST_REG += 4; \ + CNT_REG--; \ + cycles -= 15; \ + reads++; \ + writes++; \ + total_cycles += 15; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, writes, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_OUTSB_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + if (CNT_REG > 0) { \ + uint8_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + check_io_perm(DX); \ + outb(DX, temp); \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG--; \ + else \ + SRC_REG++; \ + CNT_REG--; \ + cycles -= 14; \ + reads++; \ + writes++; \ + total_cycles += 14; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_OUTSW_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + if (CNT_REG > 0) { \ + uint16_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + outw(DX, temp); \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 2; \ + else \ + SRC_REG += 2; \ + CNT_REG--; \ + cycles -= 14; \ + reads++; \ + writes++; \ + total_cycles += 14; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_OUTSL_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + if (CNT_REG > 0) { \ + uint32_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + check_io_perm(DX + 2); \ + check_io_perm(DX + 3); \ + outl(DX, temp); \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 4; \ + else \ + SRC_REG += 4; \ + CNT_REG--; \ + cycles -= 14; \ + reads++; \ + writes++; \ + total_cycles += 14; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, writes, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_MOVSB_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + addr64 = addr64_2 = 0x00000000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + } \ + while (CNT_REG > 0) { \ + uint8_t temp; \ + \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + high_page = 0; \ + do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \ + if (cpu_state.abrt) \ + break; \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + do_mmut_wb(es, DEST_REG, &addr64_2); \ + if (cpu_state.abrt) \ + break; \ + temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); \ + if (cpu_state.abrt) \ + return 1; \ + writememb_n(es, DEST_REG, addr64_2, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG--; \ + SRC_REG--; \ + } else { \ + DEST_REG++; \ + SRC_REG++; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 3 : 4; \ + reads++; \ + writes++; \ + total_cycles += is486 ? 3 : 4; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_MOVSW_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + addr64a[0] = addr64a[1] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = 0x00000000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + } \ + while (CNT_REG > 0) { \ + uint16_t temp; \ + \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + high_page = 0; \ + do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + break; \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + do_mmut_ww(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + break; \ + temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + writememw_n(es, DEST_REG, addr64a_2, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 2; \ + SRC_REG -= 2; \ + } else { \ + DEST_REG += 2; \ + SRC_REG += 2; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 3 : 4; \ + reads++; \ + writes++; \ + total_cycles += is486 ? 3 : 4; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_MOVSL_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + } \ + while (CNT_REG > 0) { \ + uint32_t temp; \ + \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + high_page = 0; \ + do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + break; \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + do_mmut_wl(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + break; \ + temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + writememl_n(es, DEST_REG, addr64a_2, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 4; \ + SRC_REG -= 4; \ + } else { \ + DEST_REG += 4; \ + SRC_REG += 4; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 3 : 4; \ + reads++; \ + writes++; \ + total_cycles += is486 ? 3 : 4; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_STOSB_##size(uint32_t fetchdat) \ + { \ + int writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + while (CNT_REG > 0) { \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + writememb(es, DEST_REG, AL); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG--; \ + else \ + DEST_REG++; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + writes++; \ + total_cycles += is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_STOSW_##size(uint32_t fetchdat) \ + { \ + int writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + while (CNT_REG > 0) { \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + writememw(es, DEST_REG, AX); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 2; \ + else \ + DEST_REG += 2; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + writes++; \ + total_cycles += is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_STOSL_##size(uint32_t fetchdat) \ + { \ + int writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + while (CNT_REG > 0) { \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + writememl(es, DEST_REG, EAX); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 4; \ + else \ + DEST_REG += 4; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + writes++; \ + total_cycles += is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, 0, 0, writes, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_LODSB_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + while (CNT_REG > 0) { \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + AL = readmemb(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG--; \ + else \ + SRC_REG++; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + reads++; \ + total_cycles += is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_LODSW_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + while (CNT_REG > 0) { \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + AX = readmemw(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 2; \ + else \ + SRC_REG += 2; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + reads++; \ + total_cycles += is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_LODSL_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + while (CNT_REG > 0) { \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 4; \ + else \ + SRC_REG += 4; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + reads++; \ + total_cycles += is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } #define CHEK_READ(a, b, c) - -#define REP_OPS_CMPS_SCAS(size, CNT_REG, SRC_REG, DEST_REG, FV) \ -static int opREP_CMPSB_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0, tempz; \ - \ - addr64 = addr64_2 = 0x00000000; \ - \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - uint8_t temp, temp2; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - high_page = uncached = 0; \ - do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \ - if (cpu_state.abrt) return 1; \ - CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - do_mmut_rb2(es, DEST_REG, &addr64_2); \ - if (cpu_state.abrt) return 1; \ - temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = old_rl2; \ - temp2 = readmemb_n(es, DEST_REG, addr64_2); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = (uintptr_t) LOOKUP_INV; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ - else { DEST_REG++; SRC_REG++; } \ - CNT_REG--; \ - cycles -= is486 ? 7 : 9; \ - reads += 2; total_cycles += is486 ? 7 : 9; \ - setsub8(temp, temp2); \ - tempz = (ZF_SET()) ? 1 : 0; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_CMPSW_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0, tempz; \ - \ - addr64a[0] = addr64a[1] = 0x00000000; \ - addr64a_2[0] = addr64a_2[1] = 0x00000000; \ - \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - uint16_t temp, temp2; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - high_page = uncached = 0; \ - do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ - if (cpu_state.abrt) return 1; \ - CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - do_mmut_rw2(es, DEST_REG, addr64a_2); \ - if (cpu_state.abrt) return 1; \ - temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = old_rl2; \ - temp2 = readmemw_n(es, DEST_REG, addr64a_2); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = (uintptr_t) LOOKUP_INV; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ - else { DEST_REG += 2; SRC_REG += 2; } \ - CNT_REG--; \ - cycles -= is486 ? 7 : 9; \ - reads += 2; total_cycles += is486 ? 7 : 9; \ - setsub16(temp, temp2); \ - tempz = (ZF_SET()) ? 1 : 0; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_CMPSL_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0, tempz; \ - \ - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ - addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ - \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - uint32_t temp, temp2; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - high_page = uncached = 0; \ - do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ - if (cpu_state.abrt) return 1; \ - CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - do_mmut_rl2(es, DEST_REG, addr64a_2); \ - if (cpu_state.abrt) return 1; \ - temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = old_rl2; \ - temp2 = readmeml_n(es, DEST_REG, addr64a_2); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = (uintptr_t) LOOKUP_INV; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ - else { DEST_REG += 4; SRC_REG += 4; } \ - CNT_REG--; \ - cycles -= is486 ? 7 : 9; \ - reads += 2; total_cycles += is486 ? 7 : 9; \ - setsub32(temp, temp2); \ - tempz = (ZF_SET()) ? 1 : 0; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_SCASB_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0, tempz; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - while ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - uint8_t temp = readmemb(es, DEST_REG); if (cpu_state.abrt) break;\ - setsub8(AL, temp); \ - tempz = (ZF_SET()) ? 1 : 0; \ - if (cpu_state.flags & D_FLAG) DEST_REG--; \ - else DEST_REG++; \ - CNT_REG--; \ - cycles -= is486 ? 5 : 8; \ - reads++; total_cycles += is486 ? 5 : 8; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_SCASW_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0, tempz; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - while ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - uint16_t temp = readmemw(es, DEST_REG); if (cpu_state.abrt) break;\ - setsub16(AX, temp); \ - tempz = (ZF_SET()) ? 1 : 0; \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ - else DEST_REG += 2; \ - CNT_REG--; \ - cycles -= is486 ? 5 : 8; \ - reads++; total_cycles += is486 ? 5 : 8; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_SCASL_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0, tempz; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - while ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - uint32_t temp = readmeml(es, DEST_REG); if (cpu_state.abrt) break;\ - setsub32(EAX, temp); \ - tempz = (ZF_SET()) ? 1 : 0; \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ - else DEST_REG += 4; \ - CNT_REG--; \ - cycles -= is486 ? 5 : 8; \ - reads++; total_cycles += is486 ? 5 : 8; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} +#define REP_OPS_CMPS_SCAS(size, CNT_REG, SRC_REG, DEST_REG, FV) \ + static int opREP_CMPSB_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0, tempz; \ + \ + addr64 = addr64_2 = 0x00000000; \ + \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + uint8_t temp, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + high_page = uncached = 0; \ + do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \ + if (cpu_state.abrt) \ + return 1; \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + do_mmut_rb2(es, DEST_REG, &addr64_2); \ + if (cpu_state.abrt) \ + return 1; \ + temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = old_rl2; \ + temp2 = readmemb_n(es, DEST_REG, addr64_2); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = (uintptr_t) LOOKUP_INV; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG--; \ + SRC_REG--; \ + } else { \ + DEST_REG++; \ + SRC_REG++; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 7 : 9; \ + reads += 2; \ + total_cycles += is486 ? 7 : 9; \ + setsub8(temp, temp2); \ + tempz = (ZF_SET()) ? 1 : 0; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_CMPSW_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0, tempz; \ + \ + addr64a[0] = addr64a[1] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = 0x00000000; \ + \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + uint16_t temp, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + high_page = uncached = 0; \ + do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + do_mmut_rw2(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = old_rl2; \ + temp2 = readmemw_n(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = (uintptr_t) LOOKUP_INV; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 2; \ + SRC_REG -= 2; \ + } else { \ + DEST_REG += 2; \ + SRC_REG += 2; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 7 : 9; \ + reads += 2; \ + total_cycles += is486 ? 7 : 9; \ + setsub16(temp, temp2); \ + tempz = (ZF_SET()) ? 1 : 0; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_CMPSL_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0, tempz; \ + \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ + \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + uint32_t temp, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + high_page = uncached = 0; \ + do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + do_mmut_rl2(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = old_rl2; \ + temp2 = readmeml_n(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = (uintptr_t) LOOKUP_INV; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 4; \ + SRC_REG -= 4; \ + } else { \ + DEST_REG += 4; \ + SRC_REG += 4; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 7 : 9; \ + reads += 2; \ + total_cycles += is486 ? 7 : 9; \ + setsub32(temp, temp2); \ + tempz = (ZF_SET()) ? 1 : 0; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_SCASB_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0, tempz; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + while ((CNT_REG > 0) && (FV == tempz)) { \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + uint8_t temp = readmemb(es, DEST_REG); \ + if (cpu_state.abrt) \ + break; \ + setsub8(AL, temp); \ + tempz = (ZF_SET()) ? 1 : 0; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG--; \ + else \ + DEST_REG++; \ + CNT_REG--; \ + cycles -= is486 ? 5 : 8; \ + reads++; \ + total_cycles += is486 ? 5 : 8; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_SCASW_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0, tempz; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + while ((CNT_REG > 0) && (FV == tempz)) { \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + uint16_t temp = readmemw(es, DEST_REG); \ + if (cpu_state.abrt) \ + break; \ + setsub16(AX, temp); \ + tempz = (ZF_SET()) ? 1 : 0; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 2; \ + else \ + DEST_REG += 2; \ + CNT_REG--; \ + cycles -= is486 ? 5 : 8; \ + reads++; \ + total_cycles += is486 ? 5 : 8; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_SCASL_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0, tempz; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + while ((CNT_REG > 0) && (FV == tempz)) { \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + uint32_t temp = readmeml(es, DEST_REG); \ + if (cpu_state.abrt) \ + break; \ + setsub32(EAX, temp); \ + tempz = (ZF_SET()) ? 1 : 0; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 4; \ + else \ + DEST_REG += 4; \ + CNT_REG--; \ + cycles -= is486 ? 5 : 8; \ + reads++; \ + total_cycles += is486 ? 5 : 8; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } REP_OPS(a16, CX, SI, DI) REP_OPS(a32, ECX, ESI, EDI) REP_OPS_CMPS_SCAS(a16_NE, CX, SI, DI, 0) -REP_OPS_CMPS_SCAS(a16_E, CX, SI, DI, 1) +REP_OPS_CMPS_SCAS(a16_E, CX, SI, DI, 1) REP_OPS_CMPS_SCAS(a32_NE, ECX, ESI, EDI, 0) -REP_OPS_CMPS_SCAS(a32_E, ECX, ESI, EDI, 1) +REP_OPS_CMPS_SCAS(a32_E, ECX, ESI, EDI, 1) -static int opREPNE(uint32_t fetchdat) +static int +opREPNE(uint32_t fetchdat) { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } -static int opREPE(uint32_t fetchdat) +static int +opREPE(uint32_t fetchdat) { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } diff --git a/src/cpu/x86_ops_rep_dyn.h b/src/cpu/x86_ops_rep_dyn.h index e63ed32fe..576baa403 100644 --- a/src/cpu/x86_ops_rep_dyn.h +++ b/src/cpu/x86_ops_rep_dyn.h @@ -1,703 +1,788 @@ -#define REP_OPS(size, CNT_REG, SRC_REG, DEST_REG) \ -static int opREP_INSB_ ## size(uint32_t fetchdat) \ -{ \ - addr64 = 0x00000000; \ - \ - if (CNT_REG > 0) \ - { \ - uint8_t temp; \ - \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ - CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - high_page = 0; \ - do_mmut_wb(es, DEST_REG, &addr64); \ - if (cpu_state.abrt) return 1; \ - temp = inb(DX); \ - writememb_n(es, DEST_REG, addr64, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) DEST_REG--; \ - else DEST_REG++; \ - CNT_REG--; \ - cycles -= 15; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_INSW_ ## size(uint32_t fetchdat) \ -{ \ - addr64a[0] = addr64a[1] = 0x00000000; \ - \ - if (CNT_REG > 0) \ - { \ - uint16_t temp; \ - \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - high_page = 0; \ - do_mmut_ww(es, DEST_REG, addr64a); \ - if (cpu_state.abrt) return 1; \ - temp = inw(DX); \ - writememw_n(es, DEST_REG, addr64a, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ - else DEST_REG += 2; \ - CNT_REG--; \ - cycles -= 15; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_INSL_ ## size(uint32_t fetchdat) \ -{ \ - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ - \ - if (CNT_REG > 0) \ - { \ - uint32_t temp; \ - \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - check_io_perm(DX+2); \ - check_io_perm(DX+3); \ - CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - high_page = 0; \ - do_mmut_wl(es, DEST_REG, addr64a); \ - if (cpu_state.abrt) return 1; \ - temp = inl(DX); \ - writememl_n(es, DEST_REG, addr64a, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ - else DEST_REG += 4; \ - CNT_REG--; \ - cycles -= 15; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_OUTSB_ ## size(uint32_t fetchdat) \ -{ \ - if (CNT_REG > 0) \ - { \ - uint8_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - check_io_perm(DX); \ - outb(DX, temp); \ - if (cpu_state.flags & D_FLAG) SRC_REG--; \ - else SRC_REG++; \ - CNT_REG--; \ - cycles -= 14; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_OUTSW_ ## size(uint32_t fetchdat) \ -{ \ - if (CNT_REG > 0) \ - { \ - uint16_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - outw(DX, temp); \ - if (cpu_state.flags & D_FLAG) SRC_REG -= 2; \ - else SRC_REG += 2; \ - CNT_REG--; \ - cycles -= 14; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_OUTSL_ ## size(uint32_t fetchdat) \ -{ \ - if (CNT_REG > 0) \ - { \ - uint32_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - check_io_perm(DX+2); \ - check_io_perm(DX+3); \ - outl(DX, temp); \ - if (cpu_state.flags & D_FLAG) SRC_REG -= 4; \ - else SRC_REG += 4; \ - CNT_REG--; \ - cycles -= 14; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_MOVSB_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - addr64 = addr64_2 = 0x00000000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ - while (CNT_REG > 0) \ - { \ - uint8_t temp; \ - \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - high_page = 0; \ - do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64) ; \ - if (cpu_state.abrt) break; \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - do_mmut_wb(es, DEST_REG, &addr64_2); \ - if (cpu_state.abrt) break; \ - temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); if (cpu_state.abrt) return 1; \ - writememb_n(es, DEST_REG, addr64_2, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ - else { DEST_REG++; SRC_REG++; } \ - CNT_REG--; \ - cycles -= is486 ? 3 : 4; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_MOVSW_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - addr64a[0] = addr64a[1] = 0x00000000; \ - addr64a_2[0] = addr64a_2[1] = 0x00000000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ - while (CNT_REG > 0) \ - { \ - uint16_t temp; \ - \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - high_page = 0; \ - do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ - if (cpu_state.abrt) break; \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - do_mmut_ww(es, DEST_REG, addr64a_2); \ - if (cpu_state.abrt) break; \ - temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ - writememw_n(es, DEST_REG, addr64a_2, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ - else { DEST_REG += 2; SRC_REG += 2; } \ - CNT_REG--; \ - cycles -= is486 ? 3 : 4; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_MOVSL_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ - addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ - while (CNT_REG > 0) \ - { \ - uint32_t temp; \ - \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - high_page = 0; \ - do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ - if (cpu_state.abrt) break; \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - do_mmut_wl(es, DEST_REG, addr64a_2); \ - if (cpu_state.abrt) break; \ - temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ - writememl_n(es, DEST_REG, addr64a_2, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ - else { DEST_REG += 4; SRC_REG += 4; } \ - CNT_REG--; \ - cycles -= is486 ? 3 : 4; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ - \ -static int opREP_STOSB_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - while (CNT_REG > 0) \ - { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - writememb(es, DEST_REG, AL); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) DEST_REG--; \ - else DEST_REG++; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_STOSW_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - while (CNT_REG > 0) \ - { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - writememw(es, DEST_REG, AX); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ - else DEST_REG += 2; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_STOSL_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - while (CNT_REG > 0) \ - { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - writememl(es, DEST_REG, EAX); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ - else DEST_REG += 4; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_LODSB_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - while (CNT_REG > 0) \ - { \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - AL = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) SRC_REG--; \ - else SRC_REG++; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_LODSW_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - while (CNT_REG > 0) \ - { \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - AX = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) SRC_REG -= 2; \ - else SRC_REG += 2; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_LODSL_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - while (CNT_REG > 0) \ - { \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) SRC_REG -= 4; \ - else SRC_REG += 4; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - +#define REP_OPS(size, CNT_REG, SRC_REG, DEST_REG) \ + static int opREP_INSB_##size(uint32_t fetchdat) \ + { \ + addr64 = 0x00000000; \ + \ + if (CNT_REG > 0) { \ + uint8_t temp; \ + \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + check_io_perm(DX); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + high_page = 0; \ + do_mmut_wb(es, DEST_REG, &addr64); \ + if (cpu_state.abrt) \ + return 1; \ + temp = inb(DX); \ + writememb_n(es, DEST_REG, addr64, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG--; \ + else \ + DEST_REG++; \ + CNT_REG--; \ + cycles -= 15; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_INSW_##size(uint32_t fetchdat) \ + { \ + addr64a[0] = addr64a[1] = 0x00000000; \ + \ + if (CNT_REG > 0) { \ + uint16_t temp; \ + \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + high_page = 0; \ + do_mmut_ww(es, DEST_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + temp = inw(DX); \ + writememw_n(es, DEST_REG, addr64a, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 2; \ + else \ + DEST_REG += 2; \ + CNT_REG--; \ + cycles -= 15; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_INSL_##size(uint32_t fetchdat) \ + { \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + \ + if (CNT_REG > 0) { \ + uint32_t temp; \ + \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + check_io_perm(DX + 2); \ + check_io_perm(DX + 3); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + high_page = 0; \ + do_mmut_wl(es, DEST_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + temp = inl(DX); \ + writememl_n(es, DEST_REG, addr64a, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 4; \ + else \ + DEST_REG += 4; \ + CNT_REG--; \ + cycles -= 15; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_OUTSB_##size(uint32_t fetchdat) \ + { \ + if (CNT_REG > 0) { \ + uint8_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + check_io_perm(DX); \ + outb(DX, temp); \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG--; \ + else \ + SRC_REG++; \ + CNT_REG--; \ + cycles -= 14; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_OUTSW_##size(uint32_t fetchdat) \ + { \ + if (CNT_REG > 0) { \ + uint16_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + outw(DX, temp); \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 2; \ + else \ + SRC_REG += 2; \ + CNT_REG--; \ + cycles -= 14; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_OUTSL_##size(uint32_t fetchdat) \ + { \ + if (CNT_REG > 0) { \ + uint32_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + check_io_perm(DX + 2); \ + check_io_perm(DX + 3); \ + outl(DX, temp); \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 4; \ + else \ + SRC_REG += 4; \ + CNT_REG--; \ + cycles -= 14; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_MOVSB_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + addr64 = addr64_2 = 0x00000000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + } \ + while (CNT_REG > 0) { \ + uint8_t temp; \ + \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + high_page = 0; \ + do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \ + if (cpu_state.abrt) \ + break; \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + do_mmut_wb(es, DEST_REG, &addr64_2); \ + if (cpu_state.abrt) \ + break; \ + temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); \ + if (cpu_state.abrt) \ + return 1; \ + writememb_n(es, DEST_REG, addr64_2, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG--; \ + SRC_REG--; \ + } else { \ + DEST_REG++; \ + SRC_REG++; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 3 : 4; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_MOVSW_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + addr64a[0] = addr64a[1] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = 0x00000000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + } \ + while (CNT_REG > 0) { \ + uint16_t temp; \ + \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + high_page = 0; \ + do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + break; \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + do_mmut_ww(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + break; \ + temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + writememw_n(es, DEST_REG, addr64a_2, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 2; \ + SRC_REG -= 2; \ + } else { \ + DEST_REG += 2; \ + SRC_REG += 2; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 3 : 4; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_MOVSL_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + } \ + while (CNT_REG > 0) { \ + uint32_t temp; \ + \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + high_page = 0; \ + do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + break; \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + do_mmut_wl(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + break; \ + temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + writememl_n(es, DEST_REG, addr64a_2, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 4; \ + SRC_REG -= 4; \ + } else { \ + DEST_REG += 4; \ + SRC_REG += 4; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 3 : 4; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_STOSB_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + while (CNT_REG > 0) { \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + writememb(es, DEST_REG, AL); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG--; \ + else \ + DEST_REG++; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_STOSW_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + while (CNT_REG > 0) { \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + writememw(es, DEST_REG, AX); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 2; \ + else \ + DEST_REG += 2; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_STOSL_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + while (CNT_REG > 0) { \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + writememl(es, DEST_REG, EAX); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 4; \ + else \ + DEST_REG += 4; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_LODSB_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + while (CNT_REG > 0) { \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + AL = readmemb(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG--; \ + else \ + SRC_REG++; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_LODSW_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + while (CNT_REG > 0) { \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + AX = readmemw(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 2; \ + else \ + SRC_REG += 2; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_LODSL_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + while (CNT_REG > 0) { \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 4; \ + else \ + SRC_REG += 4; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } #define CHEK_READ(a, b, c) - -#define REP_OPS_CMPS_SCAS(size, CNT_REG, SRC_REG, DEST_REG, FV) \ -static int opREP_CMPSB_ ## size(uint32_t fetchdat) \ -{ \ - int tempz; \ - \ - addr64 = addr64_2 = 0x00000000; \ - \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - uint8_t temp, temp2; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - high_page = uncached = 0; \ - do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \ - if (cpu_state.abrt) return 1; \ - CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - do_mmut_rb2(es, DEST_REG, &addr64_2); \ - if (cpu_state.abrt) return 1; \ - temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = old_rl2; \ - temp2 = readmemb_n(es, DEST_REG, addr64_2); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = (uintptr_t) LOOKUP_INV; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ - else { DEST_REG++; SRC_REG++; } \ - CNT_REG--; \ - cycles -= is486 ? 7 : 9; \ - setsub8(temp, temp2); \ - tempz = (ZF_SET()) ? 1 : 0; \ - } \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_CMPSW_ ## size(uint32_t fetchdat) \ -{ \ - int tempz; \ - \ - addr64a[0] = addr64a[1] = 0x00000000; \ - addr64a_2[0] = addr64a_2[1] = 0x00000000; \ - \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - uint16_t temp, temp2; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - high_page = uncached = 0; \ - do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ - if (cpu_state.abrt) return 1; \ - CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - do_mmut_rw2(es, DEST_REG, addr64a_2); \ - if (cpu_state.abrt) return 1; \ - temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = old_rl2; \ - temp2 = readmemw_n(es, DEST_REG, addr64a_2); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = (uintptr_t) LOOKUP_INV; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ - else { DEST_REG += 2; SRC_REG += 2; } \ - CNT_REG--; \ - cycles -= is486 ? 7 : 9; \ - setsub16(temp, temp2); \ - tempz = (ZF_SET()) ? 1 : 0; \ - } \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_CMPSL_ ## size(uint32_t fetchdat) \ -{ \ - int tempz; \ - \ - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ - addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ - \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - uint32_t temp, temp2; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - high_page = uncached = 0; \ - do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ - if (cpu_state.abrt) return 1; \ - CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - do_mmut_rl2(es, DEST_REG, addr64a_2); \ - if (cpu_state.abrt) return 1; \ - temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = old_rl2; \ - temp2 = readmeml_n(es, DEST_REG, addr64a_2); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = (uintptr_t) LOOKUP_INV; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ - else { DEST_REG += 4; SRC_REG += 4; } \ - CNT_REG--; \ - cycles -= is486 ? 7 : 9; \ - setsub32(temp, temp2); \ - tempz = (ZF_SET()) ? 1 : 0; \ - } \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_SCASB_ ## size(uint32_t fetchdat) \ -{ \ - int tempz; \ - int cycles_end = cycles - 1000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - while ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - uint8_t temp = readmemb(es, DEST_REG); if (cpu_state.abrt) break;\ - setsub8(AL, temp); \ - tempz = (ZF_SET()) ? 1 : 0; \ - if (cpu_state.flags & D_FLAG) DEST_REG--; \ - else DEST_REG++; \ - CNT_REG--; \ - cycles -= is486 ? 5 : 8; \ - if (cycles < cycles_end) \ - break; \ - } \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_SCASW_ ## size(uint32_t fetchdat) \ -{ \ - int tempz; \ - int cycles_end = cycles - 1000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - while ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - uint16_t temp = readmemw(es, DEST_REG); if (cpu_state.abrt) break;\ - setsub16(AX, temp); \ - tempz = (ZF_SET()) ? 1 : 0; \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ - else DEST_REG += 2; \ - CNT_REG--; \ - cycles -= is486 ? 5 : 8; \ - if (cycles < cycles_end) \ - break; \ - } \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_SCASL_ ## size(uint32_t fetchdat) \ -{ \ - int tempz; \ - int cycles_end = cycles - 1000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - while ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - uint32_t temp = readmeml(es, DEST_REG); if (cpu_state.abrt) break;\ - setsub32(EAX, temp); \ - tempz = (ZF_SET()) ? 1 : 0; \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ - else DEST_REG += 4; \ - CNT_REG--; \ - cycles -= is486 ? 5 : 8; \ - if (cycles < cycles_end) \ - break; \ - } \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} +#define REP_OPS_CMPS_SCAS(size, CNT_REG, SRC_REG, DEST_REG, FV) \ + static int opREP_CMPSB_##size(uint32_t fetchdat) \ + { \ + int tempz; \ + \ + addr64 = addr64_2 = 0x00000000; \ + \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + uint8_t temp, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + high_page = uncached = 0; \ + do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \ + if (cpu_state.abrt) \ + return 1; \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + do_mmut_rb2(es, DEST_REG, &addr64_2); \ + if (cpu_state.abrt) \ + return 1; \ + temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = old_rl2; \ + temp2 = readmemb_n(es, DEST_REG, addr64_2); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = (uintptr_t) LOOKUP_INV; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG--; \ + SRC_REG--; \ + } else { \ + DEST_REG++; \ + SRC_REG++; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 7 : 9; \ + setsub8(temp, temp2); \ + tempz = (ZF_SET()) ? 1 : 0; \ + } \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_CMPSW_##size(uint32_t fetchdat) \ + { \ + int tempz; \ + \ + addr64a[0] = addr64a[1] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = 0x00000000; \ + \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + uint16_t temp, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + high_page = uncached = 0; \ + do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + do_mmut_rw2(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = old_rl2; \ + temp2 = readmemw_n(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = (uintptr_t) LOOKUP_INV; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 2; \ + SRC_REG -= 2; \ + } else { \ + DEST_REG += 2; \ + SRC_REG += 2; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 7 : 9; \ + setsub16(temp, temp2); \ + tempz = (ZF_SET()) ? 1 : 0; \ + } \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_CMPSL_##size(uint32_t fetchdat) \ + { \ + int tempz; \ + \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ + \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + uint32_t temp, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + high_page = uncached = 0; \ + do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + do_mmut_rl2(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = old_rl2; \ + temp2 = readmeml_n(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = (uintptr_t) LOOKUP_INV; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 4; \ + SRC_REG -= 4; \ + } else { \ + DEST_REG += 4; \ + SRC_REG += 4; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 7 : 9; \ + setsub32(temp, temp2); \ + tempz = (ZF_SET()) ? 1 : 0; \ + } \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_SCASB_##size(uint32_t fetchdat) \ + { \ + int tempz; \ + int cycles_end = cycles - 1000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + while ((CNT_REG > 0) && (FV == tempz)) { \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + uint8_t temp = readmemb(es, DEST_REG); \ + if (cpu_state.abrt) \ + break; \ + setsub8(AL, temp); \ + tempz = (ZF_SET()) ? 1 : 0; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG--; \ + else \ + DEST_REG++; \ + CNT_REG--; \ + cycles -= is486 ? 5 : 8; \ + if (cycles < cycles_end) \ + break; \ + } \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_SCASW_##size(uint32_t fetchdat) \ + { \ + int tempz; \ + int cycles_end = cycles - 1000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + while ((CNT_REG > 0) && (FV == tempz)) { \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + uint16_t temp = readmemw(es, DEST_REG); \ + if (cpu_state.abrt) \ + break; \ + setsub16(AX, temp); \ + tempz = (ZF_SET()) ? 1 : 0; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 2; \ + else \ + DEST_REG += 2; \ + CNT_REG--; \ + cycles -= is486 ? 5 : 8; \ + if (cycles < cycles_end) \ + break; \ + } \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_SCASL_##size(uint32_t fetchdat) \ + { \ + int tempz; \ + int cycles_end = cycles - 1000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + while ((CNT_REG > 0) && (FV == tempz)) { \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + uint32_t temp = readmeml(es, DEST_REG); \ + if (cpu_state.abrt) \ + break; \ + setsub32(EAX, temp); \ + tempz = (ZF_SET()) ? 1 : 0; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 4; \ + else \ + DEST_REG += 4; \ + CNT_REG--; \ + cycles -= is486 ? 5 : 8; \ + if (cycles < cycles_end) \ + break; \ + } \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } REP_OPS(a16, CX, SI, DI) REP_OPS(a32, ECX, ESI, EDI) REP_OPS_CMPS_SCAS(a16_NE, CX, SI, DI, 0) -REP_OPS_CMPS_SCAS(a16_E, CX, SI, DI, 1) +REP_OPS_CMPS_SCAS(a16_E, CX, SI, DI, 1) REP_OPS_CMPS_SCAS(a32_NE, ECX, ESI, EDI, 0) -REP_OPS_CMPS_SCAS(a32_E, ECX, ESI, EDI, 1) +REP_OPS_CMPS_SCAS(a32_E, ECX, ESI, EDI, 1) -static int opREPNE(uint32_t fetchdat) +static int +opREPNE(uint32_t fetchdat) { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - CLOCK_CYCLES(2); - if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + CLOCK_CYCLES(2); + if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } -static int opREPE(uint32_t fetchdat) +static int +opREPE(uint32_t fetchdat) { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - CLOCK_CYCLES(2); - if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + CLOCK_CYCLES(2); + if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } diff --git a/src/cpu/x86_ops_ret.h b/src/cpu/x86_ops_ret.h index 693fb0393..ec200f2d7 100644 --- a/src/cpu/x86_ops_ret.h +++ b/src/cpu/x86_ops_ret.h @@ -1,311 +1,291 @@ #ifdef USE_NEW_DYNAREC -#define CPU_SET_OXPC +# define CPU_SET_OXPC #else -#define CPU_SET_OXPC oxpc = cpu_state.pc; +# define CPU_SET_OXPC oxpc = cpu_state.pc; #endif -#define RETF_a16(stack_offset) \ - if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ - { \ - pmoderetf(0, stack_offset); \ - return 1; \ - } \ - CPU_SET_OXPC \ - if (stack32) \ - { \ - cpu_state.pc = readmemw(ss, ESP); \ - loadcs(readmemw(ss, ESP + 2)); \ - } \ - else \ - { \ - cpu_state.pc = readmemw(ss, SP); \ - loadcs(readmemw(ss, SP + 2)); \ - } \ - if (cpu_state.abrt) return 1; \ - if (stack32) ESP += 4 + stack_offset; \ - else SP += 4 + stack_offset; \ - cycles -= timing_retf_rm; +#define RETF_a16(stack_offset) \ + if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \ + pmoderetf(0, stack_offset); \ + return 1; \ + } \ + CPU_SET_OXPC \ + if (stack32) { \ + cpu_state.pc = readmemw(ss, ESP); \ + loadcs(readmemw(ss, ESP + 2)); \ + } else { \ + cpu_state.pc = readmemw(ss, SP); \ + loadcs(readmemw(ss, SP + 2)); \ + } \ + if (cpu_state.abrt) \ + return 1; \ + if (stack32) \ + ESP += 4 + stack_offset; \ + else \ + SP += 4 + stack_offset; \ + cycles -= timing_retf_rm; -#define RETF_a32(stack_offset) \ - if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ - { \ - pmoderetf(1, stack_offset); \ - return 1; \ - } \ - CPU_SET_OXPC \ - if (stack32) \ - { \ - cpu_state.pc = readmeml(ss, ESP); \ - loadcs(readmeml(ss, ESP + 4) & 0xffff); \ - } \ - else \ - { \ - cpu_state.pc = readmeml(ss, SP); \ - loadcs(readmeml(ss, SP + 4) & 0xffff); \ - } \ - if (cpu_state.abrt) return 1; \ - if (stack32) ESP += 8 + stack_offset; \ - else SP += 8 + stack_offset; \ - cycles -= timing_retf_rm; +#define RETF_a32(stack_offset) \ + if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \ + pmoderetf(1, stack_offset); \ + return 1; \ + } \ + CPU_SET_OXPC \ + if (stack32) { \ + cpu_state.pc = readmeml(ss, ESP); \ + loadcs(readmeml(ss, ESP + 4) & 0xffff); \ + } else { \ + cpu_state.pc = readmeml(ss, SP); \ + loadcs(readmeml(ss, SP + 4) & 0xffff); \ + } \ + if (cpu_state.abrt) \ + return 1; \ + if (stack32) \ + ESP += 8 + stack_offset; \ + else \ + SP += 8 + stack_offset; \ + cycles -= timing_retf_rm; -static int opRETF_a16(uint32_t fetchdat) +static int +opRETF_a16(uint32_t fetchdat) { - int cycles_old = cycles; UN_USED(cycles_old); + int cycles_old = cycles; + UN_USED(cycles_old); - CPU_BLOCK_END(); - RETF_a16(0); + CPU_BLOCK_END(); + RETF_a16(0); - PREFETCH_RUN(cycles_old-cycles, 1, -1, 2,0,0,0, 0); - PREFETCH_FLUSH(); - return 0; + PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } -static int opRETF_a32(uint32_t fetchdat) +static int +opRETF_a32(uint32_t fetchdat) { - int cycles_old = cycles; UN_USED(cycles_old); + int cycles_old = cycles; + UN_USED(cycles_old); - CPU_BLOCK_END(); - RETF_a32(0); + CPU_BLOCK_END(); + RETF_a32(0); - PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,2,0,0, 1); - PREFETCH_FLUSH(); - return 0; + PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1); + PREFETCH_FLUSH(); + return 0; } -static int opRETF_a16_imm(uint32_t fetchdat) +static int +opRETF_a16_imm(uint32_t fetchdat) { - uint16_t offset = getwordf(); - int cycles_old = cycles; UN_USED(cycles_old); + uint16_t offset = getwordf(); + int cycles_old = cycles; + UN_USED(cycles_old); - CPU_BLOCK_END(); - RETF_a16(offset); + CPU_BLOCK_END(); + RETF_a16(offset); - PREFETCH_RUN(cycles_old-cycles, 3, -1, 2,0,0,0, 0); - PREFETCH_FLUSH(); - return 0; + PREFETCH_RUN(cycles_old - cycles, 3, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } -static int opRETF_a32_imm(uint32_t fetchdat) +static int +opRETF_a32_imm(uint32_t fetchdat) { - uint16_t offset = getwordf(); - int cycles_old = cycles; UN_USED(cycles_old); + uint16_t offset = getwordf(); + int cycles_old = cycles; + UN_USED(cycles_old); - CPU_BLOCK_END(); - RETF_a32(offset); + CPU_BLOCK_END(); + RETF_a32(offset); - PREFETCH_RUN(cycles_old-cycles, 3, -1, 0,2,0,0, 1); - PREFETCH_FLUSH(); - return 0; + PREFETCH_RUN(cycles_old - cycles, 3, -1, 0, 2, 0, 0, 1); + PREFETCH_FLUSH(); + return 0; } -static int opIRET_186(uint32_t fetchdat) +static int +opIRET_186(uint32_t fetchdat) { - int cycles_old = cycles; UN_USED(cycles_old); + int cycles_old = cycles; + UN_USED(cycles_old); - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf(NULL,0); + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf(NULL, 0); + return 1; + } + if (msw & 1) { + optype = IRET; + pmodeiret(0); + optype = 0; + } else { + uint16_t new_cs; + CPU_SET_OXPC + if (stack32) { + cpu_state.pc = readmemw(ss, ESP); + new_cs = readmemw(ss, ESP + 2); + cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2; + ESP += 6; + } else { + cpu_state.pc = readmemw(ss, SP); + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); + cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2; + SP += 6; + } + loadcs(new_cs); + cycles -= timing_iret_rm; + } + flags_extract(); + nmi_enable = 1; + CPU_BLOCK_END(); + + PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return cpu_state.abrt; +} + +static int +opIRET_286(uint32_t fetchdat) +{ + int cycles_old = cycles; + UN_USED(cycles_old); + + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf(NULL, 0); + return 1; + } + if (msw & 1) { + optype = IRET; + pmodeiret(0); + optype = 0; + } else { + uint16_t new_cs; + CPU_SET_OXPC + if (stack32) { + cpu_state.pc = readmemw(ss, ESP); + new_cs = readmemw(ss, ESP + 2); + cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2; + ESP += 6; + } else { + cpu_state.pc = readmemw(ss, SP); + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); + cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2; + SP += 6; + } + loadcs(new_cs); + cycles -= timing_iret_rm; + } + flags_extract(); + nmi_enable = 1; + CPU_BLOCK_END(); + + PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return cpu_state.abrt; +} + +static int +opIRET(uint32_t fetchdat) +{ + int cycles_old = cycles; + UN_USED(cycles_old); + + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + if (cr4 & CR4_VME) { + uint16_t new_pc, new_cs, new_flags; + + new_pc = readmemw(ss, SP); + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); + new_flags = readmemw(ss, ((SP + 4) & 0xffff)); + if (cpu_state.abrt) return 1; - } - if (msw&1) - { - optype = IRET; - pmodeiret(0); - optype = 0; - } - else - { - uint16_t new_cs; - CPU_SET_OXPC - if (stack32) - { - cpu_state.pc = readmemw(ss, ESP); - new_cs = readmemw(ss, ESP + 2); - cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2; - ESP += 6; - } - else - { - cpu_state.pc = readmemw(ss, SP); - new_cs = readmemw(ss, ((SP + 2) & 0xffff)); - cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2; - SP += 6; - } - loadcs(new_cs); - cycles -= timing_iret_rm; - } - flags_extract(); - nmi_enable = 1; - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 1, -1, 2,0,0,0, 0); - PREFETCH_FLUSH(); - return cpu_state.abrt; -} - -static int opIRET_286(uint32_t fetchdat) -{ - int cycles_old = cycles; UN_USED(cycles_old); - - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf(NULL,0); + if ((new_flags & T_FLAG) || ((new_flags & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) { + x86gpf(NULL, 0); return 1; - } - if (msw&1) - { - optype = IRET; - pmodeiret(0); - optype = 0; - } - else - { - uint16_t new_cs; - CPU_SET_OXPC - if (stack32) - { - cpu_state.pc = readmemw(ss, ESP); - new_cs = readmemw(ss, ESP + 2); - cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2; - ESP += 6; - } - else - { - cpu_state.pc = readmemw(ss, SP); - new_cs = readmemw(ss, ((SP + 2) & 0xffff)); - cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2; - SP += 6; - } - loadcs(new_cs); - cycles -= timing_iret_rm; - } - flags_extract(); - nmi_enable = 1; - CPU_BLOCK_END(); + } + SP += 6; + if (new_flags & I_FLAG) + cpu_state.eflags |= VIF_FLAG; + else + cpu_state.eflags &= ~VIF_FLAG; + cpu_state.flags = (cpu_state.flags & 0x3300) | (new_flags & 0x4cd5) | 2; + loadcs(new_cs); + cpu_state.pc = new_pc; - PREFETCH_RUN(cycles_old-cycles, 1, -1, 2,0,0,0, 0); - PREFETCH_FLUSH(); - return cpu_state.abrt; + cycles -= timing_iret_rm; + } else { + x86gpf_expected(NULL, 0); + return 1; + } + } else { + if (msw & 1) { + optype = IRET; + pmodeiret(0); + optype = 0; + } else { + uint16_t new_cs; + CPU_SET_OXPC + if (stack32) { + cpu_state.pc = readmemw(ss, ESP); + new_cs = readmemw(ss, ESP + 2); + cpu_state.flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2; + ESP += 6; + } else { + cpu_state.pc = readmemw(ss, SP); + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); + cpu_state.flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2; + SP += 6; + } + loadcs(new_cs); + cycles -= timing_iret_rm; + } + } + flags_extract(); + nmi_enable = 1; + CPU_BLOCK_END(); + + PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return cpu_state.abrt; } -static int opIRET(uint32_t fetchdat) +static int +opIRETD(uint32_t fetchdat) { - int cycles_old = cycles; UN_USED(cycles_old); + int cycles_old = cycles; + UN_USED(cycles_old); - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) - { - if (cr4 & CR4_VME) - { - uint16_t new_pc, new_cs, new_flags; - - new_pc = readmemw(ss, SP); - new_cs = readmemw(ss, ((SP + 2) & 0xffff)); - new_flags = readmemw(ss, ((SP + 4) & 0xffff)); - if (cpu_state.abrt) - return 1; - - if ((new_flags & T_FLAG) || ((new_flags & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) - { - x86gpf(NULL, 0); - return 1; - } - SP += 6; - if (new_flags & I_FLAG) - cpu_state.eflags |= VIF_FLAG; - else - cpu_state.eflags &= ~VIF_FLAG; - cpu_state.flags = (cpu_state.flags & 0x3300) | (new_flags & 0x4cd5) | 2; - loadcs(new_cs); - cpu_state.pc = new_pc; - - cycles -= timing_iret_rm; - } - else - { - x86gpf_expected(NULL,0); - return 1; - } + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf_expected(NULL, 0); + return 1; + } + if (msw & 1) { + optype = IRET; + pmodeiret(1); + optype = 0; + } else { + uint16_t new_cs; + CPU_SET_OXPC + if (stack32) { + cpu_state.pc = readmeml(ss, ESP); + new_cs = readmemw(ss, ESP + 4); + cpu_state.flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2; + cpu_state.eflags = readmemw(ss, ESP + 10); + ESP += 12; + } else { + cpu_state.pc = readmeml(ss, SP); + new_cs = readmemw(ss, ((SP + 4) & 0xffff)); + cpu_state.flags = (readmemw(ss, (SP + 8) & 0xffff) & 0xffd5) | 2; + cpu_state.eflags = readmemw(ss, (SP + 10) & 0xffff); + SP += 12; } - else - { - if (msw&1) - { - optype = IRET; - pmodeiret(0); - optype = 0; - } - else - { - uint16_t new_cs; - CPU_SET_OXPC - if (stack32) - { - cpu_state.pc = readmemw(ss, ESP); - new_cs = readmemw(ss, ESP + 2); - cpu_state.flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2; - ESP += 6; - } - else - { - cpu_state.pc = readmemw(ss, SP); - new_cs = readmemw(ss, ((SP + 2) & 0xffff)); - cpu_state.flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2; - SP += 6; - } - loadcs(new_cs); - cycles -= timing_iret_rm; - } - } - flags_extract(); - nmi_enable = 1; - CPU_BLOCK_END(); + loadcs(new_cs); + cycles -= timing_iret_rm; + } + flags_extract(); + nmi_enable = 1; + CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 1, -1, 2,0,0,0, 0); - PREFETCH_FLUSH(); - return cpu_state.abrt; -} - -static int opIRETD(uint32_t fetchdat) -{ - int cycles_old = cycles; UN_USED(cycles_old); - - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf_expected(NULL,0); - return 1; - } - if (msw & 1) - { - optype = IRET; - pmodeiret(1); - optype = 0; - } - else - { - uint16_t new_cs; - CPU_SET_OXPC - if (stack32) - { - cpu_state.pc = readmeml(ss, ESP); - new_cs = readmemw(ss, ESP + 4); - cpu_state.flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2; - cpu_state.eflags = readmemw(ss, ESP + 10); - ESP += 12; - } - else - { - cpu_state.pc = readmeml(ss, SP); - new_cs = readmemw(ss, ((SP + 4) & 0xffff)); - cpu_state.flags = (readmemw(ss,(SP + 8) & 0xffff) & 0xffd5) | 2; - cpu_state.eflags = readmemw(ss, (SP + 10) & 0xffff); - SP += 12; - } - loadcs(new_cs); - cycles -= timing_iret_rm; - } - flags_extract(); - nmi_enable = 1; - CPU_BLOCK_END(); - - PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,2,0,0, 1); - PREFETCH_FLUSH(); - return cpu_state.abrt; + PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1); + PREFETCH_FLUSH(); + return cpu_state.abrt; } diff --git a/src/cpu/x86_ops_set.h b/src/cpu/x86_ops_set.h index f6fd50e69..4d2a98bcb 100644 --- a/src/cpu/x86_ops_set.h +++ b/src/cpu/x86_ops_set.h @@ -1,23 +1,23 @@ -#define opSET(condition) \ - static int opSET ## condition ## _a16(uint32_t fetchdat) \ - { \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - seteab((cond_ ## condition) ? 1 : 0); \ - CLOCK_CYCLES(4); \ - return cpu_state.abrt; \ - } \ - \ - static int opSET ## condition ## _a32(uint32_t fetchdat) \ - { \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - seteab((cond_ ## condition) ? 1 : 0); \ - CLOCK_CYCLES(4); \ - return cpu_state.abrt; \ - } +#define opSET(condition) \ + static int opSET##condition##_a16(uint32_t fetchdat) \ + { \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + seteab((cond_##condition) ? 1 : 0); \ + CLOCK_CYCLES(4); \ + return cpu_state.abrt; \ + } \ + \ + static int opSET##condition##_a32(uint32_t fetchdat) \ + { \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + seteab((cond_##condition) ? 1 : 0); \ + CLOCK_CYCLES(4); \ + return cpu_state.abrt; \ + } opSET(O) opSET(NO) diff --git a/src/cpu/x86_ops_shift.h b/src/cpu/x86_ops_shift.h index 5d03cb9a9..bba8e24f7 100644 --- a/src/cpu/x86_ops_shift.h +++ b/src/cpu/x86_ops_shift.h @@ -1,850 +1,1052 @@ #ifdef USE_NEW_DYNAREC -#define OP_SHIFT_b(c, ea32) \ - { \ - uint8_t temp_orig = temp; \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL b, c*/ \ - temp = (temp << (c & 7)) | (temp >> (8-(c & 7))); \ - seteab(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROL8, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x08: /*ROR b,CL*/ \ - temp = (temp >> (c & 7)) | (temp << (8-(c & 7))); \ - seteab(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROR8, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x10: /*RCL b,CL*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x80; \ - temp = (temp << 1) | tempc; \ - c--; \ - } \ - seteab(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x18: /*RCR b,CL*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x80 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - } \ - seteab(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x20: case 0x30: /*SHL b,CL*/ \ - seteab(temp << c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHL8, temp_orig, c, (temp << c) & 0xff); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x28: /*SHR b,CL*/ \ - seteab(temp >> c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHR8, temp_orig, c, temp >> c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x38: /*SAR b,CL*/ \ - temp = (int8_t)temp >> c; \ - seteab(temp); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SAR8, temp_orig, c, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - } \ +# define OP_SHIFT_b(c, ea32) \ + { \ + uint8_t temp_orig = temp; \ + if (!c) \ + return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) { \ + case 0x00: /*ROL b, c*/ \ + temp = (temp << (c & 7)) | (temp >> (8 - (c & 7))); \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_rotate(FLAGS_ROL8, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x08: /*ROR b,CL*/ \ + temp = (temp >> (c & 7)) | (temp << (8 - (c & 7))); \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_rotate(FLAGS_ROR8, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x10: /*RCL b,CL*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 1 : 0; \ + temp2 = temp & 0x80; \ + temp = (temp << 1) | tempc; \ + c--; \ + } \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x18: /*RCR b,CL*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 0x80 : 0; \ + temp2 = temp & 1; \ + temp = (temp >> 1) | tempc; \ + c--; \ + } \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x20: \ + case 0x30: /*SHL b,CL*/ \ + seteab(temp << c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHL8, temp_orig, c, (temp << c) & 0xff); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x28: /*SHR b,CL*/ \ + seteab(temp >> c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHR8, temp_orig, c, temp >> c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x38: /*SAR b,CL*/ \ + temp = (int8_t) temp >> c; \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SAR8, temp_orig, c, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + } \ } -#define OP_SHIFT_w(c, ea32) \ - { \ - uint16_t temp_orig = temp; \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL w, c*/ \ - temp = (temp << (c & 15)) | (temp >> (16-(c & 15))); \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROL16, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x08: /*ROR w,CL*/ \ - temp = (temp >> (c & 15)) | (temp << (16-(c & 15))); \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROR16, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x10: /*RCL w, c*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x8000; \ - temp = (temp << 1) | tempc; \ - c--; \ - } \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 15)) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x18: /*RCR w, c*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x8000 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - } \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x20: case 0x30: /*SHL w, c*/ \ - seteaw(temp << c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHL16, temp_orig, c, (temp << c) & 0xffff); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x28: /*SHR w, c*/ \ - seteaw(temp >> c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHR16, temp_orig, c, temp >> c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x38: /*SAR w, c*/ \ - temp = (int16_t)temp >> c; \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SAR16, temp_orig, c, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - } \ +# define OP_SHIFT_w(c, ea32) \ + { \ + uint16_t temp_orig = temp; \ + if (!c) \ + return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) { \ + case 0x00: /*ROL w, c*/ \ + temp = (temp << (c & 15)) | (temp >> (16 - (c & 15))); \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_rotate(FLAGS_ROL16, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x08: /*ROR w,CL*/ \ + temp = (temp >> (c & 15)) | (temp << (16 - (c & 15))); \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_rotate(FLAGS_ROR16, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x10: /*RCL w, c*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 1 : 0; \ + temp2 = temp & 0x8000; \ + temp = (temp << 1) | tempc; \ + c--; \ + } \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 15)) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x18: /*RCR w, c*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 0x8000 : 0; \ + temp2 = temp & 1; \ + temp = (temp >> 1) | tempc; \ + c--; \ + } \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x4000) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x20: \ + case 0x30: /*SHL w, c*/ \ + seteaw(temp << c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHL16, temp_orig, c, (temp << c) & 0xffff); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x28: /*SHR w, c*/ \ + seteaw(temp >> c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHR16, temp_orig, c, temp >> c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x38: /*SAR w, c*/ \ + temp = (int16_t) temp >> c; \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SAR16, temp_orig, c, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + } \ } -#define OP_SHIFT_l(c, ea32) \ - { \ - uint32_t temp_orig = temp; \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL l, c*/ \ - temp = (temp << c) | (temp >> (32-c)); \ - seteal(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROL32, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x08: /*ROR l,CL*/ \ - temp = (temp >> c) | (temp << (32-c)); \ - seteal(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROR32, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x10: /*RCL l, c*/ \ - temp2 = CF_SET(); \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x80000000; \ - temp = (temp << 1) | tempc; \ - c--; \ - } \ - seteal(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 31)) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x18: /*RCR l, c*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x80000000 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - } \ - seteal(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x20: case 0x30: /*SHL l, c*/ \ - seteal(temp << c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHL32, temp_orig, c, temp << c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x28: /*SHR l, c*/ \ - seteal(temp >> c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHR32, temp_orig, c, temp >> c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x38: /*SAR l, c*/ \ - temp = (int32_t)temp >> c; \ - seteal(temp); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SAR32, temp_orig, c, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - } \ +# define OP_SHIFT_l(c, ea32) \ + { \ + uint32_t temp_orig = temp; \ + if (!c) \ + return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) { \ + case 0x00: /*ROL l, c*/ \ + temp = (temp << c) | (temp >> (32 - c)); \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_rotate(FLAGS_ROL32, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x08: /*ROR l,CL*/ \ + temp = (temp >> c) | (temp << (32 - c)); \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_rotate(FLAGS_ROR32, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x10: /*RCL l, c*/ \ + temp2 = CF_SET(); \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 1 : 0; \ + temp2 = temp & 0x80000000; \ + temp = (temp << 1) | tempc; \ + c--; \ + } \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 31)) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + case 0x18: /*RCR l, c*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 0x80000000 : 0; \ + temp2 = temp & 1; \ + temp = (temp >> 1) | tempc; \ + c--; \ + } \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40000000) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + case 0x20: \ + case 0x30: /*SHL l, c*/ \ + seteal(temp << c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHL32, temp_orig, c, temp << c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + case 0x28: /*SHR l, c*/ \ + seteal(temp >> c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHR32, temp_orig, c, temp >> c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + case 0x38: /*SAR l, c*/ \ + temp = (int32_t) temp >> c; \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SAR32, temp_orig, c, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + } \ } #else -#define OP_SHIFT_b(c, ea32) \ - { \ - uint8_t temp_orig = temp; \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL b, c*/ \ - temp = (temp << (c & 7)) | (temp >> (8-(c & 7))); \ - seteab(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp & 1) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 7)) & 1) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x08: /*ROR b,CL*/ \ - temp = (temp >> (c & 7)) | (temp << (8-(c & 7))); \ - seteab(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp & 0x80) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x10: /*RCL b,CL*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x80; \ - temp = (temp << 1) | tempc; \ - c--; \ - } \ - seteab(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x18: /*RCR b,CL*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x80 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - } \ - seteab(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x20: case 0x30: /*SHL b,CL*/ \ - seteab(temp << c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHL8, temp_orig, c, (temp << c) & 0xff); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x28: /*SHR b,CL*/ \ - seteab(temp >> c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHR8, temp_orig, c, temp >> c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x38: /*SAR b,CL*/ \ - temp = (int8_t)temp >> c; \ - seteab(temp); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SAR8, temp_orig, c, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - } \ +# define OP_SHIFT_b(c, ea32) \ + { \ + uint8_t temp_orig = temp; \ + if (!c) \ + return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) { \ + case 0x00: /*ROL b, c*/ \ + temp = (temp << (c & 7)) | (temp >> (8 - (c & 7))); \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 1) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 7)) & 1) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x08: /*ROR b,CL*/ \ + temp = (temp >> (c & 7)) | (temp << (8 - (c & 7))); \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 0x80) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x10: /*RCL b,CL*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 1 : 0; \ + temp2 = temp & 0x80; \ + temp = (temp << 1) | tempc; \ + c--; \ + } \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x18: /*RCR b,CL*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 0x80 : 0; \ + temp2 = temp & 1; \ + temp = (temp >> 1) | tempc; \ + c--; \ + } \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x20: \ + case 0x30: /*SHL b,CL*/ \ + seteab(temp << c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHL8, temp_orig, c, (temp << c) & 0xff); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x28: /*SHR b,CL*/ \ + seteab(temp >> c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHR8, temp_orig, c, temp >> c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x38: /*SAR b,CL*/ \ + temp = (int8_t) temp >> c; \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SAR8, temp_orig, c, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + } \ } -#define OP_SHIFT_w(c, ea32) \ - { \ - uint16_t temp_orig = temp; \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL w, c*/ \ - temp = (temp << (c & 15)) | (temp >> (16-(c & 15))); \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp & 1) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 15)) & 1) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x08: /*ROR w,CL*/ \ - temp = (temp >> (c & 15)) | (temp << (16-(c & 15))); \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp & 0x8000) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x10: /*RCL w, c*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x8000; \ - temp = (temp << 1) | tempc; \ - c--; \ - } \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 15)) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x18: /*RCR w, c*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x8000 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - } \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x20: case 0x30: /*SHL w, c*/ \ - seteaw(temp << c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHL16, temp_orig, c, (temp << c) & 0xffff); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x28: /*SHR w, c*/ \ - seteaw(temp >> c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHR16, temp_orig, c, temp >> c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x38: /*SAR w, c*/ \ - temp = (int16_t)temp >> c; \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SAR16, temp_orig, c, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - } \ +# define OP_SHIFT_w(c, ea32) \ + { \ + uint16_t temp_orig = temp; \ + if (!c) \ + return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) { \ + case 0x00: /*ROL w, c*/ \ + temp = (temp << (c & 15)) | (temp >> (16 - (c & 15))); \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 1) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 15)) & 1) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x08: /*ROR w,CL*/ \ + temp = (temp >> (c & 15)) | (temp << (16 - (c & 15))); \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 0x8000) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x4000) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x10: /*RCL w, c*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 1 : 0; \ + temp2 = temp & 0x8000; \ + temp = (temp << 1) | tempc; \ + c--; \ + } \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 15)) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x18: /*RCR w, c*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 0x8000 : 0; \ + temp2 = temp & 1; \ + temp = (temp >> 1) | tempc; \ + c--; \ + } \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x4000) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x20: \ + case 0x30: /*SHL w, c*/ \ + seteaw(temp << c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHL16, temp_orig, c, (temp << c) & 0xffff); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x28: /*SHR w, c*/ \ + seteaw(temp >> c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHR16, temp_orig, c, temp >> c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x38: /*SAR w, c*/ \ + temp = (int16_t) temp >> c; \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SAR16, temp_orig, c, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + } \ } -#define OP_SHIFT_l(c, ea32) \ - { \ - uint32_t temp_orig = temp; \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL l, c*/ \ - temp = (temp << c) | (temp >> (32-c)); \ - seteal(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp & 1) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 31)) & 1) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x08: /*ROR l,CL*/ \ - temp = (temp >> c) | (temp << (32-c)); \ - seteal(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp & 0x80000000) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x10: /*RCL l, c*/ \ - temp2 = CF_SET(); \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x80000000; \ - temp = (temp << 1) | tempc; \ - c--; \ - } \ - seteal(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 31)) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x18: /*RCR l, c*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x80000000 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - } \ - seteal(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x20: case 0x30: /*SHL l, c*/ \ - seteal(temp << c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHL32, temp_orig, c, temp << c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x28: /*SHR l, c*/ \ - seteal(temp >> c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHR32, temp_orig, c, temp >> c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x38: /*SAR l, c*/ \ - temp = (int32_t)temp >> c; \ - seteal(temp); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SAR32, temp_orig, c, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - } \ +# define OP_SHIFT_l(c, ea32) \ + { \ + uint32_t temp_orig = temp; \ + if (!c) \ + return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) { \ + case 0x00: /*ROL l, c*/ \ + temp = (temp << c) | (temp >> (32 - c)); \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 1) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 31)) & 1) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x08: /*ROR l,CL*/ \ + temp = (temp >> c) | (temp << (32 - c)); \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 0x80000000) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40000000) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x10: /*RCL l, c*/ \ + temp2 = CF_SET(); \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 1 : 0; \ + temp2 = temp & 0x80000000; \ + temp = (temp << 1) | tempc; \ + c--; \ + } \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 31)) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + case 0x18: /*RCR l, c*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 0x80000000 : 0; \ + temp2 = temp & 1; \ + temp = (temp >> 1) | tempc; \ + c--; \ + } \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40000000) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + case 0x20: \ + case 0x30: /*SHL l, c*/ \ + seteal(temp << c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHL32, temp_orig, c, temp << c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + case 0x28: /*SHR l, c*/ \ + seteal(temp >> c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHR32, temp_orig, c, temp >> c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + case 0x38: /*SAR l, c*/ \ + temp = (int32_t) temp >> c; \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SAR32, temp_orig, c, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + } \ } #endif -static int opC0_a16(uint32_t fetchdat) +static int +opC0_a16(uint32_t fetchdat) { - int c; - int tempc; - uint8_t temp, temp2 = 0; + int c; + int tempc; + uint8_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = readmemb(cs, cpu_state.pc) & 31; + cpu_state.pc++; + PREFETCH_PREFIX(); + temp = geteab(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_b(c, 0); + return 0; } -static int opC0_a32(uint32_t fetchdat) +static int +opC0_a32(uint32_t fetchdat) { - int c; - int tempc; - uint8_t temp, temp2 = 0; + int c; + int tempc; + uint8_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = readmemb(cs, cpu_state.pc) & 31; + cpu_state.pc++; + PREFETCH_PREFIX(); + temp = geteab(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_b(c, 1); + return 0; } -static int opC1_w_a16(uint32_t fetchdat) +static int +opC1_w_a16(uint32_t fetchdat) { - int c; - int tempc; - uint16_t temp, temp2 = 0; + int c; + int tempc; + uint16_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = readmemb(cs, cpu_state.pc) & 31; + cpu_state.pc++; + PREFETCH_PREFIX(); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_w(c, 0); + return 0; } -static int opC1_w_a32(uint32_t fetchdat) +static int +opC1_w_a32(uint32_t fetchdat) { - int c; - int tempc; - uint16_t temp, temp2 = 0; + int c; + int tempc; + uint16_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = readmemb(cs, cpu_state.pc) & 31; + cpu_state.pc++; + PREFETCH_PREFIX(); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_w(c, 1); + return 0; } -static int opC1_l_a16(uint32_t fetchdat) +static int +opC1_l_a16(uint32_t fetchdat) { - int c; - int tempc; - uint32_t temp, temp2 = 0; + int c; + int tempc; + uint32_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = readmemb(cs, cpu_state.pc) & 31; + cpu_state.pc++; + PREFETCH_PREFIX(); + temp = geteal(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_l(c, 0); + return 0; } -static int opC1_l_a32(uint32_t fetchdat) +static int +opC1_l_a32(uint32_t fetchdat) { - int c; - int tempc; - uint32_t temp, temp2 = 0; + int c; + int tempc; + uint32_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = readmemb(cs, cpu_state.pc) & 31; + cpu_state.pc++; + PREFETCH_PREFIX(); + temp = geteal(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_l(c, 1); + return 0; } -static int opD0_a16(uint32_t fetchdat) +static int +opD0_a16(uint32_t fetchdat) { - int c = 1; - int tempc; - uint8_t temp, temp2 = 0; + int c = 1; + int tempc; + uint8_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_b(c, 0); + return 0; } -static int opD0_a32(uint32_t fetchdat) +static int +opD0_a32(uint32_t fetchdat) { - int c = 1; - int tempc; - uint8_t temp, temp2 = 0; + int c = 1; + int tempc; + uint8_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_b(c, 1); + return 0; } -static int opD1_w_a16(uint32_t fetchdat) +static int +opD1_w_a16(uint32_t fetchdat) { - int c = 1; - int tempc; - uint16_t temp, temp2 = 0; + int c = 1; + int tempc; + uint16_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_w(c, 0); + return 0; } -static int opD1_w_a32(uint32_t fetchdat) +static int +opD1_w_a32(uint32_t fetchdat) { - int c = 1; - int tempc; - uint16_t temp, temp2 = 0; + int c = 1; + int tempc; + uint16_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_w(c, 1); + return 0; } -static int opD1_l_a16(uint32_t fetchdat) +static int +opD1_l_a16(uint32_t fetchdat) { - int c = 1; - int tempc; - uint32_t temp, temp2 = 0; + int c = 1; + int tempc; + uint32_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_l(c, 0); + return 0; } -static int opD1_l_a32(uint32_t fetchdat) +static int +opD1_l_a32(uint32_t fetchdat) { - int c = 1; - int tempc; - uint32_t temp, temp2 = 0; + int c = 1; + int tempc; + uint32_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_l(c, 1); + return 0; } -static int opD2_a16(uint32_t fetchdat) +static int +opD2_a16(uint32_t fetchdat) { - int c; - int tempc; - uint8_t temp, temp2 = 0; + int c; + int tempc; + uint8_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = CL & 31; + temp = geteab(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_b(c, 0); + return 0; } -static int opD2_a32(uint32_t fetchdat) +static int +opD2_a32(uint32_t fetchdat) { - int c; - int tempc; - uint8_t temp, temp2 = 0; + int c; + int tempc; + uint8_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = CL & 31; + temp = geteab(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_b(c, 1); + return 0; } -static int opD3_w_a16(uint32_t fetchdat) +static int +opD3_w_a16(uint32_t fetchdat) { - int c; - int tempc; - uint16_t temp, temp2 = 0; + int c; + int tempc; + uint16_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = CL & 31; + temp = geteaw(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_w(c, 0); + return 0; } -static int opD3_w_a32(uint32_t fetchdat) +static int +opD3_w_a32(uint32_t fetchdat) { - int c; - int tempc; - uint16_t temp, temp2 = 0; + int c; + int tempc; + uint16_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = CL & 31; + temp = geteaw(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_w(c, 1); + return 0; } -static int opD3_l_a16(uint32_t fetchdat) +static int +opD3_l_a16(uint32_t fetchdat) { - int c; - int tempc; - uint32_t temp, temp2 = 0; + int c; + int tempc; + uint32_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = CL & 31; + temp = geteal(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_l(c, 0); + return 0; } -static int opD3_l_a32(uint32_t fetchdat) +static int +opD3_l_a32(uint32_t fetchdat) { - int c; - int tempc; - uint32_t temp, temp2 = 0; + int c; + int tempc; + uint32_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = CL & 31; + temp = geteal(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_l(c, 1); + return 0; } - -#define SHLD_w() \ - if (count) \ - { \ - int tempc; \ - uint32_t templ; \ - uint16_t tempw = geteaw(); if (cpu_state.abrt) return 1; \ - tempc = ((tempw << (count - 1)) & (1 << 15)) ? 1 : 0; \ - templ = (tempw << 16) | cpu_state.regs[cpu_reg].w; \ - if (count <= 16) tempw = templ >> (16 - count); \ - else tempw = (templ << count) >> 16; \ - seteaw(tempw); if (cpu_state.abrt) return 1; \ - setznp16(tempw); \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - } +#define SHLD_w() \ + if (count) { \ + int tempc; \ + uint32_t templ; \ + uint16_t tempw = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + tempc = ((tempw << (count - 1)) & (1 << 15)) ? 1 : 0; \ + templ = (tempw << 16) | cpu_state.regs[cpu_reg].w; \ + if (count <= 16) \ + tempw = templ >> (16 - count); \ + else \ + tempw = (templ << count) >> 16; \ + seteaw(tempw); \ + if (cpu_state.abrt) \ + return 1; \ + setznp16(tempw); \ + flags_rebuild(); \ + if (tempc) \ + cpu_state.flags |= C_FLAG; \ + } #define SHLD_l() \ - if (count) \ - { \ - int tempc; \ - uint32_t templ = geteal(); if (cpu_state.abrt) return 1; \ - tempc = ((templ << (count - 1)) & (1 << 31)) ? 1 : 0; \ - templ = (templ << count) | (cpu_state.regs[cpu_reg].l >> (32 - count)); \ - seteal(templ); if (cpu_state.abrt) return 1; \ - setznp32(templ); \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - } + if (count) { \ + int tempc; \ + uint32_t templ = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + tempc = ((templ << (count - 1)) & (1 << 31)) ? 1 : 0; \ + templ = (templ << count) | (cpu_state.regs[cpu_reg].l >> (32 - count)); \ + seteal(templ); \ + if (cpu_state.abrt) \ + return 1; \ + setznp32(templ); \ + flags_rebuild(); \ + if (tempc) \ + cpu_state.flags |= C_FLAG; \ + } - -#define SHRD_w() \ - if (count) \ - { \ - int tempc; \ - uint32_t templ; \ - uint16_t tempw = geteaw(); if (cpu_state.abrt) return 1; \ - tempc = (tempw >> (count - 1)) & 1; \ - templ = tempw | (cpu_state.regs[cpu_reg].w << 16); \ - tempw = templ >> count; \ - seteaw(tempw); if (cpu_state.abrt) return 1; \ - setznp16(tempw); \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - } +#define SHRD_w() \ + if (count) { \ + int tempc; \ + uint32_t templ; \ + uint16_t tempw = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + tempc = (tempw >> (count - 1)) & 1; \ + templ = tempw | (cpu_state.regs[cpu_reg].w << 16); \ + tempw = templ >> count; \ + seteaw(tempw); \ + if (cpu_state.abrt) \ + return 1; \ + setznp16(tempw); \ + flags_rebuild(); \ + if (tempc) \ + cpu_state.flags |= C_FLAG; \ + } #define SHRD_l() \ - if (count) \ - { \ - int tempc; \ - uint32_t templ = geteal(); if (cpu_state.abrt) return 1; \ - tempc = (templ >> (count - 1)) & 1; \ - templ = (templ >> count) | (cpu_state.regs[cpu_reg].l << (32 - count)); \ - seteal(templ); if (cpu_state.abrt) return 1; \ - setznp32(templ); \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - } + if (count) { \ + int tempc; \ + uint32_t templ = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + tempc = (templ >> (count - 1)) & 1; \ + templ = (templ >> count) | (cpu_state.regs[cpu_reg].l << (32 - count)); \ + seteal(templ); \ + if (cpu_state.abrt) \ + return 1; \ + setznp32(templ); \ + flags_rebuild(); \ + if (tempc) \ + cpu_state.flags |= C_FLAG; \ + } -#define opSHxD(operation) \ - static int op ## operation ## _i_a16(uint32_t fetchdat) \ - { \ - int count; \ - \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - count = getbyte() & 31; \ - operation(); \ - \ - CLOCK_CYCLES(3); \ - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); \ - return 0; \ - } \ - static int op ## operation ## _CL_a16(uint32_t fetchdat) \ - { \ - int count; \ - \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - count = CL & 31; \ - operation(); \ - \ - CLOCK_CYCLES(3); \ - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); \ - return 0; \ - } \ - static int op ## operation ## _i_a32(uint32_t fetchdat) \ - { \ - int count; \ - \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - count = getbyte() & 31; \ - operation(); \ - \ - CLOCK_CYCLES(3); \ - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); \ - return 0; \ - } \ - static int op ## operation ## _CL_a32(uint32_t fetchdat) \ - { \ - int count; \ - \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - count = CL & 31; \ - operation(); \ - \ - CLOCK_CYCLES(3); \ - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); \ - return 0; \ - } +#define opSHxD(operation) \ + static int op##operation##_i_a16(uint32_t fetchdat) \ + { \ + int count; \ + \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + count = getbyte() & 31; \ + operation(); \ + \ + CLOCK_CYCLES(3); \ + PREFETCH_RUN(3, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); \ + return 0; \ + } \ + static int op##operation##_CL_a16(uint32_t fetchdat) \ + { \ + int count; \ + \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + count = CL & 31; \ + operation(); \ + \ + CLOCK_CYCLES(3); \ + PREFETCH_RUN(3, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); \ + return 0; \ + } \ + static int op##operation##_i_a32(uint32_t fetchdat) \ + { \ + int count; \ + \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + count = getbyte() & 31; \ + operation(); \ + \ + CLOCK_CYCLES(3); \ + PREFETCH_RUN(3, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); \ + return 0; \ + } \ + static int op##operation##_CL_a32(uint32_t fetchdat) \ + { \ + int count; \ + \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + count = CL & 31; \ + operation(); \ + \ + CLOCK_CYCLES(3); \ + PREFETCH_RUN(3, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); \ + return 0; \ + } opSHxD(SHLD_w) opSHxD(SHLD_l) diff --git a/src/cpu/x86_ops_stack.h b/src/cpu/x86_ops_stack.h index 58f24c6f9..374dad9f4 100644 --- a/src/cpu/x86_ops_stack.h +++ b/src/cpu/x86_ops_stack.h @@ -1,38 +1,38 @@ -#define PUSH_W_OP(reg) \ - static int opPUSH_ ## reg (uint32_t fetchdat) \ - { \ - PUSH_W(reg); \ - CLOCK_CYCLES((is486) ? 1 : 2); \ - PREFETCH_RUN(2, 1, -1, 0,0,1,0, 0); \ - return cpu_state.abrt; \ - } +#define PUSH_W_OP(reg) \ + static int opPUSH_##reg(uint32_t fetchdat) \ + { \ + PUSH_W(reg); \ + CLOCK_CYCLES((is486) ? 1 : 2); \ + PREFETCH_RUN(2, 1, -1, 0, 0, 1, 0, 0); \ + return cpu_state.abrt; \ + } -#define PUSH_L_OP(reg) \ - static int opPUSH_ ## reg (uint32_t fetchdat) \ - { \ - PUSH_L(reg); \ - CLOCK_CYCLES((is486) ? 1 : 2); \ - PREFETCH_RUN(2, 1, -1, 0,0,0,1, 0); \ - return cpu_state.abrt; \ - } +#define PUSH_L_OP(reg) \ + static int opPUSH_##reg(uint32_t fetchdat) \ + { \ + PUSH_L(reg); \ + CLOCK_CYCLES((is486) ? 1 : 2); \ + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 1, 0); \ + return cpu_state.abrt; \ + } -#define POP_W_OP(reg) \ - static int opPOP_ ## reg (uint32_t fetchdat) \ - { \ - reg = POP_W(); \ - CLOCK_CYCLES((is486) ? 1 : 4); \ - PREFETCH_RUN(4, 1, -1, 1,0,0,0, 0); \ - return cpu_state.abrt; \ - } +#define POP_W_OP(reg) \ + static int opPOP_##reg(uint32_t fetchdat) \ + { \ + reg = POP_W(); \ + CLOCK_CYCLES((is486) ? 1 : 4); \ + PREFETCH_RUN(4, 1, -1, 1, 0, 0, 0, 0); \ + return cpu_state.abrt; \ + } -#define POP_L_OP(reg) \ - static int opPOP_ ## reg (uint32_t fetchdat) \ - { \ - reg = POP_L(); \ - CLOCK_CYCLES((is486) ? 1 : 4); \ - PREFETCH_RUN(4, 1, -1, 0,1,0,0, 0); \ - return cpu_state.abrt; \ - } +#define POP_L_OP(reg) \ + static int opPOP_##reg(uint32_t fetchdat) \ + { \ + reg = POP_L(); \ + CLOCK_CYCLES((is486) ? 1 : 4); \ + PREFETCH_RUN(4, 1, -1, 0, 1, 0, 0, 0); \ + return cpu_state.abrt; \ + } PUSH_W_OP(AX) PUSH_W_OP(BX) @@ -70,100 +70,125 @@ POP_L_OP(EDI) POP_L_OP(EBP) POP_L_OP(ESP) - -static int opPUSHA_w(uint32_t fetchdat) +static int +opPUSHA_w(uint32_t fetchdat) { - if (stack32) - { - writememw(ss, ESP - 2, AX); - writememw(ss, ESP - 4, CX); - writememw(ss, ESP - 6, DX); - writememw(ss, ESP - 8, BX); - writememw(ss, ESP - 10, SP); - writememw(ss, ESP - 12, BP); - writememw(ss, ESP - 14, SI); - writememw(ss, ESP - 16, DI); - if (!cpu_state.abrt) ESP -= 16; - } - else - { - writememw(ss, ((SP - 2) & 0xFFFF), AX); - writememw(ss, ((SP - 4) & 0xFFFF), CX); - writememw(ss, ((SP - 6) & 0xFFFF), DX); - writememw(ss, ((SP - 8) & 0xFFFF), BX); - writememw(ss, ((SP - 10) & 0xFFFF), SP); - writememw(ss, ((SP - 12) & 0xFFFF), BP); - writememw(ss, ((SP - 14) & 0xFFFF), SI); - writememw(ss, ((SP - 16) & 0xFFFF), DI); - if (!cpu_state.abrt) SP -= 16; - } - CLOCK_CYCLES((is486) ? 11 : 18); - PREFETCH_RUN(18, 1, -1, 0,0,8,0, 0); - return cpu_state.abrt; + if (stack32) { + writememw(ss, ESP - 2, AX); + writememw(ss, ESP - 4, CX); + writememw(ss, ESP - 6, DX); + writememw(ss, ESP - 8, BX); + writememw(ss, ESP - 10, SP); + writememw(ss, ESP - 12, BP); + writememw(ss, ESP - 14, SI); + writememw(ss, ESP - 16, DI); + if (!cpu_state.abrt) + ESP -= 16; + } else { + writememw(ss, ((SP - 2) & 0xFFFF), AX); + writememw(ss, ((SP - 4) & 0xFFFF), CX); + writememw(ss, ((SP - 6) & 0xFFFF), DX); + writememw(ss, ((SP - 8) & 0xFFFF), BX); + writememw(ss, ((SP - 10) & 0xFFFF), SP); + writememw(ss, ((SP - 12) & 0xFFFF), BP); + writememw(ss, ((SP - 14) & 0xFFFF), SI); + writememw(ss, ((SP - 16) & 0xFFFF), DI); + if (!cpu_state.abrt) + SP -= 16; + } + CLOCK_CYCLES((is486) ? 11 : 18); + PREFETCH_RUN(18, 1, -1, 0, 0, 8, 0, 0); + return cpu_state.abrt; } -static int opPUSHA_l(uint32_t fetchdat) +static int +opPUSHA_l(uint32_t fetchdat) { - if (stack32) - { - writememl(ss, ESP - 4, EAX); - writememl(ss, ESP - 8, ECX); - writememl(ss, ESP - 12, EDX); - writememl(ss, ESP - 16, EBX); - writememl(ss, ESP - 20, ESP); - writememl(ss, ESP - 24, EBP); - writememl(ss, ESP - 28, ESI); - writememl(ss, ESP - 32, EDI); - if (!cpu_state.abrt) ESP -= 32; - } - else - { - writememl(ss, ((SP - 4) & 0xFFFF), EAX); - writememl(ss, ((SP - 8) & 0xFFFF), ECX); - writememl(ss, ((SP - 12) & 0xFFFF), EDX); - writememl(ss, ((SP - 16) & 0xFFFF), EBX); - writememl(ss, ((SP - 20) & 0xFFFF), ESP); - writememl(ss, ((SP - 24) & 0xFFFF), EBP); - writememl(ss, ((SP - 28) & 0xFFFF), ESI); - writememl(ss, ((SP - 32) & 0xFFFF), EDI); - if (!cpu_state.abrt) SP -= 32; - } - CLOCK_CYCLES((is486) ? 11 : 18); - PREFETCH_RUN(18, 1, -1, 0,0,0,8, 0); - return cpu_state.abrt; + if (stack32) { + writememl(ss, ESP - 4, EAX); + writememl(ss, ESP - 8, ECX); + writememl(ss, ESP - 12, EDX); + writememl(ss, ESP - 16, EBX); + writememl(ss, ESP - 20, ESP); + writememl(ss, ESP - 24, EBP); + writememl(ss, ESP - 28, ESI); + writememl(ss, ESP - 32, EDI); + if (!cpu_state.abrt) + ESP -= 32; + } else { + writememl(ss, ((SP - 4) & 0xFFFF), EAX); + writememl(ss, ((SP - 8) & 0xFFFF), ECX); + writememl(ss, ((SP - 12) & 0xFFFF), EDX); + writememl(ss, ((SP - 16) & 0xFFFF), EBX); + writememl(ss, ((SP - 20) & 0xFFFF), ESP); + writememl(ss, ((SP - 24) & 0xFFFF), EBP); + writememl(ss, ((SP - 28) & 0xFFFF), ESI); + writememl(ss, ((SP - 32) & 0xFFFF), EDI); + if (!cpu_state.abrt) + SP -= 32; + } + CLOCK_CYCLES((is486) ? 11 : 18); + PREFETCH_RUN(18, 1, -1, 0, 0, 0, 8, 0); + return cpu_state.abrt; } -static int opPOPA_w(uint32_t fetchdat) +static int +opPOPA_w(uint32_t fetchdat) { - if (stack32) - { - DI = readmemw(ss, ESP); if (cpu_state.abrt) return 1; - SI = readmemw(ss, ESP + 2); if (cpu_state.abrt) return 1; - BP = readmemw(ss, ESP + 4); if (cpu_state.abrt) return 1; - BX = readmemw(ss, ESP + 8); if (cpu_state.abrt) return 1; - DX = readmemw(ss, ESP + 10); if (cpu_state.abrt) return 1; - CX = readmemw(ss, ESP + 12); if (cpu_state.abrt) return 1; - AX = readmemw(ss, ESP + 14); if (cpu_state.abrt) return 1; - ESP += 16; - } - else - { - DI = readmemw(ss, ((SP) & 0xFFFF)); if (cpu_state.abrt) return 1; - SI = readmemw(ss, ((SP + 2) & 0xFFFF)); if (cpu_state.abrt) return 1; - BP = readmemw(ss, ((SP + 4) & 0xFFFF)); if (cpu_state.abrt) return 1; - BX = readmemw(ss, ((SP + 8) & 0xFFFF)); if (cpu_state.abrt) return 1; - DX = readmemw(ss, ((SP + 10) & 0xFFFF)); if (cpu_state.abrt) return 1; - CX = readmemw(ss, ((SP + 12) & 0xFFFF)); if (cpu_state.abrt) return 1; - AX = readmemw(ss, ((SP + 14) & 0xFFFF)); if (cpu_state.abrt) return 1; - SP += 16; - } - CLOCK_CYCLES((is486) ? 9 : 24); - PREFETCH_RUN(24, 1, -1, 7,0,0,0, 0); - return 0; + if (stack32) { + DI = readmemw(ss, ESP); + if (cpu_state.abrt) + return 1; + SI = readmemw(ss, ESP + 2); + if (cpu_state.abrt) + return 1; + BP = readmemw(ss, ESP + 4); + if (cpu_state.abrt) + return 1; + BX = readmemw(ss, ESP + 8); + if (cpu_state.abrt) + return 1; + DX = readmemw(ss, ESP + 10); + if (cpu_state.abrt) + return 1; + CX = readmemw(ss, ESP + 12); + if (cpu_state.abrt) + return 1; + AX = readmemw(ss, ESP + 14); + if (cpu_state.abrt) + return 1; + ESP += 16; + } else { + DI = readmemw(ss, ((SP) &0xFFFF)); + if (cpu_state.abrt) + return 1; + SI = readmemw(ss, ((SP + 2) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + BP = readmemw(ss, ((SP + 4) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + BX = readmemw(ss, ((SP + 8) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + DX = readmemw(ss, ((SP + 10) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + CX = readmemw(ss, ((SP + 12) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + AX = readmemw(ss, ((SP + 14) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + SP += 16; + } + CLOCK_CYCLES((is486) ? 9 : 24); + PREFETCH_RUN(24, 1, -1, 7, 0, 0, 0, 0); + return 0; } -static int opPOPA_l(uint32_t fetchdat) +static int +opPOPA_l(uint32_t fetchdat) { - if (stack32) - { + if (stack32) { EDI = readmeml(ss, ESP); if (cpu_state.abrt) return 1; ESI = readmeml(ss, ESP + 4); if (cpu_state.abrt) return 1; EBP = readmeml(ss, ESP + 8); if (cpu_state.abrt) return 1; @@ -172,9 +197,7 @@ static int opPOPA_l(uint32_t fetchdat) ECX = readmeml(ss, ESP + 24); if (cpu_state.abrt) return 1; EAX = readmeml(ss, ESP + 28); if (cpu_state.abrt) return 1; ESP += 32; - } - else - { + } else { EDI = readmeml(ss, ((SP) & 0xFFFF)); if (cpu_state.abrt) return 1; ESI = readmeml(ss, ((SP + 4) & 0xFFFF)); if (cpu_state.abrt) return 1; EBP = readmeml(ss, ((SP + 8) & 0xFFFF)); if (cpu_state.abrt) return 1; @@ -189,302 +212,389 @@ static int opPOPA_l(uint32_t fetchdat) return 0; } -static int opPUSH_imm_w(uint32_t fetchdat) +static int +opPUSH_imm_w(uint32_t fetchdat) { - uint16_t val = getwordf(); - PUSH_W(val); - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 3, -1, 0,0,1,0, 0); - return cpu_state.abrt; + uint16_t val = getwordf(); + PUSH_W(val); + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 3, -1, 0, 0, 1, 0, 0); + return cpu_state.abrt; } -static int opPUSH_imm_l(uint32_t fetchdat) +static int +opPUSH_imm_l(uint32_t fetchdat) { - uint32_t val = getlong(); if (cpu_state.abrt) return 1; - PUSH_L(val); - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 3, -1, 0,0,0,1, 0); - return cpu_state.abrt; + uint32_t val = getlong(); + if (cpu_state.abrt) + return 1; + PUSH_L(val); + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 3, -1, 0, 0, 0, 1, 0); + return cpu_state.abrt; } -static int opPUSH_imm_bw(uint32_t fetchdat) +static int +opPUSH_imm_bw(uint32_t fetchdat) { - uint16_t tempw = getbytef(); + uint16_t tempw = getbytef(); - if (tempw & 0x80) tempw |= 0xFF00; - PUSH_W(tempw); + if (tempw & 0x80) + tempw |= 0xFF00; + PUSH_W(tempw); - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 2, -1, 0,0,1,0, 0); - return cpu_state.abrt; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 2, -1, 0, 0, 1, 0, 0); + return cpu_state.abrt; } -static int opPUSH_imm_bl(uint32_t fetchdat) +static int +opPUSH_imm_bl(uint32_t fetchdat) { - uint32_t templ = getbytef(); + uint32_t templ = getbytef(); - if (templ & 0x80) templ |= 0xFFFFFF00; - PUSH_L(templ); + if (templ & 0x80) + templ |= 0xFFFFFF00; + PUSH_L(templ); - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 2, -1, 0,0,0,1, 0); - return cpu_state.abrt; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 2, -1, 0, 0, 0, 1, 0); + return cpu_state.abrt; } -static int opPOPW_a16(uint32_t fetchdat) +static int +opPOPW_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - temp = POP_W(); if (cpu_state.abrt) return 1; + temp = POP_W(); + if (cpu_state.abrt) + return 1; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(temp); - if (cpu_state.abrt) - { - if (stack32) ESP -= 2; - else SP -= 2; - } + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(temp); + if (cpu_state.abrt) { + if (stack32) + ESP -= 2; + else + SP -= 2; + } - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1,0,(cpu_mod == 3) ? 0:1,0, 0); - return cpu_state.abrt; + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + return cpu_state.abrt; } -static int opPOPW_a32(uint32_t fetchdat) +static int +opPOPW_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - temp = POP_W(); if (cpu_state.abrt) return 1; + temp = POP_W(); + if (cpu_state.abrt) + return 1; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(temp); - if (cpu_state.abrt) - { - if (stack32) ESP -= 2; - else SP -= 2; - } + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(temp); + if (cpu_state.abrt) { + if (stack32) + ESP -= 2; + else + SP -= 2; + } - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1,0,(cpu_mod == 3) ? 0:1,0, 1); - return cpu_state.abrt; + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + return cpu_state.abrt; } -static int opPOPL_a16(uint32_t fetchdat) +static int +opPOPL_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - temp = POP_L(); if (cpu_state.abrt) return 1; + temp = POP_L(); + if (cpu_state.abrt) + return 1; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(temp); - if (cpu_state.abrt) - { - if (stack32) ESP -= 4; - else SP -= 4; - } + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(temp); + if (cpu_state.abrt) { + if (stack32) + ESP -= 4; + else + SP -= 4; + } - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0,1,0,(cpu_mod == 3) ? 0:1, 0); - return cpu_state.abrt; + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0, 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + return cpu_state.abrt; } -static int opPOPL_a32(uint32_t fetchdat) +static int +opPOPL_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - temp = POP_L(); if (cpu_state.abrt) return 1; + temp = POP_L(); + if (cpu_state.abrt) + return 1; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(temp); - if (cpu_state.abrt) - { - if (stack32) ESP -= 4; - else SP -= 4; - } + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(temp); + if (cpu_state.abrt) { + if (stack32) + ESP -= 4; + else + SP -= 4; + } - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0,1,0,(cpu_mod == 3) ? 0:1, 1); - return cpu_state.abrt; + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0, 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + return cpu_state.abrt; } - -static int opENTER_w(uint32_t fetchdat) +static int +opENTER_w(uint32_t fetchdat) { - uint16_t offset; - int count; - uint32_t tempEBP, tempESP, frame_ptr; + uint16_t offset; + int count; + uint32_t tempEBP, tempESP, frame_ptr; #ifndef IS_DYNAREC - int reads = 0, writes = 1, instr_cycles = 0; + int reads = 0, writes = 1, instr_cycles = 0; #endif - uint16_t tempw; + uint16_t tempw; - offset = getwordf(); - count = (fetchdat >> 16) & 0xff; cpu_state.pc++; - tempEBP = EBP; - tempESP = ESP; + offset = getwordf(); + count = (fetchdat >> 16) & 0xff; + cpu_state.pc++; + tempEBP = EBP; + tempESP = ESP; - PUSH_W(BP); if (cpu_state.abrt) return 1; - frame_ptr = ESP; + PUSH_W(BP); + if (cpu_state.abrt) + return 1; + frame_ptr = ESP; - if (count > 0) - { - while (--count) - { - BP -= 2; - tempw = readmemw(ss, BP); - if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } - PUSH_W(tempw); - if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } - CLOCK_CYCLES((is486) ? 3 : 4); + if (count > 0) { + while (--count) { + BP -= 2; + tempw = readmemw(ss, BP); + if (cpu_state.abrt) { + ESP = tempESP; + EBP = tempEBP; + return 1; + } + PUSH_W(tempw); + if (cpu_state.abrt) { + ESP = tempESP; + EBP = tempEBP; + return 1; + } + CLOCK_CYCLES((is486) ? 3 : 4); #ifndef IS_DYNAREC - reads++; writes++; instr_cycles += (is486) ? 3 : 4; -#endif - } - PUSH_W(frame_ptr); - if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } - CLOCK_CYCLES((is486) ? 3 : 5); -#ifndef IS_DYNAREC - writes++; instr_cycles += (is486) ? 3 : 5; + reads++; + writes++; + instr_cycles += (is486) ? 3 : 4; #endif } - BP = frame_ptr; - - if (stack32) ESP -= offset; - else SP -= offset; - CLOCK_CYCLES((is486) ? 14 : 10); + PUSH_W(frame_ptr); + if (cpu_state.abrt) { + ESP = tempESP; + EBP = tempEBP; + return 1; + } + CLOCK_CYCLES((is486) ? 3 : 5); #ifndef IS_DYNAREC - instr_cycles += (is486) ? 14 : 10; - PREFETCH_RUN(instr_cycles, 3, -1, reads,0,writes,0, 0); + writes++; + instr_cycles += (is486) ? 3 : 5; #endif - return 0; + } + BP = frame_ptr; + + if (stack32) + ESP -= offset; + else + SP -= offset; + CLOCK_CYCLES((is486) ? 14 : 10); +#ifndef IS_DYNAREC + instr_cycles += (is486) ? 14 : 10; + PREFETCH_RUN(instr_cycles, 3, -1, reads, 0, writes, 0, 0); +#endif + return 0; } -static int opENTER_l(uint32_t fetchdat) +static int +opENTER_l(uint32_t fetchdat) { - uint16_t offset; - int count; - uint32_t tempEBP, tempESP, frame_ptr; + uint16_t offset; + int count; + uint32_t tempEBP, tempESP, frame_ptr; #ifndef IS_DYNAREC - int reads = 0, writes = 1, instr_cycles = 0; + int reads = 0, writes = 1, instr_cycles = 0; #endif - uint32_t templ; + uint32_t templ; - offset = getwordf(); - count = (fetchdat >> 16) & 0xff; cpu_state.pc++; - tempEBP = EBP; tempESP = ESP; + offset = getwordf(); + count = (fetchdat >> 16) & 0xff; + cpu_state.pc++; + tempEBP = EBP; + tempESP = ESP; - PUSH_L(EBP); if (cpu_state.abrt) return 1; - frame_ptr = ESP; + PUSH_L(EBP); + if (cpu_state.abrt) + return 1; + frame_ptr = ESP; - if (count > 0) - { - while (--count) - { - EBP -= 4; - templ = readmeml(ss, EBP); - if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } - PUSH_L(templ); - if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } - CLOCK_CYCLES((is486) ? 3 : 4); + if (count > 0) { + while (--count) { + EBP -= 4; + templ = readmeml(ss, EBP); + if (cpu_state.abrt) { + ESP = tempESP; + EBP = tempEBP; + return 1; + } + PUSH_L(templ); + if (cpu_state.abrt) { + ESP = tempESP; + EBP = tempEBP; + return 1; + } + CLOCK_CYCLES((is486) ? 3 : 4); #ifndef IS_DYNAREC - reads++; writes++; instr_cycles += (is486) ? 3 : 4; -#endif - } - PUSH_L(frame_ptr); - if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } - CLOCK_CYCLES((is486) ? 3 : 5); -#ifndef IS_DYNAREC - writes++; instr_cycles += (is486) ? 3 : 5; + reads++; + writes++; + instr_cycles += (is486) ? 3 : 4; #endif } - EBP = frame_ptr; - - if (stack32) ESP -= offset; - else SP -= offset; - CLOCK_CYCLES((is486) ? 14 : 10); + PUSH_L(frame_ptr); + if (cpu_state.abrt) { + ESP = tempESP; + EBP = tempEBP; + return 1; + } + CLOCK_CYCLES((is486) ? 3 : 5); #ifndef IS_DYNAREC - instr_cycles += (is486) ? 14 : 10; - PREFETCH_RUN(instr_cycles, 3, -1, reads,0,writes,0, 0); + writes++; + instr_cycles += (is486) ? 3 : 5; #endif - return 0; + } + EBP = frame_ptr; + + if (stack32) + ESP -= offset; + else + SP -= offset; + CLOCK_CYCLES((is486) ? 14 : 10); +#ifndef IS_DYNAREC + instr_cycles += (is486) ? 14 : 10; + PREFETCH_RUN(instr_cycles, 3, -1, reads, 0, writes, 0, 0); +#endif + return 0; } - -static int opLEAVE_w(uint32_t fetchdat) +static int +opLEAVE_w(uint32_t fetchdat) { - uint32_t tempESP = ESP; - uint16_t temp; + uint32_t tempESP = ESP; + uint16_t temp; - SP = BP; - temp = POP_W(); - if (cpu_state.abrt) { ESP = tempESP; return 1; } - BP = temp; + SP = BP; + temp = POP_W(); + if (cpu_state.abrt) { + ESP = tempESP; + return 1; + } + BP = temp; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 1,0,0,0, 0); - return 0; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 1, 0, 0, 0, 0); + return 0; } -static int opLEAVE_l(uint32_t fetchdat) +static int +opLEAVE_l(uint32_t fetchdat) { - uint32_t tempESP = ESP; - uint32_t temp; + uint32_t tempESP = ESP; + uint32_t temp; - ESP = EBP; - temp = POP_L(); - if (cpu_state.abrt) { ESP = tempESP; return 1; } - EBP = temp; + ESP = EBP; + temp = POP_L(); + if (cpu_state.abrt) { + ESP = tempESP; + return 1; + } + EBP = temp; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,1,0,0, 0); - return 0; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 1, 0, 0, 0); + return 0; } +#define PUSH_SEG_OPS(seg) \ + static int opPUSH_##seg##_w(uint32_t fetchdat) \ + { \ + PUSH_W(seg); \ + CLOCK_CYCLES(2); \ + PREFETCH_RUN(2, 1, -1, 0, 0, 1, 0, 0); \ + return cpu_state.abrt; \ + } \ + static int opPUSH_##seg##_l(uint32_t fetchdat) \ + { \ + PUSH_L(seg); \ + CLOCK_CYCLES(2); \ + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 1, 0); \ + return cpu_state.abrt; \ + } -#define PUSH_SEG_OPS(seg) \ - static int opPUSH_ ## seg ## _w(uint32_t fetchdat) \ - { \ - PUSH_W(seg); \ - CLOCK_CYCLES(2); \ - PREFETCH_RUN(2, 1, -1, 0,0,1,0, 0); \ - return cpu_state.abrt; \ - } \ - static int opPUSH_ ## seg ## _l(uint32_t fetchdat) \ - { \ - PUSH_L(seg); \ - CLOCK_CYCLES(2); \ - PREFETCH_RUN(2, 1, -1, 0,0,0,1, 0); \ - return cpu_state.abrt; \ - } - -#define POP_SEG_OPS(seg, realseg) \ - static int opPOP_ ## seg ## _w(uint32_t fetchdat) \ - { \ - uint16_t temp_seg; \ - uint32_t temp_esp = ESP; \ - temp_seg = POP_W(); if (cpu_state.abrt) return 1; \ - loadseg(temp_seg, realseg); if (cpu_state.abrt) ESP = temp_esp; \ - CLOCK_CYCLES(is486 ? 3 : 7); \ - PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0); \ - return cpu_state.abrt; \ - } \ - static int opPOP_ ## seg ## _l(uint32_t fetchdat) \ - { \ - uint32_t temp_seg; \ - uint32_t temp_esp = ESP; \ - temp_seg = POP_L(); if (cpu_state.abrt) return 1; \ - loadseg(temp_seg & 0xffff, realseg); if (cpu_state.abrt) ESP = temp_esp; \ - CLOCK_CYCLES(is486 ? 3 : 7); \ - PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0); \ - return cpu_state.abrt; \ - } - +#define POP_SEG_OPS(seg, realseg) \ + static int opPOP_##seg##_w(uint32_t fetchdat) \ + { \ + uint16_t temp_seg; \ + uint32_t temp_esp = ESP; \ + temp_seg = POP_W(); \ + if (cpu_state.abrt) \ + return 1; \ + loadseg(temp_seg, realseg); \ + if (cpu_state.abrt) \ + ESP = temp_esp; \ + CLOCK_CYCLES(is486 ? 3 : 7); \ + PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0, 0, 1, 0, 0); \ + return cpu_state.abrt; \ + } \ + static int opPOP_##seg##_l(uint32_t fetchdat) \ + { \ + uint32_t temp_seg; \ + uint32_t temp_esp = ESP; \ + temp_seg = POP_L(); \ + if (cpu_state.abrt) \ + return 1; \ + loadseg(temp_seg & 0xffff, realseg); \ + if (cpu_state.abrt) \ + ESP = temp_esp; \ + CLOCK_CYCLES(is486 ? 3 : 7); \ + PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0, 0, 1, 0, 0); \ + return cpu_state.abrt; \ + } PUSH_SEG_OPS(CS) PUSH_SEG_OPS(DS) @@ -497,44 +607,59 @@ POP_SEG_OPS(ES, &cpu_state.seg_es) POP_SEG_OPS(FS, &cpu_state.seg_fs) POP_SEG_OPS(GS, &cpu_state.seg_gs) - -static int opPOP_SS_w(uint32_t fetchdat) +static int +opPOP_SS_w(uint32_t fetchdat) { - uint16_t temp_seg; - uint32_t temp_esp = ESP; - temp_seg = POP_W(); if (cpu_state.abrt) return 1; - loadseg(temp_seg, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } - CLOCK_CYCLES(is486 ? 3 : 7); - PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0); - - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; - cpu_state.ssegs = 0; - cpu_state.ea_seg = &cpu_state.seg_ds; - fetchdat = fastreadl(cs + cpu_state.pc); - cpu_state.pc++; - if (cpu_state.abrt) return 1; - x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - + uint16_t temp_seg; + uint32_t temp_esp = ESP; + temp_seg = POP_W(); + if (cpu_state.abrt) return 1; + loadseg(temp_seg, &cpu_state.seg_ss); + if (cpu_state.abrt) { + ESP = temp_esp; + return 1; + } + CLOCK_CYCLES(is486 ? 3 : 7); + PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0, 0, 1, 0, 0); + + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + fetchdat = fastreadl(cs + cpu_state.pc); + cpu_state.pc++; + if (cpu_state.abrt) + return 1; + x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + + return 1; } -static int opPOP_SS_l(uint32_t fetchdat) +static int +opPOP_SS_l(uint32_t fetchdat) { - uint32_t temp_seg; - uint32_t temp_esp = ESP; - temp_seg = POP_L(); if (cpu_state.abrt) return 1; - loadseg(temp_seg & 0xffff, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } - CLOCK_CYCLES(is486 ? 3 : 7); - PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0); - - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; - cpu_state.ssegs = 0; - cpu_state.ea_seg = &cpu_state.seg_ds; - fetchdat = fastreadl(cs + cpu_state.pc); - cpu_state.pc++; - if (cpu_state.abrt) return 1; - x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - + uint32_t temp_seg; + uint32_t temp_esp = ESP; + temp_seg = POP_L(); + if (cpu_state.abrt) return 1; + loadseg(temp_seg & 0xffff, &cpu_state.seg_ss); + if (cpu_state.abrt) { + ESP = temp_esp; + return 1; + } + CLOCK_CYCLES(is486 ? 3 : 7); + PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0, 0, 1, 0, 0); + + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + fetchdat = fastreadl(cs + cpu_state.pc); + cpu_state.pc++; + if (cpu_state.abrt) + return 1; + x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + + return 1; } diff --git a/src/cpu/x86_ops_string.h b/src/cpu/x86_ops_string.h index 54a22d4b8..5cc5f3806 100644 --- a/src/cpu/x86_ops_string.h +++ b/src/cpu/x86_ops_string.h @@ -1,792 +1,1095 @@ -static int opMOVSB_a16(uint32_t fetchdat) +static int +opMOVSB_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - addr64 = addr64_2 = 0x00000000; + addr64 = addr64_2 = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI); - high_page = 0; - do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64); - if (cpu_state.abrt) return 1; - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, DI, DI); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI); + high_page = 0; + do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, DI, DI); - do_mmut_wb(es, DI, &addr64_2); - if (cpu_state.abrt) return 1; - temp = readmemb_n(cpu_state.ea_seg->base, SI, addr64); if (cpu_state.abrt) return 1; - writememb_n(es, DI, addr64_2, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) { DI--; SI--; } - else { DI++; SI++; } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,1,0, 0); - return 0; + do_mmut_wb(es, DI, &addr64_2); + if (cpu_state.abrt) + return 1; + temp = readmemb_n(cpu_state.ea_seg->base, SI, addr64); + if (cpu_state.abrt) + return 1; + writememb_n(es, DI, addr64_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + DI--; + SI--; + } else { + DI++; + SI++; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 1, 0, 0); + return 0; } -static int opMOVSB_a32(uint32_t fetchdat) +static int +opMOVSB_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - addr64 = addr64_2 = 0x00000000; + addr64 = addr64_2 = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI); - high_page = 0; - do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64); - if (cpu_state.abrt) return 1; - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); - do_mmut_wb(es, EDI, &addr64_2); - if (cpu_state.abrt) return 1; - temp = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); if (cpu_state.abrt) return 1; - writememb_n(es, EDI, addr64_2, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } - else { EDI++; ESI++; } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,1,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI); + high_page = 0; + do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); + do_mmut_wb(es, EDI, &addr64_2); + if (cpu_state.abrt) + return 1; + temp = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); + if (cpu_state.abrt) + return 1; + writememb_n(es, EDI, addr64_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + EDI--; + ESI--; + } else { + EDI++; + ESI++; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 1, 0, 1); + return 0; } -static int opMOVSW_a16(uint32_t fetchdat) +static int +opMOVSW_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - addr64a[0] = addr64a[1] = 0x00000000; - addr64a_2[0] = addr64a_2[1] = 0x00000000; + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); - high_page = 0; - do_mmut_rw(cpu_state.ea_seg->base, SI, addr64a); - if (cpu_state.abrt) return 1; - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); - do_mmut_ww(es, DI, addr64a_2); - if (cpu_state.abrt) return 1; - temp = readmemw_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; - writememw_n(es, DI, addr64a_2, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } - else { DI += 2; SI += 2; } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,1,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); + high_page = 0; + do_mmut_rw(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); + do_mmut_ww(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + temp = readmemw_n(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + writememw_n(es, DI, addr64a_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + DI -= 2; + SI -= 2; + } else { + DI += 2; + SI += 2; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 1, 0, 0); + return 0; } -static int opMOVSW_a32(uint32_t fetchdat) +static int +opMOVSW_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - addr64a[0] = addr64a[1] = 0x00000000; - addr64a_2[0] = addr64a_2[1] = 0x00000000; + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); - high_page = 0; - do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64a); - if (cpu_state.abrt) return 1; - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); - do_mmut_ww(es, EDI, addr64a_2); - if (cpu_state.abrt) return 1; - temp = readmemw_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; - writememw_n(es, EDI, addr64a_2, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } - else { EDI += 2; ESI += 2; } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,1,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); + high_page = 0; + do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); + do_mmut_ww(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + temp = readmemw_n(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + writememw_n(es, EDI, addr64a_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + EDI -= 2; + ESI -= 2; + } else { + EDI += 2; + ESI += 2; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 1, 0, 1); + return 0; } -static int opMOVSL_a16(uint32_t fetchdat) +static int +opMOVSL_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; - addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); - high_page = 0; - do_mmut_rl(cpu_state.ea_seg->base, SI, addr64a); - if (cpu_state.abrt) return 1; - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); - do_mmut_wl(es, DI, addr64a_2); - if (cpu_state.abrt) return 1; - temp = readmeml_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; - writememl_n(es, DI, addr64a_2, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } - else { DI += 4; SI += 4; } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 0,1,0,1, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); + high_page = 0; + do_mmut_rl(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); + do_mmut_wl(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + temp = readmeml_n(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + writememl_n(es, DI, addr64a_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + DI -= 4; + SI -= 4; + } else { + DI += 4; + SI += 4; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 0, 1, 0, 1, 0); + return 0; } -static int opMOVSL_a32(uint32_t fetchdat) +static int +opMOVSL_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; - addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); - high_page = 0; - do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64a); - if (cpu_state.abrt) return 1; - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); - do_mmut_wl(es, EDI, addr64a_2); - if (cpu_state.abrt) return 1; - temp = readmeml_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; - writememl_n(es, EDI, addr64a_2, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } - else { EDI += 4; ESI += 4; } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 0,1,0,1, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); + high_page = 0; + do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); + do_mmut_wl(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + temp = readmeml_n(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + writememl_n(es, EDI, addr64a_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + EDI -= 4; + ESI -= 4; + } else { + EDI += 4; + ESI += 4; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 0, 1, 0, 1, 1); + return 0; } - -static int opCMPSB_a16(uint32_t fetchdat) +static int +opCMPSB_a16(uint32_t fetchdat) { - uint8_t src, dst; + uint8_t src, dst; - addr64 = addr64_2 = 0x00000000; + addr64 = addr64_2 = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI); - high_page = uncached = 0; - do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64); - if (cpu_state.abrt) return 1; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, DI, DI); - do_mmut_rb2(es, DI, &addr64_2); - if (cpu_state.abrt) return 1; - src = readmemb_n(cpu_state.ea_seg->base, SI, addr64); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+DI)>>12] = old_rl2; - dst = readmemb_n(es, DI, addr64_2); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+DI)>>12] = (uintptr_t) LOOKUP_INV; - setsub8(src, dst); - if (cpu_state.flags & D_FLAG) { DI--; SI--; } - else { DI++; SI++; } - CLOCK_CYCLES((is486) ? 8 : 10); - PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI); + high_page = uncached = 0; + do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64); + if (cpu_state.abrt) + return 1; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, DI, DI); + do_mmut_rb2(es, DI, &addr64_2); + if (cpu_state.abrt) + return 1; + src = readmemb_n(cpu_state.ea_seg->base, SI, addr64); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + DI) >> 12] = old_rl2; + dst = readmemb_n(es, DI, addr64_2); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + DI) >> 12] = (uintptr_t) LOOKUP_INV; + setsub8(src, dst); + if (cpu_state.flags & D_FLAG) { + DI--; + SI--; + } else { + DI++; + SI++; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2, 0, 0, 0, 0); + return 0; } -static int opCMPSB_a32(uint32_t fetchdat) +static int +opCMPSB_a32(uint32_t fetchdat) { - uint8_t src, dst; + uint8_t src, dst; - addr64 = addr64_2 = 0x00000000; + addr64 = addr64_2 = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI); - high_page = uncached = 0; - do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64); - if (cpu_state.abrt) return 1; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, EDI, EDI); - do_mmut_rb2(es, EDI, &addr64_2); - if (cpu_state.abrt) return 1; - src = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+EDI)>>12] = old_rl2; - dst = readmemb_n(es, EDI, addr64_2); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+EDI)>>12] = (uintptr_t) LOOKUP_INV; - setsub8(src, dst); - if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } - else { EDI++; ESI++; } - CLOCK_CYCLES((is486) ? 8 : 10); - PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI); + high_page = uncached = 0; + do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64); + if (cpu_state.abrt) + return 1; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, EDI, EDI); + do_mmut_rb2(es, EDI, &addr64_2); + if (cpu_state.abrt) + return 1; + src = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + EDI) >> 12] = old_rl2; + dst = readmemb_n(es, EDI, addr64_2); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + EDI) >> 12] = (uintptr_t) LOOKUP_INV; + setsub8(src, dst); + if (cpu_state.flags & D_FLAG) { + EDI--; + ESI--; + } else { + EDI++; + ESI++; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2, 0, 0, 0, 1); + return 0; } -static int opCMPSW_a16(uint32_t fetchdat) +static int +opCMPSW_a16(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src, dst; - addr64a[0] = addr64a[1] = 0x00000000; - addr64a_2[0] = addr64a_2[1] = 0x00000000; + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); - high_page = uncached = 0; - do_mmut_rw(cpu_state.ea_seg->base, SI, addr64a); - if (cpu_state.abrt) return 1; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, DI, DI + 1UL); - do_mmut_rw2(es, DI, addr64a_2); - if (cpu_state.abrt) return 1; - src = readmemw_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+DI)>>12] = old_rl2; - dst = readmemw_n(es, DI, addr64a_2); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+DI)>>12] = (uintptr_t) LOOKUP_INV; - setsub16(src, dst); - if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } - else { DI += 2; SI += 2; } - CLOCK_CYCLES((is486) ? 8 : 10); - PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); + high_page = uncached = 0; + do_mmut_rw(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, DI, DI + 1UL); + do_mmut_rw2(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + src = readmemw_n(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + DI) >> 12] = old_rl2; + dst = readmemw_n(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + DI) >> 12] = (uintptr_t) LOOKUP_INV; + setsub16(src, dst); + if (cpu_state.flags & D_FLAG) { + DI -= 2; + SI -= 2; + } else { + DI += 2; + SI += 2; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2, 0, 0, 0, 0); + return 0; } -static int opCMPSW_a32(uint32_t fetchdat) +static int +opCMPSW_a32(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src, dst; - addr64a[0] = addr64a[1] = 0x00000000; - addr64a_2[0] = addr64a_2[1] = 0x00000000; + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); - high_page = uncached = 0; - do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64a); - if (cpu_state.abrt) return 1; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, EDI, EDI + 1UL); - do_mmut_rw2(es, EDI, addr64a_2); - if (cpu_state.abrt) return 1; - src = readmemw_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+EDI)>>12] = old_rl2; - dst = readmemw_n(es, EDI, addr64a_2); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+EDI)>>12] = (uintptr_t) LOOKUP_INV; - setsub16(src, dst); - if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } - else { EDI += 2; ESI += 2; } - CLOCK_CYCLES((is486) ? 8 : 10); - PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); + high_page = uncached = 0; + do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, EDI, EDI + 1UL); + do_mmut_rw2(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + src = readmemw_n(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + EDI) >> 12] = old_rl2; + dst = readmemw_n(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + EDI) >> 12] = (uintptr_t) LOOKUP_INV; + setsub16(src, dst); + if (cpu_state.flags & D_FLAG) { + EDI -= 2; + ESI -= 2; + } else { + EDI += 2; + ESI += 2; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2, 0, 0, 0, 1); + return 0; } -static int opCMPSL_a16(uint32_t fetchdat) +static int +opCMPSL_a16(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src, dst; - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; - addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); - high_page = uncached = 0; - do_mmut_rl(cpu_state.ea_seg->base, SI, addr64a); - if (cpu_state.abrt) return 1; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, DI, DI + 3UL); - do_mmut_rl2(es, DI, addr64a_2); - if (cpu_state.abrt) return 1; - src = readmeml_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+DI)>>12] = old_rl2; - dst = readmeml_n(es, DI, addr64a_2); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+DI)>>12] = (uintptr_t) LOOKUP_INV; - setsub32(src, dst); - if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } - else { DI += 4; SI += 4; } - CLOCK_CYCLES((is486) ? 8 : 10); - PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0,2,0,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); + high_page = uncached = 0; + do_mmut_rl(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, DI, DI + 3UL); + do_mmut_rl2(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + src = readmeml_n(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + DI) >> 12] = old_rl2; + dst = readmeml_n(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + DI) >> 12] = (uintptr_t) LOOKUP_INV; + setsub32(src, dst); + if (cpu_state.flags & D_FLAG) { + DI -= 4; + SI -= 4; + } else { + DI += 4; + SI += 4; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0, 2, 0, 0, 0); + return 0; } -static int opCMPSL_a32(uint32_t fetchdat) +static int +opCMPSL_a32(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src, dst; - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; - addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); - high_page = uncached = 0; - do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64a); - if (cpu_state.abrt) return 1; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, EDI, EDI + 3UL); - do_mmut_rl2(es, EDI, addr64a_2); - if (cpu_state.abrt) return 1; - src = readmeml_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+EDI)>>12] = old_rl2; - dst = readmeml_n(es, EDI, addr64a_2); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+EDI)>>12] = (uintptr_t) LOOKUP_INV; - setsub32(src, dst); - if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } - else { EDI += 4; ESI += 4; } - CLOCK_CYCLES((is486) ? 8 : 10); - PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0,2,0,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); + high_page = uncached = 0; + do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, EDI, EDI + 3UL); + do_mmut_rl2(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + src = readmeml_n(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + EDI) >> 12] = old_rl2; + dst = readmeml_n(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + EDI) >> 12] = (uintptr_t) LOOKUP_INV; + setsub32(src, dst); + if (cpu_state.flags & D_FLAG) { + EDI -= 4; + ESI -= 4; + } else { + EDI += 4; + ESI += 4; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0, 2, 0, 0, 1); + return 0; } -static int opSTOSB_a16(uint32_t fetchdat) +static int +opSTOSB_a16(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, DI, DI); - writememb(es, DI, AL); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) DI--; - else DI++; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, DI, DI); + writememb(es, DI, AL); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI--; + else + DI++; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 0); + return 0; } -static int opSTOSB_a32(uint32_t fetchdat) +static int +opSTOSB_a32(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); - writememb(es, EDI, AL); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) EDI--; - else EDI++; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,1,0, 1); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); + writememb(es, EDI, AL); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI--; + else + EDI++; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 1); + return 0; } -static int opSTOSW_a16(uint32_t fetchdat) +static int +opSTOSW_a16(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); - writememw(es, DI, AX); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) DI -= 2; - else DI += 2; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); + writememw(es, DI, AX); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI -= 2; + else + DI += 2; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 0); + return 0; } -static int opSTOSW_a32(uint32_t fetchdat) +static int +opSTOSW_a32(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); - writememw(es, EDI, AX); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) EDI -= 2; - else EDI += 2; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,1,0, 1); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); + writememw(es, EDI, AX); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI -= 2; + else + EDI += 2; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 1); + return 0; } -static int opSTOSL_a16(uint32_t fetchdat) +static int +opSTOSL_a16(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); - writememl(es, DI, EAX); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) DI -= 4; - else DI += 4; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,0,1, 0); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); + writememl(es, DI, EAX); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI -= 4; + else + DI += 4; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0); + return 0; } -static int opSTOSL_a32(uint32_t fetchdat) +static int +opSTOSL_a32(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); - writememl(es, EDI, EAX); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) EDI -= 4; - else EDI += 4; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,0,1, 1); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); + writememl(es, EDI, EAX); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI -= 4; + else + EDI += 4; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 1); + return 0; } - -static int opLODSB_a16(uint32_t fetchdat) +static int +opLODSB_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI); - temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - AL = temp; - if (cpu_state.flags & D_FLAG) SI--; - else SI++; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI); + temp = readmemb(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + AL = temp; + if (cpu_state.flags & D_FLAG) + SI--; + else + SI++; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + return 0; } -static int opLODSB_a32(uint32_t fetchdat) +static int +opLODSB_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI); - temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - AL = temp; - if (cpu_state.flags & D_FLAG) ESI--; - else ESI++; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI); + temp = readmemb(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + AL = temp; + if (cpu_state.flags & D_FLAG) + ESI--; + else + ESI++; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 1); + return 0; } -static int opLODSW_a16(uint32_t fetchdat) +static int +opLODSW_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); - temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - AX = temp; - if (cpu_state.flags & D_FLAG) SI -= 2; - else SI += 2; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); + temp = readmemw(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + AX = temp; + if (cpu_state.flags & D_FLAG) + SI -= 2; + else + SI += 2; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + return 0; } -static int opLODSW_a32(uint32_t fetchdat) +static int +opLODSW_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); - temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - AX = temp; - if (cpu_state.flags & D_FLAG) ESI -= 2; - else ESI += 2; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); + temp = readmemw(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + AX = temp; + if (cpu_state.flags & D_FLAG) + ESI -= 2; + else + ESI += 2; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 1); + return 0; } -static int opLODSL_a16(uint32_t fetchdat) +static int +opLODSL_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); - temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - EAX = temp; - if (cpu_state.flags & D_FLAG) SI -= 4; - else SI += 4; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 0,1,0,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); + temp = readmeml(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + EAX = temp; + if (cpu_state.flags & D_FLAG) + SI -= 4; + else + SI += 4; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 0); + return 0; } -static int opLODSL_a32(uint32_t fetchdat) +static int +opLODSL_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); - temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - EAX = temp; - if (cpu_state.flags & D_FLAG) ESI -= 4; - else ESI += 4; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 0,1,0,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); + temp = readmeml(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + EAX = temp; + if (cpu_state.flags & D_FLAG) + ESI -= 4; + else + ESI += 4; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 1); + return 0; } - -static int opSCASB_a16(uint32_t fetchdat) +static int +opSCASB_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, DI, DI); - temp = readmemb(es, DI); if (cpu_state.abrt) return 1; - setsub8(AL, temp); - if (cpu_state.flags & D_FLAG) DI--; - else DI++; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,0,0, 0); - return 0; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, DI, DI); + temp = readmemb(es, DI); + if (cpu_state.abrt) + return 1; + setsub8(AL, temp); + if (cpu_state.flags & D_FLAG) + DI--; + else + DI++; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 0, 0, 0); + return 0; } -static int opSCASB_a32(uint32_t fetchdat) +static int +opSCASB_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, EDI, EDI); - temp = readmemb(es, EDI); if (cpu_state.abrt) return 1; - setsub8(AL, temp); - if (cpu_state.flags & D_FLAG) EDI--; - else EDI++; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,0,0, 1); - return 0; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, EDI, EDI); + temp = readmemb(es, EDI); + if (cpu_state.abrt) + return 1; + setsub8(AL, temp); + if (cpu_state.flags & D_FLAG) + EDI--; + else + EDI++; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 0, 0, 1); + return 0; } -static int opSCASW_a16(uint32_t fetchdat) +static int +opSCASW_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, DI, DI + 1UL); - temp = readmemw(es, DI); if (cpu_state.abrt) return 1; - setsub16(AX, temp); - if (cpu_state.flags & D_FLAG) DI -= 2; - else DI += 2; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,0,0, 0); - return 0; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, DI, DI + 1UL); + temp = readmemw(es, DI); + if (cpu_state.abrt) + return 1; + setsub16(AX, temp); + if (cpu_state.flags & D_FLAG) + DI -= 2; + else + DI += 2; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 0, 0, 0); + return 0; } -static int opSCASW_a32(uint32_t fetchdat) +static int +opSCASW_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, EDI, EDI + 1UL); - temp = readmemw(es, EDI); if (cpu_state.abrt) return 1; - setsub16(AX, temp); - if (cpu_state.flags & D_FLAG) EDI -= 2; - else EDI += 2; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,0,0, 1); - return 0; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, EDI, EDI + 1UL); + temp = readmemw(es, EDI); + if (cpu_state.abrt) + return 1; + setsub16(AX, temp); + if (cpu_state.flags & D_FLAG) + EDI -= 2; + else + EDI += 2; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 0, 0, 1); + return 0; } -static int opSCASL_a16(uint32_t fetchdat) +static int +opSCASL_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, DI, DI + 3UL); - temp = readmeml(es, DI); if (cpu_state.abrt) return 1; - setsub32(EAX, temp); - if (cpu_state.flags & D_FLAG) DI -= 4; - else DI += 4; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 0,1,0,0, 0); - return 0; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, DI, DI + 3UL); + temp = readmeml(es, DI); + if (cpu_state.abrt) + return 1; + setsub32(EAX, temp); + if (cpu_state.flags & D_FLAG) + DI -= 4; + else + DI += 4; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 0, 1, 0, 0, 0); + return 0; } -static int opSCASL_a32(uint32_t fetchdat) +static int +opSCASL_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, EDI, EDI + 3UL); - temp = readmeml(es, EDI); if (cpu_state.abrt) return 1; - setsub32(EAX, temp); - if (cpu_state.flags & D_FLAG) EDI -= 4; - else EDI += 4; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 0,1,0,0, 1); - return 0; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, EDI, EDI + 3UL); + temp = readmeml(es, EDI); + if (cpu_state.abrt) + return 1; + setsub32(EAX, temp); + if (cpu_state.flags & D_FLAG) + EDI -= 4; + else + EDI += 4; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 0, 1, 0, 0, 1); + return 0; } -static int opINSB_a16(uint32_t fetchdat) +static int +opINSB_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - addr64 = 0x00000000; + addr64 = 0x00000000; - SEG_CHECK_WRITE(&cpu_state.seg_es); - check_io_perm(DX); - CHECK_WRITE(&cpu_state.seg_es, DI, DI); - high_page = 0; - do_mmut_wb(es, DI, &addr64); if (cpu_state.abrt) return 1; - temp = inb(DX); - writememb_n(es, DI, addr64, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) DI--; - else DI++; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 1,0,1,0, 0); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); + CHECK_WRITE(&cpu_state.seg_es, DI, DI); + high_page = 0; + do_mmut_wb(es, DI, &addr64); + if (cpu_state.abrt) + return 1; + temp = inb(DX); + writememb_n(es, DI, addr64, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI--; + else + DI++; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 1, 0, 1, 0, 0); + return 0; } -static int opINSB_a32(uint32_t fetchdat) +static int +opINSB_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - addr64 = 0x00000000; + addr64 = 0x00000000; - SEG_CHECK_WRITE(&cpu_state.seg_es); - check_io_perm(DX); - high_page = 0; - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); - do_mmut_wb(es, EDI, &addr64); if (cpu_state.abrt) return 1; - temp = inb(DX); - writememb_n(es, EDI, addr64, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) EDI--; - else EDI++; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 1,0,1,0, 1); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); + high_page = 0; + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); + do_mmut_wb(es, EDI, &addr64); + if (cpu_state.abrt) + return 1; + temp = inb(DX); + writememb_n(es, EDI, addr64, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI--; + else + EDI++; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 1, 0, 1, 0, 1); + return 0; } -static int opINSW_a16(uint32_t fetchdat) +static int +opINSW_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - addr64a[0] = addr64a[1] = 0x00000000; + addr64a[0] = addr64a[1] = 0x00000000; - SEG_CHECK_WRITE(&cpu_state.seg_es); - check_io_perm(DX); - check_io_perm(DX + 1); - CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); - high_page = 0; - do_mmut_ww(es, DI, addr64a); if (cpu_state.abrt) return 1; - temp = inw(DX); - writememw_n(es, DI, addr64a, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) DI -= 2; - else DI += 2; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 1,0,1,0, 0); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); + check_io_perm(DX + 1); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); + high_page = 0; + do_mmut_ww(es, DI, addr64a); + if (cpu_state.abrt) + return 1; + temp = inw(DX); + writememw_n(es, DI, addr64a, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI -= 2; + else + DI += 2; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 1, 0, 1, 0, 0); + return 0; } -static int opINSW_a32(uint32_t fetchdat) +static int +opINSW_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - addr64a[0] = addr64a[1] = 0x00000000; + addr64a[0] = addr64a[1] = 0x00000000; - SEG_CHECK_WRITE(&cpu_state.seg_es); - high_page = 0; - check_io_perm(DX); - check_io_perm(DX + 1); - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); - do_mmut_ww(es, EDI, addr64a); if (cpu_state.abrt) return 1; - temp = inw(DX); - writememw_n(es, EDI, addr64a, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) EDI -= 2; - else EDI += 2; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 1,0,1,0, 1); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + high_page = 0; + check_io_perm(DX); + check_io_perm(DX + 1); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); + do_mmut_ww(es, EDI, addr64a); + if (cpu_state.abrt) + return 1; + temp = inw(DX); + writememw_n(es, EDI, addr64a, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI -= 2; + else + EDI += 2; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 1, 0, 1, 0, 1); + return 0; } -static int opINSL_a16(uint32_t fetchdat) +static int +opINSL_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; - SEG_CHECK_WRITE(&cpu_state.seg_es); - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); - high_page = 0; - do_mmut_wl(es, DI, addr64a); if (cpu_state.abrt) return 1; - temp = inl(DX); - writememl_n(es, DI, addr64a, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) DI -= 4; - else DI += 4; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 0,1,0,1, 0); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); + check_io_perm(DX + 1); + check_io_perm(DX + 2); + check_io_perm(DX + 3); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); + high_page = 0; + do_mmut_wl(es, DI, addr64a); + if (cpu_state.abrt) + return 1; + temp = inl(DX); + writememl_n(es, DI, addr64a, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI -= 4; + else + DI += 4; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 0, 1, 0, 1, 0); + return 0; } -static int opINSL_a32(uint32_t fetchdat) +static int +opINSL_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; - SEG_CHECK_WRITE(&cpu_state.seg_es); - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); - high_page = 0; - do_mmut_wl(es, DI, addr64a); if (cpu_state.abrt) return 1; - temp = inl(DX); - writememl_n(es, EDI, addr64a, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) EDI -= 4; - else EDI += 4; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 0,1,0,1, 1); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); + check_io_perm(DX + 1); + check_io_perm(DX + 2); + check_io_perm(DX + 3); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); + high_page = 0; + do_mmut_wl(es, DI, addr64a); + if (cpu_state.abrt) + return 1; + temp = inl(DX); + writememl_n(es, EDI, addr64a, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI -= 4; + else + EDI += 4; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 0, 1, 0, 1, 1); + return 0; } -static int opOUTSB_a16(uint32_t fetchdat) +static int +opOUTSB_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI); - temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - if (cpu_state.flags & D_FLAG) SI--; - else SI++; - outb(DX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 1,0,1,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI); + temp = readmemb(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX); + if (cpu_state.flags & D_FLAG) + SI--; + else + SI++; + outb(DX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 1, 0, 1, 0, 0); + return 0; } -static int opOUTSB_a32(uint32_t fetchdat) +static int +opOUTSB_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI); - temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - if (cpu_state.flags & D_FLAG) ESI--; - else ESI++; - outb(DX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 1,0,1,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI); + temp = readmemb(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX); + if (cpu_state.flags & D_FLAG) + ESI--; + else + ESI++; + outb(DX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 1, 0, 1, 0, 1); + return 0; } -static int opOUTSW_a16(uint32_t fetchdat) +static int +opOUTSW_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); - temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - check_io_perm(DX + 1); - if (cpu_state.flags & D_FLAG) SI -= 2; - else SI += 2; - outw(DX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 1,0,1,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); + temp = readmemw(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX); + check_io_perm(DX + 1); + if (cpu_state.flags & D_FLAG) + SI -= 2; + else + SI += 2; + outw(DX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 1, 0, 1, 0, 0); + return 0; } -static int opOUTSW_a32(uint32_t fetchdat) +static int +opOUTSW_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); - temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - check_io_perm(DX + 1); - if (cpu_state.flags & D_FLAG) ESI -= 2; - else ESI += 2; - outw(DX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 1,0,1,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); + temp = readmemw(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX); + check_io_perm(DX + 1); + if (cpu_state.flags & D_FLAG) + ESI -= 2; + else + ESI += 2; + outw(DX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 1, 0, 1, 0, 1); + return 0; } -static int opOUTSL_a16(uint32_t fetchdat) +static int +opOUTSL_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); - temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - if (cpu_state.flags & D_FLAG) SI -= 4; - else SI += 4; - outl(EDX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 0,1,0,1, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); + temp = readmeml(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX); + check_io_perm(DX + 1); + check_io_perm(DX + 2); + check_io_perm(DX + 3); + if (cpu_state.flags & D_FLAG) + SI -= 4; + else + SI += 4; + outl(EDX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 0, 1, 0, 1, 0); + return 0; } -static int opOUTSL_a32(uint32_t fetchdat) +static int +opOUTSL_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); - temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - if (cpu_state.flags & D_FLAG) ESI -= 4; - else ESI += 4; - outl(EDX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 0,1,0,1, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); + temp = readmeml(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX); + check_io_perm(DX + 1); + check_io_perm(DX + 2); + check_io_perm(DX + 3); + if (cpu_state.flags & D_FLAG) + ESI -= 4; + else + ESI += 4; + outl(EDX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 0, 1, 0, 1, 1); + return 0; } diff --git a/src/cpu/x86_ops_xchg.h b/src/cpu/x86_ops_xchg.h index 300e97f25..c572608eb 100644 --- a/src/cpu/x86_ops_xchg.h +++ b/src/cpu/x86_ops_xchg.h @@ -1,228 +1,270 @@ -static int opXCHG_b_a16(uint32_t fetchdat) +static int +opXCHG_b_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - seteab(getr8(cpu_reg)); if (cpu_state.abrt) return 1; - setr8(cpu_reg, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + seteab(getr8(cpu_reg)); + if (cpu_state.abrt) + return 1; + setr8(cpu_reg, temp); + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + return 0; } -static int opXCHG_b_a32(uint32_t fetchdat) +static int +opXCHG_b_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - seteab(getr8(cpu_reg)); if (cpu_state.abrt) return 1; - setr8(cpu_reg, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + seteab(getr8(cpu_reg)); + if (cpu_state.abrt) + return 1; + setr8(cpu_reg, temp); + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + return 0; } -static int opXCHG_w_a16(uint32_t fetchdat) +static int +opXCHG_w_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - seteaw(cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + seteaw(cpu_state.regs[cpu_reg].w); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = temp; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + return 0; } -static int opXCHG_w_a32(uint32_t fetchdat) +static int +opXCHG_w_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - seteaw(cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + seteaw(cpu_state.regs[cpu_reg].w); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = temp; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + return 0; } -static int opXCHG_l_a16(uint32_t fetchdat) +static int +opXCHG_l_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - seteal(cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = temp; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + seteal(cpu_state.regs[cpu_reg].l); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = temp; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + return 0; } -static int opXCHG_l_a32(uint32_t fetchdat) +static int +opXCHG_l_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - seteal(cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = temp; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + seteal(cpu_state.regs[cpu_reg].l); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = temp; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + return 0; } - -static int opXCHG_AX_BX(uint32_t fetchdat) +static int +opXCHG_AX_BX(uint32_t fetchdat) { - uint16_t temp = AX; - AX = BX; - BX = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint16_t temp = AX; + AX = BX; + BX = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_AX_CX(uint32_t fetchdat) +static int +opXCHG_AX_CX(uint32_t fetchdat) { - uint16_t temp = AX; - AX = CX; - CX = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint16_t temp = AX; + AX = CX; + CX = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_AX_DX(uint32_t fetchdat) +static int +opXCHG_AX_DX(uint32_t fetchdat) { - uint16_t temp = AX; - AX = DX; - DX = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint16_t temp = AX; + AX = DX; + DX = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_AX_SI(uint32_t fetchdat) +static int +opXCHG_AX_SI(uint32_t fetchdat) { - uint16_t temp = AX; - AX = SI; - SI = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint16_t temp = AX; + AX = SI; + SI = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_AX_DI(uint32_t fetchdat) +static int +opXCHG_AX_DI(uint32_t fetchdat) { - uint16_t temp = AX; - AX = DI; - DI = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint16_t temp = AX; + AX = DI; + DI = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_AX_BP(uint32_t fetchdat) +static int +opXCHG_AX_BP(uint32_t fetchdat) { - uint16_t temp = AX; - AX = BP; - BP = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint16_t temp = AX; + AX = BP; + BP = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_AX_SP(uint32_t fetchdat) +static int +opXCHG_AX_SP(uint32_t fetchdat) { - uint16_t temp = AX; - AX = SP; - SP = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint16_t temp = AX; + AX = SP; + SP = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_EAX_EBX(uint32_t fetchdat) +static int +opXCHG_EAX_EBX(uint32_t fetchdat) { - uint32_t temp = EAX; - EAX = EBX; - EBX = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint32_t temp = EAX; + EAX = EBX; + EBX = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_EAX_ECX(uint32_t fetchdat) +static int +opXCHG_EAX_ECX(uint32_t fetchdat) { - uint32_t temp = EAX; - EAX = ECX; - ECX = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint32_t temp = EAX; + EAX = ECX; + ECX = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_EAX_EDX(uint32_t fetchdat) +static int +opXCHG_EAX_EDX(uint32_t fetchdat) { - uint32_t temp = EAX; - EAX = EDX; - EDX = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint32_t temp = EAX; + EAX = EDX; + EDX = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_EAX_ESI(uint32_t fetchdat) +static int +opXCHG_EAX_ESI(uint32_t fetchdat) { - uint32_t temp = EAX; - EAX = ESI; - ESI = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint32_t temp = EAX; + EAX = ESI; + ESI = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_EAX_EDI(uint32_t fetchdat) +static int +opXCHG_EAX_EDI(uint32_t fetchdat) { - uint32_t temp = EAX; - EAX = EDI; - EDI = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint32_t temp = EAX; + EAX = EDI; + EDI = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_EAX_EBP(uint32_t fetchdat) +static int +opXCHG_EAX_EBP(uint32_t fetchdat) { - uint32_t temp = EAX; - EAX = EBP; - EBP = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint32_t temp = EAX; + EAX = EBP; + EBP = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_EAX_ESP(uint32_t fetchdat) +static int +opXCHG_EAX_ESP(uint32_t fetchdat) { - uint32_t temp = EAX; - EAX = ESP; - ESP = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint32_t temp = EAX; + EAX = ESP; + ESP = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } - -#define opBSWAP(reg) \ - static int opBSWAP_ ## reg(uint32_t fetchdat) \ - { \ - reg = (reg >> 24) | ((reg >> 8) & 0xff00) | ((reg << 8) & 0xff0000) | ((reg << 24) & 0xff000000); \ - CLOCK_CYCLES(1); \ - PREFETCH_RUN(1, 1, -1, 0,0,0,0, 0); \ - return 0; \ - } +#define opBSWAP(reg) \ + static int opBSWAP_##reg(uint32_t fetchdat) \ + { \ + reg = (reg >> 24) | ((reg >> 8) & 0xff00) | ((reg << 8) & 0xff0000) | ((reg << 24) & 0xff000000); \ + CLOCK_CYCLES(1); \ + PREFETCH_RUN(1, 1, -1, 0, 0, 0, 0, 0); \ + return 0; \ + } opBSWAP(EAX) opBSWAP(EBX) diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 74539c067..c1e9e5b3d 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -35,7 +35,6 @@ #include "x86_flags.h" #include "386_common.h" - uint8_t opcode2; int cgate16, cgate32; @@ -45,54 +44,50 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32); void pmodeint(int num, int soft); -#define DPL ((segdat[2] >> 13) & 3) +#define DPL ((segdat[2] >> 13) & 3) #define DPL2 ((segdat2[2] >> 13) & 3) #define DPL3 ((segdat3[2] >> 13) & 3) - #ifdef ENABLE_X86SEG_LOG int x86seg_do_log = ENABLE_X86SEG_LOG; - static void x86seg_log(const char *fmt, ...) { va_list ap; if (x86seg_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define x86seg_log(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->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; + 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; + s->base = 0; + s->seg = 0; } } - void x86seg_reset(void) { @@ -104,239 +99,234 @@ x86seg_reset(void) seg_reset(&cpu_state.seg_ss); } - void x86_doabrt(int x86_abrt) { #ifndef USE_NEW_DYNAREC CS = oldcs; #endif - cpu_state.pc = cpu_state.oldpc; - cpu_state.seg_cs.access = (oldcpl << 5) | 0x80; + cpu_state.pc = cpu_state.oldpc; + cpu_state.seg_cs.access = (oldcpl << 5) | 0x80; cpu_state.seg_cs.ar_high = 0x10; if (msw & 1) - pmodeint(x86_abrt, 0); + pmodeint(x86_abrt, 0); else { - uint32_t addr = (x86_abrt << 2) + idt.base; - if (stack32) { - writememw(ss, ESP - 2, cpu_state.flags); - writememw(ss, ESP - 4, CS); - writememw(ss, ESP - 6, cpu_state.pc); - ESP -= 6; - } else { - writememw(ss, ((SP - 2) & 0xffff), cpu_state.flags); - writememw(ss, ((SP - 4) & 0xffff), CS); - writememw(ss, ((SP - 6) & 0xffff), cpu_state.pc); - SP -= 6; - } + uint32_t addr = (x86_abrt << 2) + idt.base; + if (stack32) { + writememw(ss, ESP - 2, cpu_state.flags); + writememw(ss, ESP - 4, CS); + writememw(ss, ESP - 6, cpu_state.pc); + ESP -= 6; + } else { + writememw(ss, ((SP - 2) & 0xffff), cpu_state.flags); + writememw(ss, ((SP - 4) & 0xffff), CS); + writememw(ss, ((SP - 6) & 0xffff), cpu_state.pc); + SP -= 6; + } - cpu_state.flags &= ~(I_FLAG | T_FLAG); + cpu_state.flags &= ~(I_FLAG | T_FLAG); #ifndef USE_NEW_DYNAREC - oxpc = cpu_state.pc; + oxpc = cpu_state.pc; #endif - cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); - return; + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + return; } if (cpu_state.abrt || x86_was_reset) - return; + return; if (intgatesize == 16) { - if (stack32) { - writememw(ss, ESP - 2, abrt_error); - ESP -= 2; - } else { - writememw(ss, ((SP - 2) & 0xffff), abrt_error); - SP -= 2; - } + if (stack32) { + writememw(ss, ESP - 2, abrt_error); + ESP -= 2; + } else { + writememw(ss, ((SP - 2) & 0xffff), abrt_error); + SP -= 2; + } } else { - if (stack32) { - writememl(ss, ESP - 4, abrt_error); - ESP -= 4; - } else { - writememl(ss, ((SP - 4) & 0xffff), abrt_error); - SP -= 4; - } + if (stack32) { + writememl(ss, ESP - 4, abrt_error); + ESP -= 4; + } else { + writememl(ss, ((SP - 4) & 0xffff), abrt_error); + SP -= 4; + } } } - void x86de(char *s, uint16_t error) { #ifdef BAD_CODE cpu_state.abrt = ABRT_DE; - abrt_error = error; + abrt_error = error; #else x86_int(0); #endif } - void x86gpf(char *s, uint16_t error) { cpu_state.abrt = ABRT_GPF; - abrt_error = error; + abrt_error = error; } - void x86gpf_expected(char *s, uint16_t error) { cpu_state.abrt = ABRT_GPF | ABRT_EXPECTED; - abrt_error = error; + abrt_error = error; } - void x86ss(char *s, uint16_t error) { cpu_state.abrt = ABRT_SS; - abrt_error = error; + abrt_error = error; } - -void x86ts(char *s, uint16_t error) +void +x86ts(char *s, uint16_t error) { cpu_state.abrt = ABRT_TS; - abrt_error = error; + abrt_error = error; } - void x86np(char *s, uint16_t error) { cpu_state.abrt = ABRT_NP; - abrt_error = error; + abrt_error = error; } - static void set_stack32(int s) { stack32 = s; if (stack32) - cpu_cur_status |= CPU_STATUS_STACK32; + cpu_cur_status |= CPU_STATUS_STACK32; else - cpu_cur_status &= ~CPU_STATUS_STACK32; + cpu_cur_status &= ~CPU_STATUS_STACK32; } - static void set_use32(int u) { use32 = u ? 0x300 : 0; if (u) - cpu_cur_status |= CPU_STATUS_USE32; + cpu_cur_status |= CPU_STATUS_USE32; else - cpu_cur_status &= ~CPU_STATUS_USE32; + cpu_cur_status &= ~CPU_STATUS_USE32; } - void do_seg_load(x86seg *s, uint16_t *segdat) { s->limit = segdat[0] | ((segdat[3] & 0x000f) << 16); if (segdat[3] & 0x0080) - s->limit = (s->limit << 12) | 0xfff; + s->limit = (s->limit << 12) | 0xfff; s->base = segdat[1] | ((segdat[2] & 0x00ff) << 16); if (is386) - s->base |= ((segdat[3] >> 8) << 24); - s->access = segdat[2] >> 8; + s->base |= ((segdat[3] >> 8) << 24); + s->access = segdat[2] >> 8; s->ar_high = segdat[3] & 0xff; if (((segdat[2] & 0x1800) != 0x1000) || !(segdat[2] & (1 << 10))) { - /* Expand-down */ - s->limit_high = s->limit; - s->limit_low = 0; + /* Expand-down */ + s->limit_high = s->limit; + s->limit_low = 0; } else { - s->limit_high = (segdat[3] & 0x40) ? 0xffffffff : 0xffff; - s->limit_low = s->limit + 1; + s->limit_high = (segdat[3] & 0x40) ? 0xffffffff : 0xffff; + s->limit_low = s->limit + 1; } if (s == &cpu_state.seg_ds) { - if ((s->base == 0) && (s->limit_low == 0) && (s->limit_high == 0xffffffff)) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; + if ((s->base == 0) && (s->limit_low == 0) && (s->limit_high == 0xffffffff)) + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATDS; } if (s == &cpu_state.seg_ss) { - if ((s->base == 0) && (s->limit_low == 0) && (s->limit_high == 0xffffffff)) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; + if ((s->base == 0) && (s->limit_low == 0) && (s->limit_high == 0xffffffff)) + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATSS; } } - static void do_seg_v86_init(x86seg *s) { - s->access = 0xe2; - s->ar_high = 0x10; - s->limit = 0xffff; - s->limit_low = 0; + s->access = 0xe2; + s->ar_high = 0x10; + s->limit = 0xffff; + s->limit_low = 0; s->limit_high = 0xffff; } - static void check_seg_valid(x86seg *s) { - int dpl = (s->access >> 5) & 3; - int valid = 1; - x86seg *dt = (s->seg & 0x0004) ? &ldt : &gdt; + int dpl = (s->access >> 5) & 3; + int valid = 1; + x86seg *dt = (s->seg & 0x0004) ? &ldt : &gdt; if (((s->seg & 0xfff8UL) + 7UL) > dt->limit) - valid = 0; + valid = 0; switch (s->access & 0x1f) { - case 0x10: case 0x11: case 0x12: case 0x13: /* Data segments */ - case 0x14: case 0x15: case 0x16: case 0x17: - case 0x1a: case 0x1b: /* Readable non-conforming code */ - if (((s->seg & 3) > dpl) || ((CPL) > dpl)) { - valid = 0; - break; - } - break; + case 0x10: + case 0x11: + case 0x12: + case 0x13: /* Data segments */ + case 0x14: + case 0x15: + case 0x16: + case 0x17: + case 0x1a: + case 0x1b: /* Readable non-conforming code */ + if (((s->seg & 3) > dpl) || ((CPL) > dpl)) { + valid = 0; + break; + } + break; - case 0x1e: case 0x1f: /* Readable conforming code */ - break; + case 0x1e: + case 0x1f: /* Readable conforming code */ + break; - default: - valid = 0; - break; + default: + valid = 0; + break; } if (!valid) - loadseg(0, s); + loadseg(0, s); } - static void read_descriptor(uint32_t addr, uint16_t *segdat, uint32_t *segdat32, int override) { if (override) - cpl_override = 1; + cpl_override = 1; if (cpu_16bitbus) { - segdat[0] = readmemw(0, addr); - segdat[1] = readmemw(0, addr + 2); - segdat[2] = readmemw(0, addr + 4); - segdat[3] = readmemw(0, addr + 6); + segdat[0] = readmemw(0, addr); + segdat[1] = readmemw(0, addr + 2); + segdat[2] = readmemw(0, addr + 4); + segdat[3] = readmemw(0, addr + 6); } else { - segdat32[0] = readmeml(0, addr); - segdat32[1] = readmeml(0, addr + 4); + segdat32[0] = readmeml(0, addr); + segdat32[1] = readmeml(0, addr + 4); } if (override) - cpl_override = 0; + cpl_override = 0; } - #ifdef USE_NEW_DYNAREC int #else @@ -346,180 +336,191 @@ loadseg(uint16_t seg, x86seg *s) { uint16_t segdat[4]; uint32_t addr, *segdat32 = (uint32_t *) segdat; - int dpl; - x86seg *dt; + int dpl; + x86seg *dt; if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { - if (!(seg & 0xfffc)) { - if (s == &cpu_state.seg_ss) { - x86ss(NULL,0); + if (!(seg & 0xfffc)) { + if (s == &cpu_state.seg_ss) { + x86ss(NULL, 0); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - s->seg = 0; - s->access = 0x80; - s->ar_high = 0x10; - s->base = -1; - if (s == &cpu_state.seg_ds) - cpu_cur_status |= CPU_STATUS_NOTFLATDS; + } + s->seg = 0; + s->access = 0x80; + s->ar_high = 0x10; + s->base = -1; + if (s == &cpu_state.seg_ds) + cpu_cur_status |= CPU_STATUS_NOTFLATDS; #ifdef USE_NEW_DYNAREC - return 0; + return 0; #else - return; + return; #endif - } - addr = seg & 0xfff8; - dt = (seg & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("loadseg(): Bigger than LDT limit", seg & 0xfffc); + } + addr = seg & 0xfff8; + dt = (seg & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("loadseg(): Bigger than LDT limit", seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - addr += dt->base; - read_descriptor(addr, segdat, segdat32, 1); - if (cpu_state.abrt) + } + addr += dt->base; + read_descriptor(addr, segdat, segdat32, 1); + if (cpu_state.abrt) #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - dpl = (segdat[2] >> 13) & 3; - if (s == &cpu_state.seg_ss) { - if (!(seg & 0xfffc)) { - x86gpf("loadseg(): Zero stack segment", seg & 0xfffc); + dpl = (segdat[2] >> 13) & 3; + if (s == &cpu_state.seg_ss) { + if (!(seg & 0xfffc)) { + x86gpf("loadseg(): Zero stack segment", seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - if ((seg & 0x0003) != CPL) { - x86gpf("loadseg(): Stack segment RPL != CPL", seg & 0xfffc); + } + if ((seg & 0x0003) != CPL) { + x86gpf("loadseg(): Stack segment RPL != CPL", seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - if (dpl != CPL) { - x86gpf("loadseg(): Stack segment DPL != CPL", seg & 0xfffc); + } + if (dpl != CPL) { + x86gpf("loadseg(): Stack segment DPL != CPL", seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - switch ((segdat[2] >> 8) & 0x1f) { - case 0x12: case 0x13: case 0x16: case 0x17: - /* R/W */ - break; - default: - x86gpf("loadseg(): Unknown stack segment type", seg & ~3); + } + switch ((segdat[2] >> 8) & 0x1f) { + case 0x12: + case 0x13: + case 0x16: + case 0x17: + /* R/W */ + break; + default: + x86gpf("loadseg(): Unknown stack segment type", seg & ~3); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - if (!(segdat[2] & 0x8000)) { - x86ss(NULL, seg & 0xfffc); + } + if (!(segdat[2] & 0x8000)) { + x86ss(NULL, seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - set_stack32((segdat[3] & 0x40) ? 1 : 0); - } else if (s != &cpu_state.seg_cs) { - x86seg_log("Seg data %04X %04X %04X %04X\n", segdat[0], segdat[1], segdat[2], segdat[3]); - x86seg_log("Seg type %03X\n",segdat[2] & 0x1f00); - switch ((segdat[2] >> 8) & 0x1f) { - case 0x10: case 0x11: case 0x12: case 0x13: /* Data segments */ - case 0x14: case 0x15: case 0x16: case 0x17: - case 0x1a: case 0x1b: /* Readable non-conforming code */ - if ((seg & 0x0003) > dpl) { - x86gpf("loadseg(): Normal segment RPL > DPL", seg & 0xfffc); + } + set_stack32((segdat[3] & 0x40) ? 1 : 0); + } else if (s != &cpu_state.seg_cs) { + x86seg_log("Seg data %04X %04X %04X %04X\n", segdat[0], segdat[1], segdat[2], segdat[3]); + x86seg_log("Seg type %03X\n", segdat[2] & 0x1f00); + switch ((segdat[2] >> 8) & 0x1f) { + case 0x10: + case 0x11: + case 0x12: + case 0x13: /* Data segments */ + case 0x14: + case 0x15: + case 0x16: + case 0x17: + case 0x1a: + case 0x1b: /* Readable non-conforming code */ + if ((seg & 0x0003) > dpl) { + x86gpf("loadseg(): Normal segment RPL > DPL", seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - if ((CPL) > dpl) { - x86gpf("loadseg(): Normal segment DPL < CPL", seg& 0xfffc); + } + if ((CPL) > dpl) { + x86gpf("loadseg(): Normal segment DPL < CPL", seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - break; - case 0x1e: case 0x1f: /* Readable conforming code */ - break; - default: - x86gpf("loadseg(): Unknown normal segment type", seg & 0xfffc); + } + break; + case 0x1e: + case 0x1f: /* Readable conforming code */ + break; + default: + x86gpf("loadseg(): Unknown normal segment type", seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - } + } + } - if (!(segdat[2] & 0x8000)) { - x86np("Load data seg not present", seg & 0xfffc); + if (!(segdat[2] & 0x8000)) { + x86np("Load data seg not present", seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - s->seg = seg; - do_seg_load(s, segdat); + } + s->seg = seg; + do_seg_load(s, segdat); - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; - s->checked = 0; + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; + s->checked = 0; #ifdef USE_DYNAREC - if (s == &cpu_state.seg_ds) - codegen_flat_ds = 0; - if (s == &cpu_state.seg_ss) - codegen_flat_ss = 0; + if (s == &cpu_state.seg_ds) + codegen_flat_ds = 0; + if (s == &cpu_state.seg_ss) + codegen_flat_ss = 0; #endif } else { - s->access = 0xe2; - s->ar_high = 0x10; - s->base = seg << 4; - s->seg = seg; - s->checked = 1; + s->access = 0xe2; + s->ar_high = 0x10; + s->base = seg << 4; + s->seg = seg; + s->checked = 1; #ifdef USE_DYNAREC - if (s == &cpu_state.seg_ds) - codegen_flat_ds = 0; - if (s == &cpu_state.seg_ss) - codegen_flat_ss = 0; + if (s == &cpu_state.seg_ds) + codegen_flat_ds = 0; + if (s == &cpu_state.seg_ss) + codegen_flat_ss = 0; #endif - if (s == &cpu_state.seg_ss && (cpu_state.eflags & VM_FLAG)) - set_stack32(0); + if (s == &cpu_state.seg_ss && (cpu_state.eflags & VM_FLAG)) + set_stack32(0); } if (s == &cpu_state.seg_ds) { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATDS; } if (s == &cpu_state.seg_ss) { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATSS; } #ifdef USE_NEW_DYNAREC @@ -527,1884 +528,1922 @@ loadseg(uint16_t seg, x86seg *s) #endif } - void loadcs(uint16_t seg) { uint16_t segdat[4]; uint32_t addr, *segdat32 = (uint32_t *) segdat; - x86seg *dt; + x86seg *dt; x86seg_log("Load CS %04X\n", seg); if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { - if (!(seg & 0xfffc)) { - x86gpf("loadcs(): Protected mode selector is zero", 0); - return; - } + if (!(seg & 0xfffc)) { + x86gpf("loadcs(): Protected mode selector is zero", 0); + return; + } - addr = seg & 0xfff8; - dt = (seg & 0x0004)? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("loadcs(): Protected mode selector > DT limit", seg & 0xfffc); - return; - } - addr += dt->base; + addr = seg & 0xfff8; + dt = (seg & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("loadcs(): Protected mode selector > DT limit", seg & 0xfffc); + return; + } + addr += dt->base; - read_descriptor(addr, segdat, segdat32, 1); - if (cpu_state.abrt) - return; - if (segdat[2] & 0x1000) { - /* Normal code segment */ - if (!(segdat[2] & 0x0400)) { - /* Not conforming */ - if ((seg & 3) > CPL) { - x86gpf("loadcs(): Non-conforming RPL > CPL", seg & 0xfffc); - return; - } - if (CPL != DPL) { - x86gpf("loadcs(): Non-conforming CPL != DPL", seg & 0xfffc); - return; - } - } - if (CPL < DPL) { - x86gpf("loadcs(): CPL < DPL", seg & ~3); - return; - } - if (!(segdat[2] & 0x8000)) { - x86np("Load CS not present", seg & 0xfffc); - return; - } - set_use32(segdat[3] & 0x40); - CS = (seg & 0xfffc) | CPL; - do_seg_load(&cpu_state.seg_cs, segdat); - use32 = (segdat[3] & 0x40) ? 0x300 : 0; - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + read_descriptor(addr, segdat, segdat32, 1); + if (cpu_state.abrt) + return; + if (segdat[2] & 0x1000) { + /* Normal code segment */ + if (!(segdat[2] & 0x0400)) { + /* Not conforming */ + if ((seg & 3) > CPL) { + x86gpf("loadcs(): Non-conforming RPL > CPL", seg & 0xfffc); + return; + } + if (CPL != DPL) { + x86gpf("loadcs(): Non-conforming CPL != DPL", seg & 0xfffc); + return; + } + } + if (CPL < DPL) { + x86gpf("loadcs(): CPL < DPL", seg & ~3); + return; + } + if (!(segdat[2] & 0x8000)) { + x86np("Load CS not present", seg & 0xfffc); + return; + } + set_use32(segdat[3] & 0x40); + CS = (seg & 0xfffc) | CPL; + do_seg_load(&cpu_state.seg_cs, segdat); + use32 = (segdat[3] & 0x40) ? 0x300 : 0; + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x0100); /* Set accessed bit */ - cpl_override = 0; - } else { - /* System segment */ - if (!(segdat[2] & 0x8000)) { - x86np("Load CS system seg not present", seg & 0xfffc); - return; - } - switch (segdat[2] & 0x0f00) { - default: - x86gpf("Load CS system segment has bits 0-3 of access rights set", seg & 0xfffc); - return; - } - } + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x0100); /* Set accessed bit */ + cpl_override = 0; + } else { + /* System segment */ + if (!(segdat[2] & 0x8000)) { + x86np("Load CS system seg not present", seg & 0xfffc); + return; + } + switch (segdat[2] & 0x0f00) { + default: + x86gpf("Load CS system segment has bits 0-3 of access rights set", seg & 0xfffc); + return; + } + } } else { - cpu_state.seg_cs.base = (seg << 4); - cpu_state.seg_cs.limit = 0xffff; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - cpu_state.seg_cs.seg = seg & 0xffff; - cpu_state.seg_cs.access = (cpu_state.eflags & VM_FLAG) ? 0xe2 : 0x82; - cpu_state.seg_cs.ar_high = 0x10; - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + cpu_state.seg_cs.base = (seg << 4); + cpu_state.seg_cs.limit = 0xffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; + cpu_state.seg_cs.seg = seg & 0xffff; + cpu_state.seg_cs.access = (cpu_state.eflags & VM_FLAG) ? 0xe2 : 0x82; + cpu_state.seg_cs.ar_high = 0x10; + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif } } - void loadcsjmp(uint16_t seg, uint32_t old_pc) { - uint16_t type, seg2; - uint16_t segdat[4]; - uint32_t addr, newpc; + uint16_t type, seg2; + uint16_t segdat[4]; + uint32_t addr, newpc; uint32_t *segdat32 = (uint32_t *) segdat; - x86seg *dt; + x86seg *dt; if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { - if (!(seg & 0xfffc)) { - x86gpf("loadcsjmp(): Selector is zero", 0); - return; - } - addr = seg & 0xfff8; - dt = (seg & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("loacsjmp(): Selector > DT limit", seg & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat, segdat32, 1); - if (cpu_state.abrt) - return; - x86seg_log("%04X %04X %04X %04X\n", segdat[0], segdat[1], segdat[2], segdat[3]); - if (segdat[2] & 0x1000) { - /* Normal code segment */ - if (!(segdat[2] & 0x0400)) { - /* Not conforming */ - if ((seg & 0x0003) > CPL) { - x86gpf("loadcsjmp(): segment PL > CPL", seg & 0xfffc); - return; - } - if (CPL != DPL) { - x86gpf("loadcsjmp(): CPL != DPL", seg & 0xfffc); - return; - } - } - if (CPL < DPL) { - x86gpf("loadcsjmp(): CPL < DPL",seg & 0xfffc); - return; - } - if (!(segdat[2] & 0x8000)) { - x86np("Load CS JMP not present", seg & 0xfffc); - return; - } - set_use32(segdat[3] & 0x0040); + if (!(seg & 0xfffc)) { + x86gpf("loadcsjmp(): Selector is zero", 0); + return; + } + addr = seg & 0xfff8; + dt = (seg & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("loacsjmp(): Selector > DT limit", seg & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat, segdat32, 1); + if (cpu_state.abrt) + return; + x86seg_log("%04X %04X %04X %04X\n", segdat[0], segdat[1], segdat[2], segdat[3]); + if (segdat[2] & 0x1000) { + /* Normal code segment */ + if (!(segdat[2] & 0x0400)) { + /* Not conforming */ + if ((seg & 0x0003) > CPL) { + x86gpf("loadcsjmp(): segment PL > CPL", seg & 0xfffc); + return; + } + if (CPL != DPL) { + x86gpf("loadcsjmp(): CPL != DPL", seg & 0xfffc); + return; + } + } + if (CPL < DPL) { + x86gpf("loadcsjmp(): CPL < DPL", seg & 0xfffc); + return; + } + if (!(segdat[2] & 0x8000)) { + x86np("Load CS JMP not present", seg & 0xfffc); + return; + } + set_use32(segdat[3] & 0x0040); - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x0100); /* Set accessed bit */ - cpl_override = 0; + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x0100); /* Set accessed bit */ + cpl_override = 0; - CS = (seg & 0xfffc) | CPL; - segdat[2] = (segdat[2] & ~(3 << 13)) | (CPL << 13); + CS = (seg & 0xfffc) | CPL; + segdat[2] = (segdat[2] & ~(3 << 13)) | (CPL << 13); - do_seg_load(&cpu_state.seg_cs, segdat); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + do_seg_load(&cpu_state.seg_cs, segdat); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - cycles -= timing_jmp_pm; - } else { /* System segment */ - if (!(segdat[2] & 0x8000)) { - x86np("Load CS JMP system selector not present", seg & 0xfffc); - return; - } - type = segdat[2] & 0x0f00; - newpc = segdat[0]; - if (type & 0x0800) - newpc |= (segdat[3] << 16); - switch (type) { - case 0x0400: /* Call gate */ - case 0x0c00: - cgate32 = (type & 0x0800); - cgate16 = !cgate32; + cycles -= timing_jmp_pm; + } else { /* System segment */ + if (!(segdat[2] & 0x8000)) { + x86np("Load CS JMP system selector not present", seg & 0xfffc); + return; + } + type = segdat[2] & 0x0f00; + newpc = segdat[0]; + if (type & 0x0800) + newpc |= (segdat[3] << 16); + switch (type) { + case 0x0400: /* Call gate */ + case 0x0c00: + cgate32 = (type & 0x0800); + cgate16 = !cgate32; #ifndef USE_NEW_DYNAREC - oldcs=CS; + oldcs = CS; #endif - cpu_state.oldpc = cpu_state.pc; - if (DPL < CPL) { - x86gpf("loadcsjmp(): Call gate DPL < CPL",seg & 0xfffc); - return; - } - if (DPL < (seg & 0x0003)) { - x86gpf("loadcsjmp(): Call gate DPL< RPL",seg&~3); - return; - } - if (!(segdat[2] & 0x8000)) { - x86np("Load CS JMP call gate not present", seg & 0xfffc); - return; - } - seg2 = segdat[1]; + cpu_state.oldpc = cpu_state.pc; + if (DPL < CPL) { + x86gpf("loadcsjmp(): Call gate DPL < CPL", seg & 0xfffc); + return; + } + if (DPL < (seg & 0x0003)) { + x86gpf("loadcsjmp(): Call gate DPL< RPL", seg & ~3); + return; + } + if (!(segdat[2] & 0x8000)) { + x86np("Load CS JMP call gate not present", seg & 0xfffc); + return; + } + seg2 = segdat[1]; - if (!(seg2 & 0xfffc)) { - x86gpf("Load CS JMP call gate selector is NULL", 0); - return; - } - addr = seg2 & 0xfff8; - dt = (seg2 & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("loadcsjmp(): Call gate selector > DT limit", seg2 & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat, segdat32, 1); - if (cpu_state.abrt) - return; + if (!(seg2 & 0xfffc)) { + x86gpf("Load CS JMP call gate selector is NULL", 0); + return; + } + addr = seg2 & 0xfff8; + dt = (seg2 & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("loadcsjmp(): Call gate selector > DT limit", seg2 & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat, segdat32, 1); + if (cpu_state.abrt) + return; - if (DPL > CPL) { - x86gpf("loadcsjmp(): ex DPL > CPL",seg2 & 0xfffc); - return; - } - if (!(segdat[2] & 0x8000)) { - x86np("Load CS JMP from call gate not present", seg2 & 0xfffc); - return; - } + if (DPL > CPL) { + x86gpf("loadcsjmp(): ex DPL > CPL", seg2 & 0xfffc); + return; + } + if (!(segdat[2] & 0x8000)) { + x86np("Load CS JMP from call gate not present", seg2 & 0xfffc); + return; + } - switch (segdat[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming code */ - if (DPL > CPL) { - x86gpf("loadcsjmp(): Non-conforming DPL > CPL", seg2 & 0xfffc); - return; - } - /*FALLTHROUGH*/ - case 0x1c00: case 0x1d00: case 0x1e00: case 0x1f00: /* Conforming */ - CS = seg2; - do_seg_load(&cpu_state.seg_cs, segdat); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + switch (segdat[2] & 0x1f00) { + case 0x1800: + case 0x1900: + case 0x1a00: + case 0x1b00: /* Non-conforming code */ + if (DPL > CPL) { + x86gpf("loadcsjmp(): Non-conforming DPL > CPL", seg2 & 0xfffc); + return; + } + /*FALLTHROUGH*/ + case 0x1c00: + case 0x1d00: + case 0x1e00: + case 0x1f00: /* Conforming */ + CS = seg2; + do_seg_load(&cpu_state.seg_cs, segdat); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat[3]&0x40); - cpu_state.pc=newpc; + set_use32(segdat[3] & 0x40); + cpu_state.pc = newpc; - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; - break; + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; + break; - default: - x86gpf("loadcsjmp(): Unknown type", seg2 & 0xfffc); - return; - } - cycles -= timing_jmp_pm_gate; - break; + default: + x86gpf("loadcsjmp(): Unknown type", seg2 & 0xfffc); + return; + } + cycles -= timing_jmp_pm_gate; + break; - case 0x100: /* 286 Task gate */ - case 0x900: /* 386 Task gate */ - cpu_state.pc = old_pc; - optype = JMP; - cpl_override = 1; - taskswitch286(seg,segdat,segdat[2] & 0x800); - cpu_state.flags &= ~NT_FLAG; - cpl_override=0; - return; + case 0x100: /* 286 Task gate */ + case 0x900: /* 386 Task gate */ + cpu_state.pc = old_pc; + optype = JMP; + cpl_override = 1; + taskswitch286(seg, segdat, segdat[2] & 0x800); + cpu_state.flags &= ~NT_FLAG; + cpl_override = 0; + return; - default: - x86gpf("Load CS JMP call gate selector unknown type", 0); - return; - } - } + default: + x86gpf("Load CS JMP call gate selector unknown type", 0); + return; + } + } } else { - cpu_state.seg_cs.base = seg << 4; - cpu_state.seg_cs.limit = 0xffff; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - cpu_state.seg_cs.seg = seg; - cpu_state.seg_cs.access = (cpu_state.eflags & VM_FLAG) ? 0xe2 : 0x82; - cpu_state.seg_cs.ar_high = 0x10; - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + cpu_state.seg_cs.base = seg << 4; + cpu_state.seg_cs.limit = 0xffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; + cpu_state.seg_cs.seg = seg; + cpu_state.seg_cs.access = (cpu_state.eflags & VM_FLAG) ? 0xe2 : 0x82; + cpu_state.seg_cs.ar_high = 0x10; + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - cycles -= timing_jmp_rm; + cycles -= timing_jmp_rm; } } - void PUSHW(uint16_t v) { if (stack32) { - writememw(ss, ESP - 2, v); - if (cpu_state.abrt) - return; - ESP -= 2; + writememw(ss, ESP - 2, v); + if (cpu_state.abrt) + return; + ESP -= 2; } else { - writememw(ss, ((SP - 2) & 0xffff), v); - if (cpu_state.abrt) - return; - SP -= 2; + writememw(ss, ((SP - 2) & 0xffff), v); + if (cpu_state.abrt) + return; + SP -= 2; } } - void PUSHL(uint32_t v) { if (cpu_16bitbus) { - PUSHW(v >> 16); - PUSHW(v & 0xffff); + PUSHW(v >> 16); + PUSHW(v & 0xffff); } else { - if (stack32) { - writememl(ss, ESP - 4, v); - if (cpu_state.abrt) - return; - ESP -= 4; - } else { - writememl(ss, ((SP - 4) & 0xffff), v); - if (cpu_state.abrt) - return; - SP -= 4; - } + if (stack32) { + writememl(ss, ESP - 4, v); + if (cpu_state.abrt) + return; + ESP -= 4; + } else { + writememl(ss, ((SP - 4) & 0xffff), v); + if (cpu_state.abrt) + return; + SP -= 4; + } } } - uint16_t POPW(void) { uint16_t tempw; if (stack32) { - tempw = readmemw(ss, ESP); - if (cpu_state.abrt) - return 0; - ESP += 2; + tempw = readmemw(ss, ESP); + if (cpu_state.abrt) + return 0; + ESP += 2; } else { - tempw = readmemw(ss, SP); - if (cpu_state.abrt) - return 0; - SP += 2; + tempw = readmemw(ss, SP); + if (cpu_state.abrt) + return 0; + SP += 2; } return tempw; } - uint32_t POPL(void) { uint32_t templ; if (cpu_16bitbus) { - templ = POPW(); - templ |= (POPW() << 16); + templ = POPW(); + templ |= (POPW() << 16); } else { - if (stack32) { - templ = readmeml(ss, ESP); - if (cpu_state.abrt) - return 0; - ESP += 4; - } else { - templ = readmeml(ss, SP); - if (cpu_state.abrt) - return 0; - SP += 4; - } + if (stack32) { + templ = readmeml(ss, ESP); + if (cpu_state.abrt) + return 0; + ESP += 4; + } else { + templ = readmeml(ss, SP); + if (cpu_state.abrt) + return 0; + SP += 4; + } } return templ; } - #ifdef USE_NEW_DYNAREC -void loadcscall(uint16_t seg, uint32_t old_pc) +void +loadcscall(uint16_t seg, uint32_t old_pc) #else -void loadcscall(uint16_t seg) +void +loadcscall(uint16_t seg) #endif { - uint16_t seg2, newss; - uint16_t segdat[4], segdat2[4]; - uint32_t addr, oldssbase = ss; - uint32_t oaddr, newpc; - uint32_t *segdat32 = (uint32_t *) segdat; + uint16_t seg2, newss; + uint16_t segdat[4], segdat2[4]; + uint32_t addr, oldssbase = ss; + uint32_t oaddr, newpc; + uint32_t *segdat32 = (uint32_t *) segdat; uint32_t *segdat232 = (uint32_t *) segdat2; - int count, type; - uint32_t oldss, oldsp, newsp, oldsp2; - uint16_t tempw; - x86seg *dt; + int count, type; + uint32_t oldss, oldsp, newsp, oldsp2; + uint16_t tempw; + x86seg *dt; if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { - x86seg_log("Protected mode CS load! %04X\n", seg); - if (!(seg & 0xfffc)) { - x86gpf("loadcscall(): Protected mode selector is zero",0); - return; - } - addr = seg & 0xfff8; - dt = (seg & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("loadcscall(): Selector > DT limit", seg & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat, segdat32, 1); - if (cpu_state.abrt) - return; - type = segdat[2] & 0x0f00; - newpc = segdat[0]; - if (type & 0x0800) - newpc |= segdat[3] << 16; + x86seg_log("Protected mode CS load! %04X\n", seg); + if (!(seg & 0xfffc)) { + x86gpf("loadcscall(): Protected mode selector is zero", 0); + return; + } + addr = seg & 0xfff8; + dt = (seg & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("loadcscall(): Selector > DT limit", seg & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat, segdat32, 1); + if (cpu_state.abrt) + return; + type = segdat[2] & 0x0f00; + newpc = segdat[0]; + if (type & 0x0800) + newpc |= segdat[3] << 16; - x86seg_log("Code seg call - %04X - %04X %04X %04X\n", seg, segdat[0], segdat[1], segdat[2]); - if (segdat[2] & 0x1000) { - if (!(segdat[2] & 0x0400)) { /* Not conforming */ - if ((seg & 0x0003) > CPL) { - x86gpf("loadcscall(): Non-conforming RPL > CPL", seg & 0xfffc); - return; - } - if (CPL != DPL) { - x86gpf("loadcscall(): Non-conforming CPL != DPL", seg & 0xfffc); - return; - } - } - if (CPL < DPL) { - x86gpf("loadcscall(): CPL < DPL", seg & 0xfffc); - return; - } - if (!(segdat[2] & 0x8000)) { - x86np("Load CS call not present", seg & 0xfffc); - return; - } - set_use32(segdat[3] & 0x0040); + x86seg_log("Code seg call - %04X - %04X %04X %04X\n", seg, segdat[0], segdat[1], segdat[2]); + if (segdat[2] & 0x1000) { + if (!(segdat[2] & 0x0400)) { /* Not conforming */ + if ((seg & 0x0003) > CPL) { + x86gpf("loadcscall(): Non-conforming RPL > CPL", seg & 0xfffc); + return; + } + if (CPL != DPL) { + x86gpf("loadcscall(): Non-conforming CPL != DPL", seg & 0xfffc); + return; + } + } + if (CPL < DPL) { + x86gpf("loadcscall(): CPL < DPL", seg & 0xfffc); + return; + } + if (!(segdat[2] & 0x8000)) { + x86np("Load CS call not present", seg & 0xfffc); + return; + } + set_use32(segdat[3] & 0x0040); - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; - /* Conforming segments don't change CPL, so preserve existing CPL */ - if (segdat[2] & 0x0400) { - seg = (seg & 0xfffc) | CPL; - segdat[2] = (segdat[2] & ~(3 << (5+8))) | (CPL << (5+8)); - } else /* On non-conforming segments, set RPL = CPL */ - seg = (seg & 0xfffc) | CPL; - CS = seg; - do_seg_load(&cpu_state.seg_cs, segdat); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + /* Conforming segments don't change CPL, so preserve existing CPL */ + if (segdat[2] & 0x0400) { + seg = (seg & 0xfffc) | CPL; + segdat[2] = (segdat[2] & ~(3 << (5 + 8))) | (CPL << (5 + 8)); + } else /* On non-conforming segments, set RPL = CPL */ + seg = (seg & 0xfffc) | CPL; + CS = seg; + do_seg_load(&cpu_state.seg_cs, segdat); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif #ifdef ENABLE_X86SEG_LOG - x86seg_log("Complete\n"); + x86seg_log("Complete\n"); #endif - cycles -= timing_call_pm; - } else { - type = segdat[2] & 0x0f00; - x86seg_log("Type %03X\n", type); - switch (type) { - case 0x0400: /* Call gate */ - case 0x0c00: /* 386 Call gate */ - x86seg_log("Callgate %08X\n", cpu_state.pc); - cgate32 = (type & 0x0800); - cgate16 = !cgate32; + cycles -= timing_call_pm; + } else { + type = segdat[2] & 0x0f00; + x86seg_log("Type %03X\n", type); + switch (type) { + case 0x0400: /* Call gate */ + case 0x0c00: /* 386 Call gate */ + x86seg_log("Callgate %08X\n", cpu_state.pc); + cgate32 = (type & 0x0800); + cgate16 = !cgate32; #ifndef USE_NEW_DYNAREC - oldcs = CS; + oldcs = CS; #endif - count = segdat[2] & 0x001f; - if (DPL < CPL) { - x86gpf("loadcscall(): ex DPL < CPL",seg & 0xfffc); - return; - } - if (DPL < (seg & 0x0003)) { - x86gpf("loadcscall(): ex DPL < RPL", seg & 0xfffc); - return; - } - if (!(segdat[2] & 0x8000)) { - x86np("Call gate not present", seg & 0xfffc); - return; - } - seg2 = segdat[1]; + count = segdat[2] & 0x001f; + if (DPL < CPL) { + x86gpf("loadcscall(): ex DPL < CPL", seg & 0xfffc); + return; + } + if (DPL < (seg & 0x0003)) { + x86gpf("loadcscall(): ex DPL < RPL", seg & 0xfffc); + return; + } + if (!(segdat[2] & 0x8000)) { + x86np("Call gate not present", seg & 0xfffc); + return; + } + seg2 = segdat[1]; - x86seg_log("New address : %04X:%08X\n", seg2, newpc); + x86seg_log("New address : %04X:%08X\n", seg2, newpc); - if (!(seg2 & 0xfffc)) { - x86gpf("loadcscall(): ex selector is NULL", 0); - return; - } - addr = seg2 & 0xfff8; - dt = (seg2 & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("loadcscall(): ex Selector > DT limit", seg2 & 0xfff8); - return; - } - addr += dt->base; - read_descriptor(addr, segdat, segdat32, 1); - if (cpu_state.abrt) - return; + if (!(seg2 & 0xfffc)) { + x86gpf("loadcscall(): ex selector is NULL", 0); + return; + } + addr = seg2 & 0xfff8; + dt = (seg2 & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("loadcscall(): ex Selector > DT limit", seg2 & 0xfff8); + return; + } + addr += dt->base; + read_descriptor(addr, segdat, segdat32, 1); + if (cpu_state.abrt) + return; - x86seg_log("Code seg2 call - %04X - %04X %04X %04X\n", seg2, segdat[0], segdat[1], segdat[2]); + x86seg_log("Code seg2 call - %04X - %04X %04X %04X\n", seg2, segdat[0], segdat[1], segdat[2]); - if (DPL > CPL) { - x86gpf("loadcscall(): ex DPL > CPL", seg2 & 0xfffc); - return; - } - if (!(segdat[2] & 0x8000)) { - x86seg_log("Call gate CS not present %04X\n", seg2); - x86np("Call gate CS not present", seg2 & 0xfffc); - return; - } + if (DPL > CPL) { + x86gpf("loadcscall(): ex DPL > CPL", seg2 & 0xfffc); + return; + } + if (!(segdat[2] & 0x8000)) { + x86seg_log("Call gate CS not present %04X\n", seg2); + x86np("Call gate CS not present", seg2 & 0xfffc); + return; + } - switch (segdat[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming code */ - if (DPL < CPL) { + switch (segdat[2] & 0x1f00) { + case 0x1800: + case 0x1900: + case 0x1a00: + case 0x1b00: /* Non-conforming code */ + if (DPL < CPL) { #ifdef USE_NEW_DYNAREC - uint16_t oldcs = CS; + uint16_t oldcs = CS; #endif - oaddr = addr; - /* Load new stack */ - oldss = SS; - oldsp = oldsp2 = ESP; - cpl_override = 1; - if (tr.access & 8) { - addr = 4 + tr.base + (DPL << 3); - newss = readmemw(0, addr + 4); - if (cpu_16bitbus) { - newsp = readmemw(0, addr); - newsp |= (readmemw(0, addr + 2) << 16); - } else - newsp = readmeml(0, addr); - } else { - addr = 2 + tr.base + (DPL * 4); - newss = readmemw(0, addr + 2); - newsp = readmemw(0, addr); - } - cpl_override = 0; - if (cpu_state.abrt) - return; - x86seg_log("New stack %04X:%08X\n", newss, newsp); - if (!(newss & 0xfffc)) { - x86ts(NULL, newss & 0xfffc); - return; - } - addr = newss & 0xfff8; - dt = (newss & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - fatal("Bigger than DT limit %04X %08X %04X CSC SS\n", newss, addr, dt->limit); - x86ts(NULL, newss & ~3); - return; - } - addr += dt->base; - x86seg_log("Read stack seg\n"); - read_descriptor(addr, segdat2, segdat232, 1); - if (cpu_state.abrt) - return; - x86seg_log("Read stack seg done!\n"); - if (((newss & 0x0003) != DPL) || (DPL2 != DPL)) { - x86ts(NULL, newss & 0xfffc); - return; - } - if ((segdat2[2] & 0x1a00) != 0x1200) { - x86ts("Call gate loading SS unknown type", newss & 0xfffc); - return; - } - if (!(segdat2[2] & 0x8000)) { - x86ss("Call gate loading SS not present", newss & 0xfffc); - return; - } - if (!stack32) - oldsp &= 0xffff; - SS = newss; - set_stack32((segdat2[3] & 0x0040) ? 1 : 0); - if (stack32) - ESP = newsp; - else - SP = newsp; + oaddr = addr; + /* Load new stack */ + oldss = SS; + oldsp = oldsp2 = ESP; + cpl_override = 1; + if (tr.access & 8) { + addr = 4 + tr.base + (DPL << 3); + newss = readmemw(0, addr + 4); + if (cpu_16bitbus) { + newsp = readmemw(0, addr); + newsp |= (readmemw(0, addr + 2) << 16); + } else + newsp = readmeml(0, addr); + } else { + addr = 2 + tr.base + (DPL * 4); + newss = readmemw(0, addr + 2); + newsp = readmemw(0, addr); + } + cpl_override = 0; + if (cpu_state.abrt) + return; + x86seg_log("New stack %04X:%08X\n", newss, newsp); + if (!(newss & 0xfffc)) { + x86ts(NULL, newss & 0xfffc); + return; + } + addr = newss & 0xfff8; + dt = (newss & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + fatal("Bigger than DT limit %04X %08X %04X CSC SS\n", newss, addr, dt->limit); + x86ts(NULL, newss & ~3); + return; + } + addr += dt->base; + x86seg_log("Read stack seg\n"); + read_descriptor(addr, segdat2, segdat232, 1); + if (cpu_state.abrt) + return; + x86seg_log("Read stack seg done!\n"); + if (((newss & 0x0003) != DPL) || (DPL2 != DPL)) { + x86ts(NULL, newss & 0xfffc); + return; + } + if ((segdat2[2] & 0x1a00) != 0x1200) { + x86ts("Call gate loading SS unknown type", newss & 0xfffc); + return; + } + if (!(segdat2[2] & 0x8000)) { + x86ss("Call gate loading SS not present", newss & 0xfffc); + return; + } + if (!stack32) + oldsp &= 0xffff; + SS = newss; + set_stack32((segdat2[3] & 0x0040) ? 1 : 0); + if (stack32) + ESP = newsp; + else + SP = newsp; - do_seg_load(&cpu_state.seg_ss, segdat2); + do_seg_load(&cpu_state.seg_ss, segdat2); - x86seg_log("Set access 1\n"); - cpl_override = 1; - writememw(0, addr + 4, segdat2[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; + x86seg_log("Set access 1\n"); + cpl_override = 1; + writememw(0, addr + 4, segdat2[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; - CS = seg2; - do_seg_load(&cpu_state.seg_cs, segdat); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + CS = seg2; + do_seg_load(&cpu_state.seg_cs, segdat); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat[3] & 0x0040); - cpu_state.pc = newpc; + set_use32(segdat[3] & 0x0040); + cpu_state.pc = newpc; - x86seg_log("Set access 2\n"); + x86seg_log("Set access 2\n"); - cpl_override = 1; - writememw(0, oaddr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; + cpl_override = 1; + writememw(0, oaddr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; - x86seg_log("Type %04X\n", type); - if (type == 0x0c00) { - PUSHL(oldss); - PUSHL(oldsp2); - if (cpu_state.abrt) { - SS = oldss; - ESP = oldsp2; + x86seg_log("Type %04X\n", type); + if (type == 0x0c00) { + PUSHL(oldss); + PUSHL(oldsp2); + if (cpu_state.abrt) { + SS = oldss; + ESP = oldsp2; #ifdef USE_NEW_DYNAREC - CS = oldcs; + CS = oldcs; #endif - return; - } - if (count) { - while (count--) { - PUSHL(readmeml(oldssbase, oldsp + (count << 2))); - if (cpu_state.abrt) { - SS = oldss; - ESP = oldsp2; + return; + } + if (count) { + while (count--) { + PUSHL(readmeml(oldssbase, oldsp + (count << 2))); + if (cpu_state.abrt) { + SS = oldss; + ESP = oldsp2; #ifdef USE_NEW_DYNAREC - CS = oldcs; + CS = oldcs; #endif - return; - } - } - } - } else { - x86seg_log("Stack %04X\n", SP); - PUSHW(oldss); - x86seg_log("Write SS to %04X:%04X\n", SS, SP); - PUSHW(oldsp2); - if (cpu_state.abrt) { - SS = oldss; - ESP = oldsp2; + return; + } + } + } + } else { + x86seg_log("Stack %04X\n", SP); + PUSHW(oldss); + x86seg_log("Write SS to %04X:%04X\n", SS, SP); + PUSHW(oldsp2); + if (cpu_state.abrt) { + SS = oldss; + ESP = oldsp2; #ifdef USE_NEW_DYNAREC - CS = oldcs; + CS = oldcs; #endif - return; - } - x86seg_log("Write SP to %04X:%04X\n", SS, SP); - if (count) { - while (count--) { - tempw = readmemw(oldssbase, (oldsp & 0xffff) + (count << 1)); - x86seg_log("PUSH %04X\n", tempw); - PUSHW(tempw); - if (cpu_state.abrt) { - SS = oldss; - ESP = oldsp2; + return; + } + x86seg_log("Write SP to %04X:%04X\n", SS, SP); + if (count) { + while (count--) { + tempw = readmemw(oldssbase, (oldsp & 0xffff) + (count << 1)); + x86seg_log("PUSH %04X\n", tempw); + PUSHW(tempw); + if (cpu_state.abrt) { + SS = oldss; + ESP = oldsp2; #ifdef USE_NEW_DYNAREC - CS = oldcs; + CS = oldcs; #endif - return; - } - } - } - } - cycles -= timing_call_pm_gate_inner; - break; - } else if (DPL > CPL) { - x86gpf("loadcscall(): Call PM Gate Inner DPL > CPL",seg2 & 0xfffc); - return; - } - /*FALLTHROUGH*/ - case 0x1c00: case 0x1d00: case 0x1e00: case 0x1f00: /* Conforming */ - CS = seg2; - do_seg_load(&cpu_state.seg_cs, segdat); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + return; + } + } + } + } + cycles -= timing_call_pm_gate_inner; + break; + } else if (DPL > CPL) { + x86gpf("loadcscall(): Call PM Gate Inner DPL > CPL", seg2 & 0xfffc); + return; + } + /*FALLTHROUGH*/ + case 0x1c00: + case 0x1d00: + case 0x1e00: + case 0x1f00: /* Conforming */ + CS = seg2; + do_seg_load(&cpu_state.seg_cs, segdat); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat[3] & 0x0040); - cpu_state.pc = newpc; + set_use32(segdat[3] & 0x0040); + cpu_state.pc = newpc; - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; - cycles -= timing_call_pm_gate; - break; + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; + cycles -= timing_call_pm_gate; + break; - default: - x86gpf("loadcscall(): Unknown subtype", seg2 & 0xfffc); - return; - } - break; + default: + x86gpf("loadcscall(): Unknown subtype", seg2 & 0xfffc); + return; + } + break; - case 0x0100: /* 286 Task gate */ - case 0x0900: /* 386 Task gate */ + case 0x0100: /* 286 Task gate */ + case 0x0900: /* 386 Task gate */ #ifdef USE_NEW_DYNAREC - cpu_state.pc = old_pc; + cpu_state.pc = old_pc; #else - cpu_state.pc = oxpc; + cpu_state.pc = oxpc; #endif - cpl_override = 1; - taskswitch286(seg, segdat, segdat[2] & 0x0800); - cpl_override = 0; - break; + cpl_override = 1; + taskswitch286(seg, segdat, segdat[2] & 0x0800); + cpl_override = 0; + break; - default: - x86gpf("loadcscall(): Unknown type", seg & 0xfffc); - return; - } - } + default: + x86gpf("loadcscall(): Unknown type", seg & 0xfffc); + return; + } + } } else { - cpu_state.seg_cs.base = seg << 4; - cpu_state.seg_cs.limit = 0xffff; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - cpu_state.seg_cs.seg = seg; - cpu_state.seg_cs.access = (cpu_state.eflags & VM_FLAG) ? 0xe2 : 0x82; - cpu_state.seg_cs.ar_high = 0x10; - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + cpu_state.seg_cs.base = seg << 4; + cpu_state.seg_cs.limit = 0xffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; + cpu_state.seg_cs.seg = seg; + cpu_state.seg_cs.access = (cpu_state.eflags & VM_FLAG) ? 0xe2 : 0x82; + cpu_state.seg_cs.ar_high = 0x10; + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif } } - void pmoderetf(int is32, uint16_t off) { - uint16_t segdat[4], segdat2[4], seg,newss; - uint32_t newpc, newsp, addr, oaddr; - uint32_t oldsp = ESP; - uint32_t *segdat32 = (uint32_t *) segdat; + uint16_t segdat[4], segdat2[4], seg, newss; + uint32_t newpc, newsp, addr, oaddr; + uint32_t oldsp = ESP; + uint32_t *segdat32 = (uint32_t *) segdat; uint32_t *segdat232 = (uint32_t *) segdat2; - x86seg *dt; + x86seg *dt; x86seg_log("RETF %i %04X:%04X %08X %04X\n", is32, CS, cpu_state.pc, cr0, cpu_state.eflags); if (is32) { - newpc = POPL(); - seg = POPL(); + newpc = POPL(); + seg = POPL(); } else { - x86seg_log("PC read from %04X:%04X\n", SS, SP); - newpc = POPW(); - x86seg_log("CS read from %04X:%04X\n", SS, SP); - seg = POPW(); + x86seg_log("PC read from %04X:%04X\n", SS, SP); + newpc = POPW(); + x86seg_log("CS read from %04X:%04X\n", SS, SP); + seg = POPW(); } if (cpu_state.abrt) - return; + return; x86seg_log("Return to %04X:%08X\n", seg, newpc); if ((seg & 0x0003) < CPL) { - ESP = oldsp; - x86gpf("pmoderetf(): seg < CPL", seg & 0xfffc); - return; + ESP = oldsp; + x86gpf("pmoderetf(): seg < CPL", seg & 0xfffc); + return; } if (!(seg & 0xfffc)) { - x86gpf("pmoderetf(): seg is NULL", 0); - return; + x86gpf("pmoderetf(): seg is NULL", 0); + return; } addr = seg & 0xfff8; - dt = (seg & 0x0004) ? &ldt : &gdt; + dt = (seg & 0x0004) ? &ldt : &gdt; if ((addr + 7) > dt->limit) { - x86gpf("pmoderetf(): Selector > DT limit", seg & 0xfffc); - return; + x86gpf("pmoderetf(): Selector > DT limit", seg & 0xfffc); + return; } addr += dt->base; read_descriptor(addr, segdat, segdat32, 1); if (cpu_state.abrt) { - ESP = oldsp; - return; + ESP = oldsp; + return; } oaddr = addr; x86seg_log("CPL %i RPL %i %i\n", CPL, seg & 0x0003, is32); if (stack32) - ESP += off; + ESP += off; else - SP += off; + SP += off; if (CPL == (seg & 0x0003)) { - x86seg_log("RETF CPL = RPL %04X\n", segdat[2]); - switch (segdat[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming */ - if (CPL != DPL) { - ESP = oldsp; - x86gpf("pmoderetf(): Non-conforming CPL != DPL", seg & 0xfffc); - return; - } - break; - case 0x1c00: case 0x1d00: case 0x1e00: case 0x1f00: /* Conforming */ - if (CPL < DPL) { - ESP = oldsp; - x86gpf("pmoderetf(): Conforming CPL < DPL", seg & 0xfffc); - return; - } - break; - default: - x86gpf("pmoderetf(): Unknown type", seg & 0xfffc); - return; - } - if (!(segdat[2] & 0x8000)) { - ESP = oldsp; - x86np("RETF CS not present", seg & 0xfffc); - return; - } + x86seg_log("RETF CPL = RPL %04X\n", segdat[2]); + switch (segdat[2] & 0x1f00) { + case 0x1800: + case 0x1900: + case 0x1a00: + case 0x1b00: /* Non-conforming */ + if (CPL != DPL) { + ESP = oldsp; + x86gpf("pmoderetf(): Non-conforming CPL != DPL", seg & 0xfffc); + return; + } + break; + case 0x1c00: + case 0x1d00: + case 0x1e00: + case 0x1f00: /* Conforming */ + if (CPL < DPL) { + ESP = oldsp; + x86gpf("pmoderetf(): Conforming CPL < DPL", seg & 0xfffc); + return; + } + break; + default: + x86gpf("pmoderetf(): Unknown type", seg & 0xfffc); + return; + } + if (!(segdat[2] & 0x8000)) { + ESP = oldsp; + x86np("RETF CS not present", seg & 0xfffc); + return; + } - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; - cpu_state.pc = newpc; - if (segdat[2] & 0x0400) - segdat[2] = (segdat[2] & ~(3 << 13)) | ((seg & 3) << 13); - CS = seg; - do_seg_load(&cpu_state.seg_cs, segdat); - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + cpu_state.pc = newpc; + if (segdat[2] & 0x0400) + segdat[2] = (segdat[2] & ~(3 << 13)) | ((seg & 3) << 13); + CS = seg; + do_seg_load(&cpu_state.seg_cs, segdat); + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat[3] & 0x0040); + set_use32(segdat[3] & 0x0040); - cycles -= timing_retf_pm; + cycles -= timing_retf_pm; } else { - switch (segdat[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming */ - if ((seg & 0x0003) != DPL) { - ESP = oldsp; - x86gpf("pmoderetf(): Non-conforming RPL != DPL", seg & 0xfffc); - return; - } - x86seg_log("RETF non-conforming, %i %i\n", seg & 0x0003, DPL); - break; - case 0x1c00: case 0x1d00: case 0x1e00: case 0x1f00: /* Conforming */ - if ((seg & 0x0003) < DPL) { - ESP = oldsp; - x86gpf("pmoderetf(): Conforming RPL < DPL", seg & 0xfffc); - return; - } - x86seg_log("RETF conforming, %i %i\n", seg & 0x0003, DPL); - break; - default: - ESP = oldsp; - x86gpf("pmoderetf(): Unknown type", seg & 0xfffc); - return; - } - if (!(segdat[2] & 0x8000)) { - ESP = oldsp; - x86np("RETF CS not present", seg & 0xfffc); - return; - } - if (is32) { - newsp = POPL(); - newss = POPL(); - if (cpu_state.abrt) - return; - } else { - x86seg_log("SP read from %04X:%04X\n", SS, SP); - newsp = POPW(); - x86seg_log("SS read from %04X:%04X\n", SS, SP); - newss = POPW(); - if (cpu_state.abrt) - return; - } - x86seg_log("Read new stack : %04X:%04X (%08X)\n", newss, newsp, ldt.base); - if (!(newss & 0xfffc)) { - ESP = oldsp; - x86gpf("pmoderetf(): New SS selector is zero",newss&~3); - return; - } - addr = newss & 0xfff8; - dt = (newss & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - ESP = oldsp; - x86gpf("pmoderetf(): New SS selector > DT limit", newss & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat2, segdat232, 1); - if (cpu_state.abrt) { - ESP = oldsp; - return; - } - x86seg_log("Segment data %04X %04X %04X %04X\n", segdat2[0], segdat2[1], segdat2[2], segdat2[3]); - if ((newss & 0x0003) != (seg & 0x0003)) { - ESP = oldsp; - x86gpf("pmoderetf(): New SS RPL > CS RPL", newss & 0xfffc); - return; - } - if ((segdat2[2] & 0x1a00) != 0x1200) { - ESP = oldsp; - x86gpf("pmoderetf(): New SS unknown type", newss & 0xfffc); - return; - } - if (!(segdat2[2] & 0x8000)) { - ESP = oldsp; - x86np("RETF loading SS not present", newss & 0xfffc); - return; - } - if (DPL2 != (seg & 3)) { - ESP = oldsp; - x86gpf("pmoderetf(): New SS DPL != CS RPL",newss & 0xfffc); - return; - } - SS = newss; - set_stack32((segdat2[3] & 0x0040) ? 1 : 0); - if (stack32) - ESP = newsp; - else - SP = newsp; - do_seg_load(&cpu_state.seg_ss, segdat2); + switch (segdat[2] & 0x1f00) { + case 0x1800: + case 0x1900: + case 0x1a00: + case 0x1b00: /* Non-conforming */ + if ((seg & 0x0003) != DPL) { + ESP = oldsp; + x86gpf("pmoderetf(): Non-conforming RPL != DPL", seg & 0xfffc); + return; + } + x86seg_log("RETF non-conforming, %i %i\n", seg & 0x0003, DPL); + break; + case 0x1c00: + case 0x1d00: + case 0x1e00: + case 0x1f00: /* Conforming */ + if ((seg & 0x0003) < DPL) { + ESP = oldsp; + x86gpf("pmoderetf(): Conforming RPL < DPL", seg & 0xfffc); + return; + } + x86seg_log("RETF conforming, %i %i\n", seg & 0x0003, DPL); + break; + default: + ESP = oldsp; + x86gpf("pmoderetf(): Unknown type", seg & 0xfffc); + return; + } + if (!(segdat[2] & 0x8000)) { + ESP = oldsp; + x86np("RETF CS not present", seg & 0xfffc); + return; + } + if (is32) { + newsp = POPL(); + newss = POPL(); + if (cpu_state.abrt) + return; + } else { + x86seg_log("SP read from %04X:%04X\n", SS, SP); + newsp = POPW(); + x86seg_log("SS read from %04X:%04X\n", SS, SP); + newss = POPW(); + if (cpu_state.abrt) + return; + } + x86seg_log("Read new stack : %04X:%04X (%08X)\n", newss, newsp, ldt.base); + if (!(newss & 0xfffc)) { + ESP = oldsp; + x86gpf("pmoderetf(): New SS selector is zero", newss & ~3); + return; + } + addr = newss & 0xfff8; + dt = (newss & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + ESP = oldsp; + x86gpf("pmoderetf(): New SS selector > DT limit", newss & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat2, segdat232, 1); + if (cpu_state.abrt) { + ESP = oldsp; + return; + } + x86seg_log("Segment data %04X %04X %04X %04X\n", segdat2[0], segdat2[1], segdat2[2], segdat2[3]); + if ((newss & 0x0003) != (seg & 0x0003)) { + ESP = oldsp; + x86gpf("pmoderetf(): New SS RPL > CS RPL", newss & 0xfffc); + return; + } + if ((segdat2[2] & 0x1a00) != 0x1200) { + ESP = oldsp; + x86gpf("pmoderetf(): New SS unknown type", newss & 0xfffc); + return; + } + if (!(segdat2[2] & 0x8000)) { + ESP = oldsp; + x86np("RETF loading SS not present", newss & 0xfffc); + return; + } + if (DPL2 != (seg & 3)) { + ESP = oldsp; + x86gpf("pmoderetf(): New SS DPL != CS RPL", newss & 0xfffc); + return; + } + SS = newss; + set_stack32((segdat2[3] & 0x0040) ? 1 : 0); + if (stack32) + ESP = newsp; + else + SP = newsp; + do_seg_load(&cpu_state.seg_ss, segdat2); - cpl_override = 1; - writememw(0, addr + 4, segdat2[2] | 0x100); /* Set accessed bit */ - writememw(0, oaddr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; - /* Conforming segments don't change CPL, so CPL = RPL */ - if (segdat[2] & 0x0400) - segdat[2] = (segdat[2] & ~(3 << 13)) | ((seg & 3) << 13); - cpu_state.pc = newpc; - CS = seg; - do_seg_load(&cpu_state.seg_cs, segdat); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + cpl_override = 1; + writememw(0, addr + 4, segdat2[2] | 0x100); /* Set accessed bit */ + writememw(0, oaddr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; + /* Conforming segments don't change CPL, so CPL = RPL */ + if (segdat[2] & 0x0400) + segdat[2] = (segdat[2] & ~(3 << 13)) | ((seg & 3) << 13); + cpu_state.pc = newpc; + CS = seg; + do_seg_load(&cpu_state.seg_cs, segdat); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat[3] & 0x0040); + set_use32(segdat[3] & 0x0040); - if (stack32) - ESP += off; - else - SP += off; + if (stack32) + ESP += off; + else + SP += off; - check_seg_valid(&cpu_state.seg_ds); - check_seg_valid(&cpu_state.seg_es); - check_seg_valid(&cpu_state.seg_fs); - check_seg_valid(&cpu_state.seg_gs); - cycles -= timing_retf_pm_outer; + check_seg_valid(&cpu_state.seg_ds); + check_seg_valid(&cpu_state.seg_es); + check_seg_valid(&cpu_state.seg_fs); + check_seg_valid(&cpu_state.seg_gs); + cycles -= timing_retf_pm_outer; } } - void pmodeint(int num, int soft) { - uint16_t segdat[4], segdat2[4]; - uint16_t segdat3[4]; - uint16_t newss, seg = 0; - int type, new_cpl; - uint32_t addr, oaddr; - uint32_t oldss, oldsp; - uint32_t newsp; - uint32_t *segdat32 = (uint32_t *) segdat; + uint16_t segdat[4], segdat2[4]; + uint16_t segdat3[4]; + uint16_t newss, seg = 0; + int type, new_cpl; + uint32_t addr, oaddr; + uint32_t oldss, oldsp; + uint32_t newsp; + uint32_t *segdat32 = (uint32_t *) segdat; uint32_t *segdat232 = (uint32_t *) segdat2; uint32_t *segdat332 = (uint32_t *) segdat3; - x86seg *dt; + x86seg *dt; if ((cpu_state.eflags & VM_FLAG) && (IOPL != 3) && soft) { - x86seg_log("V86 banned int\n"); - x86gpf("pmodeint(): V86 banned int", 0); - return; + x86seg_log("V86 banned int\n"); + x86gpf("pmodeint(): V86 banned int", 0); + return; } addr = (num << 3); if ((addr + 7) > idt.limit) { - if (num == 0x08) { - /* Triple fault - reset! */ - softresetx86(); - cpu_set_edx(); - } else if (num == 0x0d) - pmodeint(8, 0); - else - x86gpf("pmodeint(): Vector > IDT limit", (num << 3) + 2 + !soft); - x86seg_log("addr >= IDT.limit\n"); - return; + if (num == 0x08) { + /* Triple fault - reset! */ + softresetx86(); + cpu_set_edx(); + } else if (num == 0x0d) + pmodeint(8, 0); + else + x86gpf("pmodeint(): Vector > IDT limit", (num << 3) + 2 + !soft); + x86seg_log("addr >= IDT.limit\n"); + return; } addr += idt.base; read_descriptor(addr, segdat, segdat32, 1); if (cpu_state.abrt) { - x86seg_log("Abrt reading from %08X\n", addr); - return; + x86seg_log("Abrt reading from %08X\n", addr); + return; } oaddr = addr; x86seg_log("Addr %08X seg %04X %04X %04X %04X\n", addr, segdat[0], segdat[1], segdat[2], segdat[3]); if (!(segdat[2] & 0x1f00)) { - /* This fires on all V86 interrupts in EMM386. Mark as expected to prevent code churn */ - if (cpu_state.eflags & VM_FLAG) - x86gpf_expected("pmodeint(): Expected vector descriptor with bad type", (num << 3) + 2); - else - x86gpf("pmodeint(): Vector descriptor with bad type", (num << 3) + 2); - return; + /* This fires on all V86 interrupts in EMM386. Mark as expected to prevent code churn */ + if (cpu_state.eflags & VM_FLAG) + x86gpf_expected("pmodeint(): Expected vector descriptor with bad type", (num << 3) + 2); + else + x86gpf("pmodeint(): Vector descriptor with bad type", (num << 3) + 2); + return; } if ((DPL < CPL) && soft) { - x86gpf("pmodeint(): Vector DPL < CPL", (num << 3) + 2); - return; + x86gpf("pmodeint(): Vector DPL < CPL", (num << 3) + 2); + return; } type = segdat[2] & 0x1f00; if (((type == 0x0e00) || (type == 0x0f00)) && !is386) { - x86gpf("pmodeint(): Gate type illegal on 286", seg & 0xfffc); - return; + x86gpf("pmodeint(): Gate type illegal on 286", seg & 0xfffc); + return; } switch (type) { - case 0x0600: case 0x0700: case 0x0e00: case 0x0f00: /* Interrupt and trap gates */ - intgatesize = (type >= 0x0800) ? 32 : 16; - if (!(segdat[2] & 0x8000)) { - x86np("Int gate not present", (num << 3) | 2); - return; - } - seg = segdat[1]; - new_cpl = seg & 0x0003; + case 0x0600: + case 0x0700: + case 0x0e00: + case 0x0f00: /* Interrupt and trap gates */ + intgatesize = (type >= 0x0800) ? 32 : 16; + if (!(segdat[2] & 0x8000)) { + x86np("Int gate not present", (num << 3) | 2); + return; + } + seg = segdat[1]; + new_cpl = seg & 0x0003; - addr = seg & 0xfff8; - dt = (seg & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("pmodeint(): Interrupt or trap gate selector > DT limit", seg & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat2, segdat232, 1); - if (cpu_state.abrt) - return; - oaddr = addr; + addr = seg & 0xfff8; + dt = (seg & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("pmodeint(): Interrupt or trap gate selector > DT limit", seg & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat2, segdat232, 1); + if (cpu_state.abrt) + return; + oaddr = addr; - if (DPL2 > CPL) { - x86gpf("pmodeint(): Interrupt or trap gate DPL > CPL", seg & 0xfffc); - return; - } - switch (segdat2[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming */ - if (DPL2 < CPL) { - if (!(segdat2[2] & 0x8000)) { - x86np("Int gate CS not present", segdat[1] & 0xfffc); - return; - } - if ((cpu_state.eflags & VM_FLAG) && DPL2) { - x86gpf("pmodeint(): Interrupt or trap gate non-zero DPL in V86 mode", segdat[1] & 0xfffc); - return; - } - /* Load new stack */ - oldss = SS; - oldsp = ESP; - cpl_override = 1; - if (tr.access & 8) { - addr = 4 + tr.base + (DPL2 << 3); - newss = readmemw(0, addr + 4); - newsp = readmeml(0, addr); - } else { - addr = 2 + tr.base + (DPL2 << 2); - newss = readmemw(0, addr + 2); - newsp = readmemw(0, addr); - } - cpl_override = 0; - if (!(newss & 0xfffc)) { - x86ss("pmodeint(): Interrupt or trap gate stack segment is NULL", newss & 0xfffc); - return; - } - addr = newss & 0xfff8; - dt = (newss & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86ss("pmodeint(): Interrupt or trap gate stack segment > DT", newss & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat3, segdat332, 1); - if (cpu_state.abrt) - return; - if ((newss & 3) != DPL2) { - x86ss("pmodeint(): Interrupt or trap gate tack segment RPL > DPL",newss & 0xfffc); - return; - } - if (DPL3 != DPL2) { - x86ss("pmodeint(): Interrupt or trap gate tack segment DPL > DPL",newss & 0xfffc); - return; - } - if ((segdat3[2] & 0x1a00) != 0x1200) { - x86ss("pmodeint(): Interrupt or trap gate stack segment bad type", newss & 0xfffc); - return; - } - if (!(segdat3[2] & 0x8000)) { - x86np("Int gate loading SS not present", newss & 0xfffc); - return; - } - SS = newss; - set_stack32((segdat3[3] & 0x0040) ? 1 : 0); - if (stack32) - ESP = newsp; - else - SP = newsp; - do_seg_load(&cpu_state.seg_ss, segdat3); + if (DPL2 > CPL) { + x86gpf("pmodeint(): Interrupt or trap gate DPL > CPL", seg & 0xfffc); + return; + } + switch (segdat2[2] & 0x1f00) { + case 0x1800: + case 0x1900: + case 0x1a00: + case 0x1b00: /* Non-conforming */ + if (DPL2 < CPL) { + if (!(segdat2[2] & 0x8000)) { + x86np("Int gate CS not present", segdat[1] & 0xfffc); + return; + } + if ((cpu_state.eflags & VM_FLAG) && DPL2) { + x86gpf("pmodeint(): Interrupt or trap gate non-zero DPL in V86 mode", segdat[1] & 0xfffc); + return; + } + /* Load new stack */ + oldss = SS; + oldsp = ESP; + cpl_override = 1; + if (tr.access & 8) { + addr = 4 + tr.base + (DPL2 << 3); + newss = readmemw(0, addr + 4); + newsp = readmeml(0, addr); + } else { + addr = 2 + tr.base + (DPL2 << 2); + newss = readmemw(0, addr + 2); + newsp = readmemw(0, addr); + } + cpl_override = 0; + if (!(newss & 0xfffc)) { + x86ss("pmodeint(): Interrupt or trap gate stack segment is NULL", newss & 0xfffc); + return; + } + addr = newss & 0xfff8; + dt = (newss & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86ss("pmodeint(): Interrupt or trap gate stack segment > DT", newss & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat3, segdat332, 1); + if (cpu_state.abrt) + return; + if ((newss & 3) != DPL2) { + x86ss("pmodeint(): Interrupt or trap gate tack segment RPL > DPL", newss & 0xfffc); + return; + } + if (DPL3 != DPL2) { + x86ss("pmodeint(): Interrupt or trap gate tack segment DPL > DPL", newss & 0xfffc); + return; + } + if ((segdat3[2] & 0x1a00) != 0x1200) { + x86ss("pmodeint(): Interrupt or trap gate stack segment bad type", newss & 0xfffc); + return; + } + if (!(segdat3[2] & 0x8000)) { + x86np("Int gate loading SS not present", newss & 0xfffc); + return; + } + SS = newss; + set_stack32((segdat3[3] & 0x0040) ? 1 : 0); + if (stack32) + ESP = newsp; + else + SP = newsp; + do_seg_load(&cpu_state.seg_ss, segdat3); - cpl_override = 1; - writememw(0, addr + 4, segdat3[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; + cpl_override = 1; + writememw(0, addr + 4, segdat3[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; - x86seg_log("New stack %04X:%08X\n", SS, ESP); - cpl_override = 1; - if (type >= 0x0800) { - if (cpu_state.eflags & VM_FLAG) { - PUSHL(GS); - PUSHL(FS); - PUSHL(DS); - 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); - } - PUSHL(oldss); - PUSHL(oldsp); - PUSHL(cpu_state.flags | (cpu_state.eflags << 16)); - PUSHL(CS); - PUSHL(cpu_state.pc); - if (cpu_state.abrt) - return; - } else { - PUSHW(oldss); - PUSHW(oldsp); - PUSHW(cpu_state.flags); - PUSHW(CS); - PUSHW(cpu_state.pc); - if (cpu_state.abrt) - return; - } - cpl_override = 0; - cpu_state.seg_cs.access = 0x80; - cycles -= timing_int_pm_outer - timing_int_pm; - break; - } else if (DPL2 != CPL) { - x86gpf("pmodeint(): DPL != CPL", seg & 0xfffc); - return; - } - /*FALLTHROUGH*/ - case 0x1c00: case 0x1d00: case 0x1e00: case 0x1f00: /* Conforming */ - if (!(segdat2[2] & 0x8000)) { - x86np("Int gate CS not present", segdat[1] & 0xfffc); - return; - } - if ((cpu_state.eflags & VM_FLAG) && (DPL2 < CPL)) { - x86gpf("pmodeint(): DPL < CPL in V86 mode", seg &~ 0xfffc); - return; - } - if (type > 0x0800) { - PUSHL(cpu_state.flags | (cpu_state.eflags << 16)); - PUSHL(CS); - PUSHL(cpu_state.pc); - if (cpu_state.abrt) - return; - } else { - PUSHW(cpu_state.flags); - PUSHW(CS); - PUSHW(cpu_state.pc); - if (cpu_state.abrt) - return; - } - new_cpl = CS & 3; - break; - default: - x86gpf("pmodeint(): Unknown type", seg & 0xfffc); - return; - } - do_seg_load(&cpu_state.seg_cs, segdat2); - CS = (seg & 0xfffc) | new_cpl; - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | (new_cpl << 5); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + x86seg_log("New stack %04X:%08X\n", SS, ESP); + cpl_override = 1; + if (type >= 0x0800) { + if (cpu_state.eflags & VM_FLAG) { + PUSHL(GS); + PUSHL(FS); + PUSHL(DS); + 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); + } + PUSHL(oldss); + PUSHL(oldsp); + PUSHL(cpu_state.flags | (cpu_state.eflags << 16)); + PUSHL(CS); + PUSHL(cpu_state.pc); + if (cpu_state.abrt) + return; + } else { + PUSHW(oldss); + PUSHW(oldsp); + PUSHW(cpu_state.flags); + PUSHW(CS); + PUSHW(cpu_state.pc); + if (cpu_state.abrt) + return; + } + cpl_override = 0; + cpu_state.seg_cs.access = 0x80; + cycles -= timing_int_pm_outer - timing_int_pm; + break; + } else if (DPL2 != CPL) { + x86gpf("pmodeint(): DPL != CPL", seg & 0xfffc); + return; + } + /*FALLTHROUGH*/ + case 0x1c00: + case 0x1d00: + case 0x1e00: + case 0x1f00: /* Conforming */ + if (!(segdat2[2] & 0x8000)) { + x86np("Int gate CS not present", segdat[1] & 0xfffc); + return; + } + if ((cpu_state.eflags & VM_FLAG) && (DPL2 < CPL)) { + x86gpf("pmodeint(): DPL < CPL in V86 mode", seg & ~0xfffc); + return; + } + if (type > 0x0800) { + PUSHL(cpu_state.flags | (cpu_state.eflags << 16)); + PUSHL(CS); + PUSHL(cpu_state.pc); + if (cpu_state.abrt) + return; + } else { + PUSHW(cpu_state.flags); + PUSHW(CS); + PUSHW(cpu_state.pc); + if (cpu_state.abrt) + return; + } + new_cpl = CS & 3; + break; + default: + x86gpf("pmodeint(): Unknown type", seg & 0xfffc); + return; + } + do_seg_load(&cpu_state.seg_cs, segdat2); + CS = (seg & 0xfffc) | new_cpl; + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | (new_cpl << 5); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - if (type > 0x0800) - cpu_state.pc = segdat[0] | (segdat[3] << 16); - else - cpu_state.pc = segdat[0]; - set_use32(segdat2[3] & 0x40); + if (type > 0x0800) + cpu_state.pc = segdat[0] | (segdat[3] << 16); + else + cpu_state.pc = segdat[0]; + set_use32(segdat2[3] & 0x40); - cpl_override = 1; - writememw(0, oaddr + 4, segdat2[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; + cpl_override = 1; + writememw(0, oaddr + 4, segdat2[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; - cpu_state.eflags &= ~VM_FLAG; - cpu_cur_status &= ~CPU_STATUS_V86; - if (!(type & 0x100)) - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~(T_FLAG | NT_FLAG); - cycles -= timing_int_pm; - break; + cpu_state.eflags &= ~VM_FLAG; + cpu_cur_status &= ~CPU_STATUS_V86; + if (!(type & 0x100)) + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~(T_FLAG | NT_FLAG); + cycles -= timing_int_pm; + break; - case 0x500: /* Task gate */ - seg = segdat[1]; - addr = seg & 0xfff8; - dt = (seg & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("pmodeint(): Task gate selector > DT limit", seg & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat2, segdat232, 1); - if (cpu_state.abrt) - return; - if (!(segdat2[2] & 0x8000)) { - x86np("Int task gate not present", segdat[1] & 0xfffc); - return; - } - optype = OPTYPE_INT; - cpl_override = 1; - taskswitch286(seg, segdat2, segdat2[2] & 0x0800); - cpl_override = 0; - break; + case 0x500: /* Task gate */ + seg = segdat[1]; + addr = seg & 0xfff8; + dt = (seg & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("pmodeint(): Task gate selector > DT limit", seg & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat2, segdat232, 1); + if (cpu_state.abrt) + return; + if (!(segdat2[2] & 0x8000)) { + x86np("Int task gate not present", segdat[1] & 0xfffc); + return; + } + optype = OPTYPE_INT; + cpl_override = 1; + taskswitch286(seg, segdat2, segdat2[2] & 0x0800); + cpl_override = 0; + break; - default: - x86gpf("Protected mode interrupt unknown type", seg & 0xfffc); - return; + default: + x86gpf("Protected mode interrupt unknown type", seg & 0xfffc); + return; } } - void pmodeiret(int is32) { - uint16_t newss, seg = 0; - uint16_t segdat[4],segdat2[4]; - uint16_t segs[4]; - uint32_t tempflags, flagmask; - uint32_t newpc, newsp; - uint32_t addr, oaddr; - uint32_t oldsp = ESP; - uint32_t *segdat32 = (uint32_t *) segdat; + uint16_t newss, seg = 0; + uint16_t segdat[4], segdat2[4]; + uint16_t segs[4]; + uint32_t tempflags, flagmask; + uint32_t newpc, newsp; + uint32_t addr, oaddr; + uint32_t oldsp = ESP; + uint32_t *segdat32 = (uint32_t *) segdat; uint32_t *segdat232 = (uint32_t *) segdat2; - x86seg *dt; + x86seg *dt; if (is386 && (cpu_state.eflags & VM_FLAG)) { - if (IOPL != 3) { - x86gpf("Protected mode IRET: IOPL != 3", 0); - return; - } + if (IOPL != 3) { + x86gpf("Protected mode IRET: IOPL != 3", 0); + return; + } #ifndef USE_NEW_DYNAREC - oxpc = cpu_state.pc; + oxpc = cpu_state.pc; #endif - if (is32) { - newpc = POPL(); - seg = POPL(); - tempflags = POPL(); - } else { - newpc = POPW(); - seg = POPW(); - tempflags = POPW(); - } - if (cpu_state.abrt) - return; + if (is32) { + newpc = POPL(); + seg = POPL(); + tempflags = POPL(); + } else { + newpc = POPW(); + seg = POPW(); + tempflags = POPW(); + } + if (cpu_state.abrt) + return; - cpu_state.pc = newpc; - cpu_state.seg_cs.base= seg << 4; - cpu_state.seg_cs.limit = 0xffff; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - cpu_state.seg_cs.access |= 0x80; - cpu_state.seg_cs.ar_high = 0x10; - CS = seg; - cpu_state.flags = (cpu_state.flags & 0x3000) | (tempflags & 0xcfd5) | 2; - cycles -= timing_iret_rm; - return; + cpu_state.pc = newpc; + cpu_state.seg_cs.base = seg << 4; + cpu_state.seg_cs.limit = 0xffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; + cpu_state.seg_cs.access |= 0x80; + cpu_state.seg_cs.ar_high = 0x10; + CS = seg; + cpu_state.flags = (cpu_state.flags & 0x3000) | (tempflags & 0xcfd5) | 2; + cycles -= timing_iret_rm; + return; } if (cpu_state.flags & NT_FLAG) { - seg = readmemw(tr.base, 0); - addr = seg & 0xfff8; - if (seg & 0x0004) { - x86seg_log("TS LDT %04X %04X IRET\n", seg, gdt.limit); - x86ts("pmodeiret(): Selector points to LDT", seg & 0xfffc); - return; - } else { - if ((addr + 7) > gdt.limit) { - x86ts(NULL,seg & 0xfffc); - return; - } - addr += gdt.base; - } - cpl_override = 1; - read_descriptor(addr, segdat, segdat32, 1); - taskswitch286(seg, segdat,segdat[2] & 0x0800); - cpl_override = 0; - return; + seg = readmemw(tr.base, 0); + addr = seg & 0xfff8; + if (seg & 0x0004) { + x86seg_log("TS LDT %04X %04X IRET\n", seg, gdt.limit); + x86ts("pmodeiret(): Selector points to LDT", seg & 0xfffc); + return; + } else { + if ((addr + 7) > gdt.limit) { + x86ts(NULL, seg & 0xfffc); + return; + } + addr += gdt.base; + } + cpl_override = 1; + read_descriptor(addr, segdat, segdat32, 1); + taskswitch286(seg, segdat, segdat[2] & 0x0800); + cpl_override = 0; + return; } #ifndef USE_NEW_DYNAREC - oxpc=cpu_state.pc; + oxpc = cpu_state.pc; #endif flagmask = 0xffff; if (CPL != 0) - flagmask &= ~0x3000; + flagmask &= ~0x3000; if (IOPL < CPL) - flagmask &= ~0x200; + flagmask &= ~0x200; if (is32) { - newpc = POPL(); - seg = POPL(); - tempflags = POPL(); - if (cpu_state.abrt) { - ESP = oldsp; - return; - } - if (is386 && ((tempflags >> 16) & VM_FLAG)) { - newsp = POPL(); - newss = POPL(); - segs[0] = POPL(); - segs[1] = POPL(); - segs[2] = POPL(); - segs[3] = POPL(); - if (cpu_state.abrt) { - ESP = oldsp; - return; - } - cpu_state.eflags = tempflags >> 16; - cpu_cur_status |= CPU_STATUS_V86; - loadseg(segs[0], &cpu_state.seg_es); - do_seg_v86_init(&cpu_state.seg_es); - 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); - do_seg_v86_init(&cpu_state.seg_fs); - loadseg(segs[3], &cpu_state.seg_gs); - do_seg_v86_init(&cpu_state.seg_gs); + newpc = POPL(); + seg = POPL(); + tempflags = POPL(); + if (cpu_state.abrt) { + ESP = oldsp; + return; + } + if (is386 && ((tempflags >> 16) & VM_FLAG)) { + newsp = POPL(); + newss = POPL(); + segs[0] = POPL(); + segs[1] = POPL(); + segs[2] = POPL(); + segs[3] = POPL(); + if (cpu_state.abrt) { + ESP = oldsp; + return; + } + cpu_state.eflags = tempflags >> 16; + cpu_cur_status |= CPU_STATUS_V86; + loadseg(segs[0], &cpu_state.seg_es); + do_seg_v86_init(&cpu_state.seg_es); + 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); + do_seg_v86_init(&cpu_state.seg_fs); + loadseg(segs[3], &cpu_state.seg_gs); + do_seg_v86_init(&cpu_state.seg_gs); - cpu_state.pc = newpc & 0xffff; - cpu_state.seg_cs.base = seg << 4; - cpu_state.seg_cs.limit = 0xffff; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - CS = seg; - cpu_state.seg_cs.access = 0xe2; - cpu_state.seg_cs.ar_high = 0x10; - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + cpu_state.pc = newpc & 0xffff; + cpu_state.seg_cs.base = seg << 4; + cpu_state.seg_cs.limit = 0xffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; + CS = seg; + cpu_state.seg_cs.access = 0xe2; + cpu_state.seg_cs.ar_high = 0x10; + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - ESP = newsp; - loadseg(newss, &cpu_state.seg_ss); - do_seg_v86_init(&cpu_state.seg_ss); - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - use32 = 0; - cpu_cur_status &= ~CPU_STATUS_USE32; - cpu_state.flags = (tempflags & 0xffd5) | 2; - cycles -= timing_iret_v86; - return; - } + ESP = newsp; + loadseg(newss, &cpu_state.seg_ss); + do_seg_v86_init(&cpu_state.seg_ss); + cpu_cur_status |= CPU_STATUS_NOTFLATSS; + use32 = 0; + cpu_cur_status &= ~CPU_STATUS_USE32; + cpu_state.flags = (tempflags & 0xffd5) | 2; + cycles -= timing_iret_v86; + return; + } } else { - newpc = POPW(); - seg = POPW(); - tempflags = POPW(); - if (cpu_state.abrt) { - ESP = oldsp; - return; - } + newpc = POPW(); + seg = POPW(); + tempflags = POPW(); + if (cpu_state.abrt) { + ESP = oldsp; + return; + } } if (!(seg & 0xfffc)) { - ESP = oldsp; - x86gpf("pmodeiret(): Selector is NULL", 0); - return; + ESP = oldsp; + x86gpf("pmodeiret(): Selector is NULL", 0); + return; } addr = seg & 0xfff8; - dt = (seg & 0x0004) ? & ldt : &gdt; + dt = (seg & 0x0004) ? &ldt : &gdt; if ((addr + 7) > dt->limit) { - ESP = oldsp; - x86gpf("pmodeiret(): Selector > DT limit", seg & 0xfffc); - return; + ESP = oldsp; + x86gpf("pmodeiret(): Selector > DT limit", seg & 0xfffc); + return; } addr += dt->base; if ((seg & 0x0003) < CPL) { - ESP = oldsp; - x86gpf("pmodeiret(): RPL < CPL", seg & 0xfffc); - return; + ESP = oldsp; + x86gpf("pmodeiret(): RPL < CPL", seg & 0xfffc); + return; } read_descriptor(addr, segdat, segdat32, 1); if (cpu_state.abrt) { - ESP = oldsp; - return; + ESP = oldsp; + return; } switch (segdat[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming code */ - if ((seg & 0x0003) != DPL) { - ESP = oldsp; - x86gpf("pmodeiret(): Non-conforming RPL != DPL", seg & 0xfffc); - return; - } - break; - case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /* Conforming code */ - if ((seg & 0x0003) < DPL) { - ESP = oldsp; - x86gpf("pmodeiret(): Conforming RPL < DPL",seg&~3); - return; - } - break; - default: - ESP = oldsp; - x86gpf("pmodeiret(): Unknown type", seg & 0xfffc); - return; + case 0x1800: + case 0x1900: + case 0x1a00: + case 0x1b00: /* Non-conforming code */ + if ((seg & 0x0003) != DPL) { + ESP = oldsp; + x86gpf("pmodeiret(): Non-conforming RPL != DPL", seg & 0xfffc); + return; + } + break; + case 0x1C00: + case 0x1D00: + case 0x1E00: + case 0x1F00: /* Conforming code */ + if ((seg & 0x0003) < DPL) { + ESP = oldsp; + x86gpf("pmodeiret(): Conforming RPL < DPL", seg & ~3); + return; + } + break; + default: + ESP = oldsp; + x86gpf("pmodeiret(): Unknown type", seg & 0xfffc); + return; } if (!(segdat[2] & 0x8000)) { - ESP = oldsp; - x86np("IRET CS not present", seg & 0xfffc); - return; + ESP = oldsp; + x86np("IRET CS not present", seg & 0xfffc); + return; } if ((seg & 0x0003) == CPL) { - CS = seg; - do_seg_load(&cpu_state.seg_cs, segdat); - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | ((CS & 0x0003) << 5); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + CS = seg; + do_seg_load(&cpu_state.seg_cs, segdat); + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | ((CS & 0x0003) << 5); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat[3] & 0x0040); + set_use32(segdat[3] & 0x0040); - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; - cycles -= timing_iret_pm; - } else { /* Return to outer level */ - oaddr = addr; - x86seg_log("Outer level\n"); - if (is32) { - newsp = POPL(); - newss = POPL(); - if (cpu_state.abrt) { - ESP = oldsp; - return; - } - } else { - newsp = POPW(); - newss = POPW(); - if (cpu_state.abrt) { - ESP = oldsp; - return; - } - } + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; + cycles -= timing_iret_pm; + } else { /* Return to outer level */ + oaddr = addr; + x86seg_log("Outer level\n"); + if (is32) { + newsp = POPL(); + newss = POPL(); + if (cpu_state.abrt) { + ESP = oldsp; + return; + } + } else { + newsp = POPW(); + newss = POPW(); + if (cpu_state.abrt) { + ESP = oldsp; + return; + } + } - x86seg_log("IRET load stack %04X:%04X\n", newss, newsp); + x86seg_log("IRET load stack %04X:%04X\n", newss, newsp); - if (!(newss & 0xfffc)) { - ESP = oldsp; - x86gpf("pmodeiret(): New SS selector is zero", newss & 0xfffc); - return; - } - addr = newss & 0xfff8; - dt = (newss & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - ESP = oldsp; - x86gpf("pmodeiret(): New SS selector > DT limit", newss & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat2, segdat232, 1); - if (cpu_state.abrt) { - ESP = oldsp; - return; - } - if ((newss & 3) != (seg & 3)) { - SP = oldsp; - x86gpf("pmodeiret(): New SS RPL > CS RPL",newss & 0xfffc); - return; - } - if ((segdat2[2] & 0x1a00) != 0x1200) { - ESP = oldsp; - x86gpf("pmodeiret(): New SS bad type", newss & 0xfffc); - return; - } - if (DPL2 != (seg & 0x0003)) { - ESP = oldsp; - x86gpf("pmodeiret(): New SS DPL != CS RPL",newss & 0xfffc); - return; - } - if (!(segdat2[2] & 0x8000)) { - ESP = oldsp; - x86np("IRET loading SS not present", newss & 0xfffc); - return; - } - SS = newss; - set_stack32((segdat2[3] & 0x40) ? 1 : 0); - if (stack32) - ESP = newsp; - else - SP = newsp; - do_seg_load(&cpu_state.seg_ss, segdat2); + if (!(newss & 0xfffc)) { + ESP = oldsp; + x86gpf("pmodeiret(): New SS selector is zero", newss & 0xfffc); + return; + } + addr = newss & 0xfff8; + dt = (newss & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + ESP = oldsp; + x86gpf("pmodeiret(): New SS selector > DT limit", newss & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat2, segdat232, 1); + if (cpu_state.abrt) { + ESP = oldsp; + return; + } + if ((newss & 3) != (seg & 3)) { + SP = oldsp; + x86gpf("pmodeiret(): New SS RPL > CS RPL", newss & 0xfffc); + return; + } + if ((segdat2[2] & 0x1a00) != 0x1200) { + ESP = oldsp; + x86gpf("pmodeiret(): New SS bad type", newss & 0xfffc); + return; + } + if (DPL2 != (seg & 0x0003)) { + ESP = oldsp; + x86gpf("pmodeiret(): New SS DPL != CS RPL", newss & 0xfffc); + return; + } + if (!(segdat2[2] & 0x8000)) { + ESP = oldsp; + x86np("IRET loading SS not present", newss & 0xfffc); + return; + } + SS = newss; + set_stack32((segdat2[3] & 0x40) ? 1 : 0); + if (stack32) + ESP = newsp; + else + SP = newsp; + do_seg_load(&cpu_state.seg_ss, segdat2); - cpl_override = 1; - writememw(0, addr + 4, segdat2[2] | 0x100); /* Set accessed bit */ - writememw(0, oaddr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; - /* Conforming segments don't change CPL, so CPL = RPL */ - if (segdat[2] & 0x0400) - segdat[2] = (segdat[2] & ~(3 << 13)) | ((seg & 3) << 13); + cpl_override = 1; + writememw(0, addr + 4, segdat2[2] | 0x100); /* Set accessed bit */ + writememw(0, oaddr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; + /* Conforming segments don't change CPL, so CPL = RPL */ + if (segdat[2] & 0x0400) + segdat[2] = (segdat[2] & ~(3 << 13)) | ((seg & 3) << 13); - CS = seg; - do_seg_load(&cpu_state.seg_cs, segdat); - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | ((CS & 3) << 5); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + CS = seg; + do_seg_load(&cpu_state.seg_cs, segdat); + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | ((CS & 3) << 5); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat[3] & 0x40); + set_use32(segdat[3] & 0x40); - check_seg_valid(&cpu_state.seg_ds); - check_seg_valid(&cpu_state.seg_es); - check_seg_valid(&cpu_state.seg_fs); - check_seg_valid(&cpu_state.seg_gs); - cycles -= timing_iret_pm_outer; + check_seg_valid(&cpu_state.seg_ds); + check_seg_valid(&cpu_state.seg_es); + check_seg_valid(&cpu_state.seg_fs); + check_seg_valid(&cpu_state.seg_gs); + cycles -= timing_iret_pm_outer; } - cpu_state.pc = newpc; - cpu_state.flags = (cpu_state.flags &~ flagmask) | (tempflags & flagmask & 0xffd5) | 2; + cpu_state.pc = newpc; + cpu_state.flags = (cpu_state.flags & ~flagmask) | (tempflags & flagmask & 0xffd5) | 2; if (is32) - cpu_state.eflags = tempflags >> 16; + cpu_state.eflags = tempflags >> 16; } - void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) { - uint16_t tempw, new_ldt; - uint16_t new_es, new_cs, new_ss, new_ds, new_fs, new_gs; - uint16_t segdat2[4]; - uint32_t base, limit; - uint32_t templ, new_cr3 = 0; - uint32_t new_eax, new_ebx, new_ecx, new_edx, new_esp, new_ebp; - uint32_t new_esi, new_edi, new_pc, new_flags, addr; + uint16_t tempw, new_ldt; + uint16_t new_es, new_cs, new_ss, new_ds, new_fs, new_gs; + uint16_t segdat2[4]; + uint32_t base, limit; + uint32_t templ, new_cr3 = 0; + uint32_t new_eax, new_ebx, new_ecx, new_edx, new_esp, new_ebp; + uint32_t new_esi, new_edi, new_pc, new_flags, addr; uint32_t *segdat232 = (uint32_t *) segdat2; - x86seg *dt; + x86seg *dt; - base = segdat[1] | ((segdat[2] & 0x00ff) << 16); + base = segdat[1] | ((segdat[2] & 0x00ff) << 16); limit = segdat[0]; if (is386) { - base |= (segdat[3] >> 8) << 24; - limit |= (segdat[3] & 0x000f) << 16; + base |= (segdat[3] >> 8) << 24; + limit |= (segdat[3] & 0x000f) << 16; } if (is32) { - if (limit < 103) { - x86ts("taskswitch286(): limit < 103", seg); - return; - } + if (limit < 103) { + x86ts("taskswitch286(): limit < 103", seg); + return; + } - if ((optype == JMP) || (optype == CALL) || (optype == OPTYPE_INT)) { - if (tr.seg & 0x0004) - tempw = readmemw(ldt.base, (seg & 0xfff8) + 4); - else - tempw = readmemw(gdt.base, (seg & 0xfff8) + 4); - if (cpu_state.abrt) - return; - tempw |= 0x0200; - if (tr.seg & 0x0004) - writememw(ldt.base, (seg & 0xfff8) + 4, tempw); - else - writememw(gdt.base, (seg & 0xfff8) + 4, tempw); - } - if (cpu_state.abrt) - return; + if ((optype == JMP) || (optype == CALL) || (optype == OPTYPE_INT)) { + if (tr.seg & 0x0004) + tempw = readmemw(ldt.base, (seg & 0xfff8) + 4); + else + tempw = readmemw(gdt.base, (seg & 0xfff8) + 4); + if (cpu_state.abrt) + return; + tempw |= 0x0200; + if (tr.seg & 0x0004) + writememw(ldt.base, (seg & 0xfff8) + 4, tempw); + else + writememw(gdt.base, (seg & 0xfff8) + 4, tempw); + } + if (cpu_state.abrt) + return; - if (optype == IRET) - cpu_state.flags &= ~NT_FLAG; + if (optype == IRET) + cpu_state.flags &= ~NT_FLAG; - cpu_386_flags_rebuild(); - writememl(tr.base, 0x1C, cr3); - writememl(tr.base, 0x20, cpu_state.pc); - writememl(tr.base, 0x24, cpu_state.flags | (cpu_state.eflags << 16)); + cpu_386_flags_rebuild(); + writememl(tr.base, 0x1C, cr3); + writememl(tr.base, 0x20, cpu_state.pc); + writememl(tr.base, 0x24, cpu_state.flags | (cpu_state.eflags << 16)); - writememl(tr.base, 0x28, EAX); - writememl(tr.base, 0x2C, ECX); - writememl(tr.base, 0x30, EDX); - writememl(tr.base, 0x34, EBX); - writememl(tr.base, 0x38, ESP); - writememl(tr.base, 0x3C, EBP); - writememl(tr.base, 0x40, ESI); - writememl(tr.base, 0x44, EDI); + writememl(tr.base, 0x28, EAX); + writememl(tr.base, 0x2C, ECX); + writememl(tr.base, 0x30, EDX); + writememl(tr.base, 0x34, EBX); + writememl(tr.base, 0x38, ESP); + writememl(tr.base, 0x3C, EBP); + writememl(tr.base, 0x40, ESI); + writememl(tr.base, 0x44, EDI); - writememl(tr.base, 0x48, ES); - writememl(tr.base, 0x4C, CS); - writememl(tr.base, 0x50, SS); - writememl(tr.base, 0x54, DS); - writememl(tr.base, 0x58, FS); - writememl(tr.base, 0x5C, GS); + writememl(tr.base, 0x48, ES); + writememl(tr.base, 0x4C, CS); + writememl(tr.base, 0x50, SS); + writememl(tr.base, 0x54, DS); + writememl(tr.base, 0x58, FS); + writememl(tr.base, 0x5C, GS); - if ((optype == JMP) || (optype == IRET)) { - if (tr.seg & 0x0004) - tempw = readmemw(ldt.base, (tr.seg & 0xfff8) + 4); - else - tempw = readmemw(gdt.base, (tr.seg & 0xfff8) + 4); - if (cpu_state.abrt) - return; - tempw &= ~0x0200; - if (tr.seg & 0x0004) - writememw(ldt.base, (tr.seg & 0xfff8) + 4, tempw); - else - writememw(gdt.base, (tr.seg & 0xfff8) + 4, tempw); - } - if (cpu_state.abrt) - return; + if ((optype == JMP) || (optype == IRET)) { + if (tr.seg & 0x0004) + tempw = readmemw(ldt.base, (tr.seg & 0xfff8) + 4); + else + tempw = readmemw(gdt.base, (tr.seg & 0xfff8) + 4); + if (cpu_state.abrt) + return; + tempw &= ~0x0200; + if (tr.seg & 0x0004) + writememw(ldt.base, (tr.seg & 0xfff8) + 4, tempw); + else + writememw(gdt.base, (tr.seg & 0xfff8) + 4, tempw); + } + if (cpu_state.abrt) + return; - if ((optype == OPTYPE_INT) || (optype == CALL)) { - writememl(base, 0, tr.seg); - if (cpu_state.abrt) - return; - } + if ((optype == OPTYPE_INT) || (optype == CALL)) { + writememl(base, 0, tr.seg); + if (cpu_state.abrt) + return; + } - new_cr3 = readmeml(base, 0x1C); - new_pc = readmeml(base, 0x20); - new_flags = readmeml(base, 0x24); - if ((optype == OPTYPE_INT) || (optype == CALL)) - new_flags |= NT_FLAG; + new_cr3 = readmeml(base, 0x1C); + new_pc = readmeml(base, 0x20); + new_flags = readmeml(base, 0x24); + if ((optype == OPTYPE_INT) || (optype == CALL)) + new_flags |= NT_FLAG; - new_eax = readmeml(base, 0x28); - new_ecx = readmeml(base, 0x2C); - new_edx = readmeml(base, 0x30); - new_ebx = readmeml(base, 0x34); - new_esp = readmeml(base, 0x38); - new_ebp = readmeml(base, 0x3C); - new_esi = readmeml(base, 0x40); - new_edi = readmeml(base, 0x44); + new_eax = readmeml(base, 0x28); + new_ecx = readmeml(base, 0x2C); + new_edx = readmeml(base, 0x30); + new_ebx = readmeml(base, 0x34); + new_esp = readmeml(base, 0x38); + new_ebp = readmeml(base, 0x3C); + new_esi = readmeml(base, 0x40); + new_edi = readmeml(base, 0x44); - new_es = readmemw(base, 0x48); - new_cs = readmemw(base, 0x4C); - new_ss = readmemw(base, 0x50); - new_ds = readmemw(base, 0x54); - new_fs = readmemw(base, 0x58); - new_gs = readmemw(base, 0x5C); - new_ldt = readmemw(base, 0x60); + new_es = readmemw(base, 0x48); + new_cs = readmemw(base, 0x4C); + new_ss = readmemw(base, 0x50); + new_ds = readmemw(base, 0x54); + new_fs = readmemw(base, 0x58); + new_gs = readmemw(base, 0x5C); + new_ldt = readmemw(base, 0x60); - cr0 |= 8; + cr0 |= 8; - cr3 = new_cr3; - flushmmucache(); + cr3 = new_cr3; + flushmmucache(); - cpu_state.pc = new_pc; - cpu_state.flags = new_flags; - cpu_state.eflags = new_flags >> 16; - cpu_386_flags_extract(); + cpu_state.pc = new_pc; + cpu_state.flags = new_flags; + cpu_state.eflags = new_flags >> 16; + cpu_386_flags_extract(); - ldt.seg = new_ldt; - templ = (ldt.seg & ~7) + gdt.base; - ldt.limit = readmemw(0, templ); - if (readmemb(0, templ + 6) & 0x80) { - ldt.limit <<= 12; - ldt.limit |= 0xfff; - } - ldt.base = (readmemw(0, templ + 2)) | (readmemb(0, templ + 4) << 16) | (readmemb(0, templ + 7) << 24); + ldt.seg = new_ldt; + templ = (ldt.seg & ~7) + gdt.base; + ldt.limit = readmemw(0, templ); + if (readmemb(0, templ + 6) & 0x80) { + ldt.limit <<= 12; + ldt.limit |= 0xfff; + } + 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); - set_use32(0); - cpu_cur_status |= CPU_STATUS_V86; - } else { - if (!(new_cs & 0xfffc)) { - x86ts("taskswitch286(): New CS selector is null", 0); - return; - } - addr = new_cs & 0xfff8; - dt = (new_cs & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86ts("taskswitch286(): New CS selector > DT limit", new_cs & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat2, segdat232, 0); - if (!(segdat2[2] & 0x8000)) { - x86np("TS loading CS not present", new_cs & 0xfffc); - return; - } - switch (segdat2[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming */ - if ((new_cs & 0x0003) != DPL2) { - x86ts("TS loading CS RPL != DPL2", new_cs & 0xfffc); - return; - } - break; - case 0x1c00: case 0x1d00: case 0x1e00: case 0x1f00: /* Conforming */ - if ((new_cs & 0x0003) < DPL2) { - x86ts("TS loading CS RPL < DPL2", new_cs & 0xfffc); - return; - } - break; - default: - x86ts("TS loading CS unknown type", new_cs & 0xfffc); - return; - } + if (cpu_state.eflags & VM_FLAG) { + loadcs(new_cs); + set_use32(0); + cpu_cur_status |= CPU_STATUS_V86; + } else { + if (!(new_cs & 0xfffc)) { + x86ts("taskswitch286(): New CS selector is null", 0); + return; + } + addr = new_cs & 0xfff8; + dt = (new_cs & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86ts("taskswitch286(): New CS selector > DT limit", new_cs & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat2, segdat232, 0); + if (!(segdat2[2] & 0x8000)) { + x86np("TS loading CS not present", new_cs & 0xfffc); + return; + } + switch (segdat2[2] & 0x1f00) { + case 0x1800: + case 0x1900: + case 0x1a00: + case 0x1b00: /* Non-conforming */ + if ((new_cs & 0x0003) != DPL2) { + x86ts("TS loading CS RPL != DPL2", new_cs & 0xfffc); + return; + } + break; + case 0x1c00: + case 0x1d00: + case 0x1e00: + case 0x1f00: /* Conforming */ + if ((new_cs & 0x0003) < DPL2) { + x86ts("TS loading CS RPL < DPL2", new_cs & 0xfffc); + return; + } + break; + default: + x86ts("TS loading CS unknown type", new_cs & 0xfffc); + return; + } - CS = new_cs; - do_seg_load(&cpu_state.seg_cs, segdat2); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + CS = new_cs; + do_seg_load(&cpu_state.seg_cs, segdat2); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat2[3] & 0x0040); - cpu_cur_status &= ~CPU_STATUS_V86; - } + set_use32(segdat2[3] & 0x0040); + cpu_cur_status &= ~CPU_STATUS_V86; + } - EAX = new_eax; - ECX = new_ecx; - EDX = new_edx; - EBX = new_ebx; - ESP = new_esp; - EBP = new_ebp; - ESI = new_esi; - EDI = new_edi; + EAX = new_eax; + ECX = new_ecx; + EDX = new_edx; + EBX = new_ebx; + ESP = new_esp; + EBP = new_ebp; + 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); + 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); } else { - if (limit < 43) { - x86ts(NULL, seg); - return; - } + if (limit < 43) { + x86ts(NULL, seg); + return; + } - if ((optype == JMP) || (optype == CALL) || (optype == OPTYPE_INT)) { - if (tr.seg & 0x0004) - tempw = readmemw(ldt.base, (seg & 0xfff8) + 4); - else - tempw = readmemw(gdt.base, (seg & 0xfff8) + 4); - if (cpu_state.abrt) - return; - tempw |= 0x200; - if (tr.seg & 0x0004) - writememw(ldt.base, (seg & 0xfff8) + 4, tempw); - else - writememw(gdt.base, (seg & 0xfff8) + 4, tempw); - } - if (cpu_state.abrt) - return; + if ((optype == JMP) || (optype == CALL) || (optype == OPTYPE_INT)) { + if (tr.seg & 0x0004) + tempw = readmemw(ldt.base, (seg & 0xfff8) + 4); + else + tempw = readmemw(gdt.base, (seg & 0xfff8) + 4); + if (cpu_state.abrt) + return; + tempw |= 0x200; + if (tr.seg & 0x0004) + writememw(ldt.base, (seg & 0xfff8) + 4, tempw); + else + writememw(gdt.base, (seg & 0xfff8) + 4, tempw); + } + if (cpu_state.abrt) + return; - if (optype == IRET) - cpu_state.flags &= ~NT_FLAG; + if (optype == IRET) + cpu_state.flags &= ~NT_FLAG; - cpu_386_flags_rebuild(); - writememw(tr.base, 0x0e, cpu_state.pc); - writememw(tr.base, 0x10, cpu_state.flags); + cpu_386_flags_rebuild(); + writememw(tr.base, 0x0e, cpu_state.pc); + writememw(tr.base, 0x10, cpu_state.flags); - writememw(tr.base, 0x12, AX); - writememw(tr.base, 0x14, CX); - writememw(tr.base, 0x16, DX); - writememw(tr.base, 0x18, BX); - writememw(tr.base, 0x1a, SP); - writememw(tr.base, 0x1c, BP); - writememw(tr.base, 0x1e, SI); - writememw(tr.base, 0x20, DI); + writememw(tr.base, 0x12, AX); + writememw(tr.base, 0x14, CX); + writememw(tr.base, 0x16, DX); + writememw(tr.base, 0x18, BX); + writememw(tr.base, 0x1a, SP); + writememw(tr.base, 0x1c, BP); + writememw(tr.base, 0x1e, SI); + writememw(tr.base, 0x20, DI); - writememw(tr.base, 0x22, ES); - writememw(tr.base, 0x24, CS); - writememw(tr.base, 0x26, SS); - writememw(tr.base, 0x28, DS); + writememw(tr.base, 0x22, ES); + writememw(tr.base, 0x24, CS); + writememw(tr.base, 0x26, SS); + writememw(tr.base, 0x28, DS); - if ((optype == JMP) || (optype == IRET)) { - if (tr.seg & 0x0004) - tempw = readmemw(ldt.base, (tr.seg & 0xfff8) + 4); - else - tempw = readmemw(gdt.base, (tr.seg & 0xfff8) + 4); - if (cpu_state.abrt) - return; - tempw &= ~0x200; - if (tr.seg & 0x0004) - writememw(ldt.base, (tr.seg & 0xfff8) + 4, tempw); - else - writememw(gdt.base, (tr.seg & 0xfff8) + 4, tempw); - } - if (cpu_state.abrt) - return; + if ((optype == JMP) || (optype == IRET)) { + if (tr.seg & 0x0004) + tempw = readmemw(ldt.base, (tr.seg & 0xfff8) + 4); + else + tempw = readmemw(gdt.base, (tr.seg & 0xfff8) + 4); + if (cpu_state.abrt) + return; + tempw &= ~0x200; + if (tr.seg & 0x0004) + writememw(ldt.base, (tr.seg & 0xfff8) + 4, tempw); + else + writememw(gdt.base, (tr.seg & 0xfff8) + 4, tempw); + } + if (cpu_state.abrt) + return; - if ((optype == OPTYPE_INT) || (optype == CALL)) { - writememw(base, 0, tr.seg); - if (cpu_state.abrt) - return; - } + if ((optype == OPTYPE_INT) || (optype == CALL)) { + writememw(base, 0, tr.seg); + if (cpu_state.abrt) + return; + } - new_pc = readmemw(base, 0x0e); - new_flags = readmemw(base, 0x10); - if ((optype == OPTYPE_INT) || (optype == CALL)) - new_flags |= NT_FLAG; + new_pc = readmemw(base, 0x0e); + new_flags = readmemw(base, 0x10); + if ((optype == OPTYPE_INT) || (optype == CALL)) + new_flags |= NT_FLAG; - new_eax = readmemw(base, 0x12); - new_ecx = readmemw(base, 0x14); - new_edx = readmemw(base, 0x16); - new_ebx = readmemw(base, 0x18); - new_esp = readmemw(base, 0x1a); - new_ebp = readmemw(base, 0x1c); - new_esi = readmemw(base, 0x1e); - new_edi = readmemw(base, 0x20); + new_eax = readmemw(base, 0x12); + new_ecx = readmemw(base, 0x14); + new_edx = readmemw(base, 0x16); + new_ebx = readmemw(base, 0x18); + new_esp = readmemw(base, 0x1a); + new_ebp = readmemw(base, 0x1c); + new_esi = readmemw(base, 0x1e); + new_edi = readmemw(base, 0x20); - new_es = readmemw(base, 0x22); - new_cs = readmemw(base, 0x24); - new_ss = readmemw(base, 0x26); - new_ds = readmemw(base, 0x28); - new_ldt = readmemw(base, 0x2a); + new_es = readmemw(base, 0x22); + new_cs = readmemw(base, 0x24); + new_ss = readmemw(base, 0x26); + new_ds = readmemw(base, 0x28); + new_ldt = readmemw(base, 0x2a); - msw |= 8; + msw |= 8; - cpu_state.pc = new_pc; - cpu_state.flags = new_flags; - cpu_386_flags_extract(); + cpu_state.pc = new_pc; + cpu_state.flags = new_flags; + cpu_386_flags_extract(); - ldt.seg = new_ldt; - templ = (ldt.seg & 0xfff8) + gdt.base; - ldt.limit = readmemw(0, templ); - ldt.base = (readmemw(0, templ + 2)) | (readmemb(0, templ + 4) << 16); - if (is386) { - if (readmemb(0, templ + 6) & 0x80) { - ldt.limit <<= 12; - ldt.limit |= 0xfff; - } - ldt.base |= (readmemb(0, templ + 7) << 24); - } + ldt.seg = new_ldt; + templ = (ldt.seg & 0xfff8) + gdt.base; + ldt.limit = readmemw(0, templ); + ldt.base = (readmemw(0, templ + 2)) | (readmemb(0, templ + 4) << 16); + if (is386) { + if (readmemb(0, templ + 6) & 0x80) { + ldt.limit <<= 12; + ldt.limit |= 0xfff; + } + ldt.base |= (readmemb(0, templ + 7) << 24); + } - if (!(new_cs & 0xfff8)) { - x86ts(NULL, 0); - return; - } - addr = new_cs & 0xfff8; - dt = (new_cs & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86ts(NULL, new_cs & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat2, segdat232, 0); - if (!(segdat2[2] & 0x8000)) { - x86np("TS loading CS not present", new_cs & 0xfffc); - return; - } - switch (segdat2[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming */ - if ((new_cs & 0x0003) != DPL2) { - x86ts(NULL,new_cs & 0xfffc); - return; - } - break; - case 0x1c00: case 0x1d00: case 0x1e00: case 0x1f00: /* Conforming */ - if ((new_cs & 0x0003) < DPL2) { - x86ts(NULL,new_cs & 0xfffc); - return; - } - break; - default: - x86ts(NULL, new_cs & 0xfffc); - return; - } + if (!(new_cs & 0xfff8)) { + x86ts(NULL, 0); + return; + } + addr = new_cs & 0xfff8; + dt = (new_cs & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86ts(NULL, new_cs & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat2, segdat232, 0); + if (!(segdat2[2] & 0x8000)) { + x86np("TS loading CS not present", new_cs & 0xfffc); + return; + } + switch (segdat2[2] & 0x1f00) { + case 0x1800: + case 0x1900: + case 0x1a00: + case 0x1b00: /* Non-conforming */ + if ((new_cs & 0x0003) != DPL2) { + x86ts(NULL, new_cs & 0xfffc); + return; + } + break; + case 0x1c00: + case 0x1d00: + case 0x1e00: + case 0x1f00: /* Conforming */ + if ((new_cs & 0x0003) < DPL2) { + x86ts(NULL, new_cs & 0xfffc); + return; + } + break; + default: + x86ts(NULL, new_cs & 0xfffc); + return; + } - CS = new_cs; - do_seg_load(&cpu_state.seg_cs, segdat2); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + CS = new_cs; + do_seg_load(&cpu_state.seg_cs, segdat2); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(0); + set_use32(0); - EAX = new_eax | 0xffff0000; - ECX = new_ecx | 0xffff0000; - EDX = new_edx | 0xffff0000; - EBX = new_ebx | 0xffff0000; - ESP = new_esp | 0xffff0000; - EBP = new_ebp | 0xffff0000; - ESI = new_esi | 0xffff0000; - EDI = new_edi | 0xffff0000; + EAX = new_eax | 0xffff0000; + ECX = new_ecx | 0xffff0000; + EDX = new_edx | 0xffff0000; + EBX = new_ebx | 0xffff0000; + ESP = new_esp | 0xffff0000; + EBP = new_ebp | 0xffff0000; + 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); - if (is386) { - loadseg(0, &cpu_state.seg_fs); - loadseg(0, &cpu_state.seg_gs); - } + loadseg(new_es, &cpu_state.seg_es); + loadseg(new_ss, &cpu_state.seg_ss); + loadseg(new_ds, &cpu_state.seg_ds); + if (is386) { + loadseg(0, &cpu_state.seg_fs); + loadseg(0, &cpu_state.seg_gs); + } } - tr.seg = seg; - tr.base = base; - tr.limit = limit; - tr.access = segdat[2] >> 8; + tr.seg = seg; + tr.base = base; + tr.limit = limit; + tr.access = segdat[2] >> 8; tr.ar_high = segdat[3] & 0xff; } - void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg) { uint32_t limit_raw = seg->limit; if (seg->ar_high & 0x80) - limit_raw >>= 12; + limit_raw >>= 12; writememl(0, addr, (limit_raw & 0xffff) | (seg->base << 16)); - writememl(0, addr + 4, ((seg->base >> 16) & 0xff) | (seg->access << 8) | - (limit_raw & 0xf0000) | (seg->ar_high << 16) | - (seg->base & 0xff000000)); + writememl(0, addr + 4, ((seg->base >> 16) & 0xff) | (seg->access << 8) | (limit_raw & 0xf0000) | (seg->ar_high << 16) | (seg->base & 0xff000000)); } - void cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg) { @@ -2414,30 +2453,30 @@ cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg) segdat[1] = readmemw(0, addr + 2); segdat[2] = readmemw(0, addr + 4); segdat[3] = readmemw(0, addr + 6); - selector = readmemw(0, addr+8); + selector = readmemw(0, addr + 8); if (!cpu_state.abrt) { - do_seg_load(seg, segdat); - seg->seg = selector; - seg->checked = 0; - if (seg == &cpu_state.seg_ds) { - if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; + do_seg_load(seg, segdat); + seg->seg = selector; + seg->checked = 0; + if (seg == &cpu_state.seg_ds) { + if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATDS; #ifdef USE_DYNAREC - codegen_flat_ds = 0; + codegen_flat_ds = 0; #endif - } - if (seg == &cpu_state.seg_ss) { - if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - set_stack32((segdat[3] & 0x40) ? 1 : 0); + } + if (seg == &cpu_state.seg_ss) { + if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATSS; + set_stack32((segdat[3] & 0x40) ? 1 : 0); #ifdef USE_DYNAREC - codegen_flat_ss = 0; + codegen_flat_ss = 0; #endif - } + } } } diff --git a/src/cpu/x87.c b/src/cpu/x87.c index 1f05e8762..0b93af9da 100644 --- a/src/cpu/x87.c +++ b/src/cpu/x87.c @@ -16,117 +16,111 @@ #include "x87.h" #include "386_common.h" - -uint32_t x87_pc_off,x87_op_off; -uint16_t x87_pc_seg,x87_op_seg; - +uint32_t x87_pc_off, x87_op_off; +uint16_t x87_pc_seg, x87_op_seg; #ifdef ENABLE_FPU_LOG int fpu_do_log = ENABLE_FPU_LOG; - void fpu_log(const char *fmt, ...) { va_list ap; if (fpu_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define fpu_log(fmt, ...) +# define fpu_log(fmt, ...) #endif - #define X87_TAG_VALID 0 #define X87_TAG_ZERO 1 #define X87_TAG_INVALID 2 #define X87_TAG_EMPTY 3 #ifdef USE_NEW_DYNAREC -uint16_t x87_gettag(void) +uint16_t +x87_gettag(void) { - uint16_t ret = 0; - int c; + uint16_t ret = 0; + int c; - for (c = 0; c < 8; c++) - { - if (cpu_state.tag[c] == TAG_EMPTY) - ret |= X87_TAG_EMPTY << (c * 2); - else if (cpu_state.tag[c] & TAG_UINT64) - ret |= 2 << (c*2); - else if (cpu_state.ST[c] == 0.0 && !cpu_state.ismmx) - ret |= X87_TAG_ZERO << (c * 2); - else - ret |= X87_TAG_VALID << (c * 2); - } + for (c = 0; c < 8; c++) { + if (cpu_state.tag[c] == TAG_EMPTY) + ret |= X87_TAG_EMPTY << (c * 2); + else if (cpu_state.tag[c] & TAG_UINT64) + ret |= 2 << (c * 2); + else if (cpu_state.ST[c] == 0.0 && !cpu_state.ismmx) + ret |= X87_TAG_ZERO << (c * 2); + else + ret |= X87_TAG_VALID << (c * 2); + } - return ret; + return ret; } -void x87_settag(uint16_t new_tag) +void +x87_settag(uint16_t new_tag) { - int c; + int c; - for (c = 0; c < 8; c++) - { - int tag = (new_tag >> (c * 2)) & 3; + for (c = 0; c < 8; c++) { + int tag = (new_tag >> (c * 2)) & 3; - if (tag == X87_TAG_EMPTY) - cpu_state.tag[c] = TAG_EMPTY; - else if (tag == 2) - cpu_state.tag[c] = TAG_VALID | TAG_UINT64; - else - cpu_state.tag[c] = TAG_VALID; - } + if (tag == X87_TAG_EMPTY) + cpu_state.tag[c] = TAG_EMPTY; + else if (tag == 2) + cpu_state.tag[c] = TAG_VALID | TAG_UINT64; + else + cpu_state.tag[c] = TAG_VALID; + } } #else -uint16_t x87_gettag(void) +uint16_t +x87_gettag(void) { - uint16_t ret = 0; - int c; + uint16_t ret = 0; + int c; - for (c = 0; c < 8; c++) - { - if (cpu_state.tag[c] & TAG_UINT64) - ret |= 2 << (c*2); - else - ret |= (cpu_state.tag[c] << (c*2)); - } + for (c = 0; c < 8; c++) { + if (cpu_state.tag[c] & TAG_UINT64) + ret |= 2 << (c * 2); + else + ret |= (cpu_state.tag[c] << (c * 2)); + } - return ret; + return ret; } -void x87_settag(uint16_t new_tag) +void +x87_settag(uint16_t new_tag) { - cpu_state.tag[0] = new_tag & 3; - cpu_state.tag[1] = (new_tag >> 2) & 3; - cpu_state.tag[2] = (new_tag >> 4) & 3; - cpu_state.tag[3] = (new_tag >> 6) & 3; - cpu_state.tag[4] = (new_tag >> 8) & 3; - cpu_state.tag[5] = (new_tag >> 10) & 3; - cpu_state.tag[6] = (new_tag >> 12) & 3; - cpu_state.tag[7] = (new_tag >> 14) & 3; + cpu_state.tag[0] = new_tag & 3; + cpu_state.tag[1] = (new_tag >> 2) & 3; + cpu_state.tag[2] = (new_tag >> 4) & 3; + cpu_state.tag[3] = (new_tag >> 6) & 3; + cpu_state.tag[4] = (new_tag >> 8) & 3; + cpu_state.tag[5] = (new_tag >> 10) & 3; + cpu_state.tag[6] = (new_tag >> 12) & 3; + cpu_state.tag[7] = (new_tag >> 14) & 3; } #endif - #ifdef ENABLE_808X_LOG -void x87_dumpregs(void) +void +x87_dumpregs(void) { - if (cpu_state.ismmx) - { - fpu_log("MM0=%016llX\tMM1=%016llX\tMM2=%016llX\tMM3=%016llX\n", cpu_state.MM[0].q, cpu_state.MM[1].q, cpu_state.MM[2].q, cpu_state.MM[3].q); - fpu_log("MM4=%016llX\tMM5=%016llX\tMM6=%016llX\tMM7=%016llX\n", cpu_state.MM[4].q, cpu_state.MM[5].q, cpu_state.MM[6].q, cpu_state.MM[7].q); - } - else - { - fpu_log("ST(0)=%f\tST(1)=%f\tST(2)=%f\tST(3)=%f\t\n",cpu_state.ST[cpu_state.TOP],cpu_state.ST[(cpu_state.TOP+1)&7],cpu_state.ST[(cpu_state.TOP+2)&7],cpu_state.ST[(cpu_state.TOP+3)&7]); - fpu_log("ST(4)=%f\tST(5)=%f\tST(6)=%f\tST(7)=%f\t\n",cpu_state.ST[(cpu_state.TOP+4)&7],cpu_state.ST[(cpu_state.TOP+5)&7],cpu_state.ST[(cpu_state.TOP+6)&7],cpu_state.ST[(cpu_state.TOP+7)&7]); - } - fpu_log("Status = %04X Control = %04X Tag = %04X\n", cpu_state.npxs, cpu_state.npxc, x87_gettag()); + if (cpu_state.ismmx) { + fpu_log("MM0=%016llX\tMM1=%016llX\tMM2=%016llX\tMM3=%016llX\n", cpu_state.MM[0].q, cpu_state.MM[1].q, cpu_state.MM[2].q, cpu_state.MM[3].q); + fpu_log("MM4=%016llX\tMM5=%016llX\tMM6=%016llX\tMM7=%016llX\n", cpu_state.MM[4].q, cpu_state.MM[5].q, cpu_state.MM[6].q, cpu_state.MM[7].q); + } else { + fpu_log("ST(0)=%f\tST(1)=%f\tST(2)=%f\tST(3)=%f\t\n", cpu_state.ST[cpu_state.TOP], cpu_state.ST[(cpu_state.TOP + 1) & 7], cpu_state.ST[(cpu_state.TOP + 2) & 7], cpu_state.ST[(cpu_state.TOP + 3) & 7]); + fpu_log("ST(4)=%f\tST(5)=%f\tST(6)=%f\tST(7)=%f\t\n", cpu_state.ST[(cpu_state.TOP + 4) & 7], cpu_state.ST[(cpu_state.TOP + 5) & 7], cpu_state.ST[(cpu_state.TOP + 6) & 7], cpu_state.ST[(cpu_state.TOP + 7) & 7]); + } + fpu_log("Status = %04X Control = %04X Tag = %04X\n", cpu_state.npxs, cpu_state.npxc, x87_gettag()); } #endif diff --git a/src/cpu/x87.h b/src/cpu/x87.h index 48106c2e3..96ad835c8 100644 --- a/src/cpu/x87.h +++ b/src/cpu/x87.h @@ -1,43 +1,44 @@ -#define C0 (1<<8) -#define C1 (1<<9) -#define C2 (1<<10) -#define C3 (1<<14) +#define C0 (1 << 8) +#define C1 (1 << 9) +#define C2 (1 << 10) +#define C3 (1 << 14) -extern uint32_t x87_pc_off,x87_op_off; -extern uint16_t x87_pc_seg,x87_op_seg; +extern uint32_t x87_pc_off, x87_op_off; +extern uint16_t x87_pc_seg, x87_op_seg; -static __inline void x87_set_mmx(void) +static __inline void +x87_set_mmx(void) { - uint64_t *p; - cpu_state.TOP = 0; - p = (uint64_t *)cpu_state.tag; - *p = 0x0101010101010101ull; - cpu_state.ismmx = 1; + uint64_t *p; + cpu_state.TOP = 0; + p = (uint64_t *) cpu_state.tag; + *p = 0x0101010101010101ull; + cpu_state.ismmx = 1; } -static __inline void x87_emms(void) +static __inline void +x87_emms(void) { - uint64_t *p; - p = (uint64_t *)cpu_state.tag; - *p = 0; - cpu_state.ismmx = 0; + uint64_t *p; + p = (uint64_t *) cpu_state.tag; + *p = 0; + cpu_state.ismmx = 0; } - uint16_t x87_gettag(void); -void x87_settag(uint16_t new_tag); +void x87_settag(uint16_t new_tag); -#define TAG_EMPTY 0 -#define TAG_VALID (1 << 0) +#define TAG_EMPTY 0 +#define TAG_VALID (1 << 0) /*Hack for FPU copy. If set then MM[].q contains the 64-bit integer loaded by FILD*/ #ifdef USE_NEW_DYNAREC -#define TAG_UINT64 (1 << 7) +# define TAG_UINT64 (1 << 7) #else -#define TAG_UINT64 (1 << 2) +# define TAG_UINT64 (1 << 2) #endif /*Old dynarec stuff.*/ -#define TAG_NOT_UINT64 0xfb +#define TAG_NOT_UINT64 0xfb #define X87_ROUNDING_NEAREST 0 #define X87_ROUNDING_DOWN 1 diff --git a/src/cpu/x87_ops.h b/src/cpu/x87_ops.h index 64ea50a33..cb7a35323 100644 --- a/src/cpu/x87_ops.h +++ b/src/cpu/x87_ops.h @@ -24,443 +24,446 @@ #include #include "x87_timings.h" #ifdef _MSC_VER -# include +# include #endif #ifdef ENABLE_FPU_LOG -extern void fpu_log(const char *fmt, ...); +extern void fpu_log(const char *fmt, ...); #else -#ifndef fpu_log -#define fpu_log(fmt, ...) -#endif +# ifndef fpu_log +# define fpu_log(fmt, ...) +# endif #endif -static int rounding_modes[4] = {FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZERO}; +static int rounding_modes[4] = { FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZERO }; -#define ST(x) cpu_state.ST[((cpu_state.TOP+(x))&7)] +#define ST(x) cpu_state.ST[((cpu_state.TOP + (x)) & 7)] -#define C0 (1<<8) -#define C1 (1<<9) -#define C2 (1<<10) -#define C3 (1<<14) +#define C0 (1 << 8) +#define C1 (1 << 9) +#define C2 (1 << 10) +#define C3 (1 << 14) #define STATUS_ZERODIVIDE 4 #if defined(_MSC_VER) && !defined(__clang__) -# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 -# define X87_INLINE_ASM -# endif +# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 +# define X87_INLINE_ASM +# endif #else -# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 || defined __amd64__ -# define X87_INLINE_ASM -# endif +# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 || defined __amd64__ +# define X87_INLINE_ASM +# endif #endif #ifdef FPU_8087 -#define x87_div(dst, src1, src2) do \ - { \ - if (((double)src2) == 0.0) \ - { \ - cpu_state.npxs |= STATUS_ZERODIVIDE; \ - if (cpu_state.npxc & STATUS_ZERODIVIDE) \ - dst = src1 / (double)src2; \ - else \ - { \ - fpu_log("FPU : divide by zero\n"); \ - if (!(cpu_state.npxc & 0x80)) { \ - cpu_state.npxs |= 0x80; \ - nmi = 1; \ - } \ - return 1; \ - } \ - } \ - else \ - dst = src1 / (double)src2; \ +# define x87_div(dst, src1, src2) \ + do { \ + if (((double) src2) == 0.0) { \ + cpu_state.npxs |= STATUS_ZERODIVIDE; \ + if (cpu_state.npxc & STATUS_ZERODIVIDE) \ + dst = src1 / (double) src2; \ + else { \ + fpu_log("FPU : divide by zero\n"); \ + if (!(cpu_state.npxc & 0x80)) { \ + cpu_state.npxs |= 0x80; \ + nmi = 1; \ + } \ + return 1; \ + } \ + } else \ + dst = src1 / (double) src2; \ } while (0) #else -#define x87_div(dst, src1, src2) do \ - { \ - if (((double)src2) == 0.0) \ - { \ - cpu_state.npxs |= STATUS_ZERODIVIDE; \ - if (cpu_state.npxc & STATUS_ZERODIVIDE) \ - dst = src1 / (double)src2; \ - else \ - { \ - fpu_log("FPU : divide by zero\n"); \ - picint(1 << 13); \ - return 1; \ - } \ - } \ - else \ - dst = src1 / (double)src2; \ +# define x87_div(dst, src1, src2) \ + do { \ + if (((double) src2) == 0.0) { \ + cpu_state.npxs |= STATUS_ZERODIVIDE; \ + if (cpu_state.npxc & STATUS_ZERODIVIDE) \ + dst = src1 / (double) src2; \ + else { \ + fpu_log("FPU : divide by zero\n"); \ + picint(1 << 13); \ + return 1; \ + } \ + } else \ + dst = src1 / (double) src2; \ } while (0) #endif -static __inline void x87_checkexceptions(void) +static __inline void +x87_checkexceptions(void) { } -static __inline void x87_push(double i) +static __inline void +x87_push(double i) { #ifdef USE_NEW_DYNAREC - cpu_state.TOP--; + cpu_state.TOP--; #else - cpu_state.TOP=(cpu_state.TOP-1)&7; + cpu_state.TOP = (cpu_state.TOP - 1) & 7; #endif - cpu_state.ST[cpu_state.TOP&7] = i; + cpu_state.ST[cpu_state.TOP & 7] = i; #ifdef USE_NEW_DYNAREC - cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; #else - cpu_state.tag[cpu_state.TOP&7] = (i == 0.0) ? TAG_VALID : 0; + cpu_state.tag[cpu_state.TOP & 7] = (i == 0.0) ? TAG_VALID : 0; #endif } -static __inline void x87_push_u64(uint64_t i) +static __inline void +x87_push_u64(uint64_t i) { - union - { - double d; - uint64_t ll; - } td; + union { + double d; + uint64_t ll; + } td; - td.ll = i; + td.ll = i; #ifdef USE_NEW_DYNAREC - cpu_state.TOP--; + cpu_state.TOP--; #else - cpu_state.TOP=(cpu_state.TOP-1)&7; + cpu_state.TOP = (cpu_state.TOP - 1) & 7; #endif - cpu_state.ST[cpu_state.TOP&7] = td.d; + cpu_state.ST[cpu_state.TOP & 7] = td.d; #ifdef USE_NEW_DYNAREC - cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; #else - cpu_state.tag[cpu_state.TOP&7] = (td.d == 0.0) ? TAG_VALID : 0; + cpu_state.tag[cpu_state.TOP & 7] = (td.d == 0.0) ? TAG_VALID : 0; #endif } -static __inline double x87_pop(void) +static __inline double +x87_pop(void) { - double t = cpu_state.ST[cpu_state.TOP&7]; - cpu_state.tag[cpu_state.TOP&7] = TAG_EMPTY; + double t = cpu_state.ST[cpu_state.TOP & 7]; + cpu_state.tag[cpu_state.TOP & 7] = TAG_EMPTY; #ifdef USE_NEW_DYNAREC - cpu_state.TOP++; + cpu_state.TOP++; #else - cpu_state.tag[cpu_state.TOP&7] |= TAG_UINT64; - cpu_state.TOP=(cpu_state.TOP+1)&7; + cpu_state.tag[cpu_state.TOP & 7] |= TAG_UINT64; + cpu_state.TOP = (cpu_state.TOP + 1) & 7; #endif - return t; + return t; } -static __inline int16_t x87_fround16(double b) +static __inline int16_t +x87_fround16(double b) { - int16_t a, c; + int16_t a, c; - switch ((cpu_state.npxc >> 10) & 3) - { - case 0: /*Nearest*/ - a = (int16_t)floor(b); - c = (int16_t)floor(b + 1.0); - if ((b - a) < (c - b)) - return a; - else if ((b - a) > (c - b)) - return c; - else - return (a & 1) ? c : a; - case 1: /*Down*/ - return (int16_t)floor(b); - case 2: /*Up*/ - return (int16_t)ceil(b); - case 3: /*Chop*/ - return (int16_t)b; - } + switch ((cpu_state.npxc >> 10) & 3) { + case 0: /*Nearest*/ + a = (int16_t) floor(b); + c = (int16_t) floor(b + 1.0); + if ((b - a) < (c - b)) + return a; + else if ((b - a) > (c - b)) + return c; + else + return (a & 1) ? c : a; + case 1: /*Down*/ + return (int16_t) floor(b); + case 2: /*Up*/ + return (int16_t) ceil(b); + case 3: /*Chop*/ + return (int16_t) b; + } - return 0; + return 0; } -static __inline int64_t x87_fround16_64(double b) +static __inline int64_t +x87_fround16_64(double b) { return (int64_t) x87_fround16(b); } -static __inline int32_t x87_fround32(double b) +static __inline int32_t +x87_fround32(double b) { - int32_t a, c; + int32_t a, c; - switch ((cpu_state.npxc >> 10) & 3) - { - case 0: /*Nearest*/ - a = (int32_t)floor(b); - c = (int32_t)floor(b + 1.0); - if ((b - a) < (c - b)) - return a; - else if ((b - a) > (c - b)) - return c; - else - return (a & 1) ? c : a; - case 1: /*Down*/ - return (int32_t)floor(b); - case 2: /*Up*/ - return (int32_t)ceil(b); - case 3: /*Chop*/ - return (int32_t)b; - } + switch ((cpu_state.npxc >> 10) & 3) { + case 0: /*Nearest*/ + a = (int32_t) floor(b); + c = (int32_t) floor(b + 1.0); + if ((b - a) < (c - b)) + return a; + else if ((b - a) > (c - b)) + return c; + else + return (a & 1) ? c : a; + case 1: /*Down*/ + return (int32_t) floor(b); + case 2: /*Up*/ + return (int32_t) ceil(b); + case 3: /*Chop*/ + return (int32_t) b; + } - return 0; + return 0; } -static __inline int64_t x87_fround32_64(double b) +static __inline int64_t +x87_fround32_64(double b) { return (int64_t) x87_fround32(b); } -static __inline int64_t x87_fround(double b) +static __inline int64_t +x87_fround(double b) { - int64_t a, c; + int64_t a, c; - switch ((cpu_state.npxc >> 10) & 3) - { - case 0: /*Nearest*/ - a = (int64_t)floor(b); - c = (int64_t)floor(b + 1.0); - if ((b - a) < (c - b)) - return a; - else if ((b - a) > (c - b)) - return c; - else - return (a & 1) ? c : a; - case 1: /*Down*/ - return (int64_t)floor(b); - case 2: /*Up*/ - return (int64_t)ceil(b); - case 3: /*Chop*/ - return (int64_t)b; - } + switch ((cpu_state.npxc >> 10) & 3) { + case 0: /*Nearest*/ + a = (int64_t) floor(b); + c = (int64_t) floor(b + 1.0); + if ((b - a) < (c - b)) + return a; + else if ((b - a) > (c - b)) + return c; + else + return (a & 1) ? c : a; + case 1: /*Down*/ + return (int64_t) floor(b); + case 2: /*Up*/ + return (int64_t) ceil(b); + case 3: /*Chop*/ + return (int64_t) b; + } - return 0LL; + return 0LL; } #include "x87_ops_conv.h" -static __inline double x87_ld80(void) +static __inline double +x87_ld80(void) { - x87_conv_t test; - test.eind.ll = readmeml(easeg,cpu_state.eaaddr); - test.eind.ll |= (uint64_t)readmeml(easeg,cpu_state.eaaddr+4)<<32; - test.begin = readmemw(easeg,cpu_state.eaaddr+8); - return x87_from80(&test); + x87_conv_t test; + test.eind.ll = readmeml(easeg, cpu_state.eaaddr); + test.eind.ll |= (uint64_t) readmeml(easeg, cpu_state.eaaddr + 4) << 32; + test.begin = readmemw(easeg, cpu_state.eaaddr + 8); + return x87_from80(&test); } -static __inline void x87_st80(double d) +static __inline void +x87_st80(double d) { - x87_conv_t test; - x87_to80(d, &test); - writememl(easeg,cpu_state.eaaddr,test.eind.ll & 0xffffffff); - writememl(easeg,cpu_state.eaaddr+4,test.eind.ll>>32); - writememw(easeg,cpu_state.eaaddr+8,test.begin); + x87_conv_t test; + x87_to80(d, &test); + writememl(easeg, cpu_state.eaaddr, test.eind.ll & 0xffffffff); + writememl(easeg, cpu_state.eaaddr + 4, test.eind.ll >> 32); + writememw(easeg, cpu_state.eaaddr + 8, test.begin); } -static __inline void x87_st_fsave(int reg) +static __inline void +x87_st_fsave(int reg) { - reg = (cpu_state.TOP + reg) & 7; + reg = (cpu_state.TOP + reg) & 7; - if (cpu_state.tag[reg] & TAG_UINT64) - { - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[reg].q & 0xffffffff); - writememl(easeg, cpu_state.eaaddr + 4, cpu_state.MM[reg].q >> 32); - writememw(easeg, cpu_state.eaaddr + 8, 0x5555); - } - else - x87_st80(cpu_state.ST[reg]); + if (cpu_state.tag[reg] & TAG_UINT64) { + writememl(easeg, cpu_state.eaaddr, cpu_state.MM[reg].q & 0xffffffff); + writememl(easeg, cpu_state.eaaddr + 4, cpu_state.MM[reg].q >> 32); + writememw(easeg, cpu_state.eaaddr + 8, 0x5555); + } else + x87_st80(cpu_state.ST[reg]); } -static __inline void x87_ld_frstor(int reg) +static __inline void +x87_ld_frstor(int reg) { - reg = (cpu_state.TOP + reg) & 7; + reg = (cpu_state.TOP + reg) & 7; - cpu_state.MM[reg].q = readmemq(easeg, cpu_state.eaaddr); - cpu_state.MM_w4[reg] = readmemw(easeg, cpu_state.eaaddr + 8); + cpu_state.MM[reg].q = readmemq(easeg, cpu_state.eaaddr); + cpu_state.MM_w4[reg] = readmemw(easeg, cpu_state.eaaddr + 8); #ifdef USE_NEW_DYNAREC - if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] & TAG_UINT64)) + if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] & TAG_UINT64)) #else - if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] == 2)) + if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] == 2)) #endif - { + { #ifndef USE_NEW_DYNAREC - cpu_state.tag[reg] = TAG_UINT64; + cpu_state.tag[reg] = TAG_UINT64; #endif - cpu_state.ST[reg] = (double)cpu_state.MM[reg].q; - } - else - { + cpu_state.ST[reg] = (double) cpu_state.MM[reg].q; + } else { #ifdef USE_NEW_DYNAREC - cpu_state.tag[reg] &= ~TAG_UINT64; + cpu_state.tag[reg] &= ~TAG_UINT64; #endif - cpu_state.ST[reg] = x87_ld80(); - } + cpu_state.ST[reg] = x87_ld80(); + } } -static __inline void x87_ldmmx(MMX_REG *r, uint16_t *w4) +static __inline void +x87_ldmmx(MMX_REG *r, uint16_t *w4) { - r->l[0] = readmeml(easeg, cpu_state.eaaddr); - r->l[1] = readmeml(easeg, cpu_state.eaaddr + 4); - *w4 = readmemw(easeg, cpu_state.eaaddr + 8); + r->l[0] = readmeml(easeg, cpu_state.eaaddr); + r->l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + *w4 = readmemw(easeg, cpu_state.eaaddr + 8); } -static __inline void x87_stmmx(MMX_REG r) +static __inline void +x87_stmmx(MMX_REG r) { - writememl(easeg, cpu_state.eaaddr, r.l[0]); - writememl(easeg, cpu_state.eaaddr + 4, r.l[1]); - writememw(easeg, cpu_state.eaaddr + 8, 0xffff); + writememl(easeg, cpu_state.eaaddr, r.l[0]); + writememl(easeg, cpu_state.eaaddr + 4, r.l[1]); + writememw(easeg, cpu_state.eaaddr + 8, 0xffff); } #include -static __inline uint16_t x87_compare(double a, double b) +static __inline uint16_t +x87_compare(double a, double b) { #ifdef X87_INLINE_ASM - uint32_t result; - double ea = a, eb = b; - const uint64_t ia = 0x3fec1a6ff866a936ull; - const uint64_t ib = 0x3fec1a6ff866a938ull; + uint32_t result; + double ea = a, eb = b; + const uint64_t ia = 0x3fec1a6ff866a936ull; + const uint64_t ib = 0x3fec1a6ff866a938ull; - /* Hack to make CHKCOP happy. */ - if (!memcmp(&ea, &ia, 8) && !memcmp(&eb, &ib, 8)) - return C3; + /* Hack to make CHKCOP happy. */ + if (!memcmp(&ea, &ia, 8) && !memcmp(&eb, &ib, 8)) + return C3; - if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) && - ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY))) - eb = ea; + if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) && ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY))) + eb = ea; -#if !defined(_MSC_VER) || defined(__clang__) - /* Memory barrier, to force GCC to write to the input parameters - * before the compare rather than after */ - __asm volatile ("" : : : "memory"); +# if !defined(_MSC_VER) || defined(__clang__) + /* Memory barrier, to force GCC to write to the input parameters + * before the compare rather than after */ + __asm volatile("" + : + : + : "memory"); - __asm( - "fldl %2\n" - "fldl %1\n" - "fclex\n" - "fcompp\n" - "fnstsw %0\n" - : "=m" (result) - : "m" (ea), "m" (eb) - ); -#else - _ReadWriteBarrier(); - _asm - { + __asm( + "fldl %2\n" + "fldl %1\n" + "fclex\n" + "fcompp\n" + "fnstsw %0\n" + : "=m"(result) + : "m"(ea), "m"(eb)); +# else + _ReadWriteBarrier(); + _asm + { fld eb fld ea fclex fcompp fnstsw result - } -#endif + } +# endif - return result & (C0|C2|C3); + return result & (C0 | C2 | C3); #else - /* Generic C version is known to give incorrect results in some - * situations, eg comparison of infinity (Unreal) */ - uint32_t result = 0; - double ea = a, eb = b; + /* Generic C version is known to give incorrect results in some + * situations, eg comparison of infinity (Unreal) */ + uint32_t result = 0; + double ea = a, eb = b; - if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) && - ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY))) - eb = ea; + if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) && ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY))) + eb = ea; - if (ea == eb) - result |= C3; - else if (ea < eb) - result |= C0; + if (ea == eb) + result |= C3; + else if (ea < eb) + result |= C0; - return result; + return result; #endif } -static __inline uint16_t x87_ucompare(double a, double b) +static __inline uint16_t +x87_ucompare(double a, double b) { #ifdef X87_INLINE_ASM - uint32_t result; + uint32_t result; -#if !defined(_MSC_VER) || defined(__clang__) - /* Memory barrier, to force GCC to write to the input parameters - * before the compare rather than after */ - __asm volatile ("" : : : "memory"); +# if !defined(_MSC_VER) || defined(__clang__) + /* Memory barrier, to force GCC to write to the input parameters + * before the compare rather than after */ + __asm volatile("" + : + : + : "memory"); - __asm( - "fldl %2\n" - "fldl %1\n" - "fclex\n" - "fucompp\n" - "fnstsw %0\n" - : "=m" (result) - : "m" (a), "m" (b) - ); -#else - _ReadWriteBarrier(); - _asm - { + __asm( + "fldl %2\n" + "fldl %1\n" + "fclex\n" + "fucompp\n" + "fnstsw %0\n" + : "=m"(result) + : "m"(a), "m"(b)); +# else + _ReadWriteBarrier(); + _asm + { fld b fld a fclex fcompp fnstsw result - } -#endif + } +# endif - return result & (C0|C2|C3); + return result & (C0 | C2 | C3); #else - /* Generic C version is known to give incorrect results in some - * situations, eg comparison of infinity (Unreal) */ - uint32_t result = 0; + /* Generic C version is known to give incorrect results in some + * situations, eg comparison of infinity (Unreal) */ + uint32_t result = 0; - if (a == b) - result |= C3; - else if (a < b) - result |= C0; + if (a == b) + result |= C3; + else if (a < b) + result |= C0; - return result; + return result; #endif } -typedef union -{ - float s; - uint32_t i; +typedef union { + float s; + uint32_t i; } x87_ts; -typedef union -{ - double d; - uint64_t i; +typedef union { + double d; + uint64_t i; } x87_td; #ifdef FPU_8087 -#define FP_ENTER() { \ - } +# define FP_ENTER() \ + { \ + } #else -#define FP_ENTER() do \ - { \ - if (cr0 & 0xc) \ - { \ - x86_int(7); \ - return 1; \ - } \ +# define FP_ENTER() \ + do { \ + if (cr0 & 0xc) { \ + x86_int(7); \ + return 1; \ + } \ } while (0) #endif #ifdef USE_NEW_DYNAREC -# define FP_TAG_VALID cpu_state.tag[cpu_state.TOP&7] = TAG_VALID -# define FP_TAG_VALID_F cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID -# define FP_TAG_DEFAULT cpu_state.tag[cpu_state.TOP&7] = TAG_VALID | TAG_UINT64 -# define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID +# define FP_TAG_VALID cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID +# define FP_TAG_VALID_F cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID +# define FP_TAG_DEFAULT cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID | TAG_UINT64 +# define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID #else -# define FP_TAG_VALID cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64 -# define FP_TAG_VALID_F cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64 -# define FP_TAG_DEFAULT cpu_state.tag[cpu_state.TOP] |= TAG_UINT64; -# define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64 +# define FP_TAG_VALID cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64 +# define FP_TAG_VALID_F cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64 +# define FP_TAG_DEFAULT cpu_state.tag[cpu_state.TOP] |= TAG_UINT64; +# define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64 #endif #include "x87_ops_arith.h" @@ -468,56 +471,55 @@ typedef union #include "x87_ops_loadstore.h" #ifndef FPU_8087 -static int op_nofpu_a16(uint32_t fetchdat) +static int +op_nofpu_a16(uint32_t fetchdat) { - if (cr0 & 0xc) - { - x86_int(7); - return 1; - } - else - { - fetch_ea_16(fetchdat); - return 0; - } + if (cr0 & 0xc) { + x86_int(7); + return 1; + } else { + fetch_ea_16(fetchdat); + return 0; + } } -static int op_nofpu_a32(uint32_t fetchdat) +static int +op_nofpu_a32(uint32_t fetchdat) { - if (cr0 & 0xc) - { - x86_int(7); - return 1; - } - else - { - fetch_ea_32(fetchdat); - return 0; - } + if (cr0 & 0xc) { + x86_int(7); + return 1; + } else { + fetch_ea_32(fetchdat); + return 0; + } } #endif #ifdef FPU_8087 -static int FPU_ILLEGAL_a16(uint32_t fetchdat) +static int +FPU_ILLEGAL_a16(uint32_t fetchdat) { - geteaw(); - wait(timing_rr, 0); - return 0; + geteaw(); + wait(timing_rr, 0); + return 0; } #else -static int FPU_ILLEGAL_a16(uint32_t fetchdat) +static int +FPU_ILLEGAL_a16(uint32_t fetchdat) { - fetch_ea_16(fetchdat); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - return 0; + fetch_ea_16(fetchdat); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + return 0; } -static int FPU_ILLEGAL_a32(uint32_t fetchdat) +static int +FPU_ILLEGAL_a32(uint32_t fetchdat) { - fetch_ea_32(fetchdat); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - return 0; + fetch_ea_32(fetchdat); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + return 0; } #endif @@ -774,7 +776,7 @@ const OpFn OP_TABLE(fpu_8087_df)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, }; #else -#define ILLEGAL_a32 FPU_ILLEGAL_a32 +# define ILLEGAL_a32 FPU_ILLEGAL_a32 const OpFn OP_TABLE(fpu_d8_a16)[32] = { diff --git a/src/cpu/x87_ops_arith.h b/src/cpu/x87_ops_arith.h index 5e4bfceab..f5e5d7696 100644 --- a/src/cpu/x87_ops_arith.h +++ b/src/cpu/x87_ops_arith.h @@ -1,457 +1,508 @@ -#define opFPU(name, optype, a_size, load_var, get, use_var, cycle_postfix) \ -static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - if ((cpu_state.npxc >> 10) & 3) \ - fesetround(rounding_modes[(cpu_state.npxc >> 10) & 3]); \ - ST(0) += use_var; \ - if ((cpu_state.npxc >> 10) & 3) \ - fesetround(FE_TONEAREST); \ - FP_TAG_VALID; \ - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd ## cycle_postfix) : ((x87_timings.fadd ## cycle_postfix) * cpu_multi)); \ - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd ## cycle_postfix) : ((x87_concurrency.fadd ## cycle_postfix) * cpu_multi)); \ - return 0; \ -} \ -static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - cpu_state.npxs &= ~(C0|C2|C3); \ - cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom ## cycle_postfix) : ((x87_timings.fcom ## cycle_postfix) * cpu_multi)); \ - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom ## cycle_postfix) : ((x87_concurrency.fcom ## cycle_postfix) * cpu_multi)); \ - return 0; \ -} \ -static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - cpu_state.npxs &= ~(C0|C2|C3); \ - cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ - x87_pop(); \ - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom ## cycle_postfix) : ((x87_timings.fcom ## cycle_postfix) * cpu_multi)); \ - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom ## cycle_postfix) : ((x87_concurrency.fcom ## cycle_postfix) * cpu_multi)); \ - return 0; \ -} \ -static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - x87_div(ST(0), ST(0), use_var); \ - FP_TAG_VALID; \ - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv ## cycle_postfix) : ((x87_timings.fdiv ## cycle_postfix) * cpu_multi)); \ - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd ## cycle_postfix) : ((x87_concurrency.fadd ## cycle_postfix) * cpu_multi)); \ - return 0; \ -} \ -static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - x87_div(ST(0), use_var, ST(0)); \ - FP_TAG_VALID; \ - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv ## cycle_postfix) : ((x87_timings.fdiv ## cycle_postfix) * cpu_multi)); \ - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv ## cycle_postfix) : ((x87_concurrency.fdiv ## cycle_postfix) * cpu_multi)); \ - return 0; \ -} \ -static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - ST(0) *= use_var; \ - FP_TAG_VALID; \ - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul ## cycle_postfix) : ((x87_timings.fmul ## cycle_postfix) * cpu_multi)); \ - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul ## cycle_postfix) : ((x87_concurrency.fmul ## cycle_postfix) * cpu_multi)); \ - return 0; \ -} \ -static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - ST(0) -= use_var; \ - FP_TAG_VALID; \ - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd ## cycle_postfix) : ((x87_timings.fadd ## cycle_postfix) * cpu_multi)); \ - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd ## cycle_postfix) : ((x87_concurrency.fadd ## cycle_postfix) * cpu_multi)); \ - return 0; \ -} \ -static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - ST(0) = use_var - ST(0); \ - FP_TAG_VALID; \ - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd ## cycle_postfix) : ((x87_timings.fadd ## cycle_postfix) * cpu_multi)); \ - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd ## cycle_postfix) : ((x87_concurrency.fadd ## cycle_postfix) * cpu_multi)); \ - return 0; \ -} - +#define opFPU(name, optype, a_size, load_var, get, use_var, cycle_postfix) \ + static int opFADD##name##_a##a_size(uint32_t fetchdat) \ + { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + if ((cpu_state.npxc >> 10) & 3) \ + fesetround(rounding_modes[(cpu_state.npxc >> 10) & 3]); \ + ST(0) += use_var; \ + if ((cpu_state.npxc >> 10) & 3) \ + fesetround(FE_TONEAREST); \ + FP_TAG_VALID; \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd##cycle_postfix) : ((x87_timings.fadd##cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \ + return 0; \ + } \ + static int opFCOM##name##_a##a_size(uint32_t fetchdat) \ + { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.npxs &= ~(C0 | C2 | C3); \ + cpu_state.npxs |= x87_compare(ST(0), (double) use_var); \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom##cycle_postfix) : ((x87_timings.fcom##cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom##cycle_postfix) : ((x87_concurrency.fcom##cycle_postfix) * cpu_multi)); \ + return 0; \ + } \ + static int opFCOMP##name##_a##a_size(uint32_t fetchdat) \ + { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.npxs &= ~(C0 | C2 | C3); \ + cpu_state.npxs |= x87_compare(ST(0), (double) use_var); \ + x87_pop(); \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom##cycle_postfix) : ((x87_timings.fcom##cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom##cycle_postfix) : ((x87_concurrency.fcom##cycle_postfix) * cpu_multi)); \ + return 0; \ + } \ + static int opFDIV##name##_a##a_size(uint32_t fetchdat) \ + { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + x87_div(ST(0), ST(0), use_var); \ + FP_TAG_VALID; \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv##cycle_postfix) : ((x87_timings.fdiv##cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \ + return 0; \ + } \ + static int opFDIVR##name##_a##a_size(uint32_t fetchdat) \ + { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + x87_div(ST(0), use_var, ST(0)); \ + FP_TAG_VALID; \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv##cycle_postfix) : ((x87_timings.fdiv##cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv##cycle_postfix) : ((x87_concurrency.fdiv##cycle_postfix) * cpu_multi)); \ + return 0; \ + } \ + static int opFMUL##name##_a##a_size(uint32_t fetchdat) \ + { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + ST(0) *= use_var; \ + FP_TAG_VALID; \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul##cycle_postfix) : ((x87_timings.fmul##cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul##cycle_postfix) : ((x87_concurrency.fmul##cycle_postfix) * cpu_multi)); \ + return 0; \ + } \ + static int opFSUB##name##_a##a_size(uint32_t fetchdat) \ + { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + ST(0) -= use_var; \ + FP_TAG_VALID; \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd##cycle_postfix) : ((x87_timings.fadd##cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \ + return 0; \ + } \ + static int opFSUBR##name##_a##a_size(uint32_t fetchdat) \ + { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + ST(0) = use_var - ST(0); \ + FP_TAG_VALID; \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd##cycle_postfix) : ((x87_timings.fadd##cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \ + return 0; \ + } opFPU(s, x87_ts, 16, t.i, geteal, t.s, _32) #ifndef FPU_8087 -opFPU(s, x87_ts, 32, t.i, geteal, t.s, _32) + opFPU(s, x87_ts, 32, t.i, geteal, t.s, _32) #endif -opFPU(d, x87_td, 16, t.i, geteaq, t.d, _64) + opFPU(d, x87_td, 16, t.i, geteaq, t.d, _64) #ifndef FPU_8087 -opFPU(d, x87_td, 32, t.i, geteaq, t.d, _64) + opFPU(d, x87_td, 32, t.i, geteaq, t.d, _64) #endif -opFPU(iw, uint16_t, 16, t, geteaw, (double)(int16_t)t, _i16) + opFPU(iw, uint16_t, 16, t, geteaw, (double) (int16_t) t, _i16) #ifndef FPU_8087 -opFPU(iw, uint16_t, 32, t, geteaw, (double)(int16_t)t, _i16) + opFPU(iw, uint16_t, 32, t, geteaw, (double) (int16_t) t, _i16) #endif -opFPU(il, uint32_t, 16, t, geteal, (double)(int32_t)t, _i32) + opFPU(il, uint32_t, 16, t, geteal, (double) (int32_t) t, _i32) #ifndef FPU_8087 -opFPU(il, uint32_t, 32, t, geteal, (double)(int32_t)t, _i32) + opFPU(il, uint32_t, 32, t, geteal, (double) (int32_t) t, _i32) #endif - -static int opFADD(uint32_t fetchdat) + static int opFADD(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(0) = ST(0) + ST(fetchdat & 7); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(0) = ST(0) + ST(fetchdat & 7); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } -static int opFADDr(uint32_t fetchdat) +static int +opFADDr(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); - FP_TAG_VALID_F; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); + FP_TAG_VALID_F; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } -static int opFADDP(uint32_t fetchdat) +static int +opFADDP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); - FP_TAG_VALID_F; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); + FP_TAG_VALID_F; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } -static int opFCOM(uint32_t fetchdat) +static int +opFCOM(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= ~(C0|C2|C3); - if (ST(0) == ST(fetchdat & 7)) cpu_state.npxs |= C3; - else if (ST(0) < ST(fetchdat & 7)) cpu_state.npxs |= C0; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0 | C2 | C3); + if (ST(0) == ST(fetchdat & 7)) + cpu_state.npxs |= C3; + else if (ST(0) < ST(fetchdat & 7)) + cpu_state.npxs |= C0; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); + return 0; } -static int opFCOMP(uint32_t fetchdat) +static int +opFCOMP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= ~(C0|C2|C3); - cpu_state.npxs |= x87_compare(ST(0), ST(fetchdat & 7)); - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0 | C2 | C3); + cpu_state.npxs |= x87_compare(ST(0), ST(fetchdat & 7)); + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); + return 0; } -static int opFCOMPP(uint32_t fetchdat) +static int +opFCOMPP(uint32_t fetchdat) { - uint64_t *p, *q; - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= ~(C0|C2|C3); - p = (uint64_t *)&ST(0); - q = (uint64_t *)&ST(1); - if ((*p == ((uint64_t)1 << 63) && *q == 0) && (fpu_type >= FPU_287XL)) - cpu_state.npxs |= C0; /*Nasty hack to fix 80387 detection*/ - else - cpu_state.npxs |= x87_compare(ST(0), ST(1)); + uint64_t *p, *q; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0 | C2 | C3); + p = (uint64_t *) &ST(0); + q = (uint64_t *) &ST(1); + if ((*p == ((uint64_t) 1 << 63) && *q == 0) && (fpu_type >= FPU_287XL)) + cpu_state.npxs |= C0; /*Nasty hack to fix 80387 detection*/ + else + cpu_state.npxs |= x87_compare(ST(0), ST(1)); - x87_pop(); - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); - return 0; + x87_pop(); + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFUCOMPP(uint32_t fetchdat) +static int +opFUCOMPP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= ~(C0|C2|C3); - cpu_state.npxs |= x87_ucompare(ST(0), ST(1)); - x87_pop(); - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0 | C2 | C3); + cpu_state.npxs |= x87_ucompare(ST(0), ST(1)); + x87_pop(); + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); + return 0; } -static int opFCOMI(uint32_t fetchdat) +static int +opFCOMI(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - flags_rebuild(); - cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); - if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; - else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + flags_rebuild(); + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) + cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) + cpu_state.flags |= C_FLAG; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); + return 0; } -static int opFCOMIP(uint32_t fetchdat) +static int +opFCOMIP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - flags_rebuild(); - cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); - if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; - else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + flags_rebuild(); + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) + cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) + cpu_state.flags |= C_FLAG; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); + return 0; } #endif -static int opFDIV(uint32_t fetchdat) +static int +opFDIV(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - x87_div(ST(0), ST(0), ST(fetchdat & 7)); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(0), ST(0), ST(fetchdat & 7)); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); + return 0; } -static int opFDIVr(uint32_t fetchdat) +static int +opFDIVr(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); - FP_TAG_VALID_F; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); + FP_TAG_VALID_F; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); + return 0; } -static int opFDIVP(uint32_t fetchdat) +static int +opFDIVP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); - FP_TAG_VALID_F; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); + FP_TAG_VALID_F; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); + return 0; } -static int opFDIVR(uint32_t fetchdat) +static int +opFDIVR(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - x87_div(ST(0), ST(fetchdat&7), ST(0)); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(0), ST(fetchdat & 7), ST(0)); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); + return 0; } -static int opFDIVRr(uint32_t fetchdat) +static int +opFDIVRr(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); - FP_TAG_VALID_F; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); + FP_TAG_VALID_F; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); + return 0; } -static int opFDIVRP(uint32_t fetchdat) +static int +opFDIVRP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); - FP_TAG_VALID_F; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); + FP_TAG_VALID_F; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); + return 0; } -static int opFMUL(uint32_t fetchdat) +static int +opFMUL(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(0) = ST(0) * ST(fetchdat & 7); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(0) = ST(0) * ST(fetchdat & 7); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi)); + return 0; } -static int opFMULr(uint32_t fetchdat) +static int +opFMULr(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); - FP_TAG_VALID_F; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); + FP_TAG_VALID_F; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi)); + return 0; } -static int opFMULP(uint32_t fetchdat) +static int +opFMULP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); - FP_TAG_VALID_F; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); + FP_TAG_VALID_F; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi)); + return 0; } -static int opFSUB(uint32_t fetchdat) +static int +opFSUB(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(0) = ST(0) - ST(fetchdat & 7); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(0) = ST(0) - ST(fetchdat & 7); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } -static int opFSUBr(uint32_t fetchdat) +static int +opFSUBr(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); - FP_TAG_VALID_F; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); + FP_TAG_VALID_F; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } -static int opFSUBP(uint32_t fetchdat) +static int +opFSUBP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); - FP_TAG_VALID_F; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); + FP_TAG_VALID_F; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } -static int opFSUBR(uint32_t fetchdat) +static int +opFSUBR(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(0) = ST(fetchdat & 7) - ST(0); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(0) = ST(fetchdat & 7) - ST(0); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } -static int opFSUBRr(uint32_t fetchdat) +static int +opFSUBRr(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); - FP_TAG_VALID_F; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); + FP_TAG_VALID_F; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } -static int opFSUBRP(uint32_t fetchdat) +static int +opFSUBRP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); - FP_TAG_VALID_F; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); + FP_TAG_VALID_F; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFUCOM(uint32_t fetchdat) +static int +opFUCOM(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= ~(C0|C2|C3); - cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0 | C2 | C3); + cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); + return 0; } -static int opFUCOMP(uint32_t fetchdat) +static int +opFUCOMP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= ~(C0|C2|C3); - cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0 | C2 | C3); + cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); + return 0; } -static int opFUCOMI(uint32_t fetchdat) +static int +opFUCOMI(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - flags_rebuild(); - cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); - if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; - else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + flags_rebuild(); + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) + cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) + cpu_state.flags |= C_FLAG; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); + return 0; } -static int opFUCOMIP(uint32_t fetchdat) +static int +opFUCOMIP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - flags_rebuild(); - cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); - if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; - else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + flags_rebuild(); + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) + cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) + cpu_state.flags |= C_FLAG; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); + return 0; } #endif diff --git a/src/cpu/x87_ops_conv.h b/src/cpu/x87_ops_conv.h index 44304c1bc..bb1e497da 100644 --- a/src/cpu/x87_ops_conv.h +++ b/src/cpu/x87_ops_conv.h @@ -4,65 +4,66 @@ typedef struct { int16_t begin; union { - double d; + double d; uint64_t ll; } eind; } x87_conv_t; -static __inline double x87_from80(x87_conv_t *test) +static __inline double +x87_from80(x87_conv_t *test) { - int64_t exp64; - int64_t blah; - int64_t exp64final; - int64_t mant64; - int64_t sign; + int64_t exp64; + int64_t blah; + int64_t exp64final; + int64_t mant64; + int64_t sign; - exp64 = (((test->begin&0x7fff) - BIAS80)); - blah = ((exp64 >0)?exp64:-exp64)&0x3ff; - exp64final = ((exp64 >0)?blah:-blah) +BIAS64; + exp64 = (((test->begin & 0x7fff) - BIAS80)); + blah = ((exp64 > 0) ? exp64 : -exp64) & 0x3ff; + exp64final = ((exp64 > 0) ? blah : -blah) + BIAS64; - mant64 = (test->eind.ll >> 11) & (0xfffffffffffffll); - sign = (test->begin&0x8000)?1:0; + mant64 = (test->eind.ll >> 11) & (0xfffffffffffffll); + sign = (test->begin & 0x8000) ? 1 : 0; - if ((test->begin & 0x7fff) == 0x7fff) - exp64final = 0x7ff; - if ((test->begin & 0x7fff) == 0) - exp64final = 0; - if (test->eind.ll & 0x400) - mant64++; + if ((test->begin & 0x7fff) == 0x7fff) + exp64final = 0x7ff; + if ((test->begin & 0x7fff) == 0) + exp64final = 0; + if (test->eind.ll & 0x400) + mant64++; - test->eind.ll = (sign <<63)|(exp64final << 52)| mant64; + test->eind.ll = (sign << 63) | (exp64final << 52) | mant64; - return test->eind.d; + return test->eind.d; } -static __inline void x87_to80(double d, x87_conv_t *test) +static __inline void +x87_to80(double d, x87_conv_t *test) { - int64_t sign80; - int64_t exp80; - int64_t exp80final; - int64_t mant80; - int64_t mant80final; + int64_t sign80; + int64_t exp80; + int64_t exp80final; + int64_t mant80; + int64_t mant80final; - test->eind.d=d; + test->eind.d = d; - sign80 = (test->eind.ll&(0x8000000000000000ll))?1:0; - exp80 = test->eind.ll&(0x7ff0000000000000ll); - exp80final = (exp80>>52); - mant80 = test->eind.ll&(0x000fffffffffffffll); - mant80final = (mant80 << 11); + sign80 = (test->eind.ll & (0x8000000000000000ll)) ? 1 : 0; + exp80 = test->eind.ll & (0x7ff0000000000000ll); + exp80final = (exp80 >> 52); + mant80 = test->eind.ll & (0x000fffffffffffffll); + mant80final = (mant80 << 11); - if (exp80final == 0x7ff) /*Infinity / Nan*/ - { - exp80final = 0x7fff; - mant80final |= (0x8000000000000000ll); - } - else if (d != 0){ /* Zero is a special case */ - /* Elvira wants the 8 and tcalc doesn't */ - mant80final |= (0x8000000000000000ll); - /* Ca-cyber doesn't like this when result is zero. */ - exp80final += (BIAS80 - BIAS64); - } - test->begin = (((int16_t)sign80)<<15)| (int16_t)exp80final; - test->eind.ll = mant80final; + if (exp80final == 0x7ff) /*Infinity / Nan*/ + { + exp80final = 0x7fff; + mant80final |= (0x8000000000000000ll); + } else if (d != 0) { /* Zero is a special case */ + /* Elvira wants the 8 and tcalc doesn't */ + mant80final |= (0x8000000000000000ll); + /* Ca-cyber doesn't like this when result is zero. */ + exp80final += (BIAS80 - BIAS64); + } + test->begin = (((int16_t) sign80) << 15) | (int16_t) exp80final; + test->eind.ll = mant80final; } diff --git a/src/cpu/x87_ops_loadstore.h b/src/cpu/x87_ops_loadstore.h index d36cf426b..8d3c3f700 100644 --- a/src/cpu/x87_ops_loadstore.h +++ b/src/cpu/x87_ops_loadstore.h @@ -16,496 +16,582 @@ * Copyright 2008-2019 Sarah Walker. * Copyright 2016-2019 Miran Grca. */ -static int opFILDiw_a16(uint32_t fetchdat) +static int +opFILDiw_a16(uint32_t fetchdat) { - int16_t temp; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - x87_push((double)temp); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_16) : (x87_timings.fild_16 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_16) : (x87_concurrency.fild_16 * cpu_multi)); - return 0; + int16_t temp; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + x87_push((double) temp); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_16) : (x87_timings.fild_16 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_16) : (x87_concurrency.fild_16 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFILDiw_a32(uint32_t fetchdat) +static int +opFILDiw_a32(uint32_t fetchdat) { - int16_t temp; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - x87_push((double)temp); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_16) : (x87_timings.fild_16 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_16) : (x87_concurrency.fild_16 * cpu_multi)); - return 0; + int16_t temp; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + x87_push((double) temp); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_16) : (x87_timings.fild_16 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_16) : (x87_concurrency.fild_16 * cpu_multi)); + return 0; } #endif -static int opFISTiw_a16(uint32_t fetchdat) +static int +opFISTiw_a16(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(x87_fround16(ST(0))); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(x87_fround16(ST(0))); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); + return cpu_state.abrt; } #ifndef FPU_8087 -static int opFISTiw_a32(uint32_t fetchdat) +static int +opFISTiw_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(x87_fround16(ST(0))); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(x87_fround16(ST(0))); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); + return cpu_state.abrt; } #endif -static int opFISTPiw_a16(uint32_t fetchdat) +static int +opFISTPiw_a16(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(x87_fround16(ST(0))); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); - return 0; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(x87_fround16(ST(0))); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFISTPiw_a32(uint32_t fetchdat) +static int +opFISTPiw_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(x87_fround16(ST(0))); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); - return 0; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(x87_fround16(ST(0))); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); + return 0; } #endif -static int opFILDiq_a16(uint32_t fetchdat) +static int +opFILDiq_a16(uint32_t fetchdat) { - int64_t temp64; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - temp64 = geteaq(); if (cpu_state.abrt) return 1; - x87_push((double)temp64); - cpu_state.MM[cpu_state.TOP&7].q = temp64; - FP_TAG_DEFAULT; + int64_t temp64; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp64 = geteaq(); + if (cpu_state.abrt) + return 1; + x87_push((double) temp64); + cpu_state.MM[cpu_state.TOP & 7].q = temp64; + FP_TAG_DEFAULT; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi)); - return 0; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFILDiq_a32(uint32_t fetchdat) +static int +opFILDiq_a32(uint32_t fetchdat) { - int64_t temp64; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - temp64 = geteaq(); if (cpu_state.abrt) return 1; - x87_push((double)temp64); - cpu_state.MM[cpu_state.TOP&7].q = temp64; - FP_TAG_DEFAULT; + int64_t temp64; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp64 = geteaq(); + if (cpu_state.abrt) + return 1; + x87_push((double) temp64); + cpu_state.MM[cpu_state.TOP & 7].q = temp64; + FP_TAG_DEFAULT; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi)); - return 0; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi)); + return 0; } #endif -static int FBSTP_a16(uint32_t fetchdat) +static int +FBSTP_a16(uint32_t fetchdat) { - double tempd; - int c; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - tempd = ST(0); - if (tempd < 0.0) - tempd = -tempd; - for (c = 0; c < 9; c++) - { - uint8_t tempc = (uint8_t)floor(fmod(tempd, 10.0)); - tempd -= floor(fmod(tempd, 10.0)); - tempd /= 10.0; - tempc |= ((uint8_t)floor(fmod(tempd, 10.0))) << 4; - tempd -= floor(fmod(tempd, 10.0)); - tempd /= 10.0; - writememb(easeg, cpu_state.eaaddr + c, tempc); - } - tempc = (uint8_t)floor(fmod(tempd, 10.0)); - if (ST(0) < 0.0) tempc |= 0x80; - writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fbstp) : (x87_timings.fbstp * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fbstp) : (x87_concurrency.fbstp * cpu_multi)); - return 0; + double tempd; + int c; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + tempd = ST(0); + if (tempd < 0.0) + tempd = -tempd; + for (c = 0; c < 9; c++) { + uint8_t tempc = (uint8_t) floor(fmod(tempd, 10.0)); + tempd -= floor(fmod(tempd, 10.0)); + tempd /= 10.0; + tempc |= ((uint8_t) floor(fmod(tempd, 10.0))) << 4; + tempd -= floor(fmod(tempd, 10.0)); + tempd /= 10.0; + writememb(easeg, cpu_state.eaaddr + c, tempc); + } + tempc = (uint8_t) floor(fmod(tempd, 10.0)); + if (ST(0) < 0.0) + tempc |= 0x80; + writememb(easeg, cpu_state.eaaddr + 9, tempc); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fbstp) : (x87_timings.fbstp * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fbstp) : (x87_concurrency.fbstp * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int FBSTP_a32(uint32_t fetchdat) +static int +FBSTP_a32(uint32_t fetchdat) { - double tempd; - int c; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - tempd = ST(0); - if (tempd < 0.0) - tempd = -tempd; - for (c = 0; c < 9; c++) - { - uint8_t tempc = (uint8_t)floor(fmod(tempd, 10.0)); - tempd -= floor(fmod(tempd, 10.0)); - tempd /= 10.0; - tempc |= ((uint8_t)floor(fmod(tempd, 10.0))) << 4; - tempd -= floor(fmod(tempd, 10.0)); - tempd /= 10.0; - writememb(easeg, cpu_state.eaaddr + c, tempc); - } - tempc = (uint8_t)floor(fmod(tempd, 10.0)); - if (ST(0) < 0.0) tempc |= 0x80; - writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fbstp) : (x87_timings.fbstp * cpu_multi)); - return 0; + double tempd; + int c; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + tempd = ST(0); + if (tempd < 0.0) + tempd = -tempd; + for (c = 0; c < 9; c++) { + uint8_t tempc = (uint8_t) floor(fmod(tempd, 10.0)); + tempd -= floor(fmod(tempd, 10.0)); + tempd /= 10.0; + tempc |= ((uint8_t) floor(fmod(tempd, 10.0))) << 4; + tempd -= floor(fmod(tempd, 10.0)); + tempd /= 10.0; + writememb(easeg, cpu_state.eaaddr + c, tempc); + } + tempc = (uint8_t) floor(fmod(tempd, 10.0)); + if (ST(0) < 0.0) + tempc |= 0x80; + writememb(easeg, cpu_state.eaaddr + 9, tempc); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fbstp) : (x87_timings.fbstp * cpu_multi)); + return 0; } #endif -static int FISTPiq_a16(uint32_t fetchdat) +static int +FISTPiq_a16(uint32_t fetchdat) { - int64_t temp64; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - if (cpu_state.tag[cpu_state.TOP&7] & TAG_UINT64) - temp64 = cpu_state.MM[cpu_state.TOP&7].q; - else - temp64 = x87_fround(ST(0)); - seteaq(temp64); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_64) : (x87_timings.fist_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_64) : (x87_concurrency.fist_64 * cpu_multi)); - return 0; + int64_t temp64; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (cpu_state.tag[cpu_state.TOP & 7] & TAG_UINT64) + temp64 = cpu_state.MM[cpu_state.TOP & 7].q; + else + temp64 = x87_fround(ST(0)); + seteaq(temp64); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_64) : (x87_timings.fist_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_64) : (x87_concurrency.fist_64 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int FISTPiq_a32(uint32_t fetchdat) +static int +FISTPiq_a32(uint32_t fetchdat) { - int64_t temp64; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - if (cpu_state.tag[cpu_state.TOP&7] & TAG_UINT64) - temp64 = cpu_state.MM[cpu_state.TOP&7].q; - else - temp64 = x87_fround(ST(0)); - seteaq(temp64); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_64) : (x87_timings.fist_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_64) : (x87_concurrency.fist_64 * cpu_multi)); - return 0; + int64_t temp64; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (cpu_state.tag[cpu_state.TOP & 7] & TAG_UINT64) + temp64 = cpu_state.MM[cpu_state.TOP & 7].q; + else + temp64 = x87_fround(ST(0)); + seteaq(temp64); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_64) : (x87_timings.fist_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_64) : (x87_concurrency.fist_64 * cpu_multi)); + return 0; } #endif -static int opFILDil_a16(uint32_t fetchdat) +static int +opFILDil_a16(uint32_t fetchdat) { - int32_t templ; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - templ = geteal(); if (cpu_state.abrt) return 1; - x87_push((double)templ); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_32) : (x87_timings.fild_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_32) : (x87_concurrency.fild_32 * cpu_multi)); - return 0; + int32_t templ; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); + if (cpu_state.abrt) + return 1; + x87_push((double) templ); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_32) : (x87_timings.fild_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_32) : (x87_concurrency.fild_32 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFILDil_a32(uint32_t fetchdat) +static int +opFILDil_a32(uint32_t fetchdat) { - int32_t templ; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - templ = geteal(); if (cpu_state.abrt) return 1; - x87_push((double)templ); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_32) : (x87_timings.fild_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_32) : (x87_concurrency.fild_32 * cpu_multi)); - return 0; + int32_t templ; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); + if (cpu_state.abrt) + return 1; + x87_push((double) templ); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_32) : (x87_timings.fild_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_32) : (x87_concurrency.fild_32 * cpu_multi)); + return 0; } #endif -static int opFISTil_a16(uint32_t fetchdat) +static int +opFISTil_a16(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(x87_fround32(ST(0))); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(x87_fround32(ST(0))); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); + return cpu_state.abrt; } #ifndef FPU_8087 -static int opFISTil_a32(uint32_t fetchdat) +static int +opFISTil_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(x87_fround32(ST(0))); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(x87_fround32(ST(0))); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); + return cpu_state.abrt; } #endif -static int opFISTPil_a16(uint32_t fetchdat) +static int +opFISTPil_a16(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(x87_fround32(ST(0))); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); - return 0; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(x87_fround32(ST(0))); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFISTPil_a32(uint32_t fetchdat) +static int +opFISTPil_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(x87_fround32(ST(0))); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); - return 0; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(x87_fround32(ST(0))); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); + return 0; } #endif -static int opFLDe_a16(uint32_t fetchdat) +static int +opFLDe_a16(uint32_t fetchdat) { - double t; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - t=x87_ld80(); if (cpu_state.abrt) return 1; - x87_push(t); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); - return 0; + double t; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t = x87_ld80(); + if (cpu_state.abrt) + return 1; + x87_push(t); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFLDe_a32(uint32_t fetchdat) +static int +opFLDe_a32(uint32_t fetchdat) { - double t; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - t=x87_ld80(); if (cpu_state.abrt) return 1; - x87_push(t); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); - return 0; + double t; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t = x87_ld80(); + if (cpu_state.abrt) + return 1; + x87_push(t); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); + return 0; } #endif -static int opFSTPe_a16(uint32_t fetchdat) +static int +opFSTPe_a16(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - x87_st80(ST(0)); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); - return 0; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + x87_st80(ST(0)); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFSTPe_a32(uint32_t fetchdat) +static int +opFSTPe_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - x87_st80(ST(0)); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); - return 0; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + x87_st80(ST(0)); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); + return 0; } #endif -static int opFLDd_a16(uint32_t fetchdat) +static int +opFLDd_a16(uint32_t fetchdat) { - x87_td t; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - t.i = geteaq(); if (cpu_state.abrt) return 1; - x87_push(t.d); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_64) : (x87_timings.fld_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_64) : (x87_concurrency.fld_64 * cpu_multi)); - return 0; + x87_td t; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t.i = geteaq(); + if (cpu_state.abrt) + return 1; + x87_push(t.d); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_64) : (x87_timings.fld_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_64) : (x87_concurrency.fld_64 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFLDd_a32(uint32_t fetchdat) +static int +opFLDd_a32(uint32_t fetchdat) { - x87_td t; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - t.i = geteaq(); if (cpu_state.abrt) return 1; - x87_push(t.d); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_64) : (x87_timings.fld_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_64) : (x87_concurrency.fld_64 * cpu_multi)); - return 0; + x87_td t; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t.i = geteaq(); + if (cpu_state.abrt) + return 1; + x87_push(t.d); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_64) : (x87_timings.fld_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_64) : (x87_concurrency.fld_64 * cpu_multi)); + return 0; } #endif -static int opFSTd_a16(uint32_t fetchdat) +static int +opFSTd_a16(uint32_t fetchdat) { - x87_td t; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - t.d = ST(0); - seteaq(t.i); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); - return cpu_state.abrt; + x87_td t; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + t.d = ST(0); + seteaq(t.i); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); + return cpu_state.abrt; } #ifndef FPU_8087 -static int opFSTd_a32(uint32_t fetchdat) +static int +opFSTd_a32(uint32_t fetchdat) { - x87_td t; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - t.d = ST(0); - seteaq(t.i); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); - return cpu_state.abrt; + x87_td t; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + t.d = ST(0); + seteaq(t.i); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); + return cpu_state.abrt; } #endif -static int opFSTPd_a16(uint32_t fetchdat) +static int +opFSTPd_a16(uint32_t fetchdat) { - x87_td t; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - t.d = ST(0); - seteaq(t.i); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); - return 0; + x87_td t; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + t.d = ST(0); + seteaq(t.i); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFSTPd_a32(uint32_t fetchdat) +static int +opFSTPd_a32(uint32_t fetchdat) { - x87_td t; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - t.d = ST(0); - seteaq(t.i); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); - return 0; + x87_td t; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + t.d = ST(0); + seteaq(t.i); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); + return 0; } #endif -static int opFLDs_a16(uint32_t fetchdat) +static int +opFLDs_a16(uint32_t fetchdat) { - x87_ts ts; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - ts.i = geteal(); if (cpu_state.abrt) return 1; - x87_push((double)ts.s); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); - return 0; + x87_ts ts; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + ts.i = geteal(); + if (cpu_state.abrt) + return 1; + x87_push((double) ts.s); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFLDs_a32(uint32_t fetchdat) +static int +opFLDs_a32(uint32_t fetchdat) { - x87_ts ts; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - ts.i = geteal(); if (cpu_state.abrt) return 1; - x87_push((double)ts.s); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); - return 0; + x87_ts ts; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + ts.i = geteal(); + if (cpu_state.abrt) + return 1; + x87_push((double) ts.s); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); + return 0; } #endif -static int opFSTs_a16(uint32_t fetchdat) +static int +opFSTs_a16(uint32_t fetchdat) { - x87_ts ts; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - ts.s = (float)ST(0); - seteal(ts.i); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); - return cpu_state.abrt; + x87_ts ts; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + ts.s = (float) ST(0); + seteal(ts.i); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); + return cpu_state.abrt; } #ifndef FPU_8087 -static int opFSTs_a32(uint32_t fetchdat) +static int +opFSTs_a32(uint32_t fetchdat) { - x87_ts ts; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - ts.s = (float)ST(0); - seteal(ts.i); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); - return cpu_state.abrt; + x87_ts ts; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + ts.s = (float) ST(0); + seteal(ts.i); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); + return cpu_state.abrt; } #endif -static int opFSTPs_a16(uint32_t fetchdat) +static int +opFSTPs_a16(uint32_t fetchdat) { - x87_ts ts; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - ts.s = (float)ST(0); - seteal(ts.i); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); - return 0; + x87_ts ts; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + ts.s = (float) ST(0); + seteal(ts.i); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFSTPs_a32(uint32_t fetchdat) +static int +opFSTPs_a32(uint32_t fetchdat) { - x87_ts ts; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - ts.s = (float)ST(0); - seteal(ts.i); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); - return 0; + x87_ts ts; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + ts.s = (float) ST(0); + seteal(ts.i); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); + return 0; } #endif diff --git a/src/cpu/x87_ops_misc.h b/src/cpu/x87_ops_misc.h index 3e09cac22..0ce89311c 100644 --- a/src/cpu/x87_ops_misc.h +++ b/src/cpu/x87_ops_misc.h @@ -1,939 +1,1046 @@ #ifdef FPU_8087 -static int opFI(uint32_t fetchdat) +static int +opFI(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxc &= ~0x80; - if (rmdat == 0xe1) - cpu_state.npxc |= 0x80; - wait(3, 0); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxc &= ~0x80; + if (rmdat == 0xe1) + cpu_state.npxc |= 0x80; + wait(3, 0); + return 0; } #else -static int opFSTSW_AX(uint32_t fetchdat) +static int +opFSTSW_AX(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - AX = cpu_state.npxs; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + AX = cpu_state.npxs; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); + return 0; } #endif - -static int opFNOP(uint32_t fetchdat) +static int +opFNOP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fnop) : (x87_timings.fnop * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fnop) : (x87_concurrency.fnop * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fnop) : (x87_timings.fnop * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fnop) : (x87_concurrency.fnop * cpu_multi)); + return 0; } -static int opFCLEX(uint32_t fetchdat) +static int +opFCLEX(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= 0xff00; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fnop) : (x87_timings.fnop * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fnop) : (x87_concurrency.fnop * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= 0xff00; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fnop) : (x87_timings.fnop * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fnop) : (x87_concurrency.fnop * cpu_multi)); + return 0; } -static int opFINIT(uint32_t fetchdat) +static int +opFINIT(uint32_t fetchdat) { - uint64_t *p; - FP_ENTER(); - cpu_state.pc++; + uint64_t *p; + FP_ENTER(); + cpu_state.pc++; #ifdef FPU_8087 - cpu_state.npxc = 0x3FF; + cpu_state.npxc = 0x3FF; #else - cpu_state.npxc = 0x37F; + cpu_state.npxc = 0x37F; #endif - codegen_set_rounding_mode(X87_ROUNDING_NEAREST); - cpu_state.npxs = 0; - p = (uint64_t *)cpu_state.tag; + codegen_set_rounding_mode(X87_ROUNDING_NEAREST); + cpu_state.npxs = 0; + p = (uint64_t *) cpu_state.tag; #ifdef USE_NEW_DYNAREC - *p = 0; + *p = 0; #else - *p = 0x0303030303030303ll; + *p = 0x0303030303030303ll; #endif - cpu_state.TOP = 0; - cpu_state.ismmx = 0; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.finit) : (x87_timings.finit * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.finit) : (x87_concurrency.finit * cpu_multi)); - CPU_BLOCK_END(); - return 0; + cpu_state.TOP = 0; + cpu_state.ismmx = 0; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.finit) : (x87_timings.finit * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.finit) : (x87_concurrency.finit * cpu_multi)); + CPU_BLOCK_END(); + return 0; } - -static int opFFREE(uint32_t fetchdat) +static int +opFFREE(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; + FP_ENTER(); + cpu_state.pc++; #ifdef USE_NEW_DYNAREC - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_EMPTY; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_EMPTY; #else - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; #endif - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ffree) : (x87_timings.ffree * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ffree) : (x87_concurrency.ffree * cpu_multi)); - return 0; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ffree) : (x87_timings.ffree * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ffree) : (x87_concurrency.ffree * cpu_multi)); + return 0; } -static int opFFREEP(uint32_t fetchdat) +static int +opFFREEP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ffree) : (x87_timings.ffree * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ffree) : (x87_concurrency.ffree * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ffree) : (x87_timings.ffree * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ffree) : (x87_concurrency.ffree * cpu_multi)); + return 0; } -static int opFST(uint32_t fetchdat) +static int +opFST(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(0); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst) : (x87_timings.fst * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst) : (x87_concurrency.fst * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0); + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst) : (x87_timings.fst * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst) : (x87_concurrency.fst * cpu_multi)); + return 0; } -static int opFSTP(uint32_t fetchdat) +static int +opFSTP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(0); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst) : (x87_timings.fst * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst) : (x87_concurrency.fst * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0); + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst) : (x87_timings.fst * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst) : (x87_concurrency.fst * cpu_multi)); + return 0; } - - - -static int FSTOR(void) +static int +FSTOR(void) { - uint64_t *p; - FP_ENTER(); - switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) - { - case 0x000: /*16-bit real mode*/ - case 0x001: /*16-bit protected mode*/ - cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2); - x87_settag(readmemw(easeg, cpu_state.eaaddr+4)); - cpu_state.TOP = (cpu_state.npxs >> 11) & 7; - cpu_state.eaaddr += 14; - break; - case 0x100: /*32-bit real mode*/ - case 0x101: /*32-bit protected mode*/ - cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4); - x87_settag(readmemw(easeg, cpu_state.eaaddr+8)); - cpu_state.TOP = (cpu_state.npxs >> 11) & 7; - cpu_state.eaaddr += 28; - break; - } - x87_ld_frstor(0); cpu_state.eaaddr += 10; - x87_ld_frstor(1); cpu_state.eaaddr += 10; - x87_ld_frstor(2); cpu_state.eaaddr += 10; - x87_ld_frstor(3); cpu_state.eaaddr += 10; - x87_ld_frstor(4); cpu_state.eaaddr += 10; - x87_ld_frstor(5); cpu_state.eaaddr += 10; - x87_ld_frstor(6); cpu_state.eaaddr += 10; - x87_ld_frstor(7); + uint64_t *p; + FP_ENTER(); + switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) { + case 0x000: /*16-bit real mode*/ + case 0x001: /*16-bit protected mode*/ + cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr + 2); + x87_settag(readmemw(easeg, cpu_state.eaaddr + 4)); + cpu_state.TOP = (cpu_state.npxs >> 11) & 7; + cpu_state.eaaddr += 14; + break; + case 0x100: /*32-bit real mode*/ + case 0x101: /*32-bit protected mode*/ + cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr + 4); + x87_settag(readmemw(easeg, cpu_state.eaaddr + 8)); + cpu_state.TOP = (cpu_state.npxs >> 11) & 7; + cpu_state.eaaddr += 28; + break; + } + x87_ld_frstor(0); + cpu_state.eaaddr += 10; + x87_ld_frstor(1); + cpu_state.eaaddr += 10; + x87_ld_frstor(2); + cpu_state.eaaddr += 10; + x87_ld_frstor(3); + cpu_state.eaaddr += 10; + x87_ld_frstor(4); + cpu_state.eaaddr += 10; + x87_ld_frstor(5); + cpu_state.eaaddr += 10; + x87_ld_frstor(6); + cpu_state.eaaddr += 10; + x87_ld_frstor(7); - cpu_state.ismmx = 0; - /*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times - something like this is needed*/ - p = (uint64_t *) cpu_state.tag; + cpu_state.ismmx = 0; + /*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times + something like this is needed*/ + p = (uint64_t *) cpu_state.tag; #ifdef USE_NEW_DYNAREC - if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && - cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && - !cpu_state.TOP && (*p == 0x0101010101010101ull)) + if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && !cpu_state.TOP && (*p == 0x0101010101010101ull)) #else - if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && - cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && - !cpu_state.TOP && !(*p)) - #endif - cpu_state.ismmx = 1; + if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && !cpu_state.TOP && !(*p)) +#endif + cpu_state.ismmx = 1; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frstor) : (x87_timings.frstor * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frstor) : (x87_concurrency.frstor * cpu_multi)); - return cpu_state.abrt; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frstor) : (x87_timings.frstor * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frstor) : (x87_concurrency.frstor * cpu_multi)); + return cpu_state.abrt; } -static int opFSTOR_a16(uint32_t fetchdat) +static int +opFSTOR_a16(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - FSTOR(); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + FSTOR(); + return cpu_state.abrt; } #ifndef FPU_8087 -static int opFSTOR_a32(uint32_t fetchdat) +static int +opFSTOR_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - FSTOR(); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + FSTOR(); + return cpu_state.abrt; } #endif -static int FSAVE(void) +static int +FSAVE(void) { - uint64_t *p; + uint64_t *p; - FP_ENTER(); - cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | ((cpu_state.TOP & 7) << 11); + FP_ENTER(); + cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | ((cpu_state.TOP & 7) << 11); - switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) - { - case 0x000: /*16-bit real mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+4,x87_gettag()); - writememw(easeg,cpu_state.eaaddr+6,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+10,x87_op_off); - cpu_state.eaaddr+=14; - if (cpu_state.ismmx) - { - x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[7]); - } - else - { - x87_st_fsave(0); cpu_state.eaaddr+=10; - x87_st_fsave(1); cpu_state.eaaddr+=10; - x87_st_fsave(2); cpu_state.eaaddr+=10; - x87_st_fsave(3); cpu_state.eaaddr+=10; - x87_st_fsave(4); cpu_state.eaaddr+=10; - x87_st_fsave(5); cpu_state.eaaddr+=10; - x87_st_fsave(6); cpu_state.eaaddr+=10; - x87_st_fsave(7); - } - break; - case 0x001: /*16-bit protected mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+4,x87_gettag()); - writememw(easeg,cpu_state.eaaddr+6,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+8,x87_pc_seg); - writememw(easeg,cpu_state.eaaddr+10,x87_op_off); - writememw(easeg,cpu_state.eaaddr+12,x87_op_seg); - cpu_state.eaaddr+=14; - if (cpu_state.ismmx) - { - x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[7]); - } - else - { - x87_st_fsave(0); cpu_state.eaaddr+=10; - x87_st_fsave(1); cpu_state.eaaddr+=10; - x87_st_fsave(2); cpu_state.eaaddr+=10; - x87_st_fsave(3); cpu_state.eaaddr+=10; - x87_st_fsave(4); cpu_state.eaaddr+=10; - x87_st_fsave(5); cpu_state.eaaddr+=10; - x87_st_fsave(6); cpu_state.eaaddr+=10; - x87_st_fsave(7); - } - break; - case 0x100: /*32-bit real mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+8,x87_gettag()); - writememw(easeg,cpu_state.eaaddr+12,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+20,x87_op_off); - writememl(easeg,cpu_state.eaaddr+24,(x87_op_off>>16)<<12); - cpu_state.eaaddr+=28; - if (cpu_state.ismmx) - { - x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[7]); - } - else - { - x87_st_fsave(0); cpu_state.eaaddr+=10; - x87_st_fsave(1); cpu_state.eaaddr+=10; - x87_st_fsave(2); cpu_state.eaaddr+=10; - x87_st_fsave(3); cpu_state.eaaddr+=10; - x87_st_fsave(4); cpu_state.eaaddr+=10; - x87_st_fsave(5); cpu_state.eaaddr+=10; - x87_st_fsave(6); cpu_state.eaaddr+=10; - x87_st_fsave(7); - } - break; - case 0x101: /*32-bit protected mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+8,x87_gettag()); - writememl(easeg,cpu_state.eaaddr+12,x87_pc_off); - writememl(easeg,cpu_state.eaaddr+16,x87_pc_seg); - writememl(easeg,cpu_state.eaaddr+20,x87_op_off); - writememl(easeg,cpu_state.eaaddr+24,x87_op_seg); - cpu_state.eaaddr+=28; - if (cpu_state.ismmx) - { - x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[7]); - } - else - { - x87_st_fsave(0); cpu_state.eaaddr+=10; - x87_st_fsave(1); cpu_state.eaaddr+=10; - x87_st_fsave(2); cpu_state.eaaddr+=10; - x87_st_fsave(3); cpu_state.eaaddr+=10; - x87_st_fsave(4); cpu_state.eaaddr+=10; - x87_st_fsave(5); cpu_state.eaaddr+=10; - x87_st_fsave(6); cpu_state.eaaddr+=10; - x87_st_fsave(7); - } - break; + switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) { + case 0x000: /*16-bit real mode*/ + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 2, cpu_state.npxs); + writememw(easeg, cpu_state.eaaddr + 4, x87_gettag()); + writememw(easeg, cpu_state.eaaddr + 6, x87_pc_off); + writememw(easeg, cpu_state.eaaddr + 10, x87_op_off); + cpu_state.eaaddr += 14; + if (cpu_state.ismmx) { + x87_stmmx(cpu_state.MM[0]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[1]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[2]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[3]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[4]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[5]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[6]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[7]); + } else { + x87_st_fsave(0); + cpu_state.eaaddr += 10; + x87_st_fsave(1); + cpu_state.eaaddr += 10; + x87_st_fsave(2); + cpu_state.eaaddr += 10; + x87_st_fsave(3); + cpu_state.eaaddr += 10; + x87_st_fsave(4); + cpu_state.eaaddr += 10; + x87_st_fsave(5); + cpu_state.eaaddr += 10; + x87_st_fsave(6); + cpu_state.eaaddr += 10; + x87_st_fsave(7); + } + break; + case 0x001: /*16-bit protected mode*/ + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 2, cpu_state.npxs); + writememw(easeg, cpu_state.eaaddr + 4, x87_gettag()); + writememw(easeg, cpu_state.eaaddr + 6, x87_pc_off); + writememw(easeg, cpu_state.eaaddr + 8, x87_pc_seg); + writememw(easeg, cpu_state.eaaddr + 10, x87_op_off); + writememw(easeg, cpu_state.eaaddr + 12, x87_op_seg); + cpu_state.eaaddr += 14; + if (cpu_state.ismmx) { + x87_stmmx(cpu_state.MM[0]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[1]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[2]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[3]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[4]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[5]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[6]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[7]); + } else { + x87_st_fsave(0); + cpu_state.eaaddr += 10; + x87_st_fsave(1); + cpu_state.eaaddr += 10; + x87_st_fsave(2); + cpu_state.eaaddr += 10; + x87_st_fsave(3); + cpu_state.eaaddr += 10; + x87_st_fsave(4); + cpu_state.eaaddr += 10; + x87_st_fsave(5); + cpu_state.eaaddr += 10; + x87_st_fsave(6); + cpu_state.eaaddr += 10; + x87_st_fsave(7); + } + break; + case 0x100: /*32-bit real mode*/ + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 4, cpu_state.npxs); + writememw(easeg, cpu_state.eaaddr + 8, x87_gettag()); + writememw(easeg, cpu_state.eaaddr + 12, x87_pc_off); + writememw(easeg, cpu_state.eaaddr + 20, x87_op_off); + writememl(easeg, cpu_state.eaaddr + 24, (x87_op_off >> 16) << 12); + cpu_state.eaaddr += 28; + if (cpu_state.ismmx) { + x87_stmmx(cpu_state.MM[0]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[1]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[2]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[3]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[4]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[5]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[6]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[7]); + } else { + x87_st_fsave(0); + cpu_state.eaaddr += 10; + x87_st_fsave(1); + cpu_state.eaaddr += 10; + x87_st_fsave(2); + cpu_state.eaaddr += 10; + x87_st_fsave(3); + cpu_state.eaaddr += 10; + x87_st_fsave(4); + cpu_state.eaaddr += 10; + x87_st_fsave(5); + cpu_state.eaaddr += 10; + x87_st_fsave(6); + cpu_state.eaaddr += 10; + x87_st_fsave(7); + } + break; + case 0x101: /*32-bit protected mode*/ + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 4, cpu_state.npxs); + writememw(easeg, cpu_state.eaaddr + 8, x87_gettag()); + writememl(easeg, cpu_state.eaaddr + 12, x87_pc_off); + writememl(easeg, cpu_state.eaaddr + 16, x87_pc_seg); + writememl(easeg, cpu_state.eaaddr + 20, x87_op_off); + writememl(easeg, cpu_state.eaaddr + 24, x87_op_seg); + cpu_state.eaaddr += 28; + if (cpu_state.ismmx) { + x87_stmmx(cpu_state.MM[0]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[1]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[2]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[3]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[4]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[5]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[6]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[7]); + } else { + x87_st_fsave(0); + cpu_state.eaaddr += 10; + x87_st_fsave(1); + cpu_state.eaaddr += 10; + x87_st_fsave(2); + cpu_state.eaaddr += 10; + x87_st_fsave(3); + cpu_state.eaaddr += 10; + x87_st_fsave(4); + cpu_state.eaaddr += 10; + x87_st_fsave(5); + cpu_state.eaaddr += 10; + x87_st_fsave(6); + cpu_state.eaaddr += 10; + x87_st_fsave(7); + } + break; + } + + cpu_state.npxc = 0x37F; + codegen_set_rounding_mode(X87_ROUNDING_NEAREST); + cpu_state.npxs = 0; + p = (uint64_t *) cpu_state.tag; +#ifdef USE_NEW_DYNAREC + *p = 0; +#else + *p = 0x0303030303030303ll; +#endif + cpu_state.TOP = 0; + cpu_state.ismmx = 0; + + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsave) : (x87_timings.fsave * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsave) : (x87_concurrency.fsave * cpu_multi)); + return cpu_state.abrt; +} +static int +opFSAVE_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + FSAVE(); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int +opFSAVE_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + FSAVE(); + return cpu_state.abrt; +} +#endif + +static int +opFSTSW_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int +opFSTSW_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); + return cpu_state.abrt; +} +#endif + +static int +opFLD(uint32_t fetchdat) +{ + int old_tag; + uint64_t old_i64; + + FP_ENTER(); + cpu_state.pc++; + old_tag = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; + old_i64 = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; + x87_push(ST(fetchdat & 7)); + cpu_state.tag[cpu_state.TOP & 7] = old_tag; + cpu_state.MM[cpu_state.TOP & 7].q = old_i64; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld) : (x87_timings.fld * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld) : (x87_concurrency.fld * cpu_multi)); + return 0; +} + +static int +opFXCH(uint32_t fetchdat) +{ + double td; + uint8_t old_tag; + uint64_t old_i64; + FP_ENTER(); + cpu_state.pc++; + td = ST(0); + ST(0) = ST(fetchdat & 7); + ST(fetchdat & 7) = td; + old_tag = cpu_state.tag[cpu_state.TOP & 7]; + cpu_state.tag[cpu_state.TOP & 7] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = old_tag; + old_i64 = cpu_state.MM[cpu_state.TOP & 7].q; + cpu_state.MM[cpu_state.TOP & 7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; + cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q = old_i64; + + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fxch) : (x87_timings.fxch * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fxch) : (x87_concurrency.fxch * cpu_multi)); + return 0; +} + +static int +opFCHS(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = -ST(0); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fchs) : (x87_timings.fchs * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fchs) : (x87_concurrency.fchs * cpu_multi)); + return 0; +} + +static int +opFABS(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = fabs(ST(0)); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fabs) : (x87_timings.fabs * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fabs) : (x87_concurrency.fabs * cpu_multi)); + return 0; +} + +static int +opFTST(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0 | C2 | C3); + if (ST(0) == 0.0) + cpu_state.npxs |= C3; + else if (ST(0) < 0.0) + cpu_state.npxs |= C0; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ftst) : (x87_timings.ftst * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ftst) : (x87_concurrency.ftst * cpu_multi)); + return 0; +} + +static int +opFXAM(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0 | C1 | C2 | C3); +#ifdef USE_NEW_DYNAREC + if (cpu_state.tag[cpu_state.TOP & 7] == TAG_EMPTY) + cpu_state.npxs |= (C0 | C3); +#else + if (cpu_state.tag[cpu_state.TOP & 7] == 3) + cpu_state.npxs |= (C0 | C3); +#endif + else if (ST(0) == 0.0) + cpu_state.npxs |= C3; + else + cpu_state.npxs |= C2; + if (ST(0) < 0.0) + cpu_state.npxs |= C1; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fxam) : (x87_timings.fxam * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fxam) : (x87_concurrency.fxam * cpu_multi)); + return 0; +} + +static int +opFLD1(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(1.0); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_z1) : (x87_timings.fld_z1 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_z1) : (x87_concurrency.fld_z1 * cpu_multi)); + return 0; +} + +static int +opFLDL2T(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(3.3219280948873623); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); + return 0; +} + +static int +opFLDL2E(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(1.4426950408889634); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); + return 0; +} + +static int +opFLDPI(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(3.141592653589793); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); + return 0; +} + +static int +opFLDEG2(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(0.3010299956639812); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); + return 0; +} + +static int +opFLDLN2(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push_u64(0x3fe62e42fefa39f0ull); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); + return 0; +} + +static int +opFLDZ(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(0.0); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_z1) : (x87_timings.fld_z1 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_z1) : (x87_concurrency.fld_z1 * cpu_multi)); + return 0; +} + +static int +opF2XM1(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = pow(2.0, ST(0)) - 1.0; + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.f2xm1) : (x87_timings.f2xm1 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.f2xm1) : (x87_concurrency.f2xm1 * cpu_multi)); + return 0; +} + +static int +opFYL2X(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(1) = ST(1) * (log(ST(0)) / log(2.0)); + FP_TAG_VALID_N; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fyl2x) : (x87_timings.fyl2x * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fyl2x) : (x87_concurrency.fyl2x * cpu_multi)); + return 0; +} + +static int +opFYL2XP1(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(1) = ST(1) * (log1p(ST(0)) / log(2.0)); + FP_TAG_VALID_N; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fyl2xp1) : (x87_timings.fyl2xp1 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fyl2xp1) : (x87_concurrency.fyl2xp1 * cpu_multi)); + return 0; +} + +static int +opFPTAN(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = tan(ST(0)); + FP_TAG_VALID; + x87_push(1.0); + cpu_state.npxs &= ~C2; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fptan) : (x87_timings.fptan * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fptan) : (x87_concurrency.fptan * cpu_multi)); + return 0; +} + +static int +opFPATAN(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(1) = atan2(ST(1), ST(0)); + FP_TAG_VALID_N; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fpatan) : (x87_timings.fpatan * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fpatan) : (x87_concurrency.fpatan * cpu_multi)); + return 0; +} + +static int +opFDECSTP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; +#ifdef USE_NEW_DYNAREC + cpu_state.TOP--; +#else + cpu_state.TOP = (cpu_state.TOP - 1) & 7; +#endif + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fincdecstp) : (x87_timings.fincdecstp * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fincdecstp) : (x87_concurrency.fincdecstp * cpu_multi)); + return 0; +} + +static int +opFINCSTP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; +#ifdef USE_NEW_DYNAREC + cpu_state.TOP++; +#else + cpu_state.TOP = (cpu_state.TOP + 1) & 7; +#endif + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fincdecstp) : (x87_timings.fincdecstp * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fincdecstp) : (x87_concurrency.fincdecstp * cpu_multi)); + return 0; +} + +static int +opFPREM(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + cpu_state.pc++; + temp64 = (int64_t) (ST(0) / ST(1)); + ST(0) = ST(0) - (ST(1) * (double) temp64); + FP_TAG_VALID; + cpu_state.npxs &= ~(C0 | C1 | C2 | C3); + if (temp64 & 4) + cpu_state.npxs |= C0; + if (temp64 & 2) + cpu_state.npxs |= C3; + if (temp64 & 1) + cpu_state.npxs |= C1; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fprem) : (x87_timings.fprem * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fprem) : (x87_concurrency.fprem * cpu_multi)); + return 0; +} +#ifndef FPU_8087 +static int +opFPREM1(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + cpu_state.pc++; + temp64 = (int64_t) (ST(0) / ST(1)); + ST(0) = ST(0) - (ST(1) * (double) temp64); + FP_TAG_VALID; + cpu_state.npxs &= ~(C0 | C1 | C2 | C3); + if (temp64 & 4) + cpu_state.npxs |= C0; + if (temp64 & 2) + cpu_state.npxs |= C3; + if (temp64 & 1) + cpu_state.npxs |= C1; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fprem1) : (x87_timings.fprem1 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fprem1) : (x87_concurrency.fprem1 * cpu_multi)); + return 0; +} +#endif + +static int +opFSQRT(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = sqrt(ST(0)); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsqrt) : (x87_timings.fsqrt * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsqrt) : (x87_concurrency.fsqrt * cpu_multi)); + return 0; +} + +#ifndef FPU_8087 +static int +opFSINCOS(uint32_t fetchdat) +{ + double td; + FP_ENTER(); + cpu_state.pc++; + td = ST(0); + ST(0) = sin(td); + FP_TAG_VALID; + x87_push(cos(td)); + cpu_state.npxs &= ~C2; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsincos) : (x87_timings.fsincos * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsincos) : (x87_concurrency.fsincos * cpu_multi)); + return 0; +} +#endif + +static int +opFRNDINT(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = (double) x87_fround(ST(0)); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frndint) : (x87_timings.frndint * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frndint) : (x87_concurrency.frndint * cpu_multi)); + return 0; +} + +static int +opFSCALE(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + cpu_state.pc++; + temp64 = (int64_t) ST(1); + if (ST(0) != 0.0) + ST(0) = ST(0) * pow(2.0, (double) temp64); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fscale) : (x87_timings.fscale * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fscale) : (x87_concurrency.fscale * cpu_multi)); + return 0; +} + +#ifndef FPU_8087 +static int +opFSIN(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = sin(ST(0)); + FP_TAG_VALID; + cpu_state.npxs &= ~C2; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsin_cos) : (x87_timings.fsin_cos * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsin_cos) : (x87_concurrency.fsin_cos * cpu_multi)); + return 0; +} + +static int +opFCOS(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = cos(ST(0)); + FP_TAG_VALID; + cpu_state.npxs &= ~C2; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsin_cos) : (x87_timings.fsin_cos * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsin_cos) : (x87_concurrency.fsin_cos * cpu_multi)); + return 0; +} +#endif + +static int +FLDENV(void) +{ + FP_ENTER(); + switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) { + case 0x000: /*16-bit real mode*/ + case 0x001: /*16-bit protected mode*/ + cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr + 2); + x87_settag(readmemw(easeg, cpu_state.eaaddr + 4)); + cpu_state.TOP = (cpu_state.npxs >> 11) & 7; + break; + case 0x100: /*32-bit real mode*/ + case 0x101: /*32-bit protected mode*/ + cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr + 4); + x87_settag(readmemw(easeg, cpu_state.eaaddr + 8)); + cpu_state.TOP = (cpu_state.npxs >> 11) & 7; + break; + } + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldenv) : (x87_timings.fldenv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldenv) : (x87_concurrency.fldenv * cpu_multi)); + return cpu_state.abrt; +} + +static int +opFLDENV_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + FLDENV(); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int +opFLDENV_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + FLDENV(); + return cpu_state.abrt; +} +#endif + +static int +opFLDCW_a16(uint32_t fetchdat) +{ + uint16_t tempw; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + tempw = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.npxc = tempw; + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldcw) : (x87_timings.fldcw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldcw) : (x87_concurrency.fldcw * cpu_multi)); + return 0; +} +#ifndef FPU_8087 +static int +opFLDCW_a32(uint32_t fetchdat) +{ + uint16_t tempw; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + tempw = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.npxc = tempw; + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldcw) : (x87_timings.fldcw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldcw) : (x87_concurrency.fldcw * cpu_multi)); + return 0; +} +#endif + +static int +FSTENV(void) +{ + FP_ENTER(); + cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | ((cpu_state.TOP & 7) << 11); + + switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) { + case 0x000: /*16-bit real mode*/ + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 2, cpu_state.npxs); + writememw(easeg, cpu_state.eaaddr + 4, x87_gettag()); + writememw(easeg, cpu_state.eaaddr + 6, x87_pc_off); + writememw(easeg, cpu_state.eaaddr + 10, x87_op_off); + break; + case 0x001: /*16-bit protected mode*/ + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 2, cpu_state.npxs); + writememw(easeg, cpu_state.eaaddr + 4, x87_gettag()); + writememw(easeg, cpu_state.eaaddr + 6, x87_pc_off); + writememw(easeg, cpu_state.eaaddr + 8, x87_pc_seg); + writememw(easeg, cpu_state.eaaddr + 10, x87_op_off); + writememw(easeg, cpu_state.eaaddr + 12, x87_op_seg); + break; + case 0x100: /*32-bit real mode*/ + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 4, cpu_state.npxs); + writememw(easeg, cpu_state.eaaddr + 8, x87_gettag()); + writememw(easeg, cpu_state.eaaddr + 12, x87_pc_off); + writememw(easeg, cpu_state.eaaddr + 20, x87_op_off); + writememl(easeg, cpu_state.eaaddr + 24, (x87_op_off >> 16) << 12); + break; + case 0x101: /*32-bit protected mode*/ + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 4, cpu_state.npxs); + writememw(easeg, cpu_state.eaaddr + 8, x87_gettag()); + writememl(easeg, cpu_state.eaaddr + 12, x87_pc_off); + writememl(easeg, cpu_state.eaaddr + 16, x87_pc_seg); + writememl(easeg, cpu_state.eaaddr + 20, x87_op_off); + writememl(easeg, cpu_state.eaaddr + 24, x87_op_seg); + break; + } + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstenv) : (x87_timings.fstenv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstenv) : (x87_concurrency.fstenv * cpu_multi)); + return cpu_state.abrt; +} + +static int +opFSTENV_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + FSTENV(); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int +opFSTENV_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + FSTENV(); + return cpu_state.abrt; +} +#endif + +static int +opFSTCW_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(cpu_state.npxc); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstenv) : (x87_concurrency.fstenv * cpu_multi)); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int +opFSTCW_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(cpu_state.npxc); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); + return cpu_state.abrt; +} +#endif + +#ifndef FPU_8087 +# define opFCMOV(condition) \ + static int opFCMOV##condition(uint32_t fetchdat) \ + { \ + FP_ENTER(); \ + cpu_state.pc++; \ + if (cond_##condition) { \ + cpu_state.tag[cpu_state.TOP & 7] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \ + cpu_state.MM[cpu_state.TOP & 7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; \ + ST(0) = ST(fetchdat & 7); \ + } \ + CLOCK_CYCLES_FPU(4); \ + return 0; \ } - cpu_state.npxc = 0x37F; - codegen_set_rounding_mode(X87_ROUNDING_NEAREST); - cpu_state.npxs = 0; - p = (uint64_t *)cpu_state.tag; -#ifdef USE_NEW_DYNAREC - *p = 0; -#else - *p = 0x0303030303030303ll; -#endif - cpu_state.TOP = 0; - cpu_state.ismmx = 0; - - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsave) : (x87_timings.fsave * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsave) : (x87_concurrency.fsave * cpu_multi)); - return cpu_state.abrt; -} -static int opFSAVE_a16(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - FSAVE(); - return cpu_state.abrt; -} -#ifndef FPU_8087 -static int opFSAVE_a32(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - FSAVE(); - return cpu_state.abrt; -} -#endif - -static int opFSTSW_a16(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); - return cpu_state.abrt; -} -#ifndef FPU_8087 -static int opFSTSW_a32(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); - return cpu_state.abrt; -} -#endif - - -static int opFLD(uint32_t fetchdat) -{ - int old_tag; - uint64_t old_i64; - - FP_ENTER(); - cpu_state.pc++; - old_tag = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; - old_i64 = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; - x87_push(ST(fetchdat&7)); - cpu_state.tag[cpu_state.TOP&7] = old_tag; - cpu_state.MM[cpu_state.TOP&7].q = old_i64; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld) : (x87_timings.fld * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld) : (x87_concurrency.fld * cpu_multi)); - return 0; -} - -static int opFXCH(uint32_t fetchdat) -{ - double td; - uint8_t old_tag; - uint64_t old_i64; - FP_ENTER(); - cpu_state.pc++; - td = ST(0); - ST(0) = ST(fetchdat&7); - ST(fetchdat&7) = td; - old_tag = cpu_state.tag[cpu_state.TOP&7]; - cpu_state.tag[cpu_state.TOP&7] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = old_tag; - old_i64 = cpu_state.MM[cpu_state.TOP&7].q; - cpu_state.MM[cpu_state.TOP&7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; - cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q = old_i64; - - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fxch) : (x87_timings.fxch * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fxch) : (x87_concurrency.fxch * cpu_multi)); - return 0; -} - -static int opFCHS(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(0) = -ST(0); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fchs) : (x87_timings.fchs * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fchs) : (x87_concurrency.fchs * cpu_multi)); - return 0; -} - -static int opFABS(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(0) = fabs(ST(0)); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fabs) : (x87_timings.fabs * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fabs) : (x87_concurrency.fabs * cpu_multi)); - return 0; -} - -static int opFTST(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= ~(C0|C2|C3); - if (ST(0) == 0.0) cpu_state.npxs |= C3; - else if (ST(0) < 0.0) cpu_state.npxs |= C0; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ftst) : (x87_timings.ftst * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ftst) : (x87_concurrency.ftst * cpu_multi)); - return 0; -} - -static int opFXAM(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= ~(C0|C1|C2|C3); -#ifdef USE_NEW_DYNAREC - if (cpu_state.tag[cpu_state.TOP&7] == TAG_EMPTY) cpu_state.npxs |= (C0|C3); -#else - if (cpu_state.tag[cpu_state.TOP&7] == 3) cpu_state.npxs |= (C0|C3); -#endif - else if (ST(0) == 0.0) cpu_state.npxs |= C3; - else cpu_state.npxs |= C2; - if (ST(0) < 0.0) cpu_state.npxs |= C1; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fxam) : (x87_timings.fxam * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fxam) : (x87_concurrency.fxam * cpu_multi)); - return 0; -} - -static int opFLD1(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - x87_push(1.0); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_z1) : (x87_timings.fld_z1 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_z1) : (x87_concurrency.fld_z1 * cpu_multi)); - return 0; -} - -static int opFLDL2T(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - x87_push(3.3219280948873623); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); - return 0; -} - -static int opFLDL2E(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - x87_push(1.4426950408889634); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); - return 0; -} - -static int opFLDPI(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - x87_push(3.141592653589793); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); - return 0; -} - -static int opFLDEG2(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - x87_push(0.3010299956639812); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); - return 0; -} - -static int opFLDLN2(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - x87_push_u64(0x3fe62e42fefa39f0ull); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); - return 0; -} - -static int opFLDZ(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - x87_push(0.0); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_z1) : (x87_timings.fld_z1 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_z1) : (x87_concurrency.fld_z1 * cpu_multi)); - return 0; -} - -static int opF2XM1(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(0) = pow(2.0, ST(0)) - 1.0; - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.f2xm1) : (x87_timings.f2xm1 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.f2xm1) : (x87_concurrency.f2xm1 * cpu_multi)); - return 0; -} - -static int opFYL2X(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(1) = ST(1) * (log(ST(0)) / log(2.0)); - FP_TAG_VALID_N; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fyl2x) : (x87_timings.fyl2x * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fyl2x) : (x87_concurrency.fyl2x * cpu_multi)); - return 0; -} - -static int opFYL2XP1(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(1) = ST(1) * (log1p(ST(0)) / log(2.0)); - FP_TAG_VALID_N; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fyl2xp1) : (x87_timings.fyl2xp1 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fyl2xp1) : (x87_concurrency.fyl2xp1 * cpu_multi)); - return 0; -} - -static int opFPTAN(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(0) = tan(ST(0)); - FP_TAG_VALID; - x87_push(1.0); - cpu_state.npxs &= ~C2; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fptan) : (x87_timings.fptan * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fptan) : (x87_concurrency.fptan * cpu_multi)); - return 0; -} - -static int opFPATAN(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(1) = atan2(ST(1), ST(0)); - FP_TAG_VALID_N; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fpatan) : (x87_timings.fpatan * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fpatan) : (x87_concurrency.fpatan * cpu_multi)); - return 0; -} - -static int opFDECSTP(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; -#ifdef USE_NEW_DYNAREC - cpu_state.TOP--; -#else - cpu_state.TOP = (cpu_state.TOP - 1) & 7; -#endif - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fincdecstp) : (x87_timings.fincdecstp * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fincdecstp) : (x87_concurrency.fincdecstp * cpu_multi)); - return 0; -} - -static int opFINCSTP(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; -#ifdef USE_NEW_DYNAREC - cpu_state.TOP++; -#else - cpu_state.TOP = (cpu_state.TOP + 1) & 7; -#endif - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fincdecstp) : (x87_timings.fincdecstp * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fincdecstp) : (x87_concurrency.fincdecstp * cpu_multi)); - return 0; -} - -static int opFPREM(uint32_t fetchdat) -{ - int64_t temp64; - FP_ENTER(); - cpu_state.pc++; - temp64 = (int64_t)(ST(0) / ST(1)); - ST(0) = ST(0) - (ST(1) * (double)temp64); - FP_TAG_VALID; - cpu_state.npxs &= ~(C0|C1|C2|C3); - if (temp64 & 4) cpu_state.npxs|=C0; - if (temp64 & 2) cpu_state.npxs|=C3; - if (temp64 & 1) cpu_state.npxs|=C1; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fprem) : (x87_timings.fprem * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fprem) : (x87_concurrency.fprem * cpu_multi)); - return 0; -} -#ifndef FPU_8087 -static int opFPREM1(uint32_t fetchdat) -{ - int64_t temp64; - FP_ENTER(); - cpu_state.pc++; - temp64 = (int64_t)(ST(0) / ST(1)); - ST(0) = ST(0) - (ST(1) * (double)temp64); - FP_TAG_VALID; - cpu_state.npxs &= ~(C0|C1|C2|C3); - if (temp64 & 4) cpu_state.npxs|=C0; - if (temp64 & 2) cpu_state.npxs|=C3; - if (temp64 & 1) cpu_state.npxs|=C1; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fprem1) : (x87_timings.fprem1 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fprem1) : (x87_concurrency.fprem1 * cpu_multi)); - return 0; -} -#endif - -static int opFSQRT(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(0) = sqrt(ST(0)); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsqrt) : (x87_timings.fsqrt * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsqrt) : (x87_concurrency.fsqrt * cpu_multi)); - return 0; -} - -#ifndef FPU_8087 -static int opFSINCOS(uint32_t fetchdat) -{ - double td; - FP_ENTER(); - cpu_state.pc++; - td = ST(0); - ST(0) = sin(td); - FP_TAG_VALID; - x87_push(cos(td)); - cpu_state.npxs &= ~C2; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsincos) : (x87_timings.fsincos * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsincos) : (x87_concurrency.fsincos * cpu_multi)); - return 0; -} -#endif - -static int opFRNDINT(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(0) = (double)x87_fround(ST(0)); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frndint) : (x87_timings.frndint * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frndint) : (x87_concurrency.frndint * cpu_multi)); - return 0; -} - -static int opFSCALE(uint32_t fetchdat) -{ - int64_t temp64; - FP_ENTER(); - cpu_state.pc++; - temp64 = (int64_t)ST(1); - if(ST(0) != 0.0) - ST(0) = ST(0) * pow(2.0, (double)temp64); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fscale) : (x87_timings.fscale * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fscale) : (x87_concurrency.fscale * cpu_multi)); - return 0; -} - -#ifndef FPU_8087 -static int opFSIN(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(0) = sin(ST(0)); - FP_TAG_VALID; - cpu_state.npxs &= ~C2; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsin_cos) : (x87_timings.fsin_cos * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsin_cos) : (x87_concurrency.fsin_cos * cpu_multi)); - return 0; -} - -static int opFCOS(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(0) = cos(ST(0)); - FP_TAG_VALID; - cpu_state.npxs &= ~C2; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsin_cos) : (x87_timings.fsin_cos * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsin_cos) : (x87_concurrency.fsin_cos * cpu_multi)); - return 0; -} -#endif - - -static int FLDENV(void) -{ - FP_ENTER(); - switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) - { - case 0x000: /*16-bit real mode*/ - case 0x001: /*16-bit protected mode*/ - cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2); - x87_settag(readmemw(easeg, cpu_state.eaaddr+4)); - cpu_state.TOP = (cpu_state.npxs >> 11) & 7; - break; - case 0x100: /*32-bit real mode*/ - case 0x101: /*32-bit protected mode*/ - cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4); - x87_settag(readmemw(easeg, cpu_state.eaaddr+8)); - cpu_state.TOP = (cpu_state.npxs >> 11) & 7; - break; - } - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldenv) : (x87_timings.fldenv * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldenv) : (x87_concurrency.fldenv * cpu_multi)); - return cpu_state.abrt; -} - -static int opFLDENV_a16(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - FLDENV(); - return cpu_state.abrt; -} -#ifndef FPU_8087 -static int opFLDENV_a32(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - FLDENV(); - return cpu_state.abrt; -} -#endif - -static int opFLDCW_a16(uint32_t fetchdat) -{ - uint16_t tempw; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); - if (cpu_state.abrt) return 1; - cpu_state.npxc = tempw; - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldcw) : (x87_timings.fldcw * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldcw) : (x87_concurrency.fldcw * cpu_multi)); - return 0; -} -#ifndef FPU_8087 -static int opFLDCW_a32(uint32_t fetchdat) -{ - uint16_t tempw; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); - if (cpu_state.abrt) return 1; - cpu_state.npxc = tempw; - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldcw) : (x87_timings.fldcw * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldcw) : (x87_concurrency.fldcw * cpu_multi)); - return 0; -} -#endif - -static int FSTENV(void) -{ - FP_ENTER(); - cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | ((cpu_state.TOP & 7) << 11); - - switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) - { - case 0x000: /*16-bit real mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+4,x87_gettag()); - writememw(easeg,cpu_state.eaaddr+6,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+10,x87_op_off); - break; - case 0x001: /*16-bit protected mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+4,x87_gettag()); - writememw(easeg,cpu_state.eaaddr+6,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+8,x87_pc_seg); - writememw(easeg,cpu_state.eaaddr+10,x87_op_off); - writememw(easeg,cpu_state.eaaddr+12,x87_op_seg); - break; - case 0x100: /*32-bit real mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+8,x87_gettag()); - writememw(easeg,cpu_state.eaaddr+12,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+20,x87_op_off); - writememl(easeg,cpu_state.eaaddr+24,(x87_op_off>>16)<<12); - break; - case 0x101: /*32-bit protected mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+8,x87_gettag()); - writememl(easeg,cpu_state.eaaddr+12,x87_pc_off); - writememl(easeg,cpu_state.eaaddr+16,x87_pc_seg); - writememl(easeg,cpu_state.eaaddr+20,x87_op_off); - writememl(easeg,cpu_state.eaaddr+24,x87_op_seg); - break; - } - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstenv) : (x87_timings.fstenv * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstenv) : (x87_concurrency.fstenv * cpu_multi)); - return cpu_state.abrt; -} - -static int opFSTENV_a16(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - FSTENV(); - return cpu_state.abrt; -} -#ifndef FPU_8087 -static int opFSTENV_a32(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - FSTENV(); - return cpu_state.abrt; -} -#endif - -static int opFSTCW_a16(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(cpu_state.npxc); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstenv) : (x87_concurrency.fstenv * cpu_multi)); - return cpu_state.abrt; -} -#ifndef FPU_8087 -static int opFSTCW_a32(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(cpu_state.npxc); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); - return cpu_state.abrt; -} -#endif - -#ifndef FPU_8087 -#define opFCMOV(condition) \ - static int opFCMOV ## condition(uint32_t fetchdat) \ - { \ - FP_ENTER(); \ - cpu_state.pc++; \ - if (cond_ ## condition) \ - { \ - cpu_state.tag[cpu_state.TOP&7] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \ - cpu_state.MM[cpu_state.TOP&7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; \ - ST(0) = ST(fetchdat & 7); \ - } \ - CLOCK_CYCLES_FPU(4); \ - return 0; \ - } - -#define cond_U ( PF_SET()) -#define cond_NU (!PF_SET()) +# define cond_U (PF_SET()) +# define cond_NU (!PF_SET()) opFCMOV(B) opFCMOV(E) diff --git a/src/cpu/x87_timings.c b/src/cpu/x87_timings.c index 70ec4b95e..a23e195d2 100644 --- a/src/cpu/x87_timings.c +++ b/src/cpu/x87_timings.c @@ -85,80 +85,79 @@ const x87_timings_t x87_timings_8087 = { .fyl2xp1 = (700 + 1000) / 2 }; -const x87_timings_t x87_timings_80187 = -{ - .f2xm1 = (310 + 630) / 2, - .fabs = (10 + 17) / 2, - .fadd = (70 + 100) / 2, - .fadd_32 = (90 + 120) / 2, - .fadd_64 = (95 + 125) / 2, - .fbld = (290 + 310) / 2, - .fbstp = (520 + 540) / 2, - .fchs = (10 + 17) / 2, - .fclex = (2 + 8) / 2, - .fcom = (40 + 50) / 2, - .fcom_32 = (60 + 70) / 2, - .fcom_64 = (65 + 75) / 2, - .fcos = 0, /*387+*/ - .fincdecstp = (6 + 12) / 2, - .fdisi_eni = (6 + 12) / 2, - .fdiv = (193 + 203) / 2, - .fdiv_32 = (215 + 225) / 2, - .fdiv_64 = (220 + 230) / 2, - .ffree = (9 + 16) / 2, - .fadd_i16 = (102 + 137) / 2, - .fadd_i32 = (108 + 143) / 2, - .fcom_i16 = (72 + 86) / 2, - .fcom_i32 = (78 + 91) / 2, - .fdiv_i16 = (224 + 238) / 2, - .fdiv_i32 = (230 + 243) / 2, - .fild_16 = (46 + 54) / 2, - .fild_32 = (50 + 60) / 2, - .fild_64 = (60 + 68) / 2, - .fmul_i16 = (124 + 138) / 2, - .fmul_i32 = (130 + 144) / 2, - .finit = (2 + 8) / 2, - .fist_16 = (80 + 90) / 2, - .fist_32 = (82 + 92) / 2, - .fist_64 = (94 + 105) / 2, - .fld = (17 + 22) / 2, - .fld_32 = (38 + 56) / 2, - .fld_64 = (40 + 60) / 2, - .fld_80 = (53 + 65) / 2, - .fld_z1 = (11 + 21) / 2, - .fld_const = (15 + 24) / 2, - .fldcw = (7 + 14) / 2, - .fldenv = (35 + 45) / 2, - .fmul = (90 + 145) / 2, - .fmul_32 = (110 + 125) / 2, - .fmul_64 = (154 + 168) / 2, - .fnop = (10 + 16) / 2, - .fpatan = (250 + 800) / 2, - .fprem = (15 + 190) / 2, - .fprem1 = 0, /*387+*/ - .fptan = (30 + 540) / 2, - .frndint = (16 + 50) / 2, - .frstor = (197 + 207) / 2, - .fsave = (197 + 207) / 2, - .fscale = (32 + 38) / 2, - .fsetpm = 0, /*287+*/ - .fsin_cos = 0, /*387+*/ - .fsincos = 0, /*387+*/ - .fsqrt = (180 + 186) / 2, - .fst = (15 + 22) / 2, - .fst_32 = (84 + 90) / 2, - .fst_64 = (96 + 104) / 2, - .fst_80 = (52 + 58) / 2, - .fstcw_sw = (12 + 18) / 2, - .fstenv = (40 + 50) / 2, - .ftst = (38 + 48) / 2, - .fucom = 0, /*387+*/ - .fwait = 4, - .fxam = (12 + 23) / 2, - .fxch = (10 + 15) / 2, - .fxtract = (27 + 55) / 2, - .fyl2x = (900 + 1100) / 2, - .fyl2xp1 = (700 + 1000) / 2 +const x87_timings_t x87_timings_80187 = { + .f2xm1 = (310 + 630) / 2, + .fabs = (10 + 17) / 2, + .fadd = (70 + 100) / 2, + .fadd_32 = (90 + 120) / 2, + .fadd_64 = (95 + 125) / 2, + .fbld = (290 + 310) / 2, + .fbstp = (520 + 540) / 2, + .fchs = (10 + 17) / 2, + .fclex = (2 + 8) / 2, + .fcom = (40 + 50) / 2, + .fcom_32 = (60 + 70) / 2, + .fcom_64 = (65 + 75) / 2, + .fcos = 0, /*387+*/ + .fincdecstp = (6 + 12) / 2, + .fdisi_eni = (6 + 12) / 2, + .fdiv = (193 + 203) / 2, + .fdiv_32 = (215 + 225) / 2, + .fdiv_64 = (220 + 230) / 2, + .ffree = (9 + 16) / 2, + .fadd_i16 = (102 + 137) / 2, + .fadd_i32 = (108 + 143) / 2, + .fcom_i16 = (72 + 86) / 2, + .fcom_i32 = (78 + 91) / 2, + .fdiv_i16 = (224 + 238) / 2, + .fdiv_i32 = (230 + 243) / 2, + .fild_16 = (46 + 54) / 2, + .fild_32 = (50 + 60) / 2, + .fild_64 = (60 + 68) / 2, + .fmul_i16 = (124 + 138) / 2, + .fmul_i32 = (130 + 144) / 2, + .finit = (2 + 8) / 2, + .fist_16 = (80 + 90) / 2, + .fist_32 = (82 + 92) / 2, + .fist_64 = (94 + 105) / 2, + .fld = (17 + 22) / 2, + .fld_32 = (38 + 56) / 2, + .fld_64 = (40 + 60) / 2, + .fld_80 = (53 + 65) / 2, + .fld_z1 = (11 + 21) / 2, + .fld_const = (15 + 24) / 2, + .fldcw = (7 + 14) / 2, + .fldenv = (35 + 45) / 2, + .fmul = (90 + 145) / 2, + .fmul_32 = (110 + 125) / 2, + .fmul_64 = (154 + 168) / 2, + .fnop = (10 + 16) / 2, + .fpatan = (250 + 800) / 2, + .fprem = (15 + 190) / 2, + .fprem1 = 0, /*387+*/ + .fptan = (30 + 540) / 2, + .frndint = (16 + 50) / 2, + .frstor = (197 + 207) / 2, + .fsave = (197 + 207) / 2, + .fscale = (32 + 38) / 2, + .fsetpm = 0, /*287+*/ + .fsin_cos = 0, /*387+*/ + .fsincos = 0, /*387+*/ + .fsqrt = (180 + 186) / 2, + .fst = (15 + 22) / 2, + .fst_32 = (84 + 90) / 2, + .fst_64 = (96 + 104) / 2, + .fst_80 = (52 + 58) / 2, + .fstcw_sw = (12 + 18) / 2, + .fstenv = (40 + 50) / 2, + .ftst = (38 + 48) / 2, + .fucom = 0, /*387+*/ + .fwait = 4, + .fxam = (12 + 23) / 2, + .fxch = (10 + 15) / 2, + .fxtract = (27 + 55) / 2, + .fyl2x = (900 + 1100) / 2, + .fyl2xp1 = (700 + 1000) / 2 }; /*Mostly the same as 8087*/