<> <> <> <<>> <> DIRECTORY DragOpsCross, DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport; GenRichards: CEDAR PROGRAM IMPORTS DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport = BEGIN OPEN DragOpsCross, DragOpsCrossUtils, HandCoding, HandCodingPseudos; Area: TYPE = HandCodingSupport.Area; <> <<2.56 seconds on a Dorado>> <> <<>> <> gZ: NAT = 0; gQueuePacketCount: NAT = 1; gHoldCount: NAT = 2; gTaskTable: NAT = 3; gTaskTableSize: NAT = 7; gTaskList: NAT = 10; gCurrentTask: NAT = 11; gCurrentTaskIdentity: NAT = 12; gAllocObjects: NAT = 13; gAllocWords: NAT = 14; gAllocBase: NAT = 15; gAllocPtr: NAT = 16; gAllocPtrPtr: NAT = 17; <> gIdleFunction: NAT = 18; gDeviceFunction: NAT = 19; gHandlerFunction: NAT = 20; gWorkFunction: NAT = 21; gSIZE: NAT = 22; <> globalFrameCard: LONG CARDINAL; -- global frame base globalFrame: Word; -- global frame base as word externalAlloc: Label _ NIL; externalMove: Label _ NIL; enterInit: Label _ NIL; enterAlloc: Label _ NIL; enterInitScheduler: Label _ NIL; enterCreateTask: Label _ NIL; enterCreatePacket: Label _ NIL; enterQueuePacket: Label _ NIL; enterAppend: Label _ NIL; enterSchedule: Label _ NIL; enterWait: Label _ NIL; enterHoldSelf: Label _ NIL; enterRelease: Label _ NIL; enterFindTask: Label _ NIL; enterCreateIdler: Label _ NIL; enterIdleFunction: Label _ NIL; enterCreateDevice: Label _ NIL; enterDeviceFunction: Label _ NIL; enterCreateHandler: Label _ NIL; enterHandlerFunction: Label _ NIL; enterCreateWorker: Label _ NIL; enterWorkFunction: Label _ NIL; enterMain: Label _ NIL; <> <> <> <> <> <> <> <> <<>> tcbLink: NAT = 0; tcbIdentity: NAT = 1; tcbPriority: NAT = 2; tcbInput: NAT = 3; tcbState: NAT = 4; tcbFunction: NAT = 5; tcbHandle: NAT = 6; tcbSIZE: NAT = 7; <> <> <> <> <> <> <> <<>> pktLink: NAT = 0; pktIdentity: NAT = 1; pktKind: NAT = 2; pktDatum: NAT = 3; pktData: NAT = 4; pktBufferSize: NAT = 3; pktSIZE: NAT = pktData+pktBufferSize+1; pktKdevicePacketKind: NAT = 0; pktKworkPacketKind: NAT = 1; waiting: Word = CardToWord[10000000000B]; waitingWithPacket: Word = CardToWord[30000000000B]; <> packetPending: NAT = 31; taskWaiting: NAT = 30; taskHolding: NAT = 29; All: PROC = { <> area: Area = HandCodingSupport.GetCurrentArea[]; externalAlloc _ HandCodingPseudos.GetGlobalLabel["Basics.AllocVector"]; externalMove _ HandCodingPseudos.GetGlobalLabel["Basics.MoveVector"]; enterInit _ GenLabel[]; enterInitScheduler _ GenLabel[]; enterCreateTask _ GenLabel[]; enterCreatePacket _ GenLabel[]; enterQueuePacket _ GenLabel[]; enterAppend _ GenLabel[]; enterSchedule _ GenLabel[]; enterWait _ GenLabel[]; enterHoldSelf _ GenLabel[]; enterRelease _ GenLabel[]; enterFindTask _ GenLabel[]; enterCreateIdler _ GenLabel[]; enterIdleFunction _ GenLabel[]; enterCreateDevice _ GenLabel[]; enterDeviceFunction _ GenLabel[]; enterCreateHandler _ GenLabel[]; enterHandlerFunction _ GenLabel[]; enterCreateWorker _ GenLabel[]; enterWorkFunction _ GenLabel[]; enterMain _ GenLabel[]; enterAlloc _ GenLabel[]; GenInit[]; -- global frame initialization comes first GenAlloc[]; -- our pet simple allocator GenInitScheduler[]; GenCreateTask[]; GenCreatePacket[]; GenQueuePacket[]; GenAppend[]; GenSchedule[]; GenWait[]; GenHoldSelf[]; GenRelease[]; GenFindTask[]; GenCreateIdler[]; GenIdleFunction[]; GenCreateDevice[]; GenDeviceFunction[]; GenCreateHandler[]; GenHandlerFunction[]; GenCreateWorker[]; GenWorkFunction[]; GenMain[]; <> <> HandCodingSupport.SetOutputPC[globalFrameCard * bytesPerWord]; HandCodingSupport.OutputWord[area, ZerosWord]; }; GenInit: PROC = { <> area: Area = HandCodingSupport.GetCurrentArea[]; startLabel: Label = GenLabelHere[]; HandCodingPseudos.MakeLabelGlobal["Richards.Init", startLabel]; <> globalFrameCard _ HandCodingSupport.ReserveData[1*wordsPerPage] / bytesPerWord; globalFrame _ CardToWord[globalFrameCard]; { <> <<>> G: RegSpec = reg0; top: RegSpec = reg1; <<>> drASL[255]; -- ensure that stack is empty, regardless of where it was drLIQB[globalFrame]; drLC0[]; <> drLIQB[UseLabel32[enterIdleFunction]]; drSRIn[G, gIdleFunction]; drLIQB[UseLabel32[enterDeviceFunction]]; drSRIn[G, gDeviceFunction]; drLIQB[UseLabel32[enterHandlerFunction]]; drSRIn[G, gHandlerFunction]; drLIQB[UseLabel32[enterWorkFunction]]; drSRIn[G, gWorkFunction]; drLIDB[256+1]; drLFC[UseLabel16[externalAlloc]]; drSRIn[G, gAllocBase]; <> drLRIn[G, gAllocBase]; drLIDB[256]; drWSB[0]; <> drLIQB[UseLabel32[enterAlloc]]; drSRIn[G, gAllocPtr]; <> <<>> drLRn[G]; drADDB[gAllocPtr]; drSRIn[G, gAllocPtrPtr]; <> drLRn[G]; drADDB[gAllocPtrPtr]; drSRIn[G, gZ]; <> drLFC[UseLabel16[enterMain]]; <> }; }; GenAlloc: PROC = { <> returnLabel: Label = GenLabel[]; rZ: RegSpec = reg0; rWords: RegSpec = reg1; G: RegSpec = reg2; rIndex: RegSpec = reg3; ProcedureEntry[enterAlloc, 2]; HandCodingPseudos.MakeLabelGlobal["Richards.Alloc", enterAlloc]; drLIQB[globalFrame]; drLRIn[G, gAllocWords]; <> drLRIn[G, gAllocObjects]; drADDB[1]; drSRIn[G, gAllocObjects]; <> drLRIn[G, gAllocWords]; drQADD[topAtop, rWords]; drSRIn[G, gAllocWords]; <> drLRn[rIndex]; drLRIn[G, gAllocBase]; drRB[0]; drBC[]; drLRIn[G, gAllocBase]; drADDB[1]; drADD[]; <> drSRn[rZ]; ProcedureExit[1]; }; GenInitScheduler: PROC = { <> G: RegSpec = reg0; rZero: RegSpec = reg1; ProcedureEntry[enterInitScheduler, 0]; HandCodingPseudos.MakeLabelGlobal["Richards.InitScheduler", enterInitScheduler]; drLIQB[globalFrame]; drLC0[]; drWRI[rZero, G, gQueuePacketCount]; drWRI[rZero, G, gHoldCount]; <> drWRI[rZero, G, gAllocWords]; drWRI[rZero, G, gAllocObjects]; <> drWRI[rZero, G, gTaskTable]; drWRI[rZero, G, gTaskTable+1]; drWRI[rZero, G, gTaskTable+2]; drWRI[rZero, G, gTaskTable+3]; drWRI[rZero, G, gTaskTable+4]; drWRI[rZero, G, gTaskTable+5]; drWRI[rZero, G, gTaskTable+6]; <> drWRI[rZero, G, gTaskList]; <> ProcedureExit[0]; }; GenCreateTask: PROC = { <> rIdentity: RegSpec = reg0; rPriority: RegSpec = reg1; rInitialWorkQueue: RegSpec = reg2; rInitialState: RegSpec = reg3; rFunction: RegSpec = reg4; rPrivateData: RegSpec = reg5; G: RegSpec = reg6; rT: RegSpec = reg7; ProcedureEntry[enterCreateTask, 6]; HandCodingPseudos.MakeLabelGlobal["Richards.CreateTask", enterCreateTask]; drLIQB[globalFrame]; drLC0[]; { <> <> <> <> <> <> <> <> drLRIn[G, gZ]; drLIB[tcbSIZE]; drLRIn[G, gZ]; drRB[0]; drRB[0]; drSFC[]; drSRn[rT]; <> drLRIn[G, gTaskList]; drSRIn[rT, tcbLink]; <> drWRI[rIdentity, rT, tcbIdentity]; <> drWRI[rPriority, rT, tcbPriority]; <> drWRI[rInitialWorkQueue, rT, tcbInput]; <> drWRI[rInitialState, rT, tcbState]; <> drWRI[rFunction, rT, tcbFunction]; <> drWRI[rPrivateData, rT, tcbHandle]; <> }; drLRn[rT]; drSRIn[G, gTaskList]; <> <<>> drLRn[rT]; drRADD[pushDst, G, rIdentity]; drWB[gTaskTable]; <> ProcedureExit[0]; }; GenCreatePacket: PROC = { <> <> rLink: RegSpec = reg0; rIdentity: RegSpec = reg1; rKind: RegSpec = reg2; rWorkQueue: RegSpec = reg3; G: RegSpec = reg4; rZero: RegSpec = reg5; ProcedureEntry[enterCreatePacket, 3]; HandCodingPseudos.MakeLabelGlobal["Richards.CreatePacket", enterCreatePacket]; drLC0[]; drLIQB[globalFrame]; drLC0[]; { <> <> <> <> <> <> drLRIn[G, gZ]; drLIB[pktSIZE]; drLRIn[G, gZ]; drRB[0]; drRB[0]; drSFC[]; drSRn[rWorkQueue]; <> drWRI[rLink, rWorkQueue, pktLink]; <> drWRI[rIdentity, rWorkQueue, pktIdentity]; <> drWRI[rKind, rWorkQueue, pktKind]; <> drWRI[rZero, rWorkQueue, pktDatum]; <> drWRI[rZero, rWorkQueue, pktData]; drWRI[rZero, rWorkQueue, pktData+1]; drWRI[rZero, rWorkQueue, pktData+2]; drWRI[rZero, rWorkQueue, pktData+3]; <> }; drROR[reg0, const0, rWorkQueue]; <> ProcedureExit[1]; }; GenQueuePacket: PROC = { <> rPacket: RegSpec = reg0; rTask: RegSpec = reg1; G: RegSpec = reg2; rT: RegSpec = reg3; returnLabel: Label = GenLabel[]; ProcedureEntry[enterQueuePacket, 1]; HandCodingPseudos.MakeLabelGlobal["Richards.QueuePacket", enterQueuePacket]; drLC0[]; drLIQB[globalFrame]; drLRIn[rPacket, pktIdentity]; drLFC[UseLabel16[enterFindTask]]; <> <<>> {fiLabel: Label = GenLabel[]; drLRn[rT]; drJNEBBJ[0, UseLabel8B[fiLabel]]; drLC0[]; drJB[UseLabel8A[returnLabel]]; <> SetLabel[fiLabel]; }; <<>> drLRIn[G, gQueuePacketCount]; drLIDB[23246]; drRJGEBJ[left: popSrc, right: belowSrcPop, dist: 6]; Halt[201B]; -- bomb out here if the queuePacketCount gets too large drLRIn[G, gQueuePacketCount]; drADDB[1]; drSRIn[G, gQueuePacketCount]; <> drLC0[]; drSRIn[rPacket, pktLink]; <> drLRIn[G, gCurrentTaskIdentity]; drSRIn[rPacket, pktIdentity]; <> <<>> { elseLabel: Label = GenLabel[]; fiLabel: Label = GenLabel[]; drLRIn[rT, tcbInput]; drJNEBB[0, UseLabel8B[elseLabel]]; <> <<>> drWRI[rPacket, rT, tcbInput]; <> drLRIn[rT, tcbState]; drLC1[]; drSHDR[FieldDescriptorToCard[[insert: TRUE, mask: packetPending+1, shift: packetPending]]]; drSRIn[rT, tcbState]; <> drLRIn[rT, tcbPriority]; drLRIn[G, gCurrentTask]; drRB[tcbPriority]; drRJGEBJ[left: popSrc, right: belowSrcPop, dist: UseLabel8B[fiLabel]]; < currentTask.priority THEN ...>> drLRn[rT]; drJB[UseLabel8A[returnLabel]]; <<... RETURN [t]>> SetLabel[elseLabel]; drLRn[rPacket]; drRADD[pushDst, rT, const3]; drLFC[UseLabel16[enterAppend]]; <> <> SetLabel[fiLabel]; }; drLRIn[G, gCurrentTask]; SetLabel[returnLabel]; drSRn[reg0]; <> ProcedureExit[1]; }; GenAppend: PROC = { <> rPacket: RegSpec = reg0; rHead: RegSpec = reg1; G: RegSpec = reg2; rZero: RegSpec = reg3; returnLabel: Label = GenLabel[]; ProcedureEntry[enterAppend, 2]; HandCodingPseudos.MakeLabelGlobal["Richards.Append", enterAppend]; drLIQB[globalFrame]; drLC0[]; drWRI[rZero, rPacket, pktLink]; <> <<>> {fiLabel: Label = GenLabel[]; drLRIn[rHead, 0]; drJNEBBJ[0, UseLabel8B[fiLabel]]; drWRI[rPacket, rHead, 0]; ProcedureExit[0]; <> SetLabel[fiLabel]; }; <<>> { <> <> < mouse.link _ packet>> <> rMouse: RegSpec = reg4; loopLabel: Label = GenLabel[]; testLabel: Label = GenLabel[]; drLRIn[rHead, 0]; <> drJB[UseLabel8A[testLabel]]; HandCodingSupport.WordAlign[]; SetLabel[loopLabel]; drLRIn[rMouse, 0]; drSRn[rMouse]; <<, mouse.link>> SetLabel[testLabel]; drLRIn[rMouse, 0]; drJNEBBJ[0, UseLabel8B[loopLabel]]; <> drWRI[rPacket, rMouse, pktLink]; < mouse.link _ packet>> drDIS[]; <> }; SetLabel[returnLabel]; ProcedureExit[0]; }; GenSchedule: PROC = { <> G: RegSpec = reg0; rZero: RegSpec = reg1; rMessage: RegSpec = reg2; returnLabel: Label = GenLabel[]; ProcedureEntry[enterSchedule, 0]; HandCodingPseudos.MakeLabelGlobal["Richards.Schedule", enterSchedule]; drLIQB[globalFrame]; drLC0[]; drLC0[]; drLRIn[G, gTaskList]; drSRIn[G, gCurrentTask]; <> { testLabel: Label = GenLabel[]; loopLabel: Label = GenLabel[]; drJB[UseLabel8A[testLabel]]; <> HandCodingSupport.WordAlign[]; SetLabel[loopLabel]; drROR[rMessage, const0, const0]; <> { thenLabel: Label = GenLabel[]; elseLabel: Label = GenLabel[]; fiLabel: Label = GenLabel[]; drLRIn[G, gCurrentTask]; drRB[tcbState]; ExtractField[2, 1]; drJEBB[1, UseLabel8B[thenLabel]]; drLRIn[G, gCurrentTask]; drRB[tcbState]; drLIQB[waiting]; drRJNEB[left: popSrc, right: belowSrcPop, dist: UseLabel8B[elseLabel]]; <> SetLabel[thenLabel]; drLRIn[G, gCurrentTask]; drRB[tcbLink]; drSRIn[G, gCurrentTask]; drJB[UseLabel8A[fiLabel]]; <> SetLabel[elseLabel]; <> { innerElseLabel: Label = GenLabel[]; <> <> <> <<...>> <<};>> drLRIn[G, gCurrentTask]; drRB[tcbState]; drLIQB[waitingWithPacket]; drRJNEB[left: popSrc, right: belowSrcPop, dist: UseLabel8B[innerElseLabel]]; <> drLRIn[G, gCurrentTask]; drRB[tcbInput]; drSRn[rMessage]; <> drLRIn[rMessage, tcbLink]; drLRIn[G, gCurrentTask]; drWB[tcbInput]; <> <<>> { innerInnerElseLabel: Label = GenLabel[]; innerInnerFiLabel: Label = GenLabel[]; drLRIn[G, gCurrentTask]; drRB[tcbInput]; drJNEBB[0, UseLabel8B[innerInnerElseLabel]]; <> drLC0[]; drLRIn[G, gCurrentTask]; drWB[tcbState]; drJB[UseLabel8A[innerInnerFiLabel]]; <> <<>> SetLabel[innerInnerElseLabel]; LReg[constNI]; drLRIn[G, gCurrentTask]; drWB[tcbState]; <> <<>> SetLabel[innerInnerFiLabel]; }; SetLabel[innerElseLabel]; drLRIn[G, gCurrentTask]; drRB[tcbIdentity]; drSRIn[G, gCurrentTaskIdentity]; <> drLRn[rMessage]; drLRIn[G, gCurrentTask]; drRB[tcbHandle]; drLRIn[G, gCurrentTask]; drRB[tcbFunction]; drSFCI[]; drSRIn[G, gCurrentTask]; <> }; SetLabel[fiLabel]; }; SetLabel[testLabel]; drLRIn[G, gCurrentTask]; drJNEBBJ[0, UseLabel8B[loopLabel]]; }; SetLabel[returnLabel]; ProcedureExit[0]; }; GenWait: PROC = { <> rTask: RegSpec = reg0; G: RegSpec = reg1; ProcedureEntry[enterWait, 0]; HandCodingPseudos.MakeLabelGlobal["Richards.Wait", enterWait]; drLC0[]; drLIQB[globalFrame]; drLRIn[G, gCurrentTask]; drRB[tcbState]; drLC1[]; drSHDR[FieldDescriptorToCard[[insert: TRUE, mask: taskWaiting+1, shift: taskWaiting]]]; drLRIn[G, gCurrentTask]; drWB[tcbState]; <> drLRIn[G, gCurrentTask]; drSRn[rTask]; <> ProcedureExit[1]; }; GenHoldSelf: PROC = { <> rTask: RegSpec = reg0; G: RegSpec = reg1; ProcedureEntry[enterHoldSelf, 0]; HandCodingPseudos.MakeLabelGlobal["Richards.HoldSelf", enterHoldSelf]; drLC0[]; drLIQB[globalFrame]; drLRIn[G, gHoldCount]; drADDB[1]; drSRIn[G, gHoldCount]; <> drLRIn[G, gCurrentTask]; drRB[tcbState]; drLC1[]; drSHDR[FieldDescriptorToCard[[insert: TRUE, mask: taskHolding+1, shift: taskHolding]]]; drLRIn[G, gCurrentTask]; drWB[tcbState]; <> drLRIn[G, gCurrentTask]; drRB[tcbLink]; drSRn[rTask]; <> ProcedureExit[1]; }; GenRelease: PROC = { <> rIdentity: RegSpec = reg0; rTask: RegSpec = reg1; G: RegSpec = reg2; rT: RegSpec = reg3; ProcedureEntry[enterRelease, 1]; HandCodingPseudos.MakeLabelGlobal["Richards.Release", enterRelease]; drLC0[]; drLIQB[globalFrame]; drLRn[rIdentity]; drLFC[UseLabel16[enterFindTask]]; <> <<>> {elseLabel: Label = GenLabel[]; drLRn[rT]; drJNEBBJ[0, UseLabel8B[elseLabel]]; drROR[reg0, const0, const0]; ProcedureExit[1]; <> SetLabel[elseLabel]; }; drLRIn[rT, tcbState]; drLC0[]; drSHDR[FieldDescriptorToCard[[insert: TRUE, mask: taskHolding+1, shift: taskHolding]]]; drSRIn[rT, tcbState]; <> { elseLabel: Label = GenLabel[]; drLRIn[rT, tcbPriority]; drLRIn[G, gCurrentTask]; drRB[tcbPriority]; drRJGEB[left: popSrc, right: belowSrcPop, dist: UseLabel8B[elseLabel]]; < currentTask.priority>> drROR[reg0, const0, rT]; ProcedureExit[1]; <> SetLabel[elseLabel]; drRRI[reg0, G, gCurrentTask]; ProcedureExit[1]; <> }; }; GenFindTask: PROC = { <> rIdentity: RegSpec = reg0; rTask: RegSpec = reg1; G: RegSpec = reg2; rT: RegSpec = reg3; returnLabel: Label = GenLabel[]; ProcedureEntry[enterFindTask, 1]; HandCodingPseudos.MakeLabelGlobal["Richards.FindTask", enterFindTask]; drLC0[]; drLIQB[globalFrame]; drRVADD[pushDst, G, rIdentity]; drRB[gTaskTable]; <> <<>> { drLRn[rT]; drJNEBBJ[0, UseLabel8B[returnLabel]]; <> Halt[377B]; }; SetLabel[returnLabel]; drROR[reg0, const0, rT]; ProcedureExit[1]; }; GenCreateIdler: PROC = { <> <<[identity: TaskIdentity, priority: TaskPriority, work: WorkQueue, state: TaskState]>> rIdentity: RegSpec = reg0; rPriority: RegSpec = reg1; rWork: RegSpec = reg2; rState: RegSpec = reg3; G: RegSpec = reg4; rData: RegSpec = reg5; ProcedureEntry[enterCreateIdler, 4]; HandCodingPseudos.MakeLabelGlobal["Richards.CreateIdler", enterCreateIdler]; drLIQB[globalFrame]; drLC0[]; { <> drLRIn[G, gZ]; drLIB[2]; drLRIn[G, gZ]; drRB[0]; drRB[0]; drSFC[]; drSRn[rData]; drLIB[1]; drSRIn[rData, 0]; drLIDB[10000]; drSRIn[rData, 1]; }; { <> drLRn[rIdentity]; drLRn[rPriority]; drLRn[rWork]; drLRn[rState]; drLRn[G]; drADDB[gIdleFunction]; drLRn[rData]; drLFC[UseLabel16[enterCreateTask]]; }; ProcedureExit[0]; }; GenIdleFunction: PROC = { <> <<== [work: WorkQueue, word: LONG POINTER] RETURNS [t: Task]>> rWork: RegSpec = reg0; rWord: RegSpec = reg1; G: RegSpec = reg2; rT: RegSpec = reg3; rData: RegSpec = reg4; returnLabel: Label = GenLabel[]; ProcedureEntry[enterIdleFunction, 2+1]; HandCodingPseudos.MakeLabelGlobal["Richards.IdleFunction", enterIdleFunction]; drSUBB[gIdleFunction]; -- a pointer into the global frame is an implcit argument drLC0[]; { elseLabel: Label = GenLabel[]; drLRn[rWord]; <> drLRIn[rData, 1]; drRVSUB[topDst, topSrc, const1]; drSRIn[rData, 1]; <> drLRIn[rData, 1]; drJNEBBJ[0, UseLabel8B[elseLabel]]; drLFC[UseLabel16[enterHoldSelf]]; drJB[UseLabel8A[returnLabel]]; <> SetLabel[elseLabel]; }; { elseLabel: Label = GenLabel[]; drLRIn[rData, 0]; drQAND[topAtop, const1]; drJNEBB[0, UseLabel8B[elseLabel]]; drLRIn[rData, 0]; ExtractField[0, 31]; drSRIn[rData, 0]; <> drLIB[5]; drLFC[UseLabel16[enterRelease]]; drJB[UseLabel8A[returnLabel]]; <> SetLabel[elseLabel]; drLRIn[rData, 0]; ExtractField[0, 31]; drLIDB[0D008H]; drRXOR[belowDst, belowSrc, popSrc]; drSRIn[rData, 0]; <> drLIB[6]; drLFC[UseLabel16[enterRelease]]; <> }; SetLabel[returnLabel]; drSRn[reg0]; ProcedureExit[1]; }; GenCreateDevice: PROC = { <> <<[identity: TaskIdentity, priority: TaskPriority, work: WorkQueue, state: TaskState]>> rIdentity: RegSpec = reg0; rPriority: RegSpec = reg1; rWork: RegSpec = reg2; rState: RegSpec = reg3; G: RegSpec = reg4; rData: RegSpec = reg5; ProcedureEntry[enterCreateDevice, 4]; HandCodingPseudos.MakeLabelGlobal["Richards.CreateDevice", enterCreateDevice]; drLIQB[globalFrame]; drLC0[]; { <> drLRIn[G, gZ]; drLIB[2]; drLRIn[G, gZ]; drRB[0]; drRB[0]; drSFC[]; drSRn[rData]; drLC0[]; drSRIn[rData, 0]; }; { <> drLRn[rIdentity]; drLRn[rPriority]; drLRn[rWork]; drLRn[rState]; drLRn[G]; drADDB[gDeviceFunction]; drLRn[rData]; drLFC[UseLabel16[enterCreateTask]]; }; ProcedureExit[0]; }; GenDeviceFunction: PROC = { <> <<== [work: WorkQueue, word: LONG POINTER] RETURNS [t: Task]>> rWork: RegSpec = reg0; rWord: RegSpec = reg1; G: RegSpec = reg2; rT: RegSpec = reg3; rData: RegSpec = reg4; returnLabel: Label = GenLabel[]; ProcedureEntry[enterDeviceFunction, 2+1]; HandCodingPseudos.MakeLabelGlobal["Richards.DeviceFunction", enterDeviceFunction]; drSUBB[gDeviceFunction]; -- a pointer into the global frame is an implcit argument drLC0[]; { elseLabel: Label = GenLabel[]; drLRn[rWord]; <> drLRn[rWork]; drJNEBB[0, UseLabel8B[elseLabel]]; <> { innerElseLabel: Label = GenLabel[]; drLRIn[rData, 0]; drJNEBB[0, UseLabel8B[innerElseLabel]]; drLFC[UseLabel16[enterWait]]; drJB[UseLabel8A[returnLabel]]; <> SetLabel[innerElseLabel]; }; drRRI[rWork, rData, 0]; <> <<>> drLC0[]; drSRIn[rData, 0]; <> drLRn[rWork]; drLFC[UseLabel16[enterQueuePacket]]; drJB[UseLabel8A[returnLabel]]; <> SetLabel[elseLabel]; <> drWRI[rWork, rData, 0]; <> <<>> drLFC[UseLabel16[enterHoldSelf]]; <> }; SetLabel[returnLabel]; drSRn[reg0]; ProcedureExit[1]; }; GenCreateHandler: PROC = { <> <<[identity: TaskIdentity, priority: TaskPriority, work: WorkQueue, state: TaskState]>> rIdentity: RegSpec = reg0; rPriority: RegSpec = reg1; rWork: RegSpec = reg2; rState: RegSpec = reg3; G: RegSpec = reg4; rData: RegSpec = reg5; ProcedureEntry[enterCreateHandler, 4]; HandCodingPseudos.MakeLabelGlobal["Richards.CreateHandler", enterCreateHandler]; drLIQB[globalFrame]; drLC0[]; { <> drLRIn[G, gZ]; drLIB[2]; drLRIn[G, gZ]; drRB[0]; drRB[0]; drSFC[]; drSRn[rData]; drLC0[]; drSRIn[rData, 0]; drLC0[]; drSRIn[rData, 1]; }; { <> drLRn[rIdentity]; drLRn[rPriority]; drLRn[rWork]; drLRn[rState]; drLRn[G]; drADDB[gHandlerFunction]; drLRn[rData]; drLFC[UseLabel16[enterCreateTask]]; }; ProcedureExit[0]; }; GenHandlerFunction: PROC = { <> <<== [work: WorkQueue, word: LONG POINTER] RETURNS [t: Task]>> rWork: RegSpec = reg0; rWord: RegSpec = reg1; G: RegSpec = reg2; rT: RegSpec = reg3; rData: RegSpec = reg4; rWorkPacket: RegSpec = reg5; rDevicePacket: RegSpec = reg6; rCount: RegSpec = reg7; returnLabel: Label = GenLabel[]; ProcedureEntry[enterHandlerFunction, 2+1]; HandCodingPseudos.MakeLabelGlobal["Richards.HandlerFunction", enterHandlerFunction]; drSUBB[gHandlerFunction]; -- a pointer into the global frame is an implcit argument drLC0[]; drLRn[rWord]; <> drLC0[]; drLC0[]; <> drLC0[]; <> {elseLabel: Label = GenLabel[]; drLRn[rWork]; drJEBB[0, UseLabel8B[elseLabel]]; <> { innerElseLabel: Label = GenLabel[]; innerFiLabel: Label = GenLabel[]; drLRIn[rWork, pktKind]; drJNEBB[1, UseLabel8B[innerElseLabel]]; <> drLRn[rWork]; drLRn[rData]; drLFC[UseLabel16[enterAppend]]; <> drJB[UseLabel8A[innerFiLabel]]; SetLabel[innerElseLabel]; drLRn[rWork]; drQADD[pushA1, rData]; drLFC[UseLabel16[enterAppend]]; <> SetLabel[innerFiLabel]; }; SetLabel[elseLabel]; }; {elseLabel: Label = GenLabel[]; drLRIn[rData, 0]; drJEBB[0, UseLabel8B[elseLabel]]; <> drRRI[rWorkPacket, rData, 0]; <> drLRIn[rWorkPacket, pktDatum]; drRBC[rCount, topSrc, constNI]; -- (check for negative while assigning) <> <<>> { innerElseLabel: Label = GenLabel[]; drLRn[rCount]; drRJLEBJ[left: popSrc, right: const3, dist: UseLabel8B[innerElseLabel]]; < packetBufferSize THEN>> drLRIn[rData, 0]; drRB[pktLink]; drSRIn[rData, 0]; <> <<>> drLRn[rWorkPacket]; drLFC[UseLabel16[enterQueuePacket]]; drJB[UseLabel8A[returnLabel]]; <> <<>> SetLabel[innerElseLabel]; }; { drLRIn[rData, 1]; drJEBB[0, UseLabel8B[elseLabel]]; <> drRRI[rDevicePacket, rData, 1]; <> drLRIn[rData, 1]; drRB[pktLink]; drSRIn[rData, 1]; <> <<>> drRBC[pushDst, rCount, const4]; drQADD[topAtop, rWorkPacket]; drRB[pktData]; drSRIn[rDevicePacket, pktDatum]; <> <<>> drQADD[pushA1, rCount]; drQBC[topAtop, constNI]; -- INT => CARDINAL coercion drSRIn[rWorkPacket, pktDatum]; <> drLRn[rDevicePacket]; drLFC[UseLabel16[enterQueuePacket]]; drJB[UseLabel8A[returnLabel]]; <> <<>> }; SetLabel[elseLabel]; }; drLFC[UseLabel16[enterWait]]; <> SetLabel[returnLabel]; drSRn[reg0]; ProcedureExit[1]; }; GenCreateWorker: PROC = { <> <<[identity: TaskIdentity, priority: TaskPriority, work: WorkQueue, state: TaskState]>> rIdentity: RegSpec = reg0; rPriority: RegSpec = reg1; rWork: RegSpec = reg2; rState: RegSpec = reg3; G: RegSpec = reg4; rData: RegSpec = reg5; ProcedureEntry[enterCreateWorker, 4]; HandCodingPseudos.MakeLabelGlobal["Richards.CreateWorker", enterCreateWorker]; drLIQB[globalFrame]; drLC0[]; { <> drLRIn[G, gZ]; drLIB[2]; drLRIn[G, gZ]; drRB[0]; drRB[0]; drSFC[]; drSRn[rData]; drLC3[]; drSRIn[rData, 0]; drLC0[]; drSRIn[rData, 1]; }; { <> drLRn[rIdentity]; drLRn[rPriority]; drLRn[rWork]; drLRn[rState]; drLRn[G]; drADDB[gWorkFunction]; drLRn[rData]; drLFC[UseLabel16[enterCreateTask]]; }; ProcedureExit[0]; }; GenWorkFunction: PROC = { <> <<== [work: WorkQueue, word: LONG POINTER] RETURNS [t: Task]>> rWork: RegSpec = reg0; rWord: RegSpec = reg1; G: RegSpec = reg2; rT: RegSpec = reg3; rData: RegSpec = reg4; returnLabel: Label = GenLabel[]; ProcedureEntry[enterWorkFunction, 2+1]; HandCodingPseudos.MakeLabelGlobal["Richards.WorkFunction", enterWorkFunction]; drSUBB[gWorkFunction]; -- a pointer into the global frame is an implcit argument drLC0[]; drLRn[rWord]; <> {elseLabel: Label = GenLabel[]; drLRn[rWork]; drJNEBB[0, UseLabel8B[elseLabel]]; <> drLFC[UseLabel16[enterWait]]; drJB[UseLabel8A[returnLabel]]; <> SetLabel[elseLabel]; { <> <<(IF data.destination = handlerA THEN handlerB ELSE handlerA);>> drLC3[]; drLRIn[rData, 0]; drJNEBB[3, 6]; drROR[topDst, const0, const4]; drSRIn[rData, 0]; }; drLRIn[rData, 0]; drSRIn[rWork, pktIdentity]; <> <<>> drLC0[]; drSRIn[rWork, pktDatum]; <> <<>> { rI: RegSpec = reg5; rLimit: RegSpec = reg6; testLabel: Label = GenLabel[]; loopLabel: Label = GenLabel[]; drLC0[]; drLC3[]; drJB[UseLabel8A[testLabel]]; HandCodingSupport.WordAlign[]; SetLabel[loopLabel]; drLRIn[rData, 1]; drRVADD[topDst, topSrc, const1]; drSRIn[rData, 1]; <> {elseLabel: Label = GenLabel[]; < 26 THEN data.count _ 1;>> drLRIn[rData, 1]; drRXOR[topDst, topSrc, constNI]; drLIB[26]; drRXOR[topDst, topSrc, constNI]; drRJGEBJ[left: popSrc, right: belowSrcPop, dist: UseLabel8B[elseLabel]]; drLC1[]; drSRIn[rData, 1]; SetLabel[elseLabel]; }; drLRIn[rData, 1]; drADDB[100B]; drRBC[pushDst, rI, const4]; drQADD[topAtop, rWork]; drWB[pktData]; <> drRADD[rI, rI, const1]; SetLabel[testLabel]; drRJGEBJ[left: topSrc, right: rI, dist: UseLabel8B[loopLabel]]; drAS[256-2]; <> }; drLRn[rWork]; drLFC[UseLabel16[enterQueuePacket]]; <> }; SetLabel[returnLabel]; drSRn[reg0]; ProcedureExit[1]; }; GenMain: PROC = { <> rTime: RegSpec = reg0; G: RegSpec = reg1; rWorkQ: RegSpec = reg2; rPulses: RegSpec = reg3; ProcedureEntry[enterMain, 0]; HandCodingPseudos.MakeLabelGlobal["Richards.Main", enterMain]; <> <<>> <> drLC0[]; drLIQB[globalFrame]; drLC0[]; drLC0[]; <> drLFC[UseLabel16[enterInitScheduler]]; <> drLC1[]; drLC0[]; drLC0[]; drLC0[]; drLFC[UseLabel16[enterCreateIdler]]; <> drLC0[]; drLC2[]; drLC1[]; drLFC[UseLabel16[enterCreatePacket]]; drSRn[rWorkQ]; <> drLRn[rWorkQ]; drLC2[]; drLC1[]; drLFC[UseLabel16[enterCreatePacket]]; drSRn[rWorkQ]; <> drLC2[]; drLIDB[1000]; drLRn[rWorkQ]; drLIQB[waitingWithPacket]; drLFC[UseLabel16[enterCreateWorker]]; <> drLC0[]; drLIB[5]; drLC0[]; drLFC[UseLabel16[enterCreatePacket]]; drSRn[rWorkQ]; <> drLRn[rWorkQ]; drLIB[5]; drLC0[]; drLFC[UseLabel16[enterCreatePacket]]; drSRn[rWorkQ]; <> drLRn[rWorkQ]; drLIB[5]; drLC0[]; drLFC[UseLabel16[enterCreatePacket]]; drSRn[rWorkQ]; <> drLC3[]; drLIDB[2000]; drLRn[rWorkQ]; drLIQB[waitingWithPacket]; drLFC[UseLabel16[enterCreateHandler]]; <> drLC0[]; drLIB[6]; drLC0[]; drLFC[UseLabel16[enterCreatePacket]]; drSRn[rWorkQ]; <> drLRn[rWorkQ]; drLIB[6]; drLC0[]; drLFC[UseLabel16[enterCreatePacket]]; drSRn[rWorkQ]; <> drLRn[rWorkQ]; drLIB[6]; drLC0[]; drLFC[UseLabel16[enterCreatePacket]]; drSRn[rWorkQ]; <> drLC4[]; drLIDB[2000]; drLRn[rWorkQ]; drLIQB[waitingWithPacket]; drLFC[UseLabel16[enterCreateHandler]]; <> drLIB[5]; drLIDB[4000]; drLC0[]; drLIQB[waiting]; drLFC[UseLabel16[enterCreateDevice]]; <> <<>> drLIB[6]; drLIDB[5000]; drLC0[]; drLIQB[waiting]; drLFC[UseLabel16[enterCreateDevice]]; <> drLFC[UseLabel16[enterSchedule]]; <> <<>> drLRIn[G, gQueuePacketCount]; drLIDB[23246]; drRJEBJ[left: popSrc, right: belowSrcPop, dist: 6]; Halt[100B]; <> <<>> drLRIn[G, gHoldCount]; drLIDB[9297]; drRJEBJ[left: popSrc, right: belowSrcPop, dist: 6]; Halt[101B]; <> <<>> drLRIn[G, gAllocObjects]; drLIDB[20]; drRJEBJ[left: popSrc, right: belowSrcPop, dist: 6]; Halt[102B]; <> <<>> <<>> Halt[0]; ProcedureExit[1]; <<>> <> <<>> <> <<>> <