DIRECTORY DragOpsCross, DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport; GenPuzzle: CEDAR PROGRAM IMPORTS DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport = BEGIN OPEN DragOpsCross, DragOpsCrossUtils, HandCoding, HandCodingPseudos; Area: TYPE = HandCodingSupport.Area; 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 = { 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 = { 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]; SetLabel[labelLabel1]; drROR[c: reg0, a: const0, b: rFR]; ProcedureExit[1]; }; GenPlace: PROC = { 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 = { 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 = { 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]; SetLabel[labelLabel1]; drROR[c: reg0, a: const0, b: rPR]; ProcedureExit[1]; }; GenRemove: PROC = { 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 = { 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 = { 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 = { 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]; 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. šGenPuzzle.mesa Copyright c 1984, 1985, 1986 by Xerox Corporation. All rights reserved. Russ Atkinson (RRA) March 18, 1986 2:08:50 pm PST This program takes 3.66 seconds on a Dorado (March 18, 1986) Total instructions: 985, Bytes: 1282 (no I/O code) Offsets in the global frame Global labels Global constants This procedure generates the initialzation code for Puzzle. reserve data statically Initialialize the global variables. PuzzleRun[] Just in case we return to this goodie, we loop on the all 1s byte To halt, we execute the all 0s byte. The top of stack has the return code (0 for success, non-zero for failure). This procedure generates all of the code for Puzzle. Reserve the static storage Reserve the global frame (a page is quite sufficient) Reserve the rest of the storage (32 pages is more than enough) [I: Piecetype, J: Position] RETURNS [FitResult: BOOL] FitResult _ FALSE; FOR K IN [0..Piecemax^[I]] DO IF P^[I][K] THEN IF Puzzle^[J + K] THEN GO TO Label1; ENDLOOP; [loopLabel, testLabel, exitLabel: Label] IF P^[I][K] THEN ... IF Puzzle^[J + K] THEN GO TO Label1; FitResult _ TRUE EXITS Label1 => NULL [I: Piecetype, J: Position] RETURNS [PlaceResult: BOOL] FOR K IN [0..Piecemax^[I]] DO IF P^[I][K] THEN Puzzle^[J + K] _ TRUE; ENDLOOP; [loopLabel, testLabel, exitLabel: Label] IF P^[I][K] THEN Puzzle^[J + K] _ TRUE Piececount^[Class^[I]] _ Piececount^[Class^[I]] - 1; FOR K IN [J..Size] DO IF NOT Puzzle^[K] THEN {PlaceResult _ K; GO TO Label1} ENDLOOP; [loopLabel, testLabel, exitLabel: Label] PlaceResult _ 0 EXITS Label1 => NULL [I: Piecetype, J: Position] FOR K IN [0..Piecemax^[I]] DO FOR K IN [0..Piecemax^[I]] DO IF P^[I][K] THEN Puzzle^[J + K] _ TRUE; ENDLOOP; [loopLabel, testLabel, exitLabel: Label] IF P^[I][K] THEN Puzzle^[J + K] _ FALSE Piececount^[Class^[I]] _ Piececount^[Class^[I]] + 1; [J: Position] RETURNS [TrialResult: BOOL] for testing against the depth test against known max FOR I IN [0..Typemax] DO IF Piececount^[Class^[I]] # 0 THEN IF Fit[I, J] THEN { K _ Place[I, J]; IF Trial[K] OR K = 0 THEN {TrialResult _ TRUE; GO TO Label1} ELSE Remove[I, J]; }; ENDLOOP; [loopLabel, testLabel, exitLabel: Label] IF Piececount^[Class^[I]] # 0 THEN IF Fit[I, J] THEN K _ Place[I, J]; IF Trial[K] OR K = 0 THEN {TrialResult _ TRUE; GO TO Label1} ELSE Remove[I, J] TrialResult _ FALSE EXITS Label1 => NULL Kount _ Kount + 1 TrialDepth _ TrialDepth - 1; test for running too long This procedure generates code based on var being in a register. We assume that at entry the initial value is on the stack and should be stored into var. P^[which][I + D * (J + D * K)] _ TRUE FOR I IN [0..iLim] DO FOR J IN [0..jLim] DO FOR K IN [0..kLim] DO P^[which][I + D * (J + D * K)] _ TRUE ENDLOOP ENDLOOP ENDLOOP; Class^[which] _ class; Piecemax^[which] _ iLim + D*jLim + D*D*kLim; TrialDepth _ 0; MaxTrialDepth _ 0; FOR M IN [0..Size] DO Puzzle^[M] _ TRUE ENDLOOP; FOR I IN [1..5] DO FOR J IN [1..5] DO FOR K IN [1..5] DO Puzzle^[I + D * (J + D * K)] _ FALSE ENDLOOP ENDLOOP ENDLOOP; Puzzle^[I + D * (J + D * K)] _ FALSE FOR I IN [0..Typemax] DO FOR M IN [0..Size] DO P^[I][M] _ FALSE ENDLOOP ENDLOOP; FOR I IN [0..3] DO FOR J IN [0..1] DO FOR K IN [0..0] DO P^[0][I + D * (J + D * K)] _ TRUE ENDLOOP ENDLOOP ENDLOOP; Class^[0] _ 0; Piecemax^[0] _ 3 + D * 1 + D * D * 0; FOR I IN [0..1] DO FOR J IN [0..0] DO FOR K IN [0..3] DO P^[1][I + D * (J + D * K)] _ TRUE ENDLOOP ENDLOOP ENDLOOP; Class^[1] _ 0; Piecemax^[1] _ 1 + D * 0 + D * D * 3; FOR I IN [0..0] DO FOR J IN [0..3] DO FOR K IN [0..1] DO P^[2][I + D * (J + D * K)] _ TRUE ENDLOOP ENDLOOP ENDLOOP; Class^[2] _ 0; Piecemax^[2] _ 0 + D * 3 + D * D * 1; FOR I IN [0..1] DO FOR J IN [0..3] DO FOR K IN [0..0] DO P^[3][I + D * (J + D * K)] _ TRUE ENDLOOP ENDLOOP ENDLOOP; Class^[3] _ 0; Piecemax^[3] _ 1 + D * 3 + D * D * 0; FOR I IN [0..3] DO FOR J IN [0..0] DO FOR K IN [0..1] DO P^[4][I + D * (J + D * K)] _ TRUE ENDLOOP ENDLOOP ENDLOOP; Class^[4] _ 0; Piecemax^[4] _ 3 + D * 0 + D * D * 1; FOR I IN [0..0] DO FOR J IN [0..1] DO FOR K IN [0..3] DO P^[5][I + D * (J + D * K)] _ TRUE ENDLOOP ENDLOOP ENDLOOP; Class^[5] _ 0; Piecemax^[5] _ 0 + D * 1 + D * D * 3; FOR I IN [0..2] DO FOR J IN [0..0] DO FOR K IN [0..0] DO P^[6][I + D * (J + D * K)] _ TRUE ENDLOOP ENDLOOP ENDLOOP; Class^[6] _ 1; Piecemax^[6] _ 2 + D * 0 + D * D * 0; FOR I IN [0..0] DO FOR J IN [0..2] DO FOR K IN [0..0] DO P^[7][I + D * (J + D * K)] _ TRUE ENDLOOP ENDLOOP ENDLOOP; Class^[7] _ 1; Piecemax^[7] _ 0 + D * 2 + D * D * 0; FOR I IN [0..0] DO FOR J IN [0..0] DO FOR K IN [0..2] DO P^[8][I + D * (J + D * K)] _ TRUE ENDLOOP ENDLOOP ENDLOOP; Class^[8] _ 1; Piecemax^[8] _ 0 + D * 0 + D * D * 2; FOR I IN [0..1] DO FOR J IN [0..1] DO FOR K IN [0..0] DO P^[9][I + D * (J + D * K)] _ TRUE ENDLOOP ENDLOOP ENDLOOP; Class^[9] _ 2; Piecemax^[9] _ 1 + D * 1 + D * D * 0; FOR I IN [0..1] DO FOR J IN [0..0] DO FOR K IN [0..1] DO P^[10][I + D * (J + D * K)] _ TRUE ENDLOOP ENDLOOP ENDLOOP; Class^[10] _ 2; Piecemax^[10] _ 1 + D * 0 + D * D * 1; FOR I IN [0..0] DO FOR J IN [0..1] DO FOR K IN [0..1] DO P^[11][I + D * (J + D * K)] _ TRUE ENDLOOP ENDLOOP ENDLOOP; Class^[11] _ 2; Piecemax^[11] _ 0 + D * 1 + D * D * 1; FOR I IN [0..1] DO FOR J IN [0..1] DO FOR K IN [0..1] DO P^[12][I + D * (J + D * K)] _ TRUE ENDLOOP ENDLOOP ENDLOOP; Class^[12] _ 3; Piecemax^[12] _ 1 + D * 1 + D * D * 1; Piececount^[0] _ 13; Piececount^[1] _ 3; Piececount^[2] _ 1; Piececount^[3] _ 1; M _ 1 + D * (1 + D * 1); Kount _ 0; IF Fit[0, M] THEN N _ Place[0, M] ELSE ERROR; IF Trial[N] THEN { IO.PutF[out, "success in %g trials\n", [integer[Kount]]]; } ELSE { IO.PutRope[out, "failure\n"]; }; Leaves a boolean on the stack, 1 for success, 0 for failure Little Helpers This procedure generates a loop where the variable in question goes from its initial value (not generated by this routine) to some static limit (inclusive). The variable must be in a local register. Κ σ–12 sp tabStops˜codešœ™Kšœ Οmœ=™HK™1K™—šΟk ˜ K˜ K˜K˜ K˜K˜K˜—šœ žœž˜KšžœD˜KKšœžœžœ@˜LK˜Kšœžœ˜$K™—™K™)K™2K™—–2.25 in tabStopsšœ™K–2.25 in tabStopsšœžœΟc˜$K–2.25 in tabStopsšœ žœŸ˜1K–2.25 in tabStopsšœ žœŸΠckŸ  Ÿ˜HK–2.25 in tabStopsšœžœŸ Ÿ  Ÿ ˜AK–2.25 in tabStopsšœ žœŸ Ÿ  Ÿ ˜BK–2.25 in tabStopsšœ žœŸ Ÿ  ˜;K–2.25 in tabStopsš œžœŸ Ÿ  Ÿ  ˜IK–2.25 in tabStopsšœžœŸ ˜K–2.25 in tabStopsšœ žœŸ ˜K–2.25 in tabStopsšœ žœŸ ˜K–2.25 in tabStopsšœžœŸ˜(K–2.25 in tabStops˜—–32 sp tabStopsšœ ™ K–32 sp tabStopsšœžœžœŸ˜6K–32 sp tabStopsšœŸ˜1K–32 sp tabStopsšœžœ˜K–32 sp tabStopsšœžœ˜K–32 sp tabStopsšœžœ˜K–32 sp tabStopsšœžœ˜K–32 sp tabStopsšœžœ˜K–32 sp tabStopsšœžœ˜K–32 sp tabStops˜—–32 sp tabStopsšœ™K–32 sp tabStopsšžœžœ˜ —K–32 sp tabStops˜šΟnœžœ˜Kšœ;™;Kšœ0˜0K˜#K˜Kšœ=˜=K˜Kšœ™KšœQ˜Qšœ,˜,K˜—šœ˜Kšœ#™#K™Kšžœ˜K˜K™KšœŸ˜+šœ Ÿ9˜FK˜—Kšœ˜K˜šžœžœžœ ž˜Kšœ žœ˜Kšžœ˜—Kšœžœ˜K˜ Kšœ žœ˜K˜ Kšœ žœ ˜K˜ Kšœ žœ ˜K˜ Kšœ žœ ˜K˜ Kšœ žœ˜K˜K˜K˜—Kšœ ™ K˜Kšœ"˜"KšœF˜FK˜KšœA™AK˜Kšœ Ÿ˜K˜K˜K˜K™qK˜Kšœ Ÿ˜K˜K˜K˜—š‘œžœ˜ Kšœ4™4Kšœ0˜0K˜K–32 sp tabStops˜K–32 sp tabStopsšœ˜K–32 sp tabStopsšœ˜K–32 sp tabStopsšœ˜K–32 sp tabStopsšœ˜K–32 sp tabStopsšœ˜K˜Kšœ Ÿ$˜0K˜ K˜ K˜ K˜ K˜K˜šœ™K˜Kšœ5™5Kšœ0˜0Kšœ.˜.K˜Kšœ>™>šžœžœžœ ž˜Kšœ1žœ˜RKšœ.˜.Kšžœ˜——K˜—K™š‘œžœ˜Kšœ5™5K˜K˜K˜K˜K˜K˜K˜K˜ K˜K˜Kšœ:˜:K˜K–2.0 in tabStopsšœ Ÿ ˜K–2.0 in tabStopsšœŸ˜%K–2.0 in tabStopsšœ Ÿ˜K–2.0 in tabStopsšœ Ÿ˜K–2.0 in tabStopsšœ Ÿ ˜K™Kšœ žœ™K˜K˜$K˜šœ˜š žœžœžœžœž™Kšžœžœžœžœžœžœ žœžœžœžœžœ™5Kšžœ™K™—šœ˜Kšœ(™(K™Kš žœžœžœžœžœ™Kšœ ˜ Kšœ+Ÿ˜˜>K˜K–2.0 in tabStopsšœ Ÿ˜K–2.0 in tabStopsšœŸ˜%K–2.0 in tabStopsšœ Ÿ˜ K–2.0 in tabStopsšœ Ÿ˜K–2.0 in tabStopsšœ Ÿ ˜K™šœ˜š žœžœžœžœž™Kšžœžœžœžœžœ žœžœžœ™'Kšžœ™K™—šœ˜Kšœ(™(Kš žœžœžœžœžœ™K˜K˜ Kšœ+Ÿ˜˜>K˜Kšœ Ÿ˜KšœŸ˜Kšœ Ÿ˜Kšœ Ÿ˜K˜˜Kšœ™Kšœ"˜"K˜#Kšœ ˜ K˜KšœB˜BK˜Kšœžœ-žœ˜EKšœžœ ˜KšœG˜GK˜Kšœ˜KšœE˜EK˜Kšœžœ ˜Kšœ™K˜ KšœI˜IK˜K˜K˜K˜K˜K˜—K™šœ˜šžœžœžœž™šžœžœž™"šžœžœžœž™Kšžœ žœžœ™šžœžœžœžœ™Kš žœžœžœžœžœ™'Kšœ žœžœ™—K™——Kšžœ™K™—šœ˜Kšœ(™(Kšžœžœž™"K˜Kšœžœ ˜Kšœ˜Kšœžœ˜K˜K˜"K˜Kšžœžœžœžœ™K™K˜ K˜ K˜K˜"K™˜K˜K˜K˜Kšžœ žœžœ™K˜K˜ K˜ K˜K˜ K˜Kšžœžœžœžœ™K˜K˜ K˜Kšœ!˜!K˜ K˜#K˜Kš žœžœžœžœžœ™'Kšœ˜K˜$K˜K˜Kšžœžœžœ™K˜K˜K˜ K˜ K˜K˜—K˜K˜—K˜#Kšœ˜K˜K˜—Kšœž™K˜K˜$K˜Kšžœ ž™K˜K˜K˜K™K˜Kšœžœ ˜K˜ Kšœžœ ˜K˜Kšœ™Kšœžœ$žœ˜