|
|
| version 1.1, 2003/12/08 00:55:31 | version 1.32, 2005/03/05 16:47:04 |
|---|---|
| Line 32 | Line 32 |
| Copyright by Yui/Studio Milmake 1999-2000 | Copyright by Yui/Studio Milmake 1999-2000 |
| Copyright by Norio HATTORI 2000,2001 | Copyright by Norio HATTORI 2000,2001 |
| Copyright by NONAKA Kimihiro 2002-2003 | Copyright by NONAKA Kimihiro 2002-2004 |
| */ | */ |
| #ifndef IA32_CPU_CPU_H__ | #ifndef IA32_CPU_CPU_H__ |
| #define IA32_CPU_CPU_H__ | #define IA32_CPU_CPU_H__ |
| #if 0 // -> compiler.h | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <strings.h> | |
| #include <unistd.h> | |
| #include <setjmp.h> | |
| #endif | |
| #include "interface.h" | #include "interface.h" |
| #ifdef __cplusplus | #ifdef __cplusplus |
| Line 56 extern "C" { | Line 47 extern "C" { |
| typedef union { | typedef union { |
| #if defined(BYTESEX_LITTLE) | #if defined(BYTESEX_LITTLE) |
| struct { | struct { |
| BYTE l; | UINT8 l; |
| BYTE h; | UINT8 h; |
| BYTE _hl; | UINT8 _hl; |
| BYTE _hh; | UINT8 _hh; |
| } b; | } b; |
| struct { | struct { |
| WORD w; | UINT16 w; |
| WORD _hw; | UINT16 _hw; |
| } w; | } w; |
| #elif defined(BYTESEX_BIG) | #elif defined(BYTESEX_BIG) |
| struct { | struct { |
| BYTE _hh; | UINT8 _hh; |
| BYTE _hl; | UINT8 _hl; |
| BYTE h; | UINT8 h; |
| BYTE l; | UINT8 l; |
| } b; | } b; |
| struct { | struct { |
| WORD _hw; | UINT16 _hw; |
| WORD w; | UINT16 w; |
| } w; | } w; |
| #endif | #endif |
| DWORD d; | UINT32 d; |
| } REG32; | } REG32; |
| typedef struct { | |
| UINT8 b[10]; | |
| } REG80; | |
| #ifdef __cplusplus | #ifdef __cplusplus |
| } | } |
| #endif | #endif |
| #include "cpu_io.h" | |
| #include "cpu_mem.h" | |
| #include "exception.h" | |
| #include "paging.h" | |
| #include "resolve.h" | |
| #include "segments.h" | #include "segments.h" |
| #include "task.h" | |
| #ifdef __cplusplus | #ifdef __cplusplus |
| extern "C" { | extern "C" { |
| Line 119 enum { | Line 108 enum { |
| CPU_SEGREG_NUM | CPU_SEGREG_NUM |
| }; | }; |
| #if 1 // パックしないとだめ? | enum { |
| CPU_TEST_REG_NUM = 8 | |
| }; | |
| enum { | |
| CPU_DEBUG_REG_NUM = 8, | |
| CPU_DEBUG_REG_INDEX_NUM = 4 | |
| }; | |
| enum { | |
| MAX_PREFIX = 8 | |
| }; | |
| typedef struct { | typedef struct { |
| REG32 reg[CPU_REG_NUM]; | REG32 reg[CPU_REG_NUM]; |
| WORD sreg[CPU_SEGREG_NUM]; | UINT16 sreg[CPU_SEGREG_NUM]; |
| REG32 eflags; | REG32 eflags; |
| REG32 eip; | REG32 eip; |
| REG32 prev_eip; | REG32 prev_eip; |
| REG32 prev_esp; | |
| UINT32 tr[CPU_TEST_REG_NUM]; | |
| UINT32 dr[CPU_DEBUG_REG_NUM]; | |
| } CPU_REGS; | } CPU_REGS; |
| typedef struct { | typedef struct { |
| WORD gdtr_limit; | UINT16 gdtr_limit; |
| DWORD gdtr_base; | UINT16 pad0; |
| WORD idtr_limit; | UINT32 gdtr_base; |
| DWORD idtr_base; | UINT16 idtr_limit; |
| UINT16 pad1; | |
| WORD ldtr; | UINT32 idtr_base; |
| WORD tr; | |
| descriptor_t ldtr_desc; | UINT16 ldtr; |
| descriptor_t tr_desc; | UINT16 tr; |
| DWORD cr0; | UINT32 cr0; |
| DWORD cr1; | UINT32 cr1; |
| DWORD cr2; | UINT32 cr2; |
| DWORD cr3; | UINT32 cr3; |
| DWORD cr4; | UINT32 cr4; |
| DWORD mxcsr; | UINT32 mxcsr; |
| } CPU_SYSREGS; | } CPU_SYSREGS; |
| typedef struct { | typedef struct { |
| descriptor_t sreg[CPU_SEGREG_NUM]; | descriptor_t sreg[CPU_SEGREG_NUM]; |
| descriptor_t ldtr; | |
| descriptor_t tr; | |
| UINT32 adrsmask; | |
| UINT32 ovflag; | |
| UINT8 ss_32; | |
| UINT8 resetreq; | |
| UINT8 trap; | |
| UINT8 page_wp; | |
| DWORD inport; | UINT8 protected_mode; |
| DWORD ovflag; | UINT8 paging; |
| UINT8 vm86; | |
| UINT8 user_mode; | |
| BYTE ss_32; | UINT8 hlt; |
| BYTE trap; | UINT8 bp; /* break point bitmap */ |
| BYTE cpu_type; | UINT8 bp_ev; /* break point event */ |
| BYTE _dummy; | UINT8 pad; |
| BYTE cpl; | |
| BYTE protected_mode; | |
| BYTE paging; | |
| BYTE vm86; | |
| DWORD ioaddr; /* I/O bitmap linear address */ | UINT32 pde_base; |
| WORD iolimit; /* I/O bitmap count */ | |
| BYTE nerror; /* double fault/ triple fault */ | UINT32 ioaddr; /* I/O bitmap linear address */ |
| BYTE prev_exception; | UINT16 iolimit; /* I/O bitmap count */ |
| UINT8 nerror; /* double fault/ triple fault */ | |
| UINT8 prev_exception; | |
| } CPU_STAT; | } CPU_STAT; |
| typedef struct { | typedef struct { |
| BYTE op_32; | UINT8 op_32; |
| BYTE as_32; | UINT8 as_32; |
| BYTE rep_used; | UINT8 rep_used; |
| BYTE seg_used; | UINT8 seg_used; |
| DWORD seg_base; | UINT32 seg_base; |
| } CPU_INST; | } CPU_INST; |
| #else | /* FPU */ |
| enum { | |
| FPU_REG_NUM = 8 | |
| }; | |
| typedef struct { | typedef struct { |
| REG32 reg[CPU_REG_NUM]; | UINT16 seg; |
| WORD sreg[CPU_SEGREG_NUM]; | UINT16 pad; |
| UINT32 offset; | |
| } FPU_PTR; | |
| REG32 eflags; | typedef struct { |
| UINT16 control; | |
| UINT16 status; | |
| UINT16 op; | |
| FPU_PTR inst; | |
| FPU_PTR data; | |
| } FPU_REGS; | |
| REG32 eip; | typedef struct { |
| REG32 prev_eip; | UINT8 valid; /* レジスタ有効 */ |
| } __attribute__((packed)) CPU_REGS; | UINT8 sign; /* 符号 */ |
| UINT8 zero; /* ゼロ */ | |
| UINT8 inf; /* ∞ */ | |
| UINT8 nan; /* NaN */ | |
| UINT8 denorm; /* 非正規化 */ | |
| SINT16 exp; /* 指数部 */ | |
| UINT64 num; /* 小数部 */ | |
| } FP_REG; | |
| typedef struct { | typedef struct { |
| WORD gdtr_limit; | UINT8 top; /* スタック位置 */ |
| DWORD gdtr_base; | UINT8 pc; /* 精度 */ |
| WORD idtr_limit; | UINT8 rc; /* 丸め */ |
| DWORD idtr_base; | UINT8 dmy[1]; |
| WORD ldtr; | FP_REG reg[FPU_REG_NUM]; |
| WORD tr; | } FPU_STAT; |
| descriptor_t ldtr_desc; | |
| descriptor_t tr_desc; | |
| DWORD cr0; | |
| DWORD cr1; | |
| DWORD cr2; | |
| DWORD cr3; | |
| DWORD cr4; | |
| DWORD mxcsr; | |
| } __attribute__((packed)) CPU_SYSREGS; | |
| typedef struct { | typedef struct { |
| descriptor_t sreg[CPU_SEGREG_NUM]; | CPU_REGS cpu_regs; |
| CPU_SYSREGS cpu_sysregs; | |
| CPU_STAT cpu_stat; | |
| CPU_INST cpu_inst; | |
| CPU_INST cpu_inst_default; | |
| #if defined(USE_FPU) | |
| FPU_REGS fpu_regs; | |
| FPU_STAT fpu_stat; | |
| #endif | |
| DWORD inport; | /* protected by cpu shut */ |
| DWORD ovflag; | UINT8 cpu_type; |
| UINT8 itfbank; | |
| UINT16 ram_d0; | |
| SINT32 remainclock; | |
| SINT32 baseclock; | |
| UINT32 clock; | |
| } I386STAT; | |
| BYTE ss_32; | typedef struct { |
| BYTE trap; | BYTE *ext; |
| BYTE cpu_type; | UINT32 extsize; |
| BYTE _dummy; | UINT32 inport; |
| BYTE *ems[4]; | |
| BYTE cpl; | } I386EXT; |
| BYTE protected_mode; | |
| BYTE paging; | |
| BYTE vm86; | |
| DWORD ioaddr; /* I/O bitmap linear address */ | |
| WORD iolimit; /* I/O bitmap count */ | |
| BYTE nerror; /* double fault/ triple fault */ | |
| BYTE prev_exception; | |
| } __attribute__((packed)) CPU_STAT; | |
| typedef struct { | |
| BYTE op_32; | |
| BYTE as_32; | |
| BYTE rep_used; | |
| BYTE seg_used; | |
| DWORD seg_base; | |
| } __attribute__((packed)) CPU_INST; | |
| #endif | typedef struct { |
| I386STAT s; /* STATsaveされる奴 */ | |
| I386EXT e; | |
| } I386CORE; | |
| extern I386CORE i386core; | |
| #define CPU_STATSAVE i386core.s | |
| #define CPU_ADRSMASK i386core.s.cpu_stat.adrsmask | |
| #define CPU_RESETREQ i386core.s.cpu_stat.resetreq | |
| extern CPU_REGS cpu_regs; | #define CPU_REMCLOCK i386core.s.remainclock |
| extern CPU_SYSREGS cpu_sysregs; | #define CPU_BASECLOCK i386core.s.baseclock |
| extern CPU_STAT cpu_stat; | #define CPU_CLOCK i386core.s.clock |
| extern CPU_INST cpu_inst; | #define CPU_ITFBANK i386core.s.itfbank |
| extern CPU_INST cpu_inst_default; | #define CPU_RAM_D000 i386core.s.ram_d0 |
| extern BYTE iflags[]; | |
| extern jmp_buf exec_1step_jmpbuf; | #define CPU_TYPE i386core.s.cpu_type |
| #define CPUTYPE_V30 0x01 | |
| #define CPU_EXTMEM i386core.e.ext | |
| #define CPU_EXTMEMSIZE i386core.e.extsize | |
| #define CPU_INPADRS i386core.e.inport | |
| #define CPU_EMSPTR i386core.e.ems | |
| extern sigjmp_buf exec_1step_jmpbuf; | |
| /* | /* |
| Line 264 extern jmp_buf exec_1step_jmpbuf; | Line 301 extern jmp_buf exec_1step_jmpbuf; |
| #define CPU_VENDOR_3 0x6c65746e /* "ntel" */ | #define CPU_VENDOR_3 0x6c65746e /* "ntel" */ |
| /* version */ | /* version */ |
| #define CPU_FAMILY 6 | #define CPU_FAMILY 4 |
| #define CPU_MODEL 1 | #if defined(USE_FPU) |
| #define CPU_MODEL 1 /* 486DX */ | |
| #else | |
| #define CPU_MODEL 2 /* 486SX */ | |
| #endif | |
| #define CPU_STEPPING 3 | #define CPU_STEPPING 3 |
| /* feature */ | /* feature */ |
| Line 301 extern jmp_buf exec_1step_jmpbuf; | Line 342 extern jmp_buf exec_1step_jmpbuf; |
| /* (1 << 29) */ | /* (1 << 29) */ |
| /* (1 << 30) */ | /* (1 << 30) */ |
| /* (1 << 31) */ | /* (1 << 31) */ |
| #ifdef USE_FPU | #if defined(USE_FPU) |
| #define CPU_FEATURES (CPU_FEATURE_CMOV|CPU_FEATURE_FPU) | #define CPU_FEATURES (CPU_FEATURE_CMOV|CPU_FEATURE_FPU) |
| #else | #else |
| #define CPU_FEATURES (CPU_FEATURE_CMOV) | #define CPU_FEATURES (CPU_FEATURE_CMOV) |
| #endif | #endif |
| #define CPU_REGS_BYTEL(n) cpu_regs.reg[(n)].b.l | #define CPU_REGS_BYTEL(n) CPU_STATSAVE.cpu_regs.reg[(n)].b.l |
| #define CPU_REGS_BYTEH(n) cpu_regs.reg[(n)].b.h | #define CPU_REGS_BYTEH(n) CPU_STATSAVE.cpu_regs.reg[(n)].b.h |
| #define CPU_REGS_WORD(n) cpu_regs.reg[(n)].w.w | #define CPU_REGS_WORD(n) CPU_STATSAVE.cpu_regs.reg[(n)].w.w |
| #define CPU_REGS_DWORD(n) cpu_regs.reg[(n)].d | #define CPU_REGS_DWORD(n) CPU_STATSAVE.cpu_regs.reg[(n)].d |
| #define CPU_REGS_SREG(n) cpu_regs.sreg[(n)] | #define CPU_REGS_SREG(n) CPU_STATSAVE.cpu_regs.sreg[(n)] |
| #define CPU_STAT_SREG(n) cpu_stat.sreg[(n)] | #define CPU_STAT_SREG(n) CPU_STATSAVE.cpu_stat.sreg[(n)] |
| #define CPU_STAT_SREGBASE(n) cpu_stat.sreg[(n)].u.seg.segbase | #define CPU_STAT_SREGBASE(n) CPU_STATSAVE.cpu_stat.sreg[(n)].u.seg.segbase |
| #define CPU_STAT_SREGEND(n) cpu_stat.sreg[(n)].u.seg.segend | #define CPU_STAT_SREGEND(n) CPU_STATSAVE.cpu_stat.sreg[(n)].u.seg.segend |
| #define CPU_STAT_SREGLIMIT(n) cpu_stat.sreg[(n)].u.seg.limit | #define CPU_STAT_SREGLIMIT(n) CPU_STATSAVE.cpu_stat.sreg[(n)].u.seg.limit |
| #define CPU_STAT_SREG_CLEAR(n) \ | #define CPU_STAT_SREG_CLEAR(n) \ |
| do { \ | do { \ |
| memset(&CPU_STAT_SREG(n), 0, sizeof(descriptor_t)); \ | memset(&CPU_STAT_SREG(n), 0, sizeof(descriptor_t)); \ |
| Line 325 do { \ | Line 366 do { \ |
| #define CPU_STAT_SREG_INIT(n) \ | #define CPU_STAT_SREG_INIT(n) \ |
| do { \ | do { \ |
| descriptor_t sd; \ | descriptor_t sd; \ |
| memset(&CPU_STAT_SREG(n), 0, sizeof(CPU_STAT_SREG(n))); \ | \ |
| memset(&sd, 0, sizeof(sd)); \ | memset(&sd, 0, sizeof(sd)); \ |
| sd.u.seg.limit = 0xffff; \ | sd.u.seg.limit = 0xffff; \ |
| CPU_SET_SEGDESC_DEFAULT(&sd, (n), 0); \ | CPU_SET_SEGDESC_DEFAULT(&sd, (n), 0); \ |
| Line 350 do { \ | Line 391 do { \ |
| #define CPU_BP CPU_REGS_WORD(CPU_EBP_INDEX) | #define CPU_BP CPU_REGS_WORD(CPU_EBP_INDEX) |
| #define CPU_SI CPU_REGS_WORD(CPU_ESI_INDEX) | #define CPU_SI CPU_REGS_WORD(CPU_ESI_INDEX) |
| #define CPU_DI CPU_REGS_WORD(CPU_EDI_INDEX) | #define CPU_DI CPU_REGS_WORD(CPU_EDI_INDEX) |
| #define CPU_IP cpu_regs.eip.w.w | #define CPU_IP CPU_STATSAVE.cpu_regs.eip.w.w |
| #define CPU_EAX CPU_REGS_DWORD(CPU_EAX_INDEX) | #define CPU_EAX CPU_REGS_DWORD(CPU_EAX_INDEX) |
| #define CPU_ECX CPU_REGS_DWORD(CPU_ECX_INDEX) | #define CPU_ECX CPU_REGS_DWORD(CPU_ECX_INDEX) |
| Line 360 do { \ | Line 401 do { \ |
| #define CPU_EBP CPU_REGS_DWORD(CPU_EBP_INDEX) | #define CPU_EBP CPU_REGS_DWORD(CPU_EBP_INDEX) |
| #define CPU_ESI CPU_REGS_DWORD(CPU_ESI_INDEX) | #define CPU_ESI CPU_REGS_DWORD(CPU_ESI_INDEX) |
| #define CPU_EDI CPU_REGS_DWORD(CPU_EDI_INDEX) | #define CPU_EDI CPU_REGS_DWORD(CPU_EDI_INDEX) |
| #define CPU_EIP cpu_regs.eip.d | #define CPU_EIP CPU_STATSAVE.cpu_regs.eip.d |
| #define CPU_PREV_EIP cpu_regs.prev_eip.d | #define CPU_PREV_EIP CPU_STATSAVE.cpu_regs.prev_eip.d |
| #define CPU_PREV_ESP CPU_STATSAVE.cpu_regs.prev_esp.d | |
| #define CPU_ES CPU_REGS_SREG(CPU_ES_INDEX) | #define CPU_ES CPU_REGS_SREG(CPU_ES_INDEX) |
| #define CPU_CS CPU_REGS_SREG(CPU_CS_INDEX) | #define CPU_CS CPU_REGS_SREG(CPU_CS_INDEX) |
| Line 370 do { \ | Line 412 do { \ |
| #define CPU_FS CPU_REGS_SREG(CPU_FS_INDEX) | #define CPU_FS CPU_REGS_SREG(CPU_FS_INDEX) |
| #define CPU_GS CPU_REGS_SREG(CPU_GS_INDEX) | #define CPU_GS CPU_REGS_SREG(CPU_GS_INDEX) |
| #define ES_BASE cpu_stat.sreg[CPU_ES_INDEX].u.seg.segbase | #define ES_BASE CPU_STAT_SREGBASE(CPU_ES_INDEX) |
| #define CS_BASE cpu_stat.sreg[CPU_CS_INDEX].u.seg.segbase | #define CS_BASE CPU_STAT_SREGBASE(CPU_CS_INDEX) |
| #define SS_BASE cpu_stat.sreg[CPU_SS_INDEX].u.seg.segbase | #define SS_BASE CPU_STAT_SREGBASE(CPU_SS_INDEX) |
| #define DS_BASE cpu_stat.sreg[CPU_DS_INDEX].u.seg.segbase | #define DS_BASE CPU_STAT_SREGBASE(CPU_DS_INDEX) |
| #define FS_BASE cpu_stat.sreg[CPU_FS_INDEX].u.seg.segbase | #define FS_BASE CPU_STAT_SREGBASE(CPU_FS_INDEX) |
| #define GS_BASE cpu_stat.sreg[CPU_GS_INDEX].u.seg.segbase | #define GS_BASE CPU_STAT_SREGBASE(CPU_GS_INDEX) |
| #define CPU_EFLAG cpu_regs.eflags.d | #define CPU_EFLAG CPU_STATSAVE.cpu_regs.eflags.d |
| #define CPU_FLAG cpu_regs.eflags.w.w | #define CPU_FLAG CPU_STATSAVE.cpu_regs.eflags.w.w |
| #define CPU_FLAGL cpu_regs.eflags.b.l | #define CPU_FLAGL CPU_STATSAVE.cpu_regs.eflags.b.l |
| #define CPU_FLAGH cpu_regs.eflags.b.h | #define CPU_FLAGH CPU_STATSAVE.cpu_regs.eflags.b.h |
| #define CPU_TRAP cpu_stat.trap | #define CPU_TRAP CPU_STATSAVE.cpu_stat.trap |
| #define CPU_INPORT cpu_stat.inport | #define CPU_INPORT CPU_STATSAVE.cpu_stat.inport |
| #define CPU_OV cpu_stat.ovflag | #define CPU_OV CPU_STATSAVE.cpu_stat.ovflag |
| #define C_FLAG (1 << 0) | #define C_FLAG (1 << 0) |
| #define P_FLAG (1 << 2) | #define P_FLAG (1 << 2) |
| Line 409 do { \ | Line 451 do { \ |
| #define ALL_FLAG (SZAPC_FLAG|T_FLAG|I_FLAG|D_FLAG|O_FLAG|IOPL_FLAG|NT_FLAG) | #define ALL_FLAG (SZAPC_FLAG|T_FLAG|I_FLAG|D_FLAG|O_FLAG|IOPL_FLAG|NT_FLAG) |
| #define ALL_EFLAG (ALL_FLAG|RF_FLAG|VM_FLAG|AC_FLAG|VIF_FLAG|VIP_FLAG|ID_FLAG) | #define ALL_EFLAG (ALL_FLAG|RF_FLAG|VM_FLAG|AC_FLAG|VIF_FLAG|VIP_FLAG|ID_FLAG) |
| #define REAL_FLAGREG ((CPU_FLAG & 0xf7ff) | (CPU_OV ? O_FLAG : 0)) | #define REAL_FLAGREG ((CPU_FLAG & 0xf7ff) | (CPU_OV ? O_FLAG : 0) | 2) |
| #define REAL_EFLAGREG ((CPU_EFLAG & 0xfffff7ff) | (CPU_OV ? O_FLAG : 0)) | #define REAL_EFLAGREG ((CPU_EFLAG & 0xfffff7ff) | (CPU_OV ? O_FLAG : 0) | 2) |
| void set_flags(WORD new_flags, WORD mask); | #if !defined(IA32_DONT_USE_SET_EFLAGS_FUNCTION) |
| void set_eflags(DWORD new_flags, DWORD mask); | void set_flags(UINT16 new_flags, UINT16 mask); |
| void set_eflags(UINT32 new_flags, UINT32 mask); | |
| #endif | |
| #define CPU_TYPE cpu_stat.cpu_type | |
| #define CPUTYPE_V30 0x01 | |
| #define CPU_INST_OP32 cpu_inst.op_32 | #define CPU_INST_OP32 CPU_STATSAVE.cpu_inst.op_32 |
| #define CPU_INST_AS32 cpu_inst.as_32 | #define CPU_INST_AS32 CPU_STATSAVE.cpu_inst.as_32 |
| #define CPU_INST_REPUSE cpu_inst.rep_used | #define CPU_INST_REPUSE CPU_STATSAVE.cpu_inst.rep_used |
| #define CPU_INST_SEGUSE cpu_inst.seg_used | #define CPU_INST_SEGUSE CPU_STATSAVE.cpu_inst.seg_used |
| #define CPU_INST_SEGREG_INDEX cpu_inst.seg_base | #define CPU_INST_SEGREG_INDEX CPU_STATSAVE.cpu_inst.seg_base |
| #define DS_FIX (!CPU_INST_SEGUSE ? CPU_DS_INDEX : CPU_INST_SEGREG_INDEX) | #define DS_FIX (!CPU_INST_SEGUSE ? CPU_DS_INDEX : CPU_INST_SEGREG_INDEX) |
| #define SS_FIX (!CPU_INST_SEGUSE ? CPU_SS_INDEX : CPU_INST_SEGREG_INDEX) | #define SS_FIX (!CPU_INST_SEGUSE ? CPU_SS_INDEX : CPU_INST_SEGREG_INDEX) |
| #define CPU_STAT_CS_BASE cpu_stat.sreg[CPU_CS_INDEX].u.seg.limit | #define CPU_STAT_CS_BASE CPU_STAT_SREGBASE(CPU_CS_INDEX) |
| #define CPU_STAT_CS_LIMIT cpu_stat.sreg[CPU_CS_INDEX].u.seg.limit | #define CPU_STAT_CS_LIMIT CPU_STAT_SREGLIMIT(CPU_CS_INDEX) |
| #define CPU_STAT_CS_END cpu_stat.sreg[CPU_CS_INDEX].u.seg.segend | #define CPU_STAT_CS_END CPU_STAT_SREGEND(CPU_CS_INDEX) |
| #define CPU_STAT_SS32 cpu_stat.ss_32 | #define CPU_STAT_ADRSMASK CPU_STATSAVE.cpu_stat.adrsmask |
| #define CPU_STAT_PM cpu_stat.protected_mode | #define CPU_STAT_SS32 CPU_STATSAVE.cpu_stat.ss_32 |
| #define CPU_STAT_VM86 cpu_stat.vm86 | #define CPU_STAT_RESETREQ CPU_STATSAVE.cpu_stat.resetreq |
| #define CPU_STAT_PAGING cpu_stat.paging | #define CPU_STAT_PM CPU_STATSAVE.cpu_stat.protected_mode |
| #define CPU_STAT_CPL cpu_stat.cpl | #define CPU_STAT_PAGING CPU_STATSAVE.cpu_stat.paging |
| #define CPU_STAT_VM86 CPU_STATSAVE.cpu_stat.vm86 | |
| #define CPU_STAT_WP CPU_STATSAVE.cpu_stat.page_wp | |
| #define CPU_STAT_CPL CPU_STAT_SREG(CPU_CS_INDEX).rpl | |
| #define CPU_STAT_USER_MODE CPU_STATSAVE.cpu_stat.user_mode | |
| #define CPU_STAT_PDE_BASE CPU_STATSAVE.cpu_stat.pde_base | |
| #define CPU_STAT_HLT CPU_STATSAVE.cpu_stat.hlt | |
| #define CPU_STAT_IOPL ((CPU_EFLAG & IOPL_FLAG) >> 12) | #define CPU_STAT_IOPL ((CPU_EFLAG & IOPL_FLAG) >> 12) |
| #define CPU_IOPL0 0 | #define CPU_IOPL0 0 |
| Line 442 void set_eflags(DWORD new_flags, DWORD m | Line 491 void set_eflags(DWORD new_flags, DWORD m |
| #define CPU_IOPL2 2 | #define CPU_IOPL2 2 |
| #define CPU_IOPL3 3 | #define CPU_IOPL3 3 |
| #define CPU_STAT_IOADDR cpu_stat.ioaddr | #define CPU_STAT_IOADDR CPU_STATSAVE.cpu_stat.ioaddr |
| #define CPU_STAT_IOLIMIT cpu_stat.iolimit | #define CPU_STAT_IOLIMIT CPU_STATSAVE.cpu_stat.iolimit |
| #define CPU_STAT_PREV_EXCEPTION CPU_STATSAVE.cpu_stat.prev_exception | |
| #define CPU_STAT_EXCEPTION_COUNTER CPU_STATSAVE.cpu_stat.nerror | |
| #define CPU_STAT_EXCEPTION_COUNTER_INC() CPU_STATSAVE.cpu_stat.nerror++ | |
| #define CPU_STAT_EXCEPTION_COUNTER_CLEAR() CPU_STATSAVE.cpu_stat.nerror = 0 | |
| #define CPU_PREFETCH_CLEAR() | |
| #define CPU_PREFETCHQ_REMAIN_ADD(d) | |
| #define CPU_PREFETCHQ_REMAIN_SUB(d) | |
| #define CPU_MODE_SUPERVISER 0 | |
| #define CPU_MODE_USER (1 << 3) | |
| #define CPU_SET_CPL(cpl) \ | |
| do { \ | |
| UINT8 __t = (UINT8)((cpl) & 3); \ | |
| CPU_STAT_CPL = __t; \ | |
| CPU_STAT_USER_MODE = (__t == 3) ? CPU_MODE_USER : CPU_MODE_SUPERVISER; \ | |
| } while (/*CONSTCOND*/ 0) | |
| #define CPU_CLI \ | |
| do { \ | |
| CPU_FLAG &= ~I_FLAG; \ | |
| CPU_TRAP = 0; \ | |
| } while (/*CONSTCOND*/0) | |
| #define CPU_STI \ | |
| do { \ | |
| CPU_FLAG |= I_FLAG; \ | |
| CPU_TRAP = (CPU_FLAG & (I_FLAG|T_FLAG)) == (I_FLAG|T_FLAG) ; \ | |
| } while (/*CONSTCOND*/0) | |
| #define CPU_GDTR_LIMIT CPU_STATSAVE.cpu_sysregs.gdtr_limit | |
| #define CPU_GDTR_BASE CPU_STATSAVE.cpu_sysregs.gdtr_base | |
| #define CPU_IDTR_LIMIT CPU_STATSAVE.cpu_sysregs.idtr_limit | |
| #define CPU_IDTR_BASE CPU_STATSAVE.cpu_sysregs.idtr_base | |
| #define CPU_LDTR CPU_STATSAVE.cpu_sysregs.ldtr | |
| #define CPU_LDTR_DESC CPU_STATSAVE.cpu_stat.ldtr | |
| #define CPU_LDTR_BASE CPU_STATSAVE.cpu_stat.ldtr.u.seg.segbase | |
| #define CPU_LDTR_END CPU_STATSAVE.cpu_stat.ldtr.u.seg.segend | |
| #define CPU_LDTR_LIMIT CPU_STATSAVE.cpu_stat.ldtr.u.seg.limit | |
| #define CPU_TR CPU_STATSAVE.cpu_sysregs.tr | |
| #define CPU_TR_DESC CPU_STATSAVE.cpu_stat.tr | |
| #define CPU_TR_BASE CPU_STATSAVE.cpu_stat.tr.u.seg.segbase | |
| #define CPU_TR_END CPU_STATSAVE.cpu_stat.tr.u.seg.segend | |
| #define CPU_TR_LIMIT CPU_STATSAVE.cpu_stat.tr.u.seg.limit | |
| #define CPU_STAT_NERROR cpu_stat.nerror | /* |
| #define CPU_STAT_PREV_EXCEPTION cpu_stat.prev_exception | * control register |
| */ | |
| #define CPU_MSW CPU_STATSAVE.cpu_sysregs.cr0 | |
| #define CPU_CLI do { CPU_FLAG &= ~I_FLAG; \ | #define CPU_CR0 CPU_STATSAVE.cpu_sysregs.cr0 |
| CPU_TRAP = 0; } while (/*CONSTCOND*/ 0) | #define CPU_CR1 CPU_STATSAVE.cpu_sysregs.cr1 |
| #define CPU_STI do { CPU_FLAG |= I_FLAG; \ | #define CPU_CR2 CPU_STATSAVE.cpu_sysregs.cr2 |
| CPU_TRAP = (CPU_FLAG >> 8) & 1; } while (/*CONSTCOND*/0) | #define CPU_CR3 CPU_STATSAVE.cpu_sysregs.cr3 |
| #define CPU_CR4 CPU_STATSAVE.cpu_sysregs.cr4 | |
| #define CPU_GDTR_LIMIT cpu_sysregs.gdtr_limit | #define CPU_MXCSR CPU_STATSAVE.cpu_sysregs.mxcsr |
| #define CPU_GDTR_BASE cpu_sysregs.gdtr_base | |
| #define CPU_IDTR_LIMIT cpu_sysregs.idtr_limit | #define CPU_CR0_PE (1 << 0) |
| #define CPU_IDTR_BASE cpu_sysregs.idtr_base | #define CPU_CR0_MP (1 << 1) |
| #define CPU_LDTR cpu_sysregs.ldtr | #define CPU_CR0_EM (1 << 2) |
| #define CPU_LDTR_DESC cpu_sysregs.ldtr_desc | #define CPU_CR0_TS (1 << 3) |
| #define CPU_LDTR_BASE cpu_sysregs.ldtr_desc.u.seg.segbase | #define CPU_CR0_ET (1 << 4) |
| #define CPU_LDTR_END cpu_sysregs.ldtr_desc.u.seg.segend | #define CPU_CR0_NE (1 << 5) |
| #define CPU_LDTR_LIMIT cpu_sysregs.ldtr_desc.u.seg.limit | #define CPU_CR0_WP (1 << 16) |
| #define CPU_TR cpu_sysregs.tr | #define CPU_CR0_AM (1 << 18) |
| #define CPU_TR_DESC cpu_sysregs.tr_desc | #define CPU_CR0_NW (1 << 29) |
| #define CPU_TR_BASE cpu_sysregs.tr_desc.u.seg.segbase | #define CPU_CR0_CD (1 << 30) |
| #define CPU_TR_END cpu_sysregs.tr_desc.u.seg.segend | #define CPU_CR0_PG (1 << 31) |
| #define CPU_TR_LIMIT cpu_sysregs.tr_desc.u.seg.limit | #define CPU_CR0_ALL (CPU_CR0_PE|CPU_CR0_MP|CPU_CR0_EM|CPU_CR0_TS|CPU_CR0_ET|CPU_CR0_NE|CPU_CR0_WP|CPU_CR0_AM|CPU_CR0_NW|CPU_CR0_CD|CPU_CR0_PG) |
| #define CPU_CR0 cpu_sysregs.cr0 | #define CPU_CR3_PD_MASK 0xfffff000 |
| #define CPU_CR1 cpu_sysregs.cr1 | #define CPU_CR3_PWT (1 << 3) |
| #define CPU_CR2 cpu_sysregs.cr2 | #define CPU_CR3_PCD (1 << 4) |
| #define CPU_CR3 cpu_sysregs.cr3 | #define CPU_CR3_MASK (CPU_CR3_PD_MASK|CPU_CR3_PWT|CPU_CR3_PCD) |
| #define CPU_CR4 cpu_sysregs.cr4 | |
| #define CPU_MXCSR cpu_sysregs.mxcsr | |
| #define CPU_CR0_PE (1 << 0) | |
| #define CPU_CR0_MP (1 << 1) | |
| #define CPU_CR0_EM (1 << 2) | |
| #define CPU_CR0_TS (1 << 3) | |
| #define CPU_CR0_ET (1 << 4) | |
| #define CPU_CR0_NE (1 << 5) | |
| #define CPU_CR0_WP (1 << 16) | |
| #define CPU_CR0_AM (1 << 18) | |
| #define CPU_CR0_NW (1 << 29) | |
| #define CPU_CR0_CD (1 << 30) | |
| #define CPU_CR0_PG (1 << 31) | |
| #define CPU_CR3_PD_MASK 0xfffff000 | |
| #define CPU_CR3_PWT (1 << 3) | |
| #define CPU_CR3_PCD (1 << 4) | |
| #define CPU_CR4_VME (1 << 0) | #define CPU_CR4_VME (1 << 0) |
| #define CPU_CR4_PVI (1 << 1) | #define CPU_CR4_PVI (1 << 1) |
| Line 503 void set_eflags(DWORD new_flags, DWORD m | Line 581 void set_eflags(DWORD new_flags, DWORD m |
| #define CPU_CR4_OSFXSR (1 << 9) | #define CPU_CR4_OSFXSR (1 << 9) |
| #define CPU_CR4_OSXMMEXCPT (1 << 10) | #define CPU_CR4_OSXMMEXCPT (1 << 10) |
| /* | |
| void ia32_initialize(void); | * debug register |
| */ | |
| #define CPU_DR(r) CPU_STATSAVE.cpu_regs.dr[(r)] | |
| #define CPU_DR6 CPU_DR(6) | |
| #define CPU_DR7 CPU_DR(7) | |
| #define CPU_STAT_BP CPU_STATSAVE.cpu_stat.bp | |
| #define CPU_STAT_BP_EVENT CPU_STATSAVE.cpu_stat.bp_ev | |
| #define CPU_STAT_BP_EVENT_B(r) (1 << (r)) | |
| #define CPU_STAT_BP_EVENT_DR (1 << 4) /* fault */ | |
| #define CPU_STAT_BP_EVENT_STEP (1 << 5) /* as CPU_TRAP */ | |
| #define CPU_STAT_BP_EVENT_TASK (1 << 6) | |
| #define CPU_STAT_BP_EVENT_RF (1 << 7) /* RF_FLAG */ | |
| #define CPU_DR6_B(r) (1 << (r)) | |
| #define CPU_DR6_BD (1 << 13) | |
| #define CPU_DR6_BS (1 << 14) | |
| #define CPU_DR6_BT (1 << 15) | |
| #define CPU_DR7_L(r) (1 << ((r) * 2)) | |
| #define CPU_DR7_G(r) (1 << ((r) * 2 + 1)) | |
| #define CPU_DR7_LE (1 << 8) | |
| #define CPU_DR7_GE (1 << 9) | |
| #define CPU_DR7_GD (1 << 13) | |
| #define CPU_DR7_RW(r) (3 << ((r) * 4 + 16)) | |
| #define CPU_DR7_LEN(r) (3 << ((r) * 4 + 16 + 2)) | |
| #define CPU_DR7_GET_RW(r) ((CPU_DR7) >> (16 + (r) * 4)) | |
| #define CPU_DR7_RW_CODE 0 | |
| #define CPU_DR7_RW_RO 1 | |
| #define CPU_DR7_RW_IO 2 | |
| #define CPU_DR7_RW_RW 3 | |
| #define CPU_DR7_GET_LEN(r) ((CPU_DR7) >> (16 + 2 + (r) * 4)) | |
| void ia32_init(void); | |
| void ia32_initreg(void); | |
| void ia32_setextsize(UINT32 size); | |
| void ia32_setemm(UINT frame, UINT32 addr); | |
| void ia32reset(void); | void ia32reset(void); |
| void ia32shut(void); | |
| void ia32a20enable(BOOL enable); | |
| void ia32(void); | void ia32(void); |
| void ia32withtrap(void); | |
| void ia32withdma(void); | |
| void ia32_step(void); | void ia32_step(void); |
| void CPUCALL ia32_interrupt(BYTE vect); | void CPUCALL ia32_interrupt(int vect, int soft); |
| void CPUCALL ia32_exception(DWORD vect, DWORD p1, DWORD p2); | void CPUCALL ia32_exception(int vect, int p1, int p2); |
| void exec_1step(void); | void exec_1step(void); |
| #define INST_PREFIX (1 << 0) | #define INST_PREFIX (1 << 0) |
| #define INST_STRING (1 << 1) | #define INST_STRING (1 << 1) |
| #define REP_CHECKZF (1 << 7) | #define REP_CHECKZF (1 << 7) |
| void disasm(WORD cs, DWORD maddr); | |
| void ia32_printf(const char *buf, ...); | void ia32_printf(const char *buf, ...); |
| void ia32_warning(const char *buf, ...); | void ia32_warning(const char *buf, ...); |
| void ia32_panic(const char *buf, ...); | void ia32_panic(const char *buf, ...); |
| Line 530 void ia32_bioscall(void); | Line 643 void ia32_bioscall(void); |
| void FASTCALL change_pm(BOOL onoff); | void FASTCALL change_pm(BOOL onoff); |
| void FASTCALL change_vm(BOOL onoff); | void FASTCALL change_vm(BOOL onoff); |
| void FASTCALL change_pg(BOOL onoff); | |
| extern BYTE szpcflag[0x200]; | extern const UINT8 iflags[]; |
| extern BYTE szpflag_w[0x10000]; | #define szpcflag iflags |
| extern UINT8 szpflag_w[0x10000]; | |
| extern UINT8 *reg8_b20[0x100]; | |
| extern UINT8 *reg8_b53[0x100]; | |
| extern UINT16 *reg16_b20[0x100]; | |
| extern UINT16 *reg16_b53[0x100]; | |
| extern UINT32 *reg32_b20[0x100]; | |
| extern UINT32 *reg32_b53[0x100]; | |
| extern const char *reg8_str[8]; | |
| extern const char *reg16_str[8]; | |
| extern const char *reg32_str[8]; | |
| char *cpu_reg2str(void); | |
| #if defined(USE_FPU) | |
| char *fpu_reg2str(void); | |
| #endif | |
| void put_cpuinfo(void); | |
| void dbg_printf(const char *str, ...); | |
| extern BYTE *reg8_b20[0x100]; | |
| extern BYTE *reg8_b53[0x100]; | |
| extern WORD *reg16_b20[0x100]; | |
| extern WORD *reg16_b53[0x100]; | |
| extern DWORD *reg32_b20[0x100]; | |
| extern DWORD *reg32_b53[0x100]; | |
| /* | |
| * FPU | |
| */ | |
| #define FPU_REGS CPU_STATSAVE.fpu_regs | |
| #define FPU_CTRLWORD FPU_REGS.control | |
| #define FPU_STATUSWORD FPU_REGS.status | |
| #define FPU_INSTPTR FPU_REGS.inst | |
| #define FPU_DATAPTR FPU_REGS.data | |
| #define FPU_LASTINSTOP FPU_REGS.op | |
| #define FPU_INSTPTR_OFFSET FPU_REGS.inst.offset | |
| #define FPU_INSTPTR_SEG FPU_REGS.inst.seg | |
| #define FPU_DATAPTR_OFFSET FPU_REGS.data.offset | |
| #define FPU_DATAPTR_SEG FPU_REGS.data.seg | |
| #define FPU_STAT CPU_STATSAVE.fpu_stat | |
| #define FPU_STAT_TOP FPU_STAT.top | |
| #define FPU_STAT_PC FPU_STAT.pc | |
| #define FPU_STAT_RC FPU_STAT.rc | |
| #define FPU_ST(i) FPU_STAT.reg[((i) + FPU_STAT_TOP) & 7] | |
| #define FPU_REG(i) FPU_STAT.reg[i] | |
| /* FPU status register */ | |
| #define FP_IE_FLAG (1 << 0) /* 無効な動作 */ | |
| #define FP_DE_FLAG (1 << 1) /* デノーマライズド・オペランド */ | |
| #define FP_ZE_FLAG (1 << 2) /* ゼロによる除算 */ | |
| #define FP_OE_FLAG (1 << 3) /* オーバーフロー */ | |
| #define FP_UE_FLAG (1 << 4) /* アンダーフロー */ | |
| #define FP_PE_FLAG (1 << 5) /* 精度 */ | |
| #define FP_SF_FLAG (1 << 6) /* スタックフォルト */ | |
| #define FP_ES_FLAG (1 << 7) /* エラーサマリステータス */ | |
| #define FP_C0_FLAG (1 << 8) /* 条件コード */ | |
| #define FP_C1_FLAG (1 << 9) /* 条件コード */ | |
| #define FP_C2_FLAG (1 << 10) /* 条件コード */ | |
| #define FP_TOP_FLAG (7 << 11) /* スタックポイントのトップ */ | |
| #define FP_C3_FLAG (1 << 14) /* 条件コード */ | |
| #define FP_B_FLAG (1 << 15) /* FPU ビジー */ | |
| #define FP_TOP_SHIFT 11 | |
| #define FP_TOP_GET() ((FPU_STATUSWORD & FP_TOP_FLAG) >> FP_TOP_SHIFT) | |
| #define FP_TOP_SET(v) ((FPU_STATUSWORD & ~FP_TOP_FLAG) | ((v) << FP_TOP_SHIFT)) | |
| // ---- i286 | #define FPU_STAT_TOP_INC() \ |
| do { \ | |
| FPU_STAT.top = (FPU_STAT.top + 1) & 7; \ | |
| } while (/*CONSTCOND*/0) | |
| #define FPU_STAT_TOP_DEC() \ | |
| do { \ | |
| FPU_STAT.top = (FPU_STAT.top - 1) & 7; \ | |
| } while (/*CONSTCOND*/0) | |
| typedef struct { | /* FPU control register */ |
| SINT32 remainclock; | #define FP_CTRL_PC_SHIFT 8 /* 精度制御 */ |
| SINT32 baseclock; | #define FP_CTRL_RC_SHIFT 10 /* 丸め制御 */ |
| UINT32 clock; | |
| #define FP_CTRL_PC_24 0 /* 単精度 */ | |
| #define FP_CTRL_PC_53 1 /* 倍精度 */ | |
| #define FP_CTRL_PC_64 3 /* 拡張精度 */ | |
| #define FP_CTRL_RC_NEAREST_EVEN 0 | |
| #define FP_CTRL_RC_DOWN 1 | |
| #define FP_CTRL_RC_UP 2 | |
| #define FP_CTRL_RC_TO_ZERO 3 | |
| UINT32 adrsmask; // ? | |
| UINT32 inport; // ? | |
| UINT8 resetreq; | |
| UINT8 itfbank; | |
| } I386STAT; | |
| typedef struct { // for ver0.73 | /* |
| BYTE *ext; | * Misc. |
| UINT32 extsize; | */ |
| } I386EXT; | void memory_dump(int idx, UINT32 madr); |
| void gdtr_dump(UINT32 base, UINT limit); | |
| void idtr_dump(UINT32 base, UINT limit); | |
| void ldtr_dump(UINT32 base, UINT limit); | |
| void tr_dump(UINT16 selector, UINT32 base, UINT limit); | |
| UINT32 pde_dump(UINT32 base, int idx); | |
| UINT32 convert_laddr_to_paddr(UINT32 laddr); | |
| UINT32 convert_vaddr_to_paddr(unsigned int idx, UINT32 offset); | |
| /* | |
| * disasm | |
| */ | |
| /* context */ | |
| typedef struct { | typedef struct { |
| I386STAT s; // STATsaveされる奴 | UINT32 val; |
| I386EXT e; | |
| } I386CORE; | |
| extern I386CORE i386core; | UINT32 eip; |
| BOOL op32; | |
| BOOL as32; | |
| #define CPU_STATSAVE i386core.s | UINT32 baseaddr; |
| UINT8 opcode[3]; | |
| UINT8 modrm; | |
| UINT8 sib; | |
| #define CPU_REMCLOCK i386core.s.remainclock | BOOL useseg; |
| #define CPU_BASECLOCK i386core.s.baseclock | int seg; |
| #define CPU_CLOCK i386core.s.clock | |
| #define CPU_ADRSMASK i386core.s.adrsmask | |
| #define CPU_RESETREQ i386core.s.resetreq | |
| #define CPU_ITFBANK i386core.s.itfbank | |
| #define CPU_INPADRS i386core.s.inport | |
| #define CPU_EXTMEM i386core.e.ext | UINT8 opbyte[32]; |
| #define CPU_EXTMEMSIZE i386core.e.extsize | int nopbytes; |
| char str[256]; | |
| size_t remain; | |
| char *next; | |
| char *prefix; | |
| char *op; | |
| char *arg[3]; | |
| int narg; | |
| char pad; | |
| } disasm_context_t; | |
| int disasm(UINT32 *eip, disasm_context_t *ctx); | |
| #ifdef __cplusplus | #ifdef __cplusplus |
| } | } |
| #endif | #endif |
| #include "cpu_io.h" | |
| #include "cpu_mem.h" | |
| #include "exception.h" | |
| #include "paging.h" | |
| #include "resolve.h" | |
| #include "task.h" | |
| #endif /* !IA32_CPU_CPU_H__ */ | #endif /* !IA32_CPU_CPU_H__ */ |