OSDN Git Service

[VM][PC9801][FMR50][FMR30][SASI_BIOS] Add translate_address(segment,offset) to DEVICE:: .
authorK.Ohta <whatisthis.sowhat@gmail.com>
Tue, 2 Apr 2019 16:30:57 +0000 (01:30 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Tue, 2 Apr 2019 16:30:57 +0000 (01:30 +0900)
[VM][I386][WIP] Effects trap on EMM386.EXE, but not working ;_;

15 files changed:
source/src/vm/common_vm/CMakeLists.txt
source/src/vm/device.h
source/src/vm/i286.cpp
source/src/vm/i286.h
source/src/vm/i386.cpp
source/src/vm/i386.h
source/src/vm/jx/i286.cpp
source/src/vm/jx/i286.h
source/src/vm/libcpu_newdev/device.h
source/src/vm/mame/emu/cpu/i386/i386.c
source/src/vm/mame/emu/cpu/i386/i386op16.c
source/src/vm/mame/emu/cpu/i386/i386ops.c
source/src/vm/mame/emu/cpu/i386/i386priv.h
source/src/vm/pc9801/membus.cpp
source/src/vm/pc9801/sasi_bios.cpp

index 73ea2f6..a8133d3 100644 (file)
@@ -1,6 +1,6 @@
 message("* vm/common_vm")
 
-SET(THIS_LIB_VERSION 2.9.1)
+SET(THIS_LIB_VERSION 2.10.1)
 
 #include(cotire)
 set(s_vm_common_vm_srcs
index 9e47d3f..772e526 100644 (file)
@@ -209,6 +209,7 @@ public:
        
        // NOTE: the virtual bus interface functions for 16/32bit access invite the cpu is little endian.
        // if the cpu is big endian, you need to implement them in the virtual machine memory/io classes.
+       virtual uint32_t translate_address(int segment, uint32_t offset) { /* offset must be numeric, not value */ return offset; }
        
        // memory bus
        virtual void write_data8(uint32_t addr, uint32_t data) {}
index 233de8c..4fdddb4 100644 (file)
@@ -263,6 +263,12 @@ uint32_t I286::get_next_pc()
        return cpustate->pc;
 }
 
+uint32_t I286::translate_address(int segment, uint32_t offset)
+{
+       i386_state *cpustate = (i386_state *)opaque;
+       return cpustate->base[segment] + offset;
+}
+
 #ifdef USE_DEBUGGER
 void I286::write_debug_data8(uint32_t addr, uint32_t data)
 {
index 935173e..0c9fdbf 100644 (file)
@@ -74,6 +74,9 @@ public:
        int get_extra_clock();
        uint32_t get_pc();
        uint32_t get_next_pc();
+       uint32_t translate_address(int segment, uint32_t offset);
+
+
 #ifdef USE_DEBUGGER
        bool is_cpu()
        {
index e3a6a03..34bf7a1 100644 (file)
@@ -237,7 +237,7 @@ typedef UINT32      offs_t;
                        sregs[0] = cpustate->sreg[ES].selector; sregs[1] = cpustate->sreg[CS].selector; \
                        sregs[2] = cpustate->sreg[SS].selector; sregs[3] = cpustate->sreg[DS].selector; \
                        int32_t ZeroFlag = cpustate->ZF, CarryFlag = cpustate->CF;      \
-                       if(cpustate->bios->bios_int_i86(num, regs, sregs, &ZeroFlag, &CarryFlag, &(cpustate->cycles), &(cpustate->total_cycles))) { \
+if(cpustate->bios->bios_int_i86(num, regs, sregs, &ZeroFlag, &CarryFlag, &(cpustate->cycles), &(cpustate->total_cycles))) { \
                                REG16(AX) = regs[0]; REG16(CX) = regs[1]; REG16(DX) = regs[2]; REG16(BX) = regs[3]; \
                                REG16(SP) = regs[4]; REG16(BP) = regs[5]; REG16(SI) = regs[6]; REG16(DI) = regs[7]; \
                                cpustate->ZF = (UINT8)ZeroFlag; cpustate->CF = (UINT8)CarryFlag; \
@@ -455,6 +455,12 @@ void I386::write_debug_data8(uint32_t addr, uint32_t data)
        d_mem->write_data8w(addr, data, &wait);
 }
 
+uint32_t I386::translate_address(int segment, uint32_t offset)
+{
+       i386_state *cpustate = (i386_state *)opaque;
+       return i386_translate(cpustate, segment, offset, -1, 1); 
+}
+
 uint32_t I386::read_debug_data8(uint32_t addr)
 {
        int wait;
@@ -646,14 +652,14 @@ bool I386::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len)
 
        if(cpustate->operand_size) {
                my_stprintf_s(buffer, buffer_len,
-                                         _T("MODE=%s PC=%08X PREV_PC=%08X\n")
+                                         _T("MODE=%s PC=%08X PREV_PC=%08X SP(REAL)=%08X\n")
                                          _T("CR[0-4]=%08X %08X %08X %08X %08X IOPL=%d CPL=%d\n")         
                                          _T("EAX=%08X  EBX=%08X ECX=%08X EDX=%08X ESP=%08X  EBP=%08X  ESI=%08X  EDI=%08X\n")
                                          _T("DS=%04X  ES=%04X SS=%04X CS=%04X FS=%04X GS=%04X\n")
                                          _T("A20_MASK=%08X EIP=%08X  EFLAGS=%08X FLAG=[%c%c%c%c%c%c%c%c%c]\n")
                                          _T("Clocks = %llu (%llu) Since Scanline = %d/%d (%d/%d)"),
                                          (PROTECTED_MODE != 0) ? ((V8086_MODE) ? _T("PROTECTED V8086(32bit)") : _T("PROTECTED 32bit")) : ((V8086_MODE) ? _T("V8086(32bit)") : _T("32bit")),
-                                         cpustate->pc, cpustate->prev_pc,
+                                         cpustate->pc, cpustate->prev_pc, cpustate->sreg[SS].base + ((uint32_t)REG32(ESP)),
                                          cpustate->cr[0] ,cpustate->cr[1], cpustate->cr[2], cpustate->cr[3], cpustate->cr[4], (cpustate->IOP1) | (cpustate->IOP2 << 1), cpustate->CPL,
                                          REG32(EAX), REG32(EBX), REG32(ECX), REG32(EDX), REG32(ESP), REG32(EBP), REG32(ESI), REG32(EDI),
                                          cpustate->sreg[DS].selector, cpustate->sreg[ES].selector, cpustate->sreg[SS].selector, cpustate->sreg[CS].selector, cpustate->sreg[FS].selector, cpustate->sreg[GS].selector, cpustate->a20_mask, cpustate->eip, cpustate->eflags,
@@ -665,12 +671,12 @@ bool I386::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len)
                if((PROTECTED_MODE) != 0) {
                        if((V8086_MODE)) {
                                my_stprintf_s(buffer, buffer_len,
-                                         _T("MODE=V8086 (PROTECTED) PC=%08X PREV_PC=%08X\n")
+                                         _T("MODE=V8086 (PROTECTED) PC=%08X PREV_PC=%08X SP(REAL)=%08X\n")
                                          _T("CR[0-4]=%08X %08X %08X %08X %08X IOP=%d CPL=%d\n")          
                                          _T("AX=%04X  BX=%04X CX=%04X DX=%04X SP=%04X  BP=%04X  SI=%04X  DI=%04X\n")
                                          _T("DS=%04X  ES=%04X SS=%04X CS=%04X FS=%04X GS=%04X A20_MASK=%08X IP=%04X  FLAG=[%c%c%c%c%c%c%c%c%c]\n")
                                          _T("Clocks = %llu (%llu) Since Scanline = %d/%d (%d/%d)"),
-                                         cpustate->pc, cpustate->prev_pc,
+                                         cpustate->pc, cpustate->prev_pc, cpustate->sreg[SS].base + ((uint32_t)REG32(ESP) & 0xffff),
                                          cpustate->cr[0] ,cpustate->cr[1], cpustate->cr[2], cpustate->cr[3], cpustate->cr[4], (cpustate->IOP1) | (cpustate->IOP2 << 1), cpustate->CPL,
                                          REG16(AX), REG16(BX), REG16(CX), REG16(DX), REG16(SP), REG16(BP), REG16(SI), REG16(DI),
                                                          cpustate->sreg[DS].selector, cpustate->sreg[ES].selector, cpustate->sreg[SS].selector, cpustate->sreg[CS].selector, cpustate->sreg[FS].selector, cpustate->sreg[GS].selector, cpustate->a20_mask, cpustate->eip,
@@ -680,12 +686,12 @@ bool I386::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len)
                                          get_passed_clock_since_vline(), get_cur_vline_clocks(), get_cur_vline(), get_lines_per_frame());
                        } else {
                                my_stprintf_s(buffer, buffer_len,
-                         _T("MODE=PROTECTED 16bit PC=%08X PREV_PC=%08X\n")
+                         _T("MODE=PROTECTED 16bit PC=%08X PREV_PC=%08X SP(REAL)=%08X\n")
                          _T("CR[0-4]=%08X %08X %08X %08X %08X IOP=%d CPL=%d\n")          
                          _T("AX=%04X  BX=%04X CX=%04X DX=%04X SP=%04X  BP=%04X  SI=%04X  DI=%04X\n")
                          _T("DS=%04X  ES=%04X SS=%04X CS=%04X FS=%04X GS=%04X A20_MASK=%08X IP=%04X  EFLAGS=%08X FLAG=[%c%c%c%c%c%c%c%c%c]\n")
                          _T("Clocks = %llu (%llu) Since Scanline = %d/%d (%d/%d)"),
-                         cpustate->pc, cpustate->prev_pc,
+                                                         cpustate->pc, cpustate->prev_pc, cpustate->sreg[SS].base + ((uint32_t)REG32(ESP)),
                          cpustate->cr[0] ,cpustate->cr[1], cpustate->cr[2], cpustate->cr[3], cpustate->cr[4], (cpustate->IOP1) | (cpustate->IOP2 << 1), cpustate->CPL,
                          REG16(AX), REG16(BX), REG16(CX), REG16(DX), REG16(SP), REG16(BP), REG16(SI), REG16(DI),
                          cpustate->sreg[DS].selector, cpustate->sreg[ES].selector, cpustate->sreg[SS].selector, cpustate->sreg[CS].selector, cpustate->sreg[FS].selector, cpustate->sreg[GS].selector, cpustate->a20_mask, cpustate->eip, cpustate->eflags,
@@ -696,12 +702,12 @@ bool I386::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len)
                        }
                } else {
                                my_stprintf_s(buffer, buffer_len,
-                         _T("MODE=16bit PC=%08X PREV_PC=%08X\n")
+                         _T("MODE=16bit PC=%08X PREV_PC=%08X SP(REAL)=%08X\n")
                          _T("CR[0-4]=%08X %08X %08X %08X %08X IOP=%d CPL=%d\n")          
                          _T("AX=%04X  BX=%04X CX=%04X DX=%04X SP=%04X  BP=%04X  SI=%04X  DI=%04X\n")
                          _T("DS=%04X  ES=%04X SS=%04X CS=%04X FS=%04X GS=%04X A20_MASK=%08X IP=%04X EFLAGS=%08X FLAG=[%c%c%c%c%c%c%c%c%c]\n")
                          _T("Clocks = %llu (%llu) Since Scanline = %d/%d (%d/%d)"),
-                         cpustate->pc, cpustate->prev_pc,
+                                                         cpustate->pc, cpustate->prev_pc, cpustate->sreg[SS].base + ((uint32_t)REG16(SP) & 0xffff),
                          cpustate->cr[0] ,cpustate->cr[1], cpustate->cr[2], cpustate->cr[3], cpustate->cr[4], (cpustate->IOP1) | (cpustate->IOP2 << 1), cpustate->CPL,
                          REG16(AX), REG16(BX), REG16(CX), REG16(DX), REG16(SP), REG16(BP), REG16(SI), REG16(DI),
                          cpustate->sreg[DS].selector, cpustate->sreg[ES].selector, cpustate->sreg[SS].selector, cpustate->sreg[CS].selector, cpustate->sreg[FS].selector, cpustate->sreg[GS].selector, cpustate->a20_mask, cpustate->eip, cpustate->eflags,
index b190e17..f8a0572 100644 (file)
@@ -82,6 +82,8 @@ public:
        int get_extra_clock();
        uint32_t get_pc();
        uint32_t get_next_pc();
+
+       uint32_t translate_address(int segment, uint32_t offset);
 //#ifdef USE_DEBUGGER
        bool is_cpu()
        {
index 9f06f6f..489a6d1 100644 (file)
@@ -267,6 +267,12 @@ uint32_t I286::get_next_pc()
        return cpustate->pc;
 }
 
+uint32_t I286::translate_address(int segment, uint32_t offset)
+{
+       i386_state *cpustate = (i386_state *)opaque;
+       return cpustate->base[segment] + offset;
+}
+
 #ifdef USE_DEBUGGER
 void I286::write_debug_data8(uint32_t addr, uint32_t data)
 {
index ec9393b..38d82f8 100644 (file)
@@ -75,6 +75,7 @@ public:
        int get_extra_clock();
        uint32_t get_pc();
        uint32_t get_next_pc();
+       uint32_t translate_address(int segment, uint32_t offset);
 #ifdef USE_DEBUGGER
        bool is_cpu()
        {
index 93ecaf0..b0ad538 100644 (file)
@@ -113,7 +113,7 @@ public:
        
        // NOTE: the virtual bus interface functions for 16/32bit access invite the cpu is little endian.
        // if the cpu is big endian, you need to implement them in the virtual machine memory/io classes.
-       
+       virtual uint32_t translate_address(int segment, uint32_t offset) { /* offset must be numeric, not value */ return offset; }
        // memory bus
        virtual void write_data8(uint32_t addr, uint32_t data) {}
        virtual uint32_t read_data8(uint32_t addr)
index ff2026d..1fa9194 100644 (file)
@@ -306,14 +306,15 @@ static void set_flags(i386_state *cpustate, UINT32 f )
        cpustate->VIF = (f & 0x80000) ? 1 : 0;
        cpustate->VIP = (f & 0x100000) ? 1 : 0;
        cpustate->ID = (f & 0x200000) ? 1 : 0;
-       if(((cpustate->eflags & 0x3000) != (f & 0x3000)) && ((f & 0x3000) == 0)) logerror("SET IOPL to 0 PC=%08X\n", cpustate->pc);
-       if(PROTECTED_MODE) {
-               cpustate->eflags = f;
-       } else {
-               UINT32 o_e = cpustate->eflags & 0x20000;
-               cpustate->eflags = (f & ~0x00020000) | o_e;
-               //cpustate->eflags = f;
-       }
+       //if(((cpustate->eflags & 0x3000) != (f & 0x3000)) && ((f & 0x3000) == 0)) logerror("SET IOPL to 0 PC=%08X\n", cpustate->pc);
+       //if(old_vm != cpustate->VM) logerror("Change VM flag to %d at %08X\n", cpustate->VM, cpustate->pc);
+       //if(PROTECTED_MODE) {
+       cpustate->eflags = f;
+       //} else {
+       //      UINT32 o_e = cpustate->eflags & 0x20000;
+       //cpustate->eflags = (f & ~0x00020000) | o_e;
+       //cpustate->eflags = f;
+       //}
 #if 0
        if(old_vm != cpustate->VM) {
                if((V8086_MODE) && (PROTECTED_MODE)){
@@ -584,7 +585,7 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
                {
                        if((selector & ~0x0007) > cpustate->ldtr.limit)
                        {
-                               logerror("SReg Load (%08x): Selector is out of LDT bounds.LDTR.limit=%4X : selector=%04X\n",cpustate->pc, cpustate->ldtr.limit, selector);
+                               logerror("SReg Load (SS)(%08x): Selector is out of LDT bounds.LDTR.limit=%4X : selector=%04X\n",cpustate->pc, cpustate->ldtr.limit, selector);
                                FAULT(FAULT_GP,selector & ~0x03)
                        }
                }
@@ -638,7 +639,7 @@ static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, boo
                {
                        if((selector & ~0x0007) > cpustate->ldtr.limit)
                        {
-                               logerror("SReg Load (%08x): Selector is out of LDT bounds.LDTR.limit=%04X : %04X\n",cpustate->pc, cpustate->ldtr.limit, selector);
+                               logerror("SReg Load (other SS)(%08x): Selector is out of LDT bounds.LDTR.limit=%04X : %04X\n",cpustate->pc, cpustate->ldtr.limit, selector);
                                FAULT(FAULT_GP,selector & ~0x03)
                        }
                }
@@ -752,7 +753,7 @@ static void i386_trap(i386_state *cpustate,int irq, int irq_gate, int trap_level
                segment = (v1 >> 16) & 0xffff;
                type = (v2>>8) & 0x1F;
                flags = (v2>>8) & 0xf0ff;
-
+               //logdebug("TRAP: #%d PC=%08X offset = %08X segment = %04X type = %d flags = %04X\n", irq, cpustate->pc, offset, segment, type, flags);
                if(trap_level == 2)
                {
                        logdebug("IRQ: Double fault. IRQ%02Xh GATE=%d PC=%08X\n", irq, irq_gate, cpustate->pc);
@@ -968,7 +969,7 @@ static void i386_trap(i386_state *cpustate,int irq, int irq_gate, int trap_level
                                }
                                /* change CPL before accessing the stack */
                                UINT32 _oldCPL = cpustate->CPL;
-                               if(_oldCPL != DPL) logerror("TRAP/INT GATE: Privilege changed from %d to %d at %08X, INT# %d, GATE %d TYPE %d\n", _oldCPL, DPL, cpustate->pc, irq, irq_gate, type);
+                               //if(_oldCPL != DPL) logerror("TRAP/INT GATE: Privilege changed from %d to %d at %08X, INT# %d, GATE %d TYPE %d\n", _oldCPL, DPL, cpustate->prev_pc, irq, irq_gate, type);
                                cpustate->CPL = DPL;
                                /* check for page fault at new stack TODO: check if stack frame crosses page boundary */
                                WRITE_TEST(cpustate, stack.base+newESP-1);
@@ -999,7 +1000,7 @@ static void i386_trap(i386_state *cpustate,int irq, int irq_gate, int trap_level
                                        cpustate->sreg[FS].selector = 0;
                                        cpustate->sreg[DS].selector = 0;
                                        cpustate->sreg[ES].selector = 0;
-                                       //cpustate->VM = 0;
+                                       cpustate->VM = 0;
                                        //cpustate->eflags = get_flags(cpustate);
                                        cpustate->eflags &= ~I386_EFLAGS_VM; // Clear VM flag
                                        set_flags(cpustate, cpustate->eflags);
@@ -1061,7 +1062,7 @@ static void i386_trap(i386_state *cpustate,int irq, int irq_gate, int trap_level
                try
                {
                        // this is ugly but the alternative is worse
-                       if(type != 0x0e && type != 0x0f)  // if not 386 interrupt or trap gate
+                       if(/*type != 0x0e && type != 0x0f*/ (type & 0x08) == 0)  // if not 386 interrupt or trap gate
                        {
                                PUSH16(cpustate, oldflags & 0xffff );
                                PUSH16(cpustate, cpustate->sreg[CS].selector );
@@ -1099,9 +1100,9 @@ static void i386_trap(i386_state *cpustate,int irq, int irq_gate, int trap_level
                if(SetRPL != 0)
                        segment = (segment & ~0x03) | cpustate->CPL;
                cpustate->sreg[CS].selector = segment;
-               if(segment != o_selector) {
-                       i386_load_segment_descriptor(cpustate,CS);
-               }                       
+               //if(segment != o_selector) {
+               //      i386_load_segment_descriptor(cpustate,CS);
+               //}                     
                cpustate->eip = offset;
 
                if(type == 0x0e || type == 0x06)
@@ -1135,14 +1136,13 @@ static void i386_trap_with_error(i386_state *cpustate,int irq, int irq_gate, int
                i386_trap(cpustate,irq,irq_gate,trap_level);
        }               
                
-       if(irq == FAULT_DF || irq == FAULT_TS || irq == FAULT_NP || irq == FAULT_SS || irq == FAULT_GP || irq == FAULT_GP || irq == FAULT_AC)
+       if(irq == FAULT_DF || irq == FAULT_TS || irq == FAULT_NP || irq == FAULT_SS || irq == FAULT_GP || irq == FAULT_PF /*|| irq == FAULT_AC */)
        {
-               if((irq == FAULT_AC) || (irq == FAULT_DF)) error = 0;
+               //if((irq == FAULT_AC) || (irq == FAULT_DF)) error = 0;
                // for these exceptions, an error code is pushed onto the stack by the processor.
                // no error code is pushed for software interrupts, either.
                if(PROTECTED_MODE)
                {
-//                     try {
                                UINT32 entry = irq * 8;
                                UINT32 v2,type;
                                v2 = READ32PL0(cpustate, cpustate->idtr.base + entry + 4 );
@@ -1157,20 +1157,9 @@ static void i386_trap_with_error(i386_state *cpustate,int irq, int irq_gate, int
                                        PUSH32(cpustate,error);
                                else
                                        PUSH16(cpustate,error);
-//                     } catch(UINT64 e) {
-//                             logerror("Irregular exception happened %08x for protected mode in trap_with_error()_.\n", e);
-//                     } catch(UINT32 e) {
-//                             logerror("Irregular exception happened %08x for protected mode in trap_with_error()_.\n", e);
-//                     }
                }
                else {
-//                     try {
                                PUSH16(cpustate,error);
-//                     } catch(UINT64 e) {
-//                             logerror("Irregular exception happened %08x for 16bit mode in trap_with_error()_.\n", e);
-//                     } catch(UINT32 e) {
-//                             logerror("Irregular exception happened %08x for 16bit mode in trap_with_error()_.\n", e);
-//                     }
                }
        }
 }
@@ -2000,7 +1989,7 @@ static void i386_protected_mode_call(i386_state *cpustate, UINT16 seg, UINT32 of
                                        UINT32 _oldCPL = cpustate->CPL;
                                        cpustate->CPL = (stack.flags >> 5) & 0x03;
                                        UINT32 _newCPL = cpustate->CPL;
-                                       if(_oldCPL != _newCPL) logerror("Privilege changed by protected mode call from %d to %d ADDR %08X\n", _oldCPL, _newCPL, cpustate->pc);
+                                       //if(_oldCPL != _newCPL) logerror("Privilege changed by protected mode call from %d to %d ADDR %08X\n", _oldCPL, _newCPL, cpustate->pc);
                                        /* check for page fault at new stack */
                                        WRITE_TEST(cpustate, stack.base+newESP-1);
                                        /* switch to new stack */
@@ -2597,7 +2586,7 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32)
                        i386_load_segment_descriptor(cpustate,FS);
                        i386_load_segment_descriptor(cpustate,GS);
                        i386_load_segment_descriptor(cpustate,SS);
-                       logerror("IRET: Return to V8086 MODE: old CPL=%d new CPL=3 PC=%08X\n", cpustate->CPL, cpustate->pc);
+                       //logerror("IRET: Return to V8086 MODE: old CPL=%d new CPL=3 PC=%08X\n", cpustate->CPL, cpustate->pc);
                        cpustate->CPL = 3;  // Virtual 8086 tasks are always run at CPL 3
                }
                else
@@ -3366,10 +3355,10 @@ static void zero_state(i386_state *cpustate)
        // From ia32_initreg() of np2, i386c/ia32/interface.c
        cpustate->cr[0] = I386_CR0_CD | I386_CR0_NW;
        // ToDo: FPU
-       //cpustate->cr[0] &= ~I386_CR0_EM;
-       //cpustate->cr[0] |= I386_CR0_ET;
-       cpustate->cr[0] |= (I386_CR0_EM | I386_CR0_NE);
-       cpustate->cr[0] &= ~(I386_CR0_MP | I386_CR0_ET);
+       cpustate->cr[0] &= ~I386_CR0_EM;
+       cpustate->cr[0] |= I386_CR0_ET;
+       //cpustate->cr[0] |= (I386_CR0_EM | I386_CR0_NE);
+       //cpustate->cr[0] &= ~(I386_CR0_MP | I386_CR0_ET);
        // Init GDTR/IDTR
        cpustate->gdtr.base  = 0x0000;
        cpustate->gdtr.limit = 0xffff;
index 9e7de7c..7475042 100644 (file)
@@ -495,9 +495,10 @@ static void I386OP(call_abs16)(i386_state *cpustate)        // Opcode 0x9a
        CYCLES(cpustate,CYCLES_CALL_INTERSEG);      /* TODO: Timing = 17 + m */
 
 //#ifdef I386_PSEUDO_BIOS
-       //if(!(V8086_MODE)) {
+       UINT8 IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1);
+       if(!(V8086_MODE) && !(PROTECTED_MODE && (cpustate->CPL > IOPL))) {
                BIOS_CALL_FAR(((ptr << 4) + offset) & cpustate->a20_mask);
-       //}
+       }
 //#endif
 
        if( PROTECTED_MODE && !V8086_MODE)
@@ -3068,9 +3069,10 @@ static void I386OP(groupFF_16)(i386_state *cpustate)        // Opcode 0xff
                                        selector = READ16(cpustate,ea + 2);
                                        CYCLES(cpustate,CYCLES_CALL_MEM_INTERSEG);      /* TODO: Timing = 10 + m */
 //#ifdef I386_PSEUDO_BIOS
-                                       //if(!(V8086_MODE)) {
+                                       UINT8 IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1);
+                                       if(!(V8086_MODE) && !((PROTECTED_MODE) && (cpustate->CPL > IOPL))) {
                                                BIOS_CALL_FAR(((selector << 4) + address) & cpustate->a20_mask);
-                                       //}
+                                       }
 //#endif
                                        if(PROTECTED_MODE && !V8086_MODE)
                                        {
index e094e05..7ae1cb4 100644 (file)
@@ -660,13 +660,14 @@ static void I386OP(mov_r32_cr)(i386_state *cpustate)        // Opcode 0x0f 20
        //      FAULT(FAULT_UD, 0);
        //      return;
        //}
+       UINT32 oldpc = cpustate->pc;
        if((PROTECTED_MODE && (/*(V8086_MODE) || */(cpustate->CPL != 0)))) {
                logerror("Call from non-supervisor privilege: I386OP(mov_r32_cr)"); 
                FAULT(FAULT_GP, 0);
        }
        UINT8 modrm = FETCH(cpustate);
        UINT8 cr = (modrm >> 3) & 0x7;
-       logdebug("MOV r32 CR%d VAL=(%08X)\n", cr, cpustate->cr[cr]);
+       logdebug("MOV r32 CR%d VAL=(%08X)\n", cr, cpustate->cr[cr], oldpc);
        if(cr < 5) {
                STORE_RM32(modrm, cpustate->cr[cr]);
                CYCLES(cpustate,CYCLES_MOV_CR_REG);
@@ -757,6 +758,7 @@ static void I386OP(mov_cr_r32)(i386_state *cpustate)        // Opcode 0x0f 22
        //      FAULT(FAULT_UD, 0);
        //      return;
        //}
+       UINT32 oldpc = cpustate->pc;
        if((PROTECTED_MODE && (/*(V8086_MODE) || */(cpustate->CPL != 0)))) {
                logerror("Call from non-supervisor privilege: I386OP(mov_cr_r32)"); 
                FAULT(FAULT_GP, 0);
@@ -765,7 +767,7 @@ static void I386OP(mov_cr_r32)(i386_state *cpustate)        // Opcode 0x0f 22
        UINT8 cr = (modrm >> 3) & 0x7;
        UINT32 data = LOAD_RM32(modrm);
        UINT32 data_bak;
-       logdebug("MOV CR%d r32 VAL=(%08X)\n", cr, data);
+       logdebug("MOV CR%d r32 VAL=(%08X) at %08X\n", cr, data, oldpc);
        switch(cr)
        {
                case 0:
@@ -778,20 +780,20 @@ static void I386OP(mov_cr_r32)(i386_state *cpustate)        // Opcode 0x0f 22
                        if((data & (I386_CR0_NW | I386_CR0_CD)) == I386_CR0_NW) {
                                FAULT(FAULT_GP, 0);
                        }
-#if 0
+#if 1
                        data_bak = cpustate->cr[0];
                        data &= I386_CR0_ALL;
                        data &= ~I386_CR0_WP; // wp not supported on 386
                        //logdebug("MOV CR0,xxxxh %08x -> %08x \n", data_bak, data);
                        // ToDo: FPU
-                       //data |= I386_CR0_ET;  /* FPU present */
-                       //data &= ~I386_CR0_EM;
-                       data |= I386_CR0_EM | I386_CR0_NE;
-                       data &= ~(I386_CR0_MP | I386_CR0_ET);
-                       cpustate->cr[0] = data & ~(I386_CR0_PE | I386_CR0_PG);
+                       data |= I386_CR0_ET;    /* FPU present */
+                       data &= ~I386_CR0_EM;
+                       //data |= I386_CR0_EM | I386_CR0_NE;
+                       //data &= ~(I386_CR0_MP | I386_CR0_ET);
+//                     //cpustate->cr[0] = data & ~(I386_CR0_PE | I386_CR0_PG);
 #endif                 
                        cpustate->cr[0] = data;
-#if 0
+#if 1
                        if((data_bak & (I386_CR0_PE | I386_CR0_PG)) != (data & (I386_CR0_PE | I386_CR0_PG))) {
                                // ToDo: TLB flush (paging)
                                vtlb_flush_dynamic(cpustate->vtlb);
@@ -1123,7 +1125,7 @@ static void I386OP(arpl)(i386_state *cpustate)           // Opcode 0x63
 
        if(PROTECTED_MODE && !V8086_MODE)
        {
-                       if( modrm >= 0xc0 ) {
+               if( modrm >= 0xc0 ) {
                        src = LOAD_REG16(modrm);
                        dst = LOAD_RM16(modrm);
                        if( (dst&0x3) < (src&0x3) ) {
@@ -2489,6 +2491,7 @@ static void I386OP(nop)(i386_state *cpustate)               // Opcode 0x90
 static void I386OP(int3)(i386_state *cpustate)              // Opcode 0xcc
 {
        CYCLES(cpustate,CYCLES_INT3);
+       logerror("INT3 at %08X\n", cpustate->pc - 1);
        cpustate->ext = 0; // not an external interrupt
        i386_trap(cpustate,3, 1, 0);
        cpustate->ext = 1;
@@ -2499,17 +2502,20 @@ static void I386OP(int_16)(i386_state *cpustate)               // Opcode 0xcd
        int interrupt = FETCH(cpustate);
        CYCLES(cpustate,CYCLES_INT);
        if(V8086_MODE) {
-               //logerror("INT %02xh @V8086(16) mode\n", interrupt);
+               //logerror("INT %02xh @V8086(16bit) mode PC=%08X\n", interrupt, cpustate->pc - 1);
                if((!cpustate->IOP1 || !cpustate->IOP2))
                {
                        logerror("IRQ (%08x): Is in Virtual 8086 mode and IOPL != 3.\n",cpustate->pc);
-                       //FAULT(FAULT_GP,0);
+                       FAULT(FAULT_GP,0);
                } else {
-                       BIOS_INT(interrupt);
+                       //BIOS_INT(interrupt);
                }
        } else {
-               //logerror("INT %02xh @16bit mode\n", interrupt);
-               BIOS_INT(interrupt);
+               //logerror("INT %02xh @16bit mode PC=%08X\n", interrupt, cpustate->pc - 1);
+               UINT8 IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1);
+               if(!(PROTECTED_MODE && (cpustate->CPL > IOPL))) {
+                       BIOS_INT(interrupt);
+               }
        }               
        cpustate->ext = 0; // not an external interrupt
        i386_trap(cpustate,interrupt, 1, 0);
@@ -2522,18 +2528,20 @@ static void I386OP(int_32)(i386_state *cpustate)               // Opcode 0xcd
        CYCLES(cpustate,CYCLES_INT);
 #if 1
        if(V8086_MODE) {
-               //logerror("INT %02xh @V8086(32) mode\n", interrupt);
+               //logerror("INT %02xh @V8086(32bit) mode PC=%08X\n", interrupt, cpustate->pc - 1);
                if((!cpustate->IOP1 || !cpustate->IOP2))
                {
-                       //logerror("IRQ (%08x): Is in Virtual 8086 mode and IOPL != 3.\n",cpustate->pc);
-                       //FAULT(FAULT_GP,0);
+                       logerror("IRQ (%08x): Is in Virtual 8086 mode and IOPL != 3.\n",cpustate->pc);
+                       FAULT(FAULT_GP,0);
                } else {
-                       
-                       BIOS_INT(interrupt);
+                       //BIOS_INT(interrupt);
                }
        } else {
-               //logerror("INT %02xh @32bit mode\n", interrupt);
-               BIOS_INT(interrupt);
+               //logerror("INT %02xh @32bit mode PC=%08X\n", interrupt, cpustate->pc - 1);
+               UINT8 IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1);
+               if(!(PROTECTED_MODE && (cpustate->CPL > IOPL))) {
+                       BIOS_INT(interrupt);
+               }
        }
 #endif
        cpustate->ext = 0; // not an external interrupt
index 7d9ba99..bbd9603 100644 (file)
@@ -597,7 +597,7 @@ static void pf_throw_sub(i386_state* cpustate, uint32_t address, uint64_t error)
 #endif
 #define PROTECTED_MODE      (cpustate->cr[0] & 0x1)
 #define STACK_32BIT         (cpustate->sreg[SS].d)
-#define V8086_MODE          ((cpustate->VM) && (cpustate->cr[4] & I386_CR4_VME))
+#define V8086_MODE          ((cpustate->VM) /*&& (cpustate->cr[4] & I386_CR4_VME)*/)
 #define NESTED_TASK         (cpustate->NT)
 #define WP                  (cpustate->cr[0] & I386_CR0_WP)
 
index d6a425a..2fe07ff 100644 (file)
@@ -369,12 +369,11 @@ void MEMBUS::write_io8(uint32_t addr, uint32_t data)
                // ToDo: Cache flush for i486 or later.
 #if defined(SUPPORT_32BIT_ADDRESS)
                is_shadow_bank_80000h = ((data & 0xfe) == 0x08) ? true : false;
+#endif
                //if(!is_shadow_bank_80000h) {
                        window_80000h = (data & 0xfe) << 16;
                //}
-#else
                window_80000h = (data & 0xfe) << 16;
-#endif
                break;
 #if defined(SUPPORT_HIRESO)
        case 0x0093:
@@ -387,14 +386,8 @@ void MEMBUS::write_io8(uint32_t addr, uint32_t data)
                }
 #endif
                // http://www.webtech.co.jp/company/doc/undocumented_mem/io_mem.txt
-#if defined(SUPPORT_32BIT_ADDRESS)
-               is_shadow_bank_a0000h = ((data & 0xfe) == 0x0a) ? true : false;
-               //if(!is_shadow_bank_a0000h) {
                        window_a0000h = (data & 0xfe) << 16;
                //}
-#else
-               window_a0000h = (data & 0xfe) << 16;
-#endif
                break;
 #endif
        case 0x0463:
@@ -636,13 +629,19 @@ void MEMBUS::update_bios()
        //      #endif
        //}
        #if defined(SUPPORT_32BIT_ADDRESS)
+       #if !defined(SUPPORT_HIRESO)
+       unset_memory_rw(0xa0000, 0xbffff);
+       set_memory_mapped_io_rw(0xa0000, 0xbffff, d_display);
+       #else
        unset_memory_rw(0xc0000, 0xe7fff);
+       #endif
        if(shadow_ram_selected) {
                set_memory_rw(0xc0000, 0xe7fff, shadow_ram);
        } else {
                #if defined(SUPPORT_HIRESO)
                set_memory_mapped_io_rw(0xe0000, 0xe4fff, d_display);
                #else           
+               unset_memory_rw(0xc0000, 0xe7fff);
                #if defined(SUPPORT_16_COLORS)
                set_memory_mapped_io_rw(0xe0000, 0xe7fff, d_display);
                #endif
index 93c39db..c0c9d49 100644 (file)
@@ -115,13 +115,14 @@ void BIOS::reset()
        event_irq = -1;
 }
 
-bool BIOS::bios_int_i86(int intnum, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles)
+       bool BIOS::bios_int_i86(int intnum, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles)
 {
        uint8_t *regs8 = (uint8_t *)regs;
        // SASI
        switch(intnum) {
        case 0x1b: // SASI BIOS (INT3)
                if(d_mem->is_sasi_bios_load()) return false;
+               //out_debug_log("INT 1Bh\n");
                return bios_call_far_i86(0xfffc4, regs, sregs, ZeroFlag, CarryFlag, cycles, total_cycles);
                break;
        default:
@@ -130,7 +131,7 @@ bool BIOS::bios_int_i86(int intnum, uint16_t regs[], uint16_t sregs[], int32_t*
        return false;
 }
 
-bool BIOS::bios_call_far_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles)
+       bool BIOS::bios_call_far_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles)
 {
        uint8_t *regs8 = (uint8_t *)regs;
        bool need_retcall = false;
@@ -252,6 +253,7 @@ bool BIOS::sasi_bios(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t* Ze
                // ToDo: Multi SASI
                if(d_sasi->get_hdd(0) != NULL) {
                        if(sxsi_get_drive(AL) >= 0) {
+                               out_debug_log("SASI BIOS CALL AH=%02X\n", AH);
                                switch(AH & 0x0f) {
                                case 0x01:
                                        // Verify
@@ -436,8 +438,8 @@ void BIOS::sasi_command_initialize(uint32_t PC, uint16_t regs[], uint16_t sregs[
        }
        _d.u16 = disk_equip;
        d_mem->write_io8(0x043f, 0xc2); // Enable to write ram
-       d_mem->write_data8(0x055c + 0, _d.b.l);
-       d_mem->write_data8(0x055c + 1, _d.b.h);
+       d_mem->write_dma_data8(0x055c + 0, _d.b.l);
+       d_mem->write_dma_data8(0x055c + 1, _d.b.h);
        d_mem->write_io8(0x043f, 0xc0); // Disable to write ram
 #ifdef _PSEUDO_BIOS_DEBUG
        out_debug_log(_T("SASI CMD: INITIALIZE STAT=%04x"), disk_equip);
@@ -528,7 +530,13 @@ void BIOS::sasi_command_read(uint32_t PC, uint16_t regs[], uint16_t sregs[], int
        uint8_t *regs8 = (uint8_t *)regs;
        int size = (int)(BX & 0xffff);
        if(size == 0) size = 0x10000;
-       uint32_t addr = (((uint32_t)ES) << 4) + BP;
+       uint32_t addr;
+       //addr = (((uint32_t)ES) << 4) + BP;
+       try {
+               addr = d_cpu->translate_address(0, (uint32_t)BP); // ES:BP
+       } catch(...) {
+               out_debug_log("Access vioration ES:%04x\n", BP);
+       }
        //out_debug_log(_T("SASI CMD: READ ADDR=%08x\n"), addr);
 
        int drive = sxsi_get_drive(AL);
@@ -589,7 +597,7 @@ void BIOS::sasi_command_read(uint32_t PC, uint16_t regs[], uint16_t sregs[], int
                                if(harddisk->read_buffer((long)position, block_size, buffer)) {
                                        position += block_size;
                                        for(int i = 0; i < block_size; i++) {
-                                               d_mem->write_data8(addr++, buffer[i]);
+                                               d_mem->write_dma_data8(addr++, buffer[i]);
                                        }
                                        size -= block_size;
                                } else {
@@ -612,7 +620,13 @@ void BIOS::sasi_command_write(uint32_t PC, uint16_t regs[], uint16_t sregs[], in
        int size = (int)(BX & 0xffff);
        if(size == 0) size = 0x10000;
        uint8_t *regs8 = (uint8_t *)regs;
-       uint32_t addr = (((uint32_t)ES) << 4) + BP;
+       uint32_t addr;
+       try {
+               addr = d_cpu->translate_address(0, (uint32_t)BP); // ES:BP
+       } catch(...) {
+               out_debug_log("Access vioration ES:%04x\n", BP);
+       }
+       //addr = (((uint32_t)ES) << 4) + BP;
        int drive = sxsi_get_drive(AL);
        if(drive < 0) { // ToDo: Multi SASI
                AH = 0x80;
@@ -662,7 +676,7 @@ void BIOS::sasi_command_write(uint32_t PC, uint16_t regs[], uint16_t sregs[], in
                                }
                                // data transfer
                                for(int i = 0; i < block_size; i++) {
-                                       buffer[i] = d_mem->read_data8(addr++);
+                                       buffer[i] = d_mem->read_dma_data8(addr++);
                                }
                                if(harddisk->write_buffer((long)position, block_size, buffer)) {
                                        position += block_size;
@@ -708,9 +722,9 @@ void BIOS::sasi_command_format(uint32_t PC, uint16_t regs[], uint16_t sregs[], i
                        return;
                }
                HARDDISK* harddisk = d_hdd->get_disk_handler(drive);
-//#ifdef _PSEUDO_BIOS_DEBUG
+#ifdef _PSEUDO_BIOS_DEBUG
                out_debug_log(_T("SASI CMD: FORMAT DL=%02x DH=%02x CX=%04x BX=%04x\n"), DL, DH, CX, BX);
-//#endif
+#endif
                if(harddisk == NULL) {
                        AH = 0x60;
                        *CarryFlag = 1;