<> <> <> <<>> DIRECTORY DragOpsCross, DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport; GenPuzzle: CEDAR PROGRAM IMPORTS DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport = BEGIN OPEN DragOpsCross, DragOpsCrossUtils, HandCoding, HandCodingPseudos; Area: TYPE = HandCodingSupport.Area; <<>> <> <<3.66 seconds on a Dorado (March 18, 1986)>> <> <<>> <> gOut: NAT = 0; -- we don't use this gStaticZone: NAT = 1; -- we don't use this either gPiececount: NAT = 2; -- LONG POINTER TO ARRAY Piececlass OF INT [0..13] gClass: NAT = 3; -- LONG POINTER TO ARRAY Piecetype OF Piececlass gPiecemax: NAT = 4; -- LONG POINTER TO ARRAY Piecetype OF Position gPuzzle: NAT = 5; -- LONG POINTER TO ARRAY Position OF BOOL gP: NAT = 6; -- LONG POINTER TO ARRAY Piecetype OF ARRAY Position OF BOOL gKount: NAT = 7; -- INT gTrialDepth: NAT = 8; -- INT gMaxDepth: NAT = 9; -- INT gSize: NAT = 10; -- size of global frame <> globalPuzzleCard: LONG CARDINAL; -- global frame base globalPuzzle: Word; -- global frame base as word enterFit: Label _ NIL; enterPlace: Label _ NIL; enterRemove: Label _ NIL; enterTrial: Label _ NIL; enterPuzzleRun: Label _ NIL; enterHalt: Label _ NIL; <> D: NAT = 8; GenInit: PROC = { <> area: Area = HandCodingSupport.GetCurrentArea[]; startLabel: Label = GenLabelHere[]; HandCodingPseudos.MakeLabelGlobal["Puzzle.Init", startLabel]; <> globalPuzzleCard _ HandCodingSupport.ReserveData[32*wordsPerPage] / bytesPerWord; globalPuzzle _ CardToWord[globalPuzzleCard]; { <> <<>> G: RegSpec = reg0; top: RegSpec = reg1; <<>> EnableTraps[]; -- to detect stack overflow drASL[255]; -- ensure that stack is empty, regardless of where it was drLIQB[globalPuzzle]; drLC0[]; FOR i: NAT IN [0..gSize) DO drWRI[top, G, i]; ENDLOOP; drROR[c: top, a: const0, b: G]; drADDDB[256]; drWRI[top, G, gPiececount]; drADDB[4]; drWRI[top, G, gClass]; drADDB[13]; drWRI[top, G, gPiecemax]; drADDB[13]; drWRI[top, G, gPuzzle]; drADDDB[512]; drWRI[top, G, gP]; }; <> drLFC[UseLabel16[enterPuzzleRun]]; HandCodingPseudos.MakeLabelGlobal["Puzzle.PuzzleRun", enterPuzzleRun]; <> Halt[301B]; -- loop on halting ProcedureEntry[enterHalt, 1]; <> Halt[302B]; -- loop on halting }; All: PROC = { <> area: Area = HandCodingSupport.GetCurrentArea[]; enterFit _ GenLabel[]; enterPlace _ GenLabel[]; enterRemove _ GenLabel[]; enterTrial _ GenLabel[]; enterPuzzleRun _ GenLabel[]; enterHalt _ GenLabel[]; GenInit[]; -- must be the first to be generated GenFit[]; GenPlace[]; GenRemove[]; GenTrial[]; GenPuzzleRun[]; <> <> HandCodingSupport.SetOutputPC[globalPuzzleCard]; HandCodingSupport.OutputWord[area, ZerosWord]; <> FOR i: NAT IN [1..32] DO HandCodingSupport.SetOutputPC[globalPuzzleCard+i*LONG[bytesPerPage]+bytesPerPage]; HandCodingSupport.OutputWord[area, ZerosWord]; ENDLOOP; }; <<>> GenFit: PROC = { <<[I: Piecetype, J: Position] RETURNS [FitResult: BOOL]>> rI: RegSpec = reg0; rJ: RegSpec = reg1; rFR: RegSpec = reg2; G: RegSpec = reg3; rK: RegSpec = reg4; c512: RegSpec = reg5; rLim: RegSpec = reg6; labelLabel1: Label = GenLabel[]; ProcedureEntry[enterFit, 2]; HandCodingPseudos.MakeLabelGlobal["Puzzle.Fit", enterFit]; drLC0[]; -- FitResult drLIQB[globalPuzzle]; -- global frame drLC0[]; -- K: Position drLIDB[512]; -- constant 512 drLC0[]; -- loop limit <<>> <> drROR[c: rFR, a: const0, b: const0]; { <> <> <> <<>> body: LoopBodyProc = { <<[loopLabel, testLabel, exitLabel: Label]>> <<>> <> drLRn[rI]; drSHL[FieldDescriptorToCard[[shift: 9]]]; -- to mult by 512 drQADD[topAtop, rK]; drLRIn[G, gP]; drRX[]; drJNEBBJ[1, UseLabel8B[testLabel]]; <> drRADD[c: pushDst, a: rJ, b: rK]; drQBC[topAtop, c512]; drLRIn[G, gPuzzle]; drRX[]; drJEBB[1, UseLabel8B[labelLabel1]]; }; drLRIn[G, gPiecemax]; drRRX[c: rLim, a: rI, b: popSrc]; drROR[c: rK, a: const0, b: const0]; GenDynamicLoop[rK, topSrc, body]; }; <<>> <> drROR[c: rFR, a: const0, b: const1]; < NULL>> SetLabel[labelLabel1]; drROR[c: reg0, a: const0, b: rFR]; ProcedureExit[1]; }; GenPlace: PROC = { <<[I: Piecetype, J: Position] RETURNS [PlaceResult: BOOL]>> rI: RegSpec = reg0; rJ: RegSpec = reg1; rPR: RegSpec = reg2; G: RegSpec = reg3; rK: RegSpec = reg4; c512: RegSpec = reg5; rLim: RegSpec = reg6; labelLabel1: Label = GenLabel[]; ProcedureEntry[enterPlace, 2]; HandCodingPseudos.MakeLabelGlobal["Puzzle.Place", enterPlace]; drLC0[]; -- PlaceResult drLIQB[globalPuzzle]; -- global frame drLC0[]; -- K drLIDB[512]; -- constant 512 drLC0[]; -- loop limit <<>> { <> <> <> <<>> body: LoopBodyProc = { <<[loopLabel, testLabel, exitLabel: Label]>> <> drLRn[rI]; drSHL[FieldDescriptorToCard[[shift: 9]]]; -- to mult by 512 drQADD[topAtop, rK]; drLRIn[G, gP]; drRX[]; drJNEBBJ[1, UseLabel8B[testLabel]]; <> <<>> drRADD[c: pushDst, a: rJ, b: rK]; drQBC[topAtop, c512]; drLRIn[G, gPuzzle]; drADD[]; drLC1[]; drWSB[0]; }; drLRIn[G, gPiecemax]; drRRX[c: rLim, a: rI, b: popSrc]; drROR[c: rK, a: const0, b: const0]; GenDynamicLoop[rK, topSrc, body]; }; <<>> <> drLRIn[G, gClass]; drQRX[topAtop, rI]; drLRIn[G, gPiececount]; drADD[]; drRSB[0]; drSUBB[1]; drLIB[14]; drBC[]; drWSB[0]; { <> <> <> <<>> body: LoopBodyProc = { <<[loopLabel, testLabel, exitLabel: Label]>> drLRIn[G, gPuzzle]; drQRX[topAtop, rK]; drJNEBBJ[0, UseLabel8B[testLabel]]; drROR[c: rPR, a: const0, b: rK]; drJB[UseLabel8A[labelLabel1]]; }; drROR[c: rK, a: const0, b: rJ]; GenStaticLoop[rK, 511, body]; }; <> drROR[c: rPR, a: const0, b: const0]; < NULL>> SetLabel[labelLabel1]; drROR[c: reg0, a: const0, b: rPR]; ProcedureExit[1]; }; GenRemove: PROC = { <<[I: Piecetype, J: Position]>> rI: RegSpec = reg0; rJ: RegSpec = reg1; G: RegSpec = reg2; rK: RegSpec = reg3; c512: RegSpec = reg4; rLim: RegSpec = reg5; ProcedureEntry[enterRemove, 2]; HandCodingPseudos.MakeLabelGlobal["Puzzle.Remove", enterRemove]; drLIQB[globalPuzzle]; drLC0[]; -- reserve K drLIDB[512]; -- constant 512 drLC0[]; -- reserve loop limit (will be on top of stack to make testing easier) <<>> <> <<>> { <> <> <> <<>> body: LoopBodyProc = { <<[loopLabel, testLabel, exitLabel: Label]>> <> drLRn[rI]; drSHL[FieldDescriptorToCard[[shift: 9]]]; -- to mult by 512 drQADD[topAtop, rK]; drLRIn[G, gP]; drRX[]; drJNEBBJ[1, UseLabel8B[testLabel]]; <> <<>> drRADD[c: pushDst, a: rJ, b: rK]; drQBC[topAtop, c512]; drLRIn[G, gPuzzle]; drADD[]; drLC0[]; drWSB[0]; }; drLRIn[G, gPiecemax]; drRRX[c: rLim, a: rI, b: popSrc]; drROR[c: rK, a: const0, b: const0]; GenDynamicLoop[rK, topSrc, body]; }; <> drLRIn[G, gClass]; drQRX[topAtop, rI]; drLRIn[G, gPiececount]; drADD[]; drRSB[0]; drADDB[1]; drLIB[14]; drBC[]; drWSB[0]; ProcedureExit[0]; }; GenTrial: PROC = { <<[J: Position] RETURNS [TrialResult: BOOL]>> rJ: RegSpec = reg0; rTR: RegSpec = reg1; G: RegSpec = reg2; rI: RegSpec = reg3; rK: RegSpec = reg4; labelLabel1: Label = GenLabel[]; ProcedureEntry[enterTrial, 1]; HandCodingPseudos.MakeLabelGlobal["Puzzle.Trial", enterTrial]; drLC0[]; -- TrialResult drLIQB[globalPuzzle]; -- G drLC0[]; -- I drLC0[]; -- K { <> continueLabel: Label = GenLabel[]; placeLabel: Label = GenLabelHere[]; newMaxLabel: Label = GenLabel[]; HandCodingPseudos.MakeLabelGlobal["Puzzle.testDepth", placeLabel]; drLRIn[G, gTrialDepth]; drADDB[1]; drDUP[]; drSRIn[G, gTrialDepth]; drLRIn[G, gMaxDepth]; drRJLEBJ[left: topSrc, right: popSrc, dist: UseLabel8B[continueLabel]]; SetLabel[newMaxLabel]; HandCodingPseudos.MakeLabelGlobal["Puzzle.newMaxDepth", newMaxLabel]; drDUP[]; drSRIn[G, gMaxDepth]; <> drLIB[18]; drRJGEBJ[left: topSrc, right: belowSrc, dist: UseLabel8B[continueLabel]]; Pause[]; SetLabel[continueLabel]; drDIS[]; }; <<>> { <> <> <> <> <> <> <> <<};>> <> <<>> body: LoopBodyProc = { <<[loopLabel, testLabel, exitLabel: Label]>> <> drLRIn[G, gClass]; drQRX[topAtop, rI]; drLRIn[G, gPiececount]; drRX[]; drJEBBJ[0, UseLabel8B[testLabel]]; <> <<>> drLRn[rI]; drLRn[rJ]; drLFC[UseLabel16[enterFit]]; drJEBBJ[0, UseLabel8B[testLabel]]; <<>> { thenLabel: Label = GenLabel[]; elseLabel: Label = GenLabel[]; <> drLRn[rI]; drLRn[rJ]; drLFC[UseLabel16[enterPlace]]; drSRn[rK]; <> drLRn[rK]; drLFC[UseLabel16[enterTrial]]; drJEBB[1, UseLabel8B[thenLabel]]; drLRn[rK]; drJNEBBJ[0, UseLabel8B[elseLabel]]; <> SetLabel[thenLabel]; drROR[c: rTR, a: const0, b: const1]; drJB[UseLabel8A[labelLabel1]]; <> SetLabel[elseLabel]; drLRn[rI]; drLRn[rJ]; drLFC[UseLabel16[enterRemove]]; }; }; drROR[c: rI, a: const0, b: const0]; GenStaticLoop[rI, 12, body]; }; <> drROR[c: rTR, a: const0, b: const0]; < NULL>> SetLabel[labelLabel1]; <> drLRIn[G, gKount]; drADDB[1]; drSRIn[G, gKount]; <> drLRIn[G, gTrialDepth]; drSUBB[1]; drSRIn[G, gTrialDepth]; { <> continueLabel: Label = GenLabel[]; placeLabel: Label = GenLabelHere[]; HandCodingPseudos.MakeLabelGlobal["Puzzle.testKount", placeLabel]; drLRIn[G, gKount]; drLIDB[2005]; drRJGEBJ[left: popSrc, right: belowSrcPop, dist: UseLabel8B[continueLabel]]; Pause[]; SetLabel[continueLabel]; }; drROR[c: reg0, a: const0, b: rTR]; ProcedureExit[1]; }; GenPuzzleRun: PROC = { G: RegSpec = reg0; rM: RegSpec = reg1; rN: RegSpec = reg2; rI: RegSpec = reg3; rJ: RegSpec = reg4; rK: RegSpec = reg5; c512: RegSpec = reg6; c13: RegSpec = reg7; GenSetupStaticLoop: PROC [var: RegSpec, lim: CARDINAL, body: LoopBodyProc, closed: BOOL _ TRUE] = { <> loopLabel: Label = GenLabel[]; testLabel: Label = GenLabel[]; entryLabel: Label = GenLabel[]; exitLabel: Label = GenLabel[]; drJB[UseLabel8A[entryLabel]]; HandCodingSupport.WordAlign[]; SetLabel[loopLabel]; body[loopLabel, testLabel, exitLabel]; SetLabel[testLabel]; drRADD[pushDst, var, const1]; SetLabel[entryLabel]; drROR[var, topSrc, const0]; IF lim < 256 THEN drLIB[lim] ELSE drLIDB[lim]; IF closed THEN drRJGEBJ[left: popSrc, right: belowSrcPop, dist: UseLabel8B[loopLabel]] ELSE drRJGBJ[left: popSrc, right: belowSrcPop, dist: UseLabel8B[loopLabel]]; SetLabel[exitLabel]; }; GenCrap: PROC [G: RegSpec, which, class, iLim, jLim, kLim: NAT] = { body1: LoopBodyProc = { drLC0[]; GenSetupStaticLoop[rJ, jLim, body2]; }; body2: LoopBodyProc = { drLC0[]; GenSetupStaticLoop[rK, kLim, body3]; }; body3: LoopBodyProc = { <> drLRn[rK]; drSHL[FieldDescriptorToCard[[shift: 3]]]; -- to mult by 8 drQADD[topAtop, rJ]; drSHL[FieldDescriptorToCard[[shift: 3]]]; -- to mult by 8 drQADD[topAtop, rI]; drQBC[topAtop, c512]; drLRIn[G, gP]; drADD[]; IF which # 0 THEN drADDDB[which*512]; drLC1[]; drWSB[0]; }; <> <> <> <> <> <> <> drLC0[]; GenSetupStaticLoop[rI, iLim, body1]; <<>> <> <<>> drLIB[class]; drLRIn[G, gClass]; drWB[which]; <<>> <> drLIB[iLim + D*jLim + D*D*kLim]; drLRIn[G, gPiecemax]; drWB[which]; }; ProcedureEntry[enterPuzzleRun, 0]; drLIQB[globalPuzzle]; drLC0[]; -- rM drLC0[]; -- rN drLC0[]; -- rI drLC0[]; -- rJ drLC0[]; -- rK drLIDB[512]; -- constant 512 drLIDB[13]; -- constant 13 <> <> <<>> drLC0[]; drSRIn[G, gTrialDepth]; drLC0[]; drSRIn[G, gMaxDepth]; { <> <> <> <<>> body1: LoopBodyProc = { drLRIn[G, gPuzzle]; drQADD[topAtop, rM]; drLC1[]; drWSB[0]; }; drLC0[]; GenSetupStaticLoop[rM, 511, body1]; }; { <> <> <> <> <> <> <> body1: LoopBodyProc = { drLC1[]; GenSetupStaticLoop[rJ, 5, body2]; }; body2: LoopBodyProc = { drLC1[]; GenSetupStaticLoop[rK, 5, body3]; }; body3: LoopBodyProc = { <> drLRn[rK]; drSHL[FieldDescriptorToCard[[shift: 3]]]; -- to mult by 8 drQADD[topAtop, rJ]; drSHL[FieldDescriptorToCard[[shift: 3]]]; -- to mult by 8 drQADD[topAtop, rI]; drQBC[topAtop, c512]; drLRIn[G, gPuzzle]; drADD[]; drLC0[]; drWSB[0]; }; drLC1[]; GenSetupStaticLoop[rI, 5, body1]; }; { <> <> <> <> <> body1: LoopBodyProc = { drLC0[]; GenSetupStaticLoop[rM, 511, body2]; }; body2: LoopBodyProc = { drLRn[rI]; drQBC[topAtop, c13]; drSHL[FieldDescriptorToCard[[shift: 9]]]; -- to mult by 512 drQADD[topAtop, rM]; drLRIn[G, gP]; drADD[]; drLC0[]; drWSB[0]; }; drLC0[]; GenSetupStaticLoop[rI, 12, body1]; }; <> <> <> <> <> <> <> <> <> <<>> GenCrap[G, 0, 0, 3, 1, 0]; <> <> <> <> <> <> <> <> <> <<>> GenCrap[G, 1, 0, 1, 0, 3]; <> <> <> <> <> <> <> <> <> <<>> GenCrap[G, 2, 0, 0, 3, 1]; <> <> <> <> <> <> <> <> <> <<>> GenCrap[G, 3, 0, 1, 3, 0]; <> <> <> <> <> <> <> <> <> <<>> GenCrap[G, 4, 0, 3, 0, 1]; <> <> <> <> <> <> <> <> <> <<>> GenCrap[G, 5, 0, 0, 1, 3]; <> <> <> <> <> <> <> <> <> <<>> GenCrap[G, 6, 1, 2, 0, 0]; <> <> <> <> <> <> <> <> <> <<>> GenCrap[G, 7, 1, 0, 2, 0]; <> <> <> <> <> <> <> <> <> <<>> GenCrap[G, 8, 1, 0, 0, 2]; <> <> <> <> <> <> <> <> <> <<>> GenCrap[G, 9, 2, 1, 1, 0]; <> <> <> <> <> <> <> <> <> <<>> GenCrap[G, 10, 2, 1, 0, 1]; <> <> <> <> <> <> <> <> <> <<>> GenCrap[G, 11, 2, 0, 1, 1]; <> <> <> <> <> <> <> <> <> <<>> GenCrap[G, 12, 3, 1, 1, 1]; <> <> <> <> drLRIn[G, gPiececount]; drLRn[c13]; drWSB[0]; drLRIn[G, gPiececount]; drLC3[]; drWSB[1]; drLRIn[G, gPiececount]; drLC1[]; drWSB[2]; drLRIn[G, gPiececount]; drLC1[]; drWSB[3]; <> drLIB[1 + D * (1 + D * 1)]; drSRn[rM]; <> drLC0[]; drSRIn[G, gKount]; { <> <> <> elseLabel: Label = GenLabel[]; fiLabel: Label = GenLabel[]; drLC0[]; drLRn[rM]; drLFC[UseLabel16[enterFit]]; drJNEBB[1, UseLabel8B[elseLabel]]; drLC0[]; drLRn[rM]; drLFC[UseLabel16[enterPlace]]; drSRn[rN]; drJB[UseLabel8A[fiLabel]]; SetLabel[elseLabel]; Halt[3]; SetLabel[fiLabel]; }; <> <> <> <<}>> <> <> <<};>> drLRn[rN]; drLFC[UseLabel16[enterTrial]]; <> drLRIn[G, gKount]; drROR[temp, const0, popSrc]; -- leave the Kount in temp for later drLRn[G]; drROR[nregs, const0, popSrc]; -- leave the global data addr in nregs for later {oopsLabel: Label = GenLabel[]; drJNEBB[1, UseLabel8B[oopsLabel]]; Halt[0]; -- success SetLabel[oopsLabel]; Halt[101B]; -- failure }; }; <<>> <> <<>> LoopBodyProc: TYPE = PROC [loopLabel, testLabel, exitLabel: Label]; GenStaticLoop: PROC [var: RegSpec, lim: CARDINAL, body: LoopBodyProc, closed: BOOL _ TRUE] = { <<>> <> loopLabel: Label = GenLabel[]; testLabel: Label = GenLabel[]; entryLabel: Label = GenLabel[]; exitLabel: Label = GenLabel[]; drJB[UseLabel8A[entryLabel]]; HandCodingSupport.WordAlign[]; SetLabel[loopLabel]; body[loopLabel, testLabel, exitLabel]; SetLabel[testLabel]; drRADD[c: var, a: var, b: const1]; SetLabel[entryLabel]; IF lim < 256 THEN drLIB[lim] ELSE drLIDB[lim]; IF closed THEN drRJGEBJ[left: popSrc, right: var, dist: UseLabel8B[loopLabel]] ELSE drRJGBJ[left: popSrc, right: var, dist: UseLabel8B[loopLabel]]; SetLabel[exitLabel]; }; GenDynamicLoop: PROC [var: RegSpec, lim: RegSpec, body: LoopBodyProc, closed: BOOL _ TRUE] = { loopLabel: Label = GenLabel[]; testLabel: Label = GenLabel[]; entryLabel: Label = GenLabel[]; exitLabel: Label = GenLabel[]; limNeedsPush: BOOL = lim # topSrc; drJB[UseLabel8A[entryLabel]]; HandCodingSupport.WordAlign[]; SetLabel[loopLabel]; body[loopLabel, testLabel, exitLabel]; SetLabel[testLabel]; drRADD[c: var, a: var, b: const1]; SetLabel[entryLabel]; IF limNeedsPush THEN LReg[lim]; IF closed THEN drRJGEBJ[left: IF limNeedsPush THEN popSrc ELSE topSrc, right: var, dist: UseLabel8B[loopLabel]] ELSE drRJGBJ[left: IF limNeedsPush THEN popSrc ELSE topSrc, right: var, dist: UseLabel8B[loopLabel]]; SetLabel[exitLabel]; }; END.