OSDN Git Service

[VM][PC9801][I286][I86][I386][WIP] Add pseudo SASI BIOS for PC-9801.WIP.
[csp-qt/common_source_project-fm7.git] / source / src / vm / libcpu_newdev / libcpu_i386 / i386op16_real.cpp
index 70c9aa8..3100498 100644 (file)
@@ -5,9 +5,10 @@
 
 #ifdef I386_PSEUDO_BIOS
 #define BIOS_INT(num) if(cpustate->bios != NULL) { \
-       uint16_t regs[8], sregs[4]; \
+       uint16_t regs[10], sregs[4]; \
        regs[0] = REG16(AX); regs[1] = REG16(CX); regs[2] = REG16(DX); regs[3] = REG16(BX); \
        regs[4] = REG16(SP); regs[5] = REG16(BP); regs[6] = REG16(SI); regs[7] = REG16(DI); \
+       regs[8] = 0x0000; regs[9] = 0x0000; \
        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; \
                REG16(SP) = regs[4]; REG16(BP) = regs[5]; REG16(SI) = regs[6]; REG16(DI) = regs[7]; \
                cpustate->ZF = (UINT8)ZeroFlag; cpustate->CF = (UINT8)CarryFlag; \
                CYCLES(CYCLES_IRET); \
+               if((regs[8] != 0x0000) || (regs[9] != 0x0000)) {        \
+                       uint32_t hi = regs[9]; \
+                       uint32_t lo = regs[8]; \
+                       uint32_t addr = (hi << 16) | lo; \
+                       cpustate->eip = addr; \
+               }                                                                \
                return; \
        } \
 }
 
 #define BIOS_CALL_FAR(address) if(cpustate->bios != NULL) {    \
-       uint16_t regs[8], sregs[4]; \
+       uint16_t regs[10], sregs[4]; \
        regs[0] = REG16(AX); regs[1] = REG16(CX); regs[2] = REG16(DX); regs[3] = REG16(BX); \
        regs[4] = REG16(SP); regs[5] = REG16(BP); regs[6] = REG16(SI); regs[7] = REG16(DI); \
+       regs[8] = 0x0000; regs[9] = 0x0000; \
        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; \
                REG16(SP) = regs[4]; REG16(BP) = regs[5]; REG16(SI) = regs[6]; REG16(DI) = regs[7]; \
                cpustate->ZF = (UINT8)ZeroFlag; cpustate->CF = (UINT8)CarryFlag; \
                CYCLES(CYCLES_RET_INTERSEG);                                                    \
+               if((regs[8] != 0x0000) || (regs[9] != 0x0000)) {        \
+                       uint32_t hi = regs[9]; \
+                       uint32_t lo = regs[8]; \
+                       uint32_t addr = (hi << 16) | lo; \
+                       cpustate->eip = addr; \
+               }                                                                \
                return;                                                                                                                 \
        } \
 }
@@ -94,7 +108,7 @@ void I386_OPS::i386_groupFF_16()        // Opcode 0xff
                                STORE_RM16(modrm, dst);
                                CYCLES(CYCLES_INC_REG);
                        } else {
-                               UINT32 ea = GetEA(modrm,1);
+                               UINT32 ea = GetEA(modrm,1, 2);
                                UINT16 dst = READ16(ea);
                                dst = INC16(dst);
                                WRITE16(ea, dst);
@@ -108,7 +122,7 @@ void I386_OPS::i386_groupFF_16()        // Opcode 0xff
                                STORE_RM16(modrm, dst);
                                CYCLES(CYCLES_DEC_REG);
                        } else {
-                               UINT32 ea = GetEA(modrm,1);
+                               UINT32 ea = GetEA(modrm,1, 2);
                                UINT16 dst = READ16(ea);
                                dst = DEC16(dst);
                                WRITE16(ea, dst);
@@ -122,7 +136,7 @@ void I386_OPS::i386_groupFF_16()        // Opcode 0xff
                                        address = LOAD_RM16(modrm);
                                        CYCLES(CYCLES_CALL_REG);       /* TODO: Timing = 7 + m */
                                } else {
-                                       UINT32 ea = GetEA(modrm,0);
+                                       UINT32 ea = GetEA(modrm,0, 2);
                                        address = READ16(ea);
                                        CYCLES(CYCLES_CALL_MEM);       /* TODO: Timing = 10 + m */
                                }
@@ -140,7 +154,7 @@ void I386_OPS::i386_groupFF_16()        // Opcode 0xff
                                }
                                else
                                {
-                                       UINT32 ea = GetEA(modrm,0);
+                                       UINT32 ea = GetEA(modrm,0, 4);
                                        address = READ16(ea + 0);
                                        selector = READ16(ea + 2);
                                        CYCLES(CYCLES_CALL_MEM_INTERSEG);      /* TODO: Timing = 10 + m */
@@ -171,7 +185,7 @@ void I386_OPS::i386_groupFF_16()        // Opcode 0xff
                                        address = LOAD_RM16(modrm);
                                        CYCLES(CYCLES_JMP_REG);        /* TODO: Timing = 7 + m */
                                } else {
-                                       UINT32 ea = GetEA(modrm,0);
+                                       UINT32 ea = GetEA(modrm,0, 2);
                                        address = READ16(ea);
                                        CYCLES(CYCLES_JMP_MEM);        /* TODO: Timing = 10 + m */
                                }
@@ -189,7 +203,7 @@ void I386_OPS::i386_groupFF_16()        // Opcode 0xff
                                }
                                else
                                {
-                                       UINT32 ea = GetEA(modrm,0);
+                                       UINT32 ea = GetEA(modrm,0, 4);
                                        address = READ16(ea + 0);
                                        selector = READ16(ea + 2);
                                        CYCLES(CYCLES_JMP_MEM_INTERSEG);       /* TODO: Timing = 10 + m */
@@ -214,7 +228,7 @@ void I386_OPS::i386_groupFF_16()        // Opcode 0xff
                                if( modrm >= 0xc0 ) {
                                        value = LOAD_RM16(modrm);
                                } else {
-                                       UINT32 ea = GetEA(modrm,0);
+                                       UINT32 ea = GetEA(modrm,0, 2);
                                        value = READ16(ea);
                                }
                                PUSH16(value);
@@ -226,3 +240,16 @@ void I386_OPS::i386_groupFF_16()        // Opcode 0xff
                        break;
        }
 }
+
+void I386_OPS::i386__int()               // Opcode 0xcd
+{
+       int interrupt = FETCH();
+       CYCLES(CYCLES_INT);
+
+#ifdef I386_PSEUDO_BIOS
+       BIOS_INT(interrupt)
+#endif
+       cpustate->ext = 0; // not an external interrupt
+       i386_trap(interrupt, 1, 0);
+       cpustate->ext = 1;
+}