--- np2/i286x/i286x.cpp 2003/12/01 10:45:46 1.4 +++ np2/i286x/i286x.cpp 2005/03/24 02:21:21 1.26 @@ -1,23 +1,26 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "i286x.h" #include "i286xadr.h" #include "i286xs.h" #include "i286xrep.h" #include "i286xcts.h" -#include "memory.h" #include "pccore.h" #include "iocore.h" #include "i286x.mcr" #include "i286xea.mcr" #include "v30patch.h" #include "bios.h" -#include "dmap.h" +#include "dmax86.h" +#if defined(ENABLE_TRAP) +#include "steptrap.h" +#include "inttrap.h" +#endif I286CORE i286core; -const BYTE iflags[256] = { // Z_FLAG, S_FLAG, P_FLAG +const UINT8 iflags[256] = { // Z_FLAG, S_FLAG, P_FLAG 0x44, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, @@ -52,18 +55,82 @@ const BYTE iflags[256] = { // Z_FLAG 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84}; -void i286_reset(void) { +void i286x_initialize(void) { - i286xadr_init(); // 毎回通すのはどうか… - v30init(); // 毎回通すのはどうか… - ZeroMemory(&i286core.s, sizeof(i286core.s)); - I286_CS = 0x1fc0; - CS_BASE = 0x1fc00; + i286xadr_init(); + v30xinit(); +} + +void i286x_deinitialize(void) { + + if (CPU_EXTMEM) { + _MFREE(CPU_EXTMEM); + CPU_EXTMEM = NULL; + CPU_EXTMEMSIZE = 0; + } +} + +static void i286x_initreg(void) { + + I286_CS = 0xf000; + CS_BASE = 0xf0000; + I286_IP = 0xfff0; i286core.s.adrsmask = 0xfffff; + i286x_resetprefetch(); } +void i286x_reset(void) { -LABEL void i286_resetprefetch(void) { + ZeroMemory(&i286core.s, sizeof(i286core.s)); + i286x_initreg(); +} + +void i286x_shut(void) { + + ZeroMemory(&i286core.s, offsetof(I286STAT, cpu_type)); + i286x_initreg(); +} + +void i286x_setextsize(UINT32 size) { + + if (CPU_EXTMEMSIZE != size) { + if (CPU_EXTMEM) { + _MFREE(CPU_EXTMEM); + CPU_EXTMEM = NULL; + } + if (size) { + CPU_EXTMEM = (UINT8 *)_MALLOC(size + 16, "EXTMEM"); + if (CPU_EXTMEM == NULL) { + size = 0; + } + } + CPU_EXTMEMSIZE = size; + } + i286core.e.ems[0] = mem + 0xc0000; + i286core.e.ems[1] = mem + 0xc4000; + i286core.e.ems[2] = mem + 0xc8000; + i286core.e.ems[3] = mem + 0xcc000; +} + +void i286x_setemm(UINT frame, UINT32 addr) { + + UINT8 *ptr; + + frame &= 3; + if (addr < USE_HIMEM) { + ptr = mem + addr; + } + else if ((addr - 0x100000 + 0x4000) <= CPU_EXTMEMSIZE) { + ptr = CPU_EXTMEM + (addr - 0x100000); + } + else { + ptr = mem + 0xc0000 + (frame << 14); + } + i286core.e.ems[frame] = ptr; +} + + +LABEL void i286x_resetprefetch(void) { __asm { pushad @@ -75,7 +142,7 @@ LABEL void i286_resetprefetch(void) { } } -LABEL void __fastcall i286_interrupt(BYTE vect) { +LABEL void __fastcall i286x_interrupt(UINT8 vect) { __asm { pushad @@ -164,8 +231,32 @@ LABEL void __fastcall i286x_localint(voi } +// プロテクトモードのセレクタ(in ax / ret eax) +LABEL void __fastcall i286x_selector(void) { + + __asm { + mov ecx, dword ptr (I286_GDTR.base) + test eax, 4 + je short ixsl_1 + mov ecx, dword ptr (I286_LDTRC.base) +ixsl_1: and eax, not 7 + and ecx, 0ffffffh + lea ecx, [ecx + eax + 2] + call i286_memoryread_w + push eax + add ecx, 2 + call i286_memoryread + pop ecx + and eax, 0ffh + movzx ecx, cx + shl eax, 16 + add eax, ecx + ret + } +} + -LABEL void i286(void) { +LABEL void i286x(void) { __asm { pushad @@ -177,7 +268,13 @@ LABEL void i286(void) { cmp dmac.working, 0 jne short i286_dma_mnlp -i286_mnlp: movzx eax, bl +i286_mnlp: +#if defined(ENABLE_TRAP) + mov edx, esi + movzx ecx, I286_CS + call steptrap +#endif + movzx eax, bl call i286op[eax*4] cmp I286_REMCLOCK, 0 jg i286_mnlp @@ -187,9 +284,15 @@ i286_mnlp: movzx eax, bl ret align 16 -i286_dma_mnlp: movzx eax, bl +i286_dma_mnlp: +#if defined(ENABLE_TRAP) + mov edx, esi + movzx ecx, I286_CS + call steptrap +#endif + movzx eax, bl call i286op[eax*4] - call dmap_i286 + call dmax86 cmp I286_REMCLOCK, 0 jg i286_dma_mnlp mov dword ptr (i286core.s.prefetchque), ebx @@ -198,7 +301,13 @@ i286_dma_mnlp: movzx eax, bl ret align 16 -i286_trapping: movzx eax, bl +i286_trapping: +#if defined(ENABLE_TRAP) + mov edx, esi + movzx ecx, I286_CS + call steptrap +#endif + movzx eax, bl call i286op[eax*4] cmp I286_TRAP, 0 je i286notrap @@ -213,7 +322,7 @@ i286notrap: mov dword ptr (i286core.s. -LABEL void i286_step(void) { +LABEL void i286x_step(void) { __asm { pushad @@ -231,7 +340,7 @@ nexts: mov dword ptr (i286core.s.prefetchque), ebx mov I286_IP, si - call dmap_i286 + call dmax86 popad ret } @@ -256,7 +365,7 @@ LABEL void removeprefix(void) { I286 _reserved(void) { __asm { - inc si // 01/08/31 +// inc si // 01/08/31 INT_NUM(6) } } @@ -360,11 +469,16 @@ I286 pop_es(void) { // 07: pop es __asm { I286CLOCK(5) REGPOP(I286_ES) - and eax, 00ffffh + movzx eax, ax + test byte ptr (I286_MSW), MSW_PE + jne short pop_es_pe shl eax, 4 // make segreg - mov ES_BASE, eax +pop_es_base: mov ES_BASE, eax GET_NEXTPRE1 ret + +pop_es_pe: push offset pop_es_base + jmp i286x_selector } } @@ -568,18 +682,25 @@ I286 pop_ss(void) { // 17: pop ss __asm { I286CLOCK(5) REGPOP(I286_SS) - and eax, 00ffffh + movzx eax, ax + test byte ptr (I286_MSW), MSW_PE + jne short pop_ss_pe shl eax, 4 // make segreg - mov SS_BASE, eax +pop_ss_base: mov SS_BASE, eax mov SS_FIX, eax cmp i286core.s.prefix, 0 // 00/06/24 - je noprefix - call removeprefix - pop eax + jne prefix_exist noprefix: movzx ebp, bh GET_NEXTPRE1 jmp i286op[ebp*4] + +pop_ss_pe: push offset pop_ss_base + jmp i286x_selector + +prefix_exist: pop eax // eax<-offset removeprefix + call eax + jmp noprefix } } @@ -690,12 +811,17 @@ I286 pop_ds(void) { // 1F: pop ds __asm { I286CLOCK(5) REGPOP(I286_DS) - and eax, 00ffffh + movzx eax, ax + test byte ptr (I286_MSW), MSW_PE + jne short pop_ds_pe shl eax, 4 // make segreg - mov DS_BASE, eax +pop_ds_base: mov DS_BASE, eax mov DS_FIX, eax GET_NEXTPRE1 ret + +pop_ds_pe: push offset pop_ds_base + jmp i286x_selector } } @@ -1591,7 +1717,7 @@ I286 _arpl(void) { xor eax, eax cmp bh, 0c0h setc al - add si, ax + // add si, ax add eax, 10 I286CLOCK(eax) INT_NUM(6) @@ -1672,13 +1798,8 @@ I286 _insb(void) { // 6C: insb __asm { GET_NEXTPRE1 I286CLOCK(5) -#if 1 movzx ecx, I286_DX call iocore_inp8 -#else - mov cx, I286_DX - call i286_in -#endif mov dl, al movzx ecx, I286_ES shl ecx, 4 @@ -1719,13 +1840,8 @@ I286 _outsb(void) { // 6E: outsb mov dl, al STRING_DIR add I286_SI, ax -#if 1 movzx ecx, I286_DX jmp iocore_out8 -#else - mov cx, I286_DX - jmp i286_out -#endif } } @@ -2291,7 +2407,7 @@ I286 mov_ea_r8(void) { // 88: mov __asm { PREPART_EA_REG8(2) mov I286_REG[eax], dl - GET_NEXTPRE2 // ea_regの regregだけ + GET_NEXTPRE1 // ea_regの regregだけ ret align 16 memory_eareg8: @@ -2396,23 +2512,24 @@ I286 mov_seg_ea(void) { // 8E: mov GET_NEXTPRE2 mov ax, word ptr I286_REG[edi*2] jmp segset - align 16 + align 4 src_memory: I286CLOCK(5) call p_ea_dst[eax*4] call i286_memoryread_w segset: mov word ptr I286_SEGREG[ebp], ax - and eax, 0000ffffh + movzx eax, ax + test byte ptr (I286_MSW), MSW_PE + jne short mov_seg_pe shl eax, 4 // make segreg - mov SEG_BASE[ebp*2], eax +mov_seg_base: mov SEG_BASE[ebp*2], eax sub ebp, 2*2 - jc segsetr + jc short segsetr mov SS_FIX[ebp*2], eax - je setss + je short setss segsetr:ret - align 16 setss: cmp i286core.s.prefix, 0 // 00/05/13 je noprefix pop eax @@ -2421,9 +2538,10 @@ I286 mov_seg_ea(void) { // 8E: mov movzx eax, bl jmp i286op[eax*4] - align 16 - fixcs: - INT_NUM(6) +mov_seg_pe: push offset mov_seg_base + jmp i286x_selector + + fixcs: INT_NUM(6) } } @@ -2618,10 +2736,17 @@ I286 call_far(void) { // 9A: call mov si, bx shr ebx, 16 mov I286_CS, bx + test byte ptr (I286_MSW), MSW_PE + jne short call_far_pe shl ebx, 4 mov CS_BASE, ebx - RESET_XPREFETCH +call_far_base: RESET_XPREFETCH ret + +call_far_pe: mov eax, ebx + call i286x_selector + mov CS_BASE, eax + jmp short call_far_base } } @@ -2661,7 +2786,20 @@ I286 _popf(void) { // 9D: popf and ah, 3 cmp ah, 3 sete I286_TRAP - I286IRQCHECKTERM + + je irqcheck // fast_intr + test ah, 2 + je nextop + mov al, pic.pi[0 * (type _PICITEM)].imr + mov ah, pic.pi[1 * (type _PICITEM)].imr + not ax + test al, pic.pi[0 * (type _PICITEM)].irr + jne irqcheck + test ah, pic.pi[1 * (type _PICITEM)].irr + jne irqcheck +nextop: ret + +irqcheck: I286IRQCHECKTERM } } @@ -2758,10 +2896,8 @@ I286 _movsb(void) { // A4: movsb add ecx, DS_FIX call i286_memoryread mov dl, al - movzx ecx, I286_ES - shl ecx, 4 - movzx eax, I286_DI - add ecx, eax + movzx ecx, I286_DI + add ecx, ES_BASE STRING_DIR add I286_SI, ax add I286_DI, ax @@ -2778,10 +2914,8 @@ I286 _movsw(void) { // A5: movsw add ecx, DS_FIX call i286_memoryread_w mov dx, ax - movzx ecx, I286_ES - shl ecx, 4 - movzx eax, I286_DI - add ecx, eax + movzx ecx, I286_DI + add ecx, ES_BASE STRING_DIRx2 add I286_SI, ax add I286_DI, ax @@ -2798,10 +2932,8 @@ I286 _cmpsb(void) { // A6: cmpsb add ecx, DS_FIX call i286_memoryread mov dl, al - movzx ecx, I286_ES - shl ecx, 4 - movzx eax, I286_DI - add ecx, eax + movzx ecx, I286_DI + add ecx, ES_BASE call i286_memoryread cmp dl, al FLAG_STORE_OF @@ -2821,10 +2953,8 @@ I286 _cmpsw(void) { // A7: cmpsw add ecx, DS_FIX call i286_memoryread_w mov edx, eax - movzx ecx, I286_ES - shl ecx, 4 - movzx eax, I286_DI - add ecx, eax + movzx ecx, I286_DI + add ecx, ES_BASE call i286_memoryread_w cmp dx, ax FLAG_STORE_OF @@ -2863,10 +2993,8 @@ I286 _stosb(void) { // AA: stosb __asm { GET_NEXTPRE1 I286CLOCK(3) - movzx ecx, I286_ES - shl ecx, 4 - movzx eax, I286_DI - add ecx, eax + movzx ecx, I286_DI + add ecx, ES_BASE STRING_DIR add I286_DI, ax mov dl, I286_AL @@ -2879,10 +3007,8 @@ I286 _stosw(void) { // AB: stosw __asm { GET_NEXTPRE1 I286CLOCK(3) - movzx ecx, I286_ES - shl ecx, 4 - movzx eax, I286_DI - add ecx, eax + movzx ecx, I286_DI + add ecx, ES_BASE STRING_DIRx2 add I286_DI, ax mov dx, I286_AX @@ -2925,10 +3051,8 @@ I286 _scasb(void) { // AE: scasb __asm { GET_NEXTPRE1 I286CLOCK(7) - movzx ecx, I286_ES - shl ecx, 4 - movzx eax, I286_DI - add ecx, eax + movzx ecx, I286_DI + add ecx, ES_BASE call i286_memoryread cmp I286_AL, al FLAG_STORE_OF @@ -2943,10 +3067,8 @@ I286 _scasw(void) { // AF: scasw __asm { GET_NEXTPRE1 I286CLOCK(7) - movzx ecx, I286_ES - shl ecx, 4 - movzx eax, I286_DI - add ecx, eax + movzx ecx, I286_DI + add ecx, ES_BASE call i286_memoryread_w cmp I286_AX, ax FLAG_STORE_OF @@ -3270,13 +3392,17 @@ I286 les_r16_ea(void) { // C4: les lea ecx, [edi + ebp] call i286_memoryread_w mov I286_ES, ax - and eax, 0000ffffh + movzx eax, ax + test byte ptr (I286_MSW), MSW_PE + jne short les_pe shl eax, 4 // make segreg - mov ES_BASE, eax +les_base: mov ES_BASE, eax ret - align 16 - src_register: - INT_NUM(6) + +les_pe: push offset les_base + jmp i286x_selector + +src_register: INT_NUM(6) } } @@ -3299,14 +3425,19 @@ I286 lds_r16_ea(void) { // C5: lds lea ecx, [edi + ebp] call i286_memoryread_w mov I286_DS, ax - and eax, 0000ffffh + movzx eax, ax + test byte ptr (I286_MSW), MSW_PE + jne short lds_pe shl eax, 4 // make segreg - mov DS_BASE, eax +lds_base: mov DS_BASE, eax mov DS_FIX, eax ret - align 16 - src_register: - INT_NUM(6) + +lds_pe: push offset lds_base + jmp i286x_selector + +src_register: INT_NUM(6) + } } @@ -3378,7 +3509,7 @@ I286 _enter(void) { // C8: enter je enter0 dec eax je enter1 - lea ecx, [eax*4 + 12] + lea ecx, [eax*4 + 12 + 4] I286CLOCK(ecx) push ebx movzx ebx, I286_BP @@ -3458,12 +3589,17 @@ I286 ret_far_data16(void) { // CA: lea ecx, [edi + ebp] call i286_memoryread_w mov I286_CS, ax - and eax, 0000ffffh + movzx eax, ax + test byte ptr (I286_MSW), MSW_PE + jne short ret_far16_pe shl eax, 4 // make segreg - mov CS_BASE, eax +ret_far16_base: mov CS_BASE, eax add I286_SP, 4 RESET_XPREFETCH ret + +ret_far16_pe: push offset ret_far16_base + jmp i286x_selector } } @@ -3481,13 +3617,18 @@ I286 ret_far(void) { // CB: ret fa add bx, 2 call i286_memoryread_w mov I286_CS, ax - and eax, 0000ffffh + movzx eax, ax + test byte ptr (I286_MSW), MSW_PE + jne short ret_far_pe shl eax, 4 // make segreg - mov CS_BASE, eax +ret_far_base: mov CS_BASE, eax mov ebp, eax mov I286_SP, bx RESET_XPREFETCH ret + +ret_far_pe: push offset ret_far_base + jmp i286x_selector } } @@ -3516,6 +3657,13 @@ I286 int_data8(void) { // CD: int lea ecx, [edi + ebp] mov dx, I286_CS call i286_memorywrite_w +#if defined(ENABLE_TRAP) + movzx eax, bh + push eax + lea edx, [esi - 1] + movzx ecx, I286_CS + call softinttrap +#endif movzx eax, bh sub bp, 2 mov I286_SP, bp @@ -3535,14 +3683,13 @@ I286 int_data8(void) { // CD: int I286 _into(void) { // CE: into __asm { + I286CLOCK(4) test I286_FLAG, O_FLAG jne intovf - I286CLOCK(4) GET_NEXTPRE1 ret - align 16 - intovf: - I286CLOCK(24) + + intovf: inc si // ver0.80 INT_NUM(4) } } @@ -3550,7 +3697,6 @@ I286 _into(void) { // CE: into I286 _iret(void) { // CF: iret __asm { - call extirq_pop I286CLOCK(31) mov edi, SS_BASE movzx ebx, I286_SP @@ -3575,7 +3721,21 @@ I286 _iret(void) { // CF: iret cmp ah, 3 sete I286_TRAP RESET_XPREFETCH - I286IRQCHECKTERM + + cmp I286_TRAP, 0 // fast_intr + jne irqcheck + test I286_FLAG, I_FLAG + je nextop + mov al, pic.pi[0 * (type _PICITEM)].imr + mov ah, pic.pi[1 * (type _PICITEM)].imr + not ax + test al, pic.pi[0 * (type _PICITEM)].irr + jne irqcheck + test ah, pic.pi[1 * (type _PICITEM)].irr + jne irqcheck +nextop: ret + +irqcheck: I286IRQCHECKTERM } } @@ -3744,9 +3904,8 @@ nzflagsed: xor al, ah or I286_FLAGL, al GET_NEXTPRE2 ret - align 16 - div0: - INT_NUM(0) + + div0: INT_NUM(0) } } @@ -3890,15 +4049,11 @@ I286 in_al_data8(void) { // E4: in I286CLOCK(5) lea eax, [esi + 2] add eax, CS_BASE - mov i286core.s.inport, eax + mov I286_INPADRS, eax movzx ecx, bh -#if 1 call iocore_inp8 -#else - call i286_in -#endif mov I286_AL, al - mov i286core.s.inport, 0 + mov I286_INPADRS, 0 GET_NEXTPRE2 ret } @@ -3927,12 +4082,8 @@ I286 out_data8_al(void) { // E6: ou GET_NEXTPRE2 pop ecx mov dl, I286_AL -#if 1 jmp iocore_out8 -#else - jmp i286_out -#endif - } + } } I286 out_data8_ax(void) { // E7: out DATA8, ax @@ -3984,10 +4135,17 @@ I286 jmp_far(void) { // EA: jmp fa mov si, bx shr ebx, 16 mov I286_CS, bx + test byte ptr (I286_MSW), MSW_PE + jne short jmp_far_pe shl ebx, 4 // make segreg mov CS_BASE, ebx - RESET_XPREFETCH +jmp_far_base: RESET_XPREFETCH ret + +jmp_far_pe: mov eax, ebx + call i286x_selector + mov CS_BASE, eax + jmp short jmp_far_base } } @@ -4007,13 +4165,8 @@ I286 in_al_dx(void) { // EC: in al __asm { I286CLOCK(5) -#if 1 movzx ecx, I286_DX call iocore_inp8 -#else - mov cx, I286_DX - call i286_in -#endif mov I286_AL, al GET_NEXTPRE1 ret @@ -4037,15 +4190,9 @@ I286 out_dx_al(void) { // EE: out __asm { GET_NEXTPRE1 I286CLOCK(3) -#if 1 movzx ecx, I286_DX mov dl, I286_AL jmp iocore_out8 -#else - mov cx, I286_DX - mov dl, I286_AL - jmp i286_out -#endif } } @@ -4158,14 +4305,26 @@ I286 _sti(void) { // FB: sti __asm { GET_NEXTPRE1 I286CLOCK(2) - or I286_FLAG, I_FLAG + cmp i286core.s.prefix, 0 // ver0.26 00/10/08 + jne prefix_exist // 前方分岐ジャンプなので。 + noprefix: + movzx ebp, bl + bts I286_FLAG, 9 + jne jmp_nextop test I286_FLAG, T_FLAG setne I286_TRAP - cmp i286core.s.prefix, 0 // ver0.26 00/10/08 - jne prefix_exist // 前方分岐ジャンプなので。 -noprefix: movzx eax, bl - call i286op[eax*4] + jne nextopandexit // fast_intr + mov al, pic.pi[0 * (type _PICITEM)].imr + mov ah, pic.pi[1 * (type _PICITEM)].imr + not ax + test al, pic.pi[0 * (type _PICITEM)].irr + jne nextopandexit + test ah, pic.pi[1 * (type _PICITEM)].irr + jne nextopandexit +jmp_nextop: jmp i286op[ebp*4] + +nextopandexit: call i286op[ebp*4] I286IRQCHECKTERM prefix_exist: pop eax // eax<-offset removeprefix @@ -4219,7 +4378,7 @@ I286 _ope0xff(void) { // FF: // ------------------------------------------------------------------------- -void (*i286op[])(void) = { +const I286TBL i286op[256] = { add_ea_r8, // 00: add EA, REG8 add_ea_r16, // 01: add EA, REG16 add_r8_ea, // 02: add REG8, EA @@ -4543,7 +4702,7 @@ I286 repe_segprefix_ds(void) { } } -void (*i286op_repe[])(void) = { +const I286TBL i286op_repe[256] = { add_ea_r8, // 00: add EA, REG8 add_ea_r16, // 01: add EA, REG16 add_r8_ea, // 02: add REG8, EA @@ -4867,7 +5026,7 @@ I286 repne_segprefix_ds(void) { } } -void (*i286op_repne[])(void) = { +const I286TBL i286op_repne[256] = { add_ea_r8, // 00: add EA, REG8 add_ea_r16, // 01: add EA, REG16 add_r8_ea, // 02: add REG8, EA