From 8da3b4f1ef8bc374ef62c6b5e8390f71bd3777c6 Mon Sep 17 00:00:00 2001 From: cracyc Date: Mon, 27 Oct 2014 17:10:48 -0500 Subject: i386: zero descriptors and stack size (nw) --- src/emu/cpu/i386/i386.c | 21 ++++++- src/emu/cpu/i386/i386op16.inc | 136 +++++++++++++++++++++++++++++++----------- src/emu/cpu/i386/i386op32.inc | 136 +++++++++++++++++++++++++++++++----------- 3 files changed, 223 insertions(+), 70 deletions(-) diff --git a/src/emu/cpu/i386/i386.c b/src/emu/cpu/i386/i386.c index bbd83a7aa93..5b66594f22b 100644 --- a/src/emu/cpu/i386/i386.c +++ b/src/emu/cpu/i386/i386.c @@ -125,6 +125,16 @@ UINT32 i386_device::i386_load_protected_mode_segment(I386_SREG *seg, UINT64 *des UINT32 base, limit; int entry; + if(!seg->selector) + { + seg->flags = 0; + seg->base = 0; + seg->limit = 0; + seg->d = 0; + seg->valid = false; + return 0; + } + if ( seg->selector & 0x4 ) { base = m_ldtr.base; @@ -147,7 +157,7 @@ UINT32 i386_device::i386_load_protected_mode_segment(I386_SREG *seg, UINT64 *des if (seg->flags & 0x8000) seg->limit = (seg->limit << 12) | 0xfff; seg->d = (seg->flags & 0x4000) ? 1 : 0; - seg->valid = (seg->selector & ~3)?(true):(false); + seg->valid = true; if(desc) *desc = ((UINT64)v2<<32)|v1; @@ -212,7 +222,8 @@ void i386_device::i386_load_segment_descriptor(int segment ) if (!V8086_MODE) { i386_load_protected_mode_segment(&m_sreg[segment], NULL ); - i386_set_descriptor_accessed(m_sreg[segment].selector); + if(m_sreg[segment].selector) + i386_set_descriptor_accessed(m_sreg[segment].selector); } else { @@ -3132,26 +3143,32 @@ void i386_device::i386_common_init(int tlbsize) save_item(NAME(m_sreg[ES].base)); save_item(NAME(m_sreg[ES].limit)); save_item(NAME(m_sreg[ES].flags)); + save_item(NAME(m_sreg[ES].d)); save_item(NAME(m_sreg[CS].selector)); save_item(NAME(m_sreg[CS].base)); save_item(NAME(m_sreg[CS].limit)); save_item(NAME(m_sreg[CS].flags)); + save_item(NAME(m_sreg[CS].d)); save_item(NAME(m_sreg[SS].selector)); save_item(NAME(m_sreg[SS].base)); save_item(NAME(m_sreg[SS].limit)); save_item(NAME(m_sreg[SS].flags)); + save_item(NAME(m_sreg[SS].d)); save_item(NAME(m_sreg[DS].selector)); save_item(NAME(m_sreg[DS].base)); save_item(NAME(m_sreg[DS].limit)); save_item(NAME(m_sreg[DS].flags)); + save_item(NAME(m_sreg[DS].d)); save_item(NAME(m_sreg[FS].selector)); save_item(NAME(m_sreg[FS].base)); save_item(NAME(m_sreg[FS].limit)); save_item(NAME(m_sreg[FS].flags)); + save_item(NAME(m_sreg[FS].d)); save_item(NAME(m_sreg[GS].selector)); save_item(NAME(m_sreg[GS].base)); save_item(NAME(m_sreg[GS].limit)); save_item(NAME(m_sreg[GS].flags)); + save_item(NAME(m_sreg[GS].d)); save_item(NAME(m_eip)); save_item(NAME(m_prev_eip)); save_item(NAME(m_CF)); diff --git a/src/emu/cpu/i386/i386op16.inc b/src/emu/cpu/i386/i386op16.inc index 07e704128bd..7c327d12621 100644 --- a/src/emu/cpu/i386/i386op16.inc +++ b/src/emu/cpu/i386/i386op16.inc @@ -1746,8 +1746,12 @@ void i386_device::i386_popf() // Opcode 0x9d void i386_device::i386_push_ax() // Opcode 0x50 { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-2) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 2; + else + offset = (REG16(SP) - 2) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH16(REG16(AX) ); else FAULT(FAULT_SS,0) @@ -1756,8 +1760,12 @@ void i386_device::i386_push_ax() // Opcode 0x50 void i386_device::i386_push_cx() // Opcode 0x51 { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-2) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 2; + else + offset = (REG16(SP) - 2) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH16(REG16(CX) ); else FAULT(FAULT_SS,0) @@ -1766,8 +1774,12 @@ void i386_device::i386_push_cx() // Opcode 0x51 void i386_device::i386_push_dx() // Opcode 0x52 { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-2) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 2; + else + offset = (REG16(SP) - 2) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH16(REG16(DX) ); else FAULT(FAULT_SS,0) @@ -1776,8 +1788,12 @@ void i386_device::i386_push_dx() // Opcode 0x52 void i386_device::i386_push_bx() // Opcode 0x53 { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-2) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 2; + else + offset = (REG16(SP) - 2) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH16(REG16(BX) ); else FAULT(FAULT_SS,0) @@ -1786,8 +1802,12 @@ void i386_device::i386_push_bx() // Opcode 0x53 void i386_device::i386_push_sp() // Opcode 0x54 { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-2) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 2; + else + offset = (REG16(SP) - 2) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH16(REG16(SP) ); else FAULT(FAULT_SS,0) @@ -1796,8 +1816,12 @@ void i386_device::i386_push_sp() // Opcode 0x54 void i386_device::i386_push_bp() // Opcode 0x55 { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-2) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 2; + else + offset = (REG16(SP) - 2) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH16(REG16(BP) ); else FAULT(FAULT_SS,0) @@ -1806,8 +1830,12 @@ void i386_device::i386_push_bp() // Opcode 0x55 void i386_device::i386_push_si() // Opcode 0x56 { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-2) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 2; + else + offset = (REG16(SP) - 2) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH16(REG16(SI) ); else FAULT(FAULT_SS,0) @@ -1816,8 +1844,12 @@ void i386_device::i386_push_si() // Opcode 0x56 void i386_device::i386_push_di() // Opcode 0x57 { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-2) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 2; + else + offset = (REG16(SP) - 2) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH16(REG16(DI) ); else FAULT(FAULT_SS,0) @@ -1826,8 +1858,12 @@ void i386_device::i386_push_di() // Opcode 0x57 void i386_device::i386_push_cs16() // Opcode 0x0e { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-2) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 2; + else + offset = (REG16(SP) - 2) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH16(m_sreg[CS].selector ); else FAULT(FAULT_SS,0) @@ -1836,8 +1872,12 @@ void i386_device::i386_push_cs16() // Opcode 0x0e void i386_device::i386_push_ds16() // Opcode 0x1e { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-2) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 2; + else + offset = (REG16(SP) - 2) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH16(m_sreg[DS].selector ); else FAULT(FAULT_SS,0) @@ -1846,8 +1886,12 @@ void i386_device::i386_push_ds16() // Opcode 0x1e void i386_device::i386_push_es16() // Opcode 0x06 { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-2) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 2; + else + offset = (REG16(SP) - 2) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH16(m_sreg[ES].selector ); else FAULT(FAULT_SS,0) @@ -1856,8 +1900,12 @@ void i386_device::i386_push_es16() // Opcode 0x06 void i386_device::i386_push_fs16() // Opcode 0x0f a0 { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-2) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 2; + else + offset = (REG16(SP) - 2) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH16(m_sreg[FS].selector ); else FAULT(FAULT_SS,0) @@ -1866,8 +1914,12 @@ void i386_device::i386_push_fs16() // Opcode 0x0f a0 void i386_device::i386_push_gs16() // Opcode 0x0f a8 { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-2) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 2; + else + offset = (REG16(SP) - 2) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH16(m_sreg[GS].selector ); else FAULT(FAULT_SS,0) @@ -1876,8 +1928,12 @@ void i386_device::i386_push_gs16() // Opcode 0x0f a8 void i386_device::i386_push_ss16() // Opcode 0x16 { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-2) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 2; + else + offset = (REG16(SP) - 2) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH16(m_sreg[SS].selector ); else FAULT(FAULT_SS,0) @@ -1887,8 +1943,12 @@ void i386_device::i386_push_ss16() // Opcode 0x16 void i386_device::i386_push_i16() // Opcode 0x68 { UINT16 value = FETCH16(); - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-2) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 2; + else + offset = (REG16(SP) - 2) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH16(value); else FAULT(FAULT_SS,0) @@ -1898,8 +1958,12 @@ void i386_device::i386_push_i16() // Opcode 0x68 void i386_device::i386_pusha() // Opcode 0x60 { UINT16 temp = REG16(SP); - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-16) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 16; + else + offset = (REG16(SP) - 16) & 0xffff; + if(i386_limit_check(SS,offset) == 0) { PUSH16(REG16(AX) ); PUSH16(REG16(CX) ); @@ -1917,8 +1981,12 @@ void i386_device::i386_pusha() // Opcode 0x60 void i386_device::i386_pushf() // Opcode 0x9c { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-2) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 2; + else + offset = (REG16(SP) - 2) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH16(get_flags() & 0xffff ); else FAULT(FAULT_SS,0) diff --git a/src/emu/cpu/i386/i386op32.inc b/src/emu/cpu/i386/i386op32.inc index bca0ffa301a..18b4ab46f20 100644 --- a/src/emu/cpu/i386/i386op32.inc +++ b/src/emu/cpu/i386/i386op32.inc @@ -1599,8 +1599,12 @@ void i386_device::i386_popfd() // Opcode 0x9d void i386_device::i386_push_eax() // Opcode 0x50 { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-4) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 4; + else + offset = (REG16(SP) - 4) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH32(REG32(EAX) ); else FAULT(FAULT_SS,0) @@ -1609,8 +1613,12 @@ void i386_device::i386_push_eax() // Opcode 0x50 void i386_device::i386_push_ecx() // Opcode 0x51 { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-4) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 4; + else + offset = (REG16(SP) - 4) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH32(REG32(ECX) ); else FAULT(FAULT_SS,0) @@ -1619,8 +1627,12 @@ void i386_device::i386_push_ecx() // Opcode 0x51 void i386_device::i386_push_edx() // Opcode 0x52 { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-4) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 4; + else + offset = (REG16(SP) - 4) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH32(REG32(EDX) ); else FAULT(FAULT_SS,0) @@ -1629,8 +1641,12 @@ void i386_device::i386_push_edx() // Opcode 0x52 void i386_device::i386_push_ebx() // Opcode 0x53 { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-4) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 4; + else + offset = (REG16(SP) - 4) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH32(REG32(EBX) ); else FAULT(FAULT_SS,0) @@ -1639,8 +1655,12 @@ void i386_device::i386_push_ebx() // Opcode 0x53 void i386_device::i386_push_esp() // Opcode 0x54 { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-4) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 4; + else + offset = (REG16(SP) - 4) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH32(REG32(ESP) ); else FAULT(FAULT_SS,0) @@ -1649,8 +1669,12 @@ void i386_device::i386_push_esp() // Opcode 0x54 void i386_device::i386_push_ebp() // Opcode 0x55 { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-4) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 4; + else + offset = (REG16(SP) - 4) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH32(REG32(EBP) ); else FAULT(FAULT_SS,0) @@ -1659,8 +1683,12 @@ void i386_device::i386_push_ebp() // Opcode 0x55 void i386_device::i386_push_esi() // Opcode 0x56 { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-4) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 4; + else + offset = (REG16(SP) - 4) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH32(REG32(ESI) ); else FAULT(FAULT_SS,0) @@ -1669,8 +1697,12 @@ void i386_device::i386_push_esi() // Opcode 0x56 void i386_device::i386_push_edi() // Opcode 0x57 { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-4) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 4; + else + offset = (REG16(SP) - 4) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH32(REG32(EDI) ); else FAULT(FAULT_SS,0) @@ -1679,8 +1711,12 @@ void i386_device::i386_push_edi() // Opcode 0x57 void i386_device::i386_push_cs32() // Opcode 0x0e { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-4) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 4; + else + offset = (REG16(SP) - 4) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH32(m_sreg[CS].selector ); else FAULT(FAULT_SS,0) @@ -1689,8 +1725,12 @@ void i386_device::i386_push_cs32() // Opcode 0x0e void i386_device::i386_push_ds32() // Opcode 0x1e { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-4) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 4; + else + offset = (REG16(SP) - 4) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH32(m_sreg[DS].selector ); else FAULT(FAULT_SS,0) @@ -1699,8 +1739,12 @@ void i386_device::i386_push_ds32() // Opcode 0x1e void i386_device::i386_push_es32() // Opcode 0x06 { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-4) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 4; + else + offset = (REG16(SP) - 4) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH32(m_sreg[ES].selector ); else FAULT(FAULT_SS,0) @@ -1709,8 +1753,12 @@ void i386_device::i386_push_es32() // Opcode 0x06 void i386_device::i386_push_fs32() // Opcode 0x0f a0 { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-4) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 4; + else + offset = (REG16(SP) - 4) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH32(m_sreg[FS].selector ); else FAULT(FAULT_SS,0) @@ -1719,8 +1767,12 @@ void i386_device::i386_push_fs32() // Opcode 0x0f a0 void i386_device::i386_push_gs32() // Opcode 0x0f a8 { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-4) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 4; + else + offset = (REG16(SP) - 4) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH32(m_sreg[GS].selector ); else FAULT(FAULT_SS,0) @@ -1729,8 +1781,12 @@ void i386_device::i386_push_gs32() // Opcode 0x0f a8 void i386_device::i386_push_ss32() // Opcode 0x16 { - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-4) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 4; + else + offset = (REG16(SP) - 4) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH32(m_sreg[SS].selector ); else FAULT(FAULT_SS,0) @@ -1740,8 +1796,12 @@ void i386_device::i386_push_ss32() // Opcode 0x16 void i386_device::i386_push_i32() // Opcode 0x68 { UINT32 value = FETCH32(); - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-4) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 4; + else + offset = (REG16(SP) - 4) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH32(value); else FAULT(FAULT_SS,0) @@ -1751,8 +1811,12 @@ void i386_device::i386_push_i32() // Opcode 0x68 void i386_device::i386_pushad() // Opcode 0x60 { UINT32 temp = REG32(ESP); - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-32) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 32; + else + offset = (REG16(SP) - 32) & 0xffff; + if(i386_limit_check(SS,offset) == 0) { PUSH32(REG32(EAX) ); PUSH32(REG32(ECX) ); @@ -1772,8 +1836,12 @@ void i386_device::i386_pushfd() // Opcode 0x9c { if(!m_IOP1 && !m_IOP2 && V8086_MODE) FAULT(FAULT_GP,0) - UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset-4) == 0) + UINT32 offset; + if(STACK_32BIT) + offset = REG32(ESP) - 4; + else + offset = (REG16(SP) - 4) & 0xffff; + if(i386_limit_check(SS,offset) == 0) PUSH32(get_flags() & 0x00fcffff ); else FAULT(FAULT_SS,0) -- cgit v1.2.3