<> <> <> <> <> <<>> <> <<>> <<***THIS IS NOT DEBUGGED YET; DON'T TRY TO RUN IT***.>> <<>> DIRECTORY DebuggerDefs, DragOpsCross USING [ProcessorRegister, XopBase, TrapBase, TrapWidthBytes, TrapIndex], --Word, wordsPerPage, bytesPerWord, charsPerWord, bitsPerByte, bitsPerCharacter, bitsPerWord, bytesPerPage, logWordsPerPage, logBitsPerByte, logBitsPerChar, logBytesPerWord, logCharsPerWord, logBitsPerWord, logBytesPerPage, PageCount, PageNumber, maxPagesInVM, SixBitIndex, FiveBitIndex, TwoWords, FourBitIndex, Half, ThreeBitIndex, FourHalves, TwoHalves, Byte, ZerosByte, OnesByte, EightBytes, FourBytes, ByteIndex, BytesPerWord, TwoBytes, Comparison, ByteAddress, WordAddress, FieldDescriptor, RegIndex, PadByte, Lit8, Op4, Op8, JDist8, Inst, OIFormat, OQBformat, LRformat, QRformat, ShortRegQR, OBformat, LRBformat, RRformat, ODBformat, LRRBformat, RJBformat, ShortRegRJB, JBBformat, TrapWidthWords, TrapWidthBytes, XopBase, TrapBase, KernalLimit, TrapIndex, StackUnderflowTrap, IFUPageFaultTrap, ResetTrap, IFUStackOverflowTrap, EUStackOverflowTrap, RescheduleTrap, ALUCondFalse, ALUCondEZ, ALUCondLZ, ALUCondLE, ALUCondSpare, ALUCondNE, ALUCondGE, ALUCondGZ, ALUCondOver, ALUCondBC, ALUCondIL, ALUCondDO, ALUCondNotOver, ALUCondNB, ALUCondNI, ModeFault, MemAccessFault, IOAccessFault, EUPageFault, EUWriteFault, AUFault, euStack, euJunk, euToKBus, euMAR, euField, euConstant, euAux, euBogus, euLast, ifuYoungestL, ifuYoungestPC, ifuEldestL, ifuEldestPC, ifuSLimit, ifuBogus, ifuL, ifuS, ifuPC, ifuLast, EURegs, EULegalRegs, IFURegs, IFULegalRegs, StackedStatusWord, IFUStackIndex, IFUStackSize, IFUOverflow, EUStackIndex, EUStackSize, EULocalIndex, EULocals, EUAuxIndex, EUAuxRegs, EUConstIndex, EUConstants, IOLocation, ioRescheduleRequest, ioResetRequest, IOOperand, PCmdFormat, PCmdByteSelect, PCmdClass, PCmdSpace, PCmdDirection DragOpsCrossUtils USING [CardToWord], --InstToBytes, InstToFormat, BytePCToWordAddress, WordAddressToBytePC, IOOperandToCard, CardToIOOperand, FieldDescriptorToCard, CardToFieldDescriptor, BytesToWord, BytesToHalf, WordToBytes, HalfToBytes, HalvesToWord, WordToHalves, HighHalf, LowHalf, LeftHalf, RightHalf, SwapHalves, WordToInt, IntToWord, WordToCard, HalfToCard, ByteToCard, CardToWord, CardToHalf, CardToByte, DragAnd, DragOr, DragXor, DragNot, VanillaAdd, VanillaSub, AddDelta, HalfNot, HalfAnd, HalfOr, HalfXor, HalfShift, DoubleWordShiftLeft, SingleWordShiftLeft, SingleWordShiftRight, XopToBytePC, TrapIndexToBytePC, FieldUnit HandCoding, --Has opcode and register defs. HandCodingPseudos, --Label, SetLabel, GenLabel, GenLabelHere, UseLabel8A, UseLabel8B, UseLabel16, UseLabel32, LReg, PReg, SReg, AddReg, SubReg, SetRegConst, MoveReg, MoveRegI, LRegI, IndexedJump, ProcedureEntry, ProcedureExit, SetupField, ExtractField, ShiftLeft, LoadProcessorReg, StoreProcessorReg, CauseReschedule, CauseReset, GetSPLimit, SetSPLimit, GetYoungestPC, GetYoungestStatus, GetEldestPC, GetEldestStatus, SetYoungestPC, SetYoungestStatus, SetEldestPC, SetEldestStatus, Pause, Halt HandCodingSupport; --Area, GetProc, PutProc, ProcList, NewArea, GenWithArea, Gen1WithArea, ForceOut, GetCurrentArea, LoadArea, GetOutputPC, SetOutputPC, WordAlign, ReserveData, OutputByte, OutputOneByte, OutputAlphaBeta, OutputAlphaBetaGammaDelta, OutputWord GenTraps2: CEDAR PROGRAM IMPORTS DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport = BEGIN OPEN DebuggerDefs, DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport; ProcessorRegister: TYPE = DragOpsCross.ProcessorRegister; <> ifuSLimit: CARDINAL = LOOPHOLE[ProcessorRegister.ifuSLimit, CARDINAL]; <> ifuEldestPC: CARDINAL = LOOPHOLE[ProcessorRegister.ifuEldestPC, CARDINAL]; ifuEldestL: CARDINAL = LOOPHOLE[ProcessorRegister.ifuEldestL, CARDINAL]; ifuYoungestPC: CARDINAL = LOOPHOLE[ProcessorRegister.ifuYoungestPC, CARDINAL]; ifuYoungestL: CARDINAL = LOOPHOLE[ProcessorRegister.ifuYoungestL, CARDINAL]; ifuStatus: CARDINAL = LOOPHOLE[ProcessorRegister.ifuStatus, CARDINAL]; euMAR: CARDINAL = LOOPHOLE[ProcessorRegister.euMAR, CARDINAL]; <> aux0: AuxRegSpec = [aux[0]]; aux1: AuxRegSpec = [aux[1]]; aux2: AuxRegSpec = [aux[2]]; aux3: AuxRegSpec = [aux[3]]; aux4: AuxRegSpec = [aux[4]]; aux5: AuxRegSpec = [aux[5]]; aux6: AuxRegSpec = [aux[6]]; aux14: AuxRegSpec = [aux[14]]; aux15: AuxRegSpec = [aux[15]]; const5: ConstSpec = [const[5]]; const6: ConstSpec = [const[6]]; const7: ConstSpec = [const[7]]; const8: ConstSpec = [const[8]]; const9: ConstSpec = [const[9]]; const10: ConstSpec = [const[10]]; const11: ConstSpec = [const[11]]; <<>> All: PROC = { --area: Area = GetCurrentArea[]; <> IFUStackOverflow: Label = GenLabel[]; IFUStkOvfBad: Label = GenLabel[]; EUStackOverflow: Label = GenLabel[]; EUStkOvfBad: Label = GenLabel[]; Reschedule: Label = GenLabel[]; RescheduleBad: Label = GenLabel[]; ErrorXop1Trap: Label = GenLabel[]; AlreadyInKernel: Label = GenLabel[]; TurnOnTraps: Label = GenLabel[]; TurnOffTraps: Label = GenLabel[]; TurnOnUserMode: Label = GenLabel[]; enterIFUStackOverflowTest: Label = GenLabel[]; enterSLimitTest: Label = GenLabel[]; enterRescheduleTest: Label = GenLabel[]; <> IFUPageFaultAddress: LONG CARDINAL = 27000000000B; <> <<>> <> <<>> <> <> FillXop: PROC [inst: CARDINAL, dest: Label] = { SetOutputPC[inst * DragOpsCross.TrapWidthBytes + DragOpsCross.XopBase * DragOpsCross.bytesPerWord]; drJDB[UseLabel16[dest]]; }; <> FillTrap: PROC [tx: DragOpsCross.TrapIndex, dest: Label] = { SetOutputPC[LOOPHOLE[tx, CARDINAL] * DragOpsCross.TrapWidthBytes + DragOpsCross.TrapBase * DragOpsCross.bytesPerWord]; drJDB[UseLabel16[dest]]; }; <<16 bytes between consecutive trap instructions is insufficient for StandardTrap, so the trap instruction must be filled separately with FillTrap[TrapName, dest]. aux8 has previously been loaded with a code for the trap presently expected (or 0 if none), and an opcode which is supposed to trap is followed by enough XPause[] opcodes to fill out 6 bytes (i.e., enough for a 5-byte trapping opcode and a 1-byte XPause[] after it); then if no trap occurs, the first XPause[] after the opcode will stop simulation; or if the wrong trap occurs, the mismatch on aux8 will cause XPause[] to occur. Otherwise, the trap procedure will return to the 6th byte after the location that trapped.>> StandardTrap: PROC [dest: Label, code: CARDINAL] = { TrapUnexpected: Label = GenLabel[]; SetLabel[dest]; drALS[1]; --ALS[1 - nargs] drLIB[code]; drRJNEB[popSrc, aux8, UseLabel8B[TrapUnexpected]]; <> GetYoungestPC[]; drRVADD[topDst, const4, topSrc]; SetYoungestPC[]; drRET[377B]; --RET[nResults - 1] SetLabel[TrapUnexpected]; Pause[]; }; <> EnableTraps: PROC [] = { drDFC[UseLabel32[TurnOnTraps]]; }; DisableTraps: PROC [] = { drDFC[UseLabel32[TurnOffTraps]]; }; EnterUser: PROC [] = { drDFC[UseLabel32[TurnOnUserMode]]; }; <> EnterKernel: PROC [] = { drLIB[12]; drROR[aux8, popSrc, topSrc]; drKFC[]; drROR[aux8, const0, const0]; }; <> XPause: PROC = { HandCodingSupport.OutputByte[HandCodingSupport.GetCurrentArea[], LOOPHOLE[2]]; }; <> GenIFUStackOverflow: PROC [] ~ { exitIFUStkOvfTest: Label = GenLabel[]; SetLabel[enterIFUStackOverflowTest]; drASL[377B]; --0 locals, 0 pushes on the EU stack, 0 calls on the IFU stack drLIB[40B + 4B + 2B]; drSIP[ifuStatus]; --UserModeKeep + TrapsEnabled + RescheduleKeep <> drLFC[3]; --1 calls drLFC[3]; --2 calls drLFC[3]; --3 calls drLFC[3]; --4 calls drLFC[3]; --5 calls drLFC[3]; --6 calls drLFC[3]; --7 calls drLFC[3]; --8 calls drLFC[3]; --9 calls drLFC[3]; --10 calls drLIQB[UseLabel32[exitIFUStkOvfTest]]; --Return PC for stack overflow trap drLIB[1]; drROR[aux8, popSrc, topSrc]; --Indicate IFU stack overflow expected drDFC[CardToWord[IFUPageFaultAddress]]; --11 calls <> SetLabel[exitIFUStkOvfTest]; drROR[aux8, const0, const0]; --Indicate no traps expected <> FOR I: CARDINAL IN [0..10] DO GetEldestPC[]; ENDLOOP; drASL[17B]; --L = 1, S = 20B, traps enabled, Kernel mode, 0 calls on the stack }; GenSLimit: PROC [] ~ { SetLabel[enterSLimitTest]; <> drASL[377B]; --S = 0, L = 1 drLIB[1]; drSIP[ifuStatus]; --Turn off trap enable, turn on Reschedule drLC0[]; drLIB[1]; drSIP[ifuSLimit]; <> drLIB[2]; drROR[aux8, topSrc, popSrc]; --S = SLimit = 1 now drLIB[4B + 1B]; drSIP[ifuStatus]; --Trap enable + Reschedule XPause[]; XPause[]; XPause[]; XPause[]; XPause[]; XPause[]; <> drROR[aux8, const0, const0]; --No trap expected drLIB[160B]; drSIP[ifuSLimit]; drASL[377B]; --L = 1, S = 0, traps disabled, Kernel mode, 0 calls on the stack }; <> GenReschedule: PROC [] ~ { RescheduleOK: Label = GenLabel[]; SetLabel[enterRescheduleTest]; drASL[17B]; --L = 1, S = 20B, 0 calls on the stack drLIQB[UseLabel32[RescheduleOK]]; --Reschedule trap will send control here drLIB[11]; drROR[aux8, popSrc, topSrc]; --Reschedule trap expected <> drLIB[40B + 4B + 1B]; --User mode keep + TrapEnable + Reschedule drSIP[ifuYoungestL]; --**was ifuStatus XPause[]; <> SetLabel[RescheduleOK]; drROR[aux8, const0, const0]; --No traps expected drLIB[40B + 1B]; --User mode keep + Reschedule (= traps disabled) drSIP[ifuYoungestL]; --Shouldn't trap; **was ifuStatus <> drLIB[40B + 4B]; drSIP[ifuYoungestL]; --**was ifuStatus <> --CauseReschedule[]; <> --drJ1[]; drJ1[]; drJ1[]; drJ1[]; drJ1[]; --XPause[]; }; <> drLIB[128-16-1]; SetSPLimit[]; drROR[aux8, const0, const0]; --Initialize aux8 to 0, meaning no traps expected. drLIB[6]; drROR[const4, popSrc, topSrc]; --Initialize const4 to 6 for the trap routines. GenIFUStackOverflow[]; GenSLimit[]; GenReschedule[]; Halt[177777B]; --Terminate here at the end of the program <> <> <> <> SetLabel[IFUStackOverflow]; drLIB[1]; drRJNEB[popSrc, aux8, UseLabel8B[IFUStkOvfBad]]; GetYoungestPC[]; drLIQB[CardToWord[IFUPageFaultAddress]]; drRJNEB[popSrc, belowSrcPop, UseLabel8B[IFUStkOvfBad]]; SetYoungestPC[]; --Change return address drRETN[]; SetLabel[IFUStkOvfBad]; Pause[]; <> SetLabel[EUStackOverflow]; drLIB[2]; drRJNEB[popSrc, aux8, UseLabel8B[EUStkOvfBad]]; GetYoungestPC[]; drRVADD[topDst, topSrc, const4]; SetYoungestPC[]; --****Turn off reschedule-waiting and disable traps drRETN[]; SetLabel[EUStkOvfBad]; Pause[]; <<****Does Reschedule-waiting have to be cleared here?>> SetLabel[Reschedule]; --Arg is the return PC drLIB[11]; drRJNEB[popSrc, aux8, UseLabel8B[RescheduleBad]]; SetYoungestPC[]; drRETN[]; SetLabel[RescheduleBad]; Pause[]; <> SetLabel[ErrorXop1Trap]; drLIQB[CardToWord[600000B]]; GetYoungestStatus[]; drAND[]; drJEBB[0, UseLabel8B[AlreadyInKernel]]; EnterKernel[]; SetLabel[AlreadyInKernel]; Pause[]; SetLabel[TurnOnTraps]; --Call here with EnableTraps[] drLIB[377B]; GetYoungestStatus[]; drAND[]; --Preserve L drLIQB[CardToWord[200000B]]; drOR[]; SetYoungestStatus[]; --Set trapsEnabled drRETN[]; SetLabel[TurnOffTraps]; --Call here with DisableTraps[] drLIB[377B]; GetYoungestStatus[]; drAND[]; --Preserve L, clear trapsEnabled and User SetYoungestStatus[]; --Set trapsEnabled drRETN[]; SetLabel[TurnOnUserMode]; --Call here with EnterUser[] drLIB[377B]; GetYoungestStatus[]; drAND[]; --Preserve L <> drLIQB[CardToWord[600000B]]; drOR[]; SetYoungestStatus[]; drRETN[]; <> FillXop[2B, ErrorXop1Trap]; FillTrap[IFUStackOverflowTrap, IFUStackOverflow]; FillTrap[EUStackOverflowTrap, EUStackOverflow]; FillTrap[EUPageFault, EUPageFlt]; FillTrap[IFUPageFaultTrap, IFUPageFault]; FillTrap[RescheduleTrap, Reschedule]; }; END.