UINT32 opTESTB(void) /* TRUSTED */ { modAdd=PC+1; modDim=0; /* Read the operand */ amLength1=ReadAM(); _Z = (amOut == 0); _S = ((amOut & 0x80) != 0); _CY = 0; _OV = 0; return amLength1 + 1; }
static UINT32 opSTTASK(v60_state *cpustate) { int i; UINT32 adr; cpustate->modadd = cpustate->PC + 1; cpustate->moddim = 2; cpustate->amlength1 = ReadAM(cpustate); adr = cpustate->TR; v60WritePSW(cpustate, v60ReadPSW(cpustate) | 0x10000000); v60SaveStack(cpustate); cpustate->program->write_dword_unaligned(adr, cpustate->TKCW); adr += 4; if(cpustate->SYCW & 0x100) { cpustate->program->write_dword_unaligned(adr, cpustate->L0SP); adr += 4; } if(cpustate->SYCW & 0x200) { cpustate->program->write_dword_unaligned(adr, cpustate->L1SP); adr += 4; } if(cpustate->SYCW & 0x400) { cpustate->program->write_dword_unaligned(adr, cpustate->L2SP); adr += 4; } if(cpustate->SYCW & 0x800) { cpustate->program->write_dword_unaligned(adr, cpustate->L3SP); adr += 4; } // 31 registers supported, _not_ 32 for(i = 0; i < 31; i++) if(cpustate->amout & (1 << i)) { cpustate->program->write_dword_unaligned(adr, cpustate->reg[i]); adr += 4; } // #### Ignore the virtual addressing crap. return cpustate->amlength1 + 1; }
UINT32 opSTTASK(void) { int i; UINT32 adr; modAdd=PC + 1; modDim=2; amLength1 = ReadAM(); adr = TR; v60WritePSW(v60ReadPSW() | 0x10000000); v60SaveStack(); MemWrite32(adr, TKCW); adr += 4; if(SYCW & 0x100) { MemWrite32(adr, L0SP); adr += 4; } if(SYCW & 0x200) { MemWrite32(adr, L1SP); adr += 4; } if(SYCW & 0x400) { MemWrite32(adr, L2SP); adr += 4; } if(SYCW & 0x800) { MemWrite32(adr, L3SP); adr += 4; } /* 31 registers supported, _not_ 32 */ for(i=0; i<31; i++) if(amOut & (1<<i)) { MemWrite32(adr, v60.reg[i]); adr += 4; } /* #### Ignore the virtual addressing crap. */ return amLength1 + 1; }
static UINT32 opPREPARE(v60_state *cpustate) /* somewhat TRUSTED */ { cpustate->modadd = cpustate->PC + 1; cpustate->moddim = 2; // Read the operand cpustate->amlength1 = ReadAM(cpustate); // step 1: save frame pointer on the stack cpustate->SP -= 4; cpustate->program->write_dword_unaligned(cpustate->SP, cpustate->FP); // step 2: cpustate->FP = new cpustate->SP cpustate->FP = cpustate->SP; // step 3: cpustate->SP -= operand cpustate->SP -= cpustate->amout; return cpustate->amlength1 + 1; }
UINT32 opPREPARE(void) /* somewhat TRUSTED */ { modAdd=PC+1; modDim=2; /* Read the operand */ amLength1=ReadAM(); /* step 1: save frame pointer on the stack */ SP -= 4; MemWrite32(SP, FP); /* step 2: FP = new SP */ FP = SP; /* step 3: SP -= operand */ SP -= amOut; return amLength1 + 1; }
static UINT32 opRET(v60_state *cpustate) /* TRUSTED */ { cpustate->modadd = cpustate->PC + 1; cpustate->moddim = 2; // Read the operand ReadAM(cpustate); // Read return address from stack cpustate->PC = cpustate->program->read_dword_unaligned(cpustate->SP); cpustate->SP +=4; // Restore cpustate->AP from stack cpustate->AP = cpustate->program->read_dword_unaligned(cpustate->SP); cpustate->SP +=4; // Skip stack frame cpustate->SP += cpustate->amout; return 0; }
UINT32 opRET(void) /* TRUSTED */ { modAdd=PC + 1; modDim=2; /* Read the operand */ ReadAM(); /* Read return address from stack */ PC=MemRead32(SP); SP+=4; ChangePC(PC); /* Restore AP from stack */ AP=MemRead32(SP); SP+=4; /* Skip stack frame */ SP += amOut; return 0; }
static UINT32 opRETIU(v60_state *cpustate) /* TRUSTED */ { UINT32 newPSW; cpustate->modadd = cpustate->PC + 1; cpustate->moddim = 1; // Read the operand ReadAM(cpustate); // Restore cpustate->PC and cpustate->PSW from stack cpustate->PC = cpustate->program->read_dword_unaligned(cpustate->SP); cpustate->SP += 4; newPSW = cpustate->program->read_dword_unaligned(cpustate->SP); cpustate->SP += 4; // Destroy stack frame cpustate->SP += cpustate->amout; v60WritePSW(cpustate, newPSW); return 0; }
UINT32 opRETIU(void) /* TRUSTED */ { UINT32 newPSW; modAdd=PC + 1; modDim=1; /* Read the operand */ ReadAM(); /* Restore PC and PSW from stack */ PC = MemRead32(SP); SP += 4; ChangePC(PC); newPSW = MemRead32(SP); SP += 4; /* Destroy stack frame */ SP += amOut; v60WritePSW(newPSW); return 0; }
static UINT32 opTRAP(v60_state *cpustate) { UINT32 oldPSW; cpustate->modadd = cpustate->PC + 1; cpustate->moddim = 0; // Read the operand cpustate->amlength1 = ReadAM(cpustate); // Normalize the flags NORMALIZEFLAGS(cpustate); switch ((cpustate->amout >> 4) & 0xF) { case 0: if (!cpustate->_OV) return cpustate->amlength1 + 1; else break; case 1: if (cpustate->_OV) return cpustate->amlength1 + 1; else break; case 2: if (!cpustate->_CY) return cpustate->amlength1 + 1; else break; case 3: if (cpustate->_CY) return cpustate->amlength1 + 1; else break; case 4: if (!cpustate->_Z) return cpustate->amlength1 + 1; else break; case 5: if (cpustate->_Z) return cpustate->amlength1 + 1; else break; case 6: if (!(cpustate->_CY | cpustate->_Z)) return cpustate->amlength1 + 1; else break; case 7: if ((cpustate->_CY | cpustate->_Z)) return cpustate->amlength1 + 1; else break; case 8: if (!cpustate->_S) return cpustate->amlength1 + 1; else break; case 9: if (cpustate->_S) return cpustate->amlength1 + 1; else break; case 10: break; case 11: return cpustate->amlength1 + 1; case 12: if (!(cpustate->_S^cpustate->_OV)) return cpustate->amlength1 + 1; else break; case 13: if ((cpustate->_S^cpustate->_OV)) return cpustate->amlength1 + 1; else break; case 14: if (!((cpustate->_S^cpustate->_OV)|cpustate->_Z)) return cpustate->amlength1 + 1; else break; case 15: if (((cpustate->_S^cpustate->_OV)|cpustate->_Z)) return cpustate->amlength1 + 1; else break; } oldPSW = v60_update_psw_for_exception(cpustate, 0, 0); // Issue the software trap with interrupts cpustate->SP -= 4; cpustate->program->write_dword_unaligned(cpustate->SP, EXCEPTION_CODE_AND_SIZE(0x3000 + 0x100 * (cpustate->amout & 0xF), 4)); cpustate->SP -= 4; cpustate->program->write_dword_unaligned(cpustate->SP, oldPSW); cpustate->SP -= 4; cpustate->program->write_dword_unaligned(cpustate->SP, cpustate->PC + cpustate->amlength1 + 1); cpustate->PC = GETINTVECT(cpustate, 48 + (cpustate->amout & 0xF)); return 0; }
UINT32 opTRAP(void) { UINT32 oldPSW; modAdd=PC + 1; modDim=0; /* Read the operand */ amLength1=ReadAM(); /* Normalize the flags */ NORMALIZEFLAGS(); switch ((amOut >> 4) & 0xF) { case 0: if (!_OV) return amLength1+1; else break; case 1: if (_OV) return amLength1+1; else break; case 2: if (!_CY) return amLength1+1; else break; case 3: if (_CY) return amLength1+1; else break; case 4: if (!_Z) return amLength1+1; else break; case 5: if (_Z) return amLength1+1; else break; case 6: if (!(_CY | _Z)) return amLength1+1; else break; case 7: if ((_CY | _Z)) return amLength1+1; else break; case 8: if (!_S) return amLength1+1; else break; case 9: if (_S) return amLength1+1; else break; case 10: break; case 11: return amLength1+1; case 12: if (!(_S^_OV)) return amLength1+1; else break; case 13: if ((_S^_OV)) return amLength1+1; else break; case 14: if (!((_S^_OV)|_Z)) return amLength1+1; else break; case 15: if (((_S^_OV)|_Z)) return amLength1+1; else break; } oldPSW = v60_update_psw_for_exception(0, 0); /* Issue the software trap with interrupts */ SP -= 4; MemWrite32(SP, EXCEPTION_CODE_AND_SIZE(0x3000 + 0x100 * (amOut&0xF), 4)); SP -= 4; MemWrite32(SP, oldPSW); SP -= 4; MemWrite32(SP, PC + amLength1 + 1); PC = GETINTVECT(48 + (amOut&0xF)); ChangePC(PC); return 0; }