<> <> <> <> <<>> DIRECTORY DragonProcessOffsets, DragOpsCross, DragOpsCrossProcess, DragOpsCrossUtils, HandCoding, HandCodingSupport, HandCodingPseudos; GenStack: CEDAR PROGRAM IMPORTS DragOpsCrossUtils, HandCoding, HandCodingSupport, HandCodingPseudos = BEGIN OPEN DragonProcessOffsets, HandCoding, HandCodingSupport, HandCodingPseudos; <> useCST: BOOL _ FALSE; <> <<>> <> initialFrames: NAT = --5*--256; <> localFrameArraySize: NAT = --2*--16; <<# of frames in localArray>> framesToTransfer: NAT = localFrameArraySize/2; <> <<(this # should be explored)>> <> StackedStatusWord: TYPE = DragOpsCross.StackedStatusWord; Word: TYPE = DragOpsCross.Word; <> bogusPadBits: NAT _ 2; markPadBits: NAT _ 1; bogusStatus: StackedStatusWord = [ padBits: bogusPadBits, userMode: FALSE, trapsEnabled: FALSE]; bogusStatusWord: Word = LOOPHOLE[bogusStatus]; StackSize: NAT = 128; StackLog: NAT = BITS[[0..StackSize)]; <> statusMask: StackedStatusWord = [ userMode: TRUE, trapsEnabled: TRUE, lBase: StackSize-1]; <> statusMaskWord: Word = LOOPHOLE[statusMask]; regsPerNacho: NAT = 16; RegArray: TYPE = ARRAY [0..regsPerNacho) OF Word; Nacho: TYPE = LONG POINTER TO NachoRep; NachoRep: TYPE = RECORD [ link: Nacho, -- link to previous frame lastPC: Word, -- continuation PC for this frame nRegs: Word, -- number of regs used for this frame at last save others: Nacho, -- if # NIL, then it is a pointer to an aux frame regs: RegArray -- addressable by local regs ]; linkOffset: NAT = 0; constLink: ConstSpec = const0; lastPCOffset: NAT = 1; constLastPC: ConstSpec = const1; nRegsOffset: NAT = 2; constNRegs: ConstSpec = const2; othersOffset: NAT = 3; constOthers: ConstSpec = const3; regOff: CARDINAL = 4; -- offset of DumpBlock.regs LocalAllocationRep: TYPE = RECORD [ lockPtr: GlobalAllocationPtr, -- pointer to global lock for frame allocation ptrs: LocalArray -- start of frame pointers ]; LocalArray: TYPE = ARRAY [0..localFrameArraySize] OF Nacho; <> <> GlobalAllocationPtr: TYPE = LONG POINTER TO GlobalAllocationRep; GlobalAllocationRep: TYPE = RECORD [ lock: Word, -- global spin lock for frame allocation gFree: Word, -- pointer to the next free frame in frames emergency: Word, -- pointer to the emergency limit for frames frames: GlobalArray -- space for the global pool of nachos ]; GlobalArray: TYPE = ARRAY [0..initialFrames+1] OF Nacho; <> <> StackMargin: NAT _ 17; <> <> stackUnderflowTrap: Label _ NIL; <> nakedSaveFrame: Label _ NIL; <> globalFreeNacho: Label _ NIL; <> globalAllocNacho: Label _ NIL; <> <> StackUnderflowTrap: PROC [stackUnderflowTrap: Label] = { <> area: HandCodingSupport.Area _ HandCodingSupport.GetCurrentArea[]; dispatchData: Label = GenDataLabel[area, StackSize*DragOpsCross.bytesPerWord]; WordAlign[]; { <> <<>> underflowEntry1: Label = GenLabelHere[]; <> <<[S] = nRegs field of the restored frame (with status bits)>> <<>> GetEldestStatus[]; drRVSUB[topDst, topSrc, belowSrc]; ExtractField[first: 32-StackLog, bits: StackLog]; drDUP[]; <<[S] = [S-1] = the new value for L, properly masked (no status bits)>> <<[S-2] = nRegs field of the restored frame>> SetYoungestStatus[]; <> <<[S] = the new value for L (no status bits)>> <<[S-1] holds the nRegs field of the restored frame>> <> drDUP[]; <<[S] = [S-1] = new L (properly masked)>> <<[S-2] = nRegs field of the restored frame>> drSUBB[StackMargin]; ExtractField[first: 32-StackLog, bits: StackLog]; SetSPLimit[]; LRegI[hook, constLastPC]; <<[S] = return PC for restored frame>> <<[S-1] = new L (masked)>> <<[S-2] = nRegs field of the restored frame.>> drRETN[]; WordAlign[]; { MakeLabelGlobal["DragonStack.RestoreFrame", stackUnderflowTrap]; <> <> <> <<{max: caller frame, restored frame, bogus frame, FreeNacho frame}>> <> <<(plus the registers needed to restore the frame)>> <<{max: 5 = 2 at use of FreeNacho, 3 for FreeNacho}>> <<>> GetEldestPC[]; <> drDIS[]; <> }; <<>> WordAlign[]; SetLabel[stackUnderflowTrap]; MakeLabelGlobal["DragonStack.StackUnderflowTrap", stackUnderflowTrap]; <> <<>> LRegI[hook, constNRegs]; <<[S] = nRegs field of the restored frame>> drLIQB[statusMaskWord]; drAND[]; <<[S] = nRegs field & status bits for the restored frame>> <<>> drLFC[UseLabel16[underflowEntry1]]; <> <<[S] = return PC for restored frame>> <<[S-1] = new L (no status bits)>> <<[S-2] = nRegs field of the restored frame.>> SetEldestPC[]; <> <<[S] = new L (no status bits)>> <<[S-1] = nRegs field of the restored frame (with status bits, masked)>> Dupl2[]; <> drSHDR[DragOpsCrossUtils.FieldDescriptorToCard[[insert: TRUE, mask: StackLog]]]; <<[S] = new L & status bits for the restored frame>> <<[S-1] = new L (no status bits)>> <<[S-2] = nRegs field of the restored frame>> SetEldestStatus[]; <> <> <<[S] = new L (no status bits)>> <<[S-1] = nRegs field of the restored frame>> <<>> PushByteAddr[area, stackUnderflowTrap]; SetEldestPC[]; <> drADDQB[bogusStatusWord]; <> SetEldestStatus[]; <> <<>> ExtractField[first: 32-StackLog, bits: StackLog]; <<[S] = #regs (no status bits) for the restored frame>> <<>> <> <<>> PushWordAddr[area, dispatchData]; drQRX[topAtop, belowSrc]; <<[S] = dispatch PC>> <<[S-1] = #regs (no status bits)>> MoveReg[temp, hook]; <> MoveRegI[hook, hook, constLink]; <> drJSD[]; <> <<[S] = #regs (no status bits)>> }; { <> singleLabel: Label = GenLabel[]; multiLabel: Label = GenLabel[]; fatalLabel: Label = GenLabel[]; <<>> SetLabel[singleLabel]; <> <<[S] = #regs (no status bits)>> FOR i: NAT DECREASING IN [0..regsPerNacho) DO drRAI[reg1: [reg[i]], reg2: temp, disp: regOff+i]; ENDLOOP; MoveReg[topDst, temp]; FreeNacho[]; <> MakeLabelGlobal["DragonStack.StackUnderflowReturn", GenLabelHere[]]; <> <<>> drRETN[]; <> SetLabel[fatalLabel]; <> Pause[]; SetLabel[multiLabel]; <> FOR i: NAT IN [0..regsPerNacho) DO drRAI[reg1: [reg[i]], reg2: temp, disp: regOff+i]; ENDLOOP; LReg[temp]; MoveRegI[temp, temp, constOthers]; <> <<[S] = nextNacho, [S-1] = #regs>> FreeNacho[]; <> <<[S] = # regs>> <> drSUBB[regsPerNacho]; <> <<[S] = #regs left>> PushWordAddr[area, dispatchData]; drQRX[topAtop, belowSrc]; drAL[regsPerNacho]; <> drJSD[]; <> <<[S] = # of regs to save>> { <> oldPC: CARD _ HandCodingSupport.GetOutputPC[]; newPC: CARD _ dispatchData.offset; HandCodingSupport.SetOutputPC[newPC]; FOR nr: NAT DECREASING IN [0..regsPerNacho] DO OutputByteAddr[area, singleLabel, 3*nr]; ENDLOOP; FOR nr: NAT IN (regsPerNacho..regsPerNacho*4] DO OutputByteAddr[area, multiLabel, 0]; ENDLOOP; FOR nr: NAT IN (4*regsPerNacho..StackSize) DO OutputByteAddr[area, fatalLabel, 0]; ENDLOOP; HandCodingSupport.SetOutputPC[oldPC]; }; }; }; <> StackOverflowTrap: PROC [underflowLabel: Label] = { <> area: HandCodingSupport.Area _ HandCodingSupport.GetCurrentArea[]; internalSaveSetup: Label _ GenLabel[]; exitLabel: Label _ GenLabel[]; dispatchLabel: Label = GenLabel[]; dispatchData: Label = GenDataLabel[area, StackSize*DragOpsCross.bytesPerWord]; { <> ifuEntryLabel: Label = GenLabel[]; ProcedureEntry[ifuEntryLabel, 0, TRUE]; <> MakeLabelGlobal["DragonStack.IFUStackOverflowTrap", ifuEntryLabel]; FillTrap[IFUStackOverflowTrap, ifuEntryLabel]; GetEldestPC[]; <> <<[S] holds the PC for the bogus frame>> drRUADD[topDst, const0, const0]; <> <<[S] holds the carry bit>> GetEldestStatus[]; <<[S] holds the eldest status, [S-1] holds the carry bit>> <<>> AllocNacho[]; <> <<([S] = newBlock, [S-1] = eldest status)>> drLFC[UseLabel16[internalSaveSetup]]; <> <> <<[S] = #regs, [S-1] = eldest status>> SetLabel[dispatchLabel]; <> PushWordAddr[area, dispatchData]; drQRX[topAtop, belowSrc]; <> drSFC[]; <> <> <<>> <> SetLabel[exitLabel]; MakeLabelGlobal["DragonStack.StackOverflowExit", exitLabel]; <> <<>> PushByteAddr[area, underflowLabel]; SetEldestPC[]; <> ExtractField[first: 32-StackLog, bits: StackLog]; drDUP[]; drADDQB[bogusStatusWord]; SetEldestStatus[]; <> <<>> drSUBB[StackMargin]; ExtractField[first: 32-StackLog, bits: StackLog]; SetSPLimit[]; <> <<[S] holds the carry bit>> MakeLabelGlobal["DragonStack.StackOverflowReturn", GenLabelHere[]]; drRUSUB[topDst, const0, popSrc]; <> drRETN[]; <> }; { <> euEntryLabel: Label = GenLabel[]; ProcedureEntry[euEntryLabel, 0, TRUE]; <> MakeLabelGlobal["DragonStack.EUStackOverflowTrap", euEntryLabel]; FillTrap[EUStackOverflowTrap, euEntryLabel]; GetEldestPC[]; <> <<[S] holds the PC for the bogus frame>> drRUADD[topDst, const0, const0]; <> <<[S] holds the carry bit>> GetEldestStatus[]; <<[S] holds the eldest status, [S-1] holds the carry bit>> <<>> { loopLabel: Label = GenLabelHere[]; <<[S] = eldest status>> AllocNacho[]; <> <<[S] = newBlock, [S-1] = eldest status>> drLFC[UseLabel16[internalSaveSetup]]; <> <> <<[S] = #regs, [S-1] = eldest status>> drRJNEBJ[left: topSrc, right: const0, dist: UseLabel8B[dispatchLabel]]; <> drRJEBJ[popSrc, topSrc, UseLabel8B[loopLabel]]; <> <<[S] = eldest status>> }; }; { <> exitEntryLabel: Label = GenLabel[]; ProcedureEntry[exitEntryLabel, 0, TRUE]; <<>> drQADD[pushA0, const0]; <> GetEldestStatus[]; <> <<[S] holds the eldest status, [S-1] holds the carry bit>> MakeLabelGlobal["DragonStack.InstallBogusFrame", exitEntryLabel]; drJB[UseLabel8A[exitLabel]]; }; { <> exitEntryLabel: Label = GenLabel[]; ProcedureEntry[exitEntryLabel, 0]; MakeLabelGlobal["DragonStack.RemoveBogusFrame", exitEntryLabel]; GetEldestPC[]; <> <<[S] holds the PC for the bogus frame>> drRUADD[topDst, const0, const0]; <> <<[S] holds the carry bit>> GetEldestStatus[]; <<[S] holds the eldest status, [S-1] holds the carry bit>> ProcedureExit[1]; <> }; { <> <> <> <<[S] = newBlock, [S-1] = eldest status>> <> <> <<[S] = #regs, [S-1] = eldest status>> <> <<>> eldestStatus: RegSpec = reg0; localHook: RegSpec = reg1; localStatus: RegSpec = reg2; ProcedureEntry[internalSaveSetup, 2]; <> LReg[hook]; drPSB[linkOffset]; <> <<[S] = localHook = newBlock; (localHook+linkOffset)^ = hook>> PReg[hook]; PReg[temp]; <> <<[S] = localHook = hook = temp = newBlock>> LReg[eldestStatus]; ExtractField[first: 32-StackLog, bits: StackLog]; SetYoungestStatus[]; <> <<[S] = localStatus = L of frame to save; [S-1] = localHook, [S-2] = eldest status>> <<(note that the status bits must be clear in [S])>> GetEldestPC[]; drSRIn[localHook, lastPCOffset]; <> <<((localHook+lastPCOffset)^ = PC of frame to save)>> GetEldestStatus[]; <> <<[S] (aka localStatus) = eldest status (the new version)>> <<[S-1] = localHook>> <<[S-2] = eldest status (the old version)>> drRVSUB[c: pushDst, a: localStatus, b: eldestStatus]; <> <<[S] = # of regs to save (with garbage in top bits)>> <<[S-1] (aka localStatus) = status>> <<[S-2] = localHook>> <<[S-3] = eldest status>> MoveReg[eldestStatus, localStatus]; <<[S] = # of regs to save (with garbage in top bits)>> <<[S-1] (aka localStatus) = eldest status (the new version)>> <<[S-2] = localHook>> <<[S-3] = eldest status (the new version)>> drSHDR[DragOpsCrossUtils.FieldDescriptorToCard[[insert: TRUE, mask: StackLog]]]; <> <<[S] (aka localStatus) = #regs (+ status bits)>> <<[S-1] (aka localHook)>> <<[S-2] = eldest status>> drWRI[localStatus, localHook, nRegsOffset]; <> <<(localHook+nRegsOffset)^ _ localStatus>> <<[S] = #regs, [S-1] = localHook, [S-2] = eldest status>> <<>> drSHDR[DragOpsCrossUtils.FieldDescriptorToCard[[mask: StackLog]]]; <<[S] = #regs, [S-1] = eldest status>> ProcedureExit[2]; <> <<[S] = #regs, [S-1] = eldest status>> }; { <> <> <<[S] = the sampled eldest status>> <<[S-1] = the sampled carry bit>> <> <<{max: caller frame, internalSaveSetup/AllocNacho frame}>> <> <<{max: 6 = 2 at first use of AllocNacho + 4 for AllocNacho}>> <> <<[S] = the sampled eldest status>> <<[S-1] = the sampled carry bit>> singleLabel: Label = GenLabel[]; multiLabel: Label = GenLabel[]; fatalLabel: Label = GenLabel[]; shortLabel: Label = GenLabel[]; SetLabel[nakedSaveFrame]; MakeLabelGlobal["DragonStack.NakedSaveFrame", nakedSaveFrame]; AllocNacho[]; <> <<[S] = newBlock, [S-1] = eldest status, [S-2] = sampled carry bit>> drLFC[UseLabel16[internalSaveSetup]]; <> <<[S] = #regs, [S-1] = eldest status, [S-2] = sampled carry bit>> PushWordAddr[area, dispatchData]; drQRX[topAtop, belowSrc]; <> drJSD[]; <> <> SetLabel[singleLabel]; FOR i: NAT DECREASING IN [0..regsPerNacho) DO drWAI[reg1: [reg[i]], reg2: temp, disp: regOff+i]; ENDLOOP; drDIS[]; <> drRETN[]; <> <<[S] = new eldest status, [S-1] = sampled carry bit>> <<>> SetLabel[fatalLabel]; <> Pause[]; <<>> SetLabel[multiLabel]; FOR i: NAT IN [0..regsPerNacho) DO drWAI[reg1: [reg[i]], reg2: temp, disp: regOff+i]; ENDLOOP; <> LReg[temp]; <> <<[S] = temp = oldBlock; [S-1] = #regs; [S-2] = eldest status; [S-3] = sampled carry>> AllocNacho[]; -- EU stack high water mark: 8 regs <> <<[S] = newBlock; [S-1] = temp = oldBlock; [S-2] = #regs>> <<[S-3] = eldest status; [S-4] = sampled carry>> PReg[temp]; drWSB[othersOffset]; <> <> <<(temp = (temp'+othersOffset)^ = newBlock; [S] = #regs)>> drSUBB[regsPerNacho]; <> <<[S] = #regs, [S-1] = eldest status>> PushWordAddr[area, dispatchData]; drQRX[topAtop, belowSrc]; <> drAL[regsPerNacho]; <> drJSD[]; <> <<[S] = #regs, [S-1] = eldest status, [S-2] = sampled carry bit>> <<>> { <> oldPC: CARD _ HandCodingSupport.GetOutputPC[]; HandCodingSupport.SetOutputPC[dispatchData.offset]; FOR nr: NAT DECREASING IN [0..regsPerNacho] DO OutputByteAddr[area, singleLabel, 3*nr]; ENDLOOP; FOR nr: NAT IN (regsPerNacho..regsPerNacho*4] DO OutputByteAddr[area, multiLabel, 0]; ENDLOOP; FOR nr: NAT IN (4*regsPerNacho..StackSize) DO OutputByteAddr[area, fatalLabel, 0]; ENDLOOP; HandCodingSupport.SetOutputPC[oldPC]; }; }; }; <> AllocNacho: PROC = { <> <> exitLabel: Label = GenLabel[]; enterLabel: Label = GenLabelHere[]; LRegI[free, const0]; <> drLC0[]; <> drRJNEBJ[left: topSrc, right: belowSrc, dist: UseLabel8B[exitLabel]]; <> drLFC[UseLabel16[globalAllocNacho]]; <> drJB[UseLabel8A[enterLabel]]; <> SetLabel[exitLabel]; <> AddReg[free, const1]; <> <<[S] = 0, [S-1] = new nacho>> drPSB[othersOffset]; <> <<[S] = new nacho>> }; GlobalAllocNacho: PROC = { <> <> exitLabel: Label = GenLabel[]; globalAllocNacho _ GenLabelHere[]; MakeLabelGlobal["DragonStack.GlobalAllocNacho", globalAllocNacho]; drRRX[c: belowDst, a: base, b: popSrc]; <> <<[S] = @lock>> LReg[process]; <> <<[S] = process; [S-1] = @lock>> IF useCST THEN { drLC0[]; <> <<[S] = 0; [S-1] = process; [S-2] = @lock>> {retryLabel: Label = GenLabelHere[]; drCST[0]; <> <<[S] = sample; [S-1] = 0; [S-2] = process; [S-3] = @lock>> drRJNEB[left: popSrc, right: belowSrc, dist: UseLabel8B[retryLabel]]; <> <<[S] = 0; [S-1] = process; [S-2] = @lock>> drAS[256-2]; <> <<[S] = @lock>> }; } ELSE { <> drPSB[0]; }; drRSB[1]; <> <<@base.gFree = @base.lock + 1>> <<[S] = gFree; [S-1] = @lock>> drLIB[framesToTransfer]; drRVSUB[free, free, popSrc]; <> FOR i: NAT IN [0..framesToTransfer) DO drRSB[i]; LReg[free]; <> <<[S] = free, [S-1] = word from nacho, [S-2] = gFree, [S-3] = @lock>> drWB[i]; <<(free+i)^ _ (gFree+i)^>> ENDLOOP; drADDB[framesToTransfer]; <> <<[S] = new gFree; [S-1] = @lock>> drPSB[1]; <> <<[S] = @lock>> drLC0[]; drWSB[0]; <> <> drRETN[]; }; FreeNacho: PROC [] = { <> <> <> exitLabel: Label = GenLabel[]; enterLabel: Label = GenLabelHere[]; drRVSUB[c: pushDst, a: free, b: const1]; <<[S] = free-1; [S-1] = nacho to free>> drRJNEBJ[left: topSrc, right: base, dist: UseLabel8B[exitLabel]]; <> drLFC[UseLabel16[globalFreeNacho]]; <> <> SetLabel[exitLabel]; <> PReg[free]; drWB[0]; <<(free _ [S])^ _ [S-1]; S_S-2>> }; GlobalFreeNacho: PROC = { <> <<>> <> <> <<(does not include the argument register)>> <> <<>> lockReg: RegSpec = reg0; globalFreeNacho _ GenLabel[]; ProcedureEntry[globalFreeNacho, 1]; MakeLabelGlobal["DragonStack.GlobalFreeNacho", globalFreeNacho]; drRB[0]; <> <<[S] = @lock>> LReg[process]; <> <<[S] = process; [S-1] = @lock>> IF useCST THEN { drLC0[]; <> <<[S] = 0; [S-1] = process; [S-2] = @lock>> <> <<>> {retryLabel: Label = GenLabelHere[]; drCST[0]; <> <<[S] = sample; [S-1] = 0; [S-2] = process; [S-3] = @lock>> drRJNEB[left: popSrc, right: belowSrc, dist: UseLabel8B[retryLabel]]; <> <<[S] = 0; [S-1] = process; [S-2] = @lock>> drAS[256-2]; <> <<[S] = @lock>> } } ELSE { <> drPSB[0]; }; drRSB[1]; <> <<[S] = gFree; [S-1] = @lock>> drLIB[framesToTransfer]; <<[S] = framesToTransfer; [S-1] = gFree; [S-2] = @lock>> { gFreeReg: RegSpec = reg1; dataReg: RegSpec = reg2; drRVSUB[gFreeReg, gFreeReg, topSrc]; <> <<[S] = framesToTransfer; [S-1] = new gFree; [S-2] = @lock>> FOR i: NAT IN [0..framesToTransfer) DO drRAI[reg1: dataReg, reg2: free, disp: i]; drWRI[reg1: dataReg, reg2: gFreeReg, disp: i]; <<(gFree+i)^ _ (free+i)^>> <> ENDLOOP; drDIS[]; <<[S] = gFree; [S-1] = @lock>> }; drPSB[1]; <> <<[S] = @lock>> drLC0[]; drWSB[0]; <> <> drLIB[framesToTransfer-1]; drRVADD[c: topDst, a: topSrc, b: free]; <<[S] = free + (framesToTransfer-1)>> <> ProcedureExit[1]; <<[S] = new free ptr>> }; <> GenFramesInit: PROC = { allocator: Label = HandCodingPseudos.GetGlobalLabel["Basics.AllocVector"]; rZero: RegSpec = reg0; rLB: RegSpec = reg1; -- base of local frame table rSB: RegSpec = reg2; -- base of shared frame table tPtr: RegSpec = reg3; -- pointer to next slot in global table drLC0[]; -- init rZero drLIB[SIZE[LocalAllocationRep]/2]; drLFC[UseLabel16[allocator]]; drROR[base, topSrc, const0]; <> <> drLIDB[framesToTransfer*2+initialFrames]; drLFC[UseLabel16[allocator]]; drWRI[rSB, rLB, 0]; <> <> drWRI[rZero, rSB, 0]; drWRI[rZero, rSB, 2]; <> drRVADD[pushDst, rSB, const3]; drWRI[tPtr, rSB, 1]; <> { <> loopLabel: Label = GenLabelHere[]; drLIB[20]; drLFC[UseLabel16[allocator]]; drSRIn[tPtr, 0]; <> drRVADD[tPtr, tPtr, const1]; drLRn[tPtr]; drSUBDB[initialFrames]; drRJNEBJ[left: popSrc, right: rSB, dist: UseLabel8B[loopLabel]]; <> }; drLIB[17]; drRADD[free, base, popSrc]; drWRI[rZero, rLB, 17]; <> <> drAS[256-4]; <> }; All: PROC = { area: HandCodingSupport.Area _ HandCodingSupport.GetCurrentArea[]; continueLabel: Label = GenLabel[]; toUserLabel: Label = GenLabel[]; underflowLabel: Label = GenLabel[]; nakedSaveFrame _ GenLabel[]; <> GenFramesInit[]; drLFC[UseLabel16[continueLabel]]; <> GlobalAllocNacho[]; GlobalFreeNacho[]; StackUnderflowTrap[underflowLabel]; StackOverflowTrap[underflowLabel]; SetLabel[continueLabel]; <> PushWordAddr[area, underflowLabel]; SetYoungestPC[]; GetYoungestStatus[]; drLIQB[LOOPHOLE[DragOpsCross.StackedStatusWord[trapsEnabled: TRUE]]]; drOR[]; drDFC[UseLabel32[HandCodingPseudos.GetGlobalLabel["Basics.SetStatus"]]]; drLFC[UseLabel16[toUserLabel]]; <> Pause[]; SetLabel[toUserLabel]; drLC0[]; MakeLabelGlobal["DragonStack.ExitToUser", toUserLabel]; }; <> FillTrap: PROC [tx: DragOpsCross.TrapIndex, dest: Label] = { area: HandCodingSupport.Area = HandCodingSupport.GetCurrentArea[]; oldPC: CARD = HandCodingSupport.GetOutputPC[area]; SetOutputPC[DragOpsCrossUtils.TrapIndexToBytePC[tx]]; drJDB[UseLabel16[dest]]; HandCodingSupport.SetOutputPC[oldPC]; }; Dupl2: PROC = { <> <> <> drQOR[pushA0, belowSrc]; drQOR[pushA0, belowSrc]; }; END.