DIRECTORY DragOpsCross, DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport; GenPuzzleBetter: 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 gM: NAT = 7; -- Position gN: NAT = 8; -- Position gI: NAT = 9; -- [0..13] gJ: NAT = 10; -- [0..13] gK: NAT = 11; -- [0..13] gKount: NAT = 12; -- INT gTrialDepth: NAT = 13; -- INT gMaxTrialDepth: NAT = 14; -- INT gSize: NAT = 15; -- 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 ProcedureEntry[NIL, 0]; 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]; HandCodingSupport.OutputByte[area, OnesByte]; drJB[255]; -- loop on halting ProcedureEntry[enterHalt, 1]; HandCodingSupport.OutputByte[area, ZerosByte]; drJB[255]; -- 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; rLim: RegSpec = reg5; labelLabel1: Label = GenLabel[]; ProcedureEntry[enterFit, 2]; HandCodingPseudos.MakeLabelGlobal["Puzzle.Fit", enterFit]; drLC0[]; drLIQB[globalPuzzle]; drLC0[]; drLC0[]; drROR[c: rFR, a: const0, b: const0]; { body: LoopBodyProc = { drLRn[rI]; drSHL[FieldDescriptorToCard[[shift: 9]]]; -- to mult by 512 drRVADD[topDst, topSrc, rK]; drLRIn[G, gP]; drRRX[c: belowDst, a: belowSrc, b: popSrc]; drJNEBBJ[1, UseLabel8[testLabel]]; drRADD[c: pushDst, a: rJ, b: rK]; drLIDB[512]; drBNDCK[]; drLRIn[G, gPuzzle]; drRRX[c: belowDst, a: belowSrc, b: popSrc]; drJEBB[1, UseLabel8[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; rLim: RegSpec = reg5; labelLabel1: Label = GenLabel[]; ProcedureEntry[enterPlace, 2]; HandCodingPseudos.MakeLabelGlobal["Puzzle.Place", enterPlace]; drLC0[]; -- PlaceResult drLIQB[globalPuzzle]; -- G drLC0[]; -- K drLC0[]; -- loop limit { body: LoopBodyProc = { drLRn[rI]; drSHL[FieldDescriptorToCard[[shift: 9]]]; -- to mult by 512 drRVADD[topDst, topSrc, rK]; drLRIn[G, gP]; drRRX[belowDst, belowSrc, popSrc]; drJNEBB[1, UseLabel8[testLabel]]; drRADD[c: pushDst, a: rJ, b: rK]; drLIDB[512]; drBNDCK[]; drLRIn[G, gPuzzle]; drRVADD[c: belowDst, a: belowSrc, b: popSrc]; 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]; drRRX[c: topDst, a: topSrc, b: rI]; drLRIn[G, gPiececount]; drADD[]; drRSB[0]; drSUBB[1]; drLIB[14]; drBNDCK[]; drWSB[0]; { body: LoopBodyProc = { drLRIn[G, gPuzzle]; drRRX[c: topDst, a: topSrc, b: rK]; drJNEBBJ[0, UseLabel8[testLabel]]; drROR[c: rPR, a: const0, b: rK]; drJB[UseLabel8[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; rLim: RegSpec = reg4; ProcedureEntry[enterRemove, 2]; HandCodingPseudos.MakeLabelGlobal["Puzzle.Remove", enterRemove]; drLIQB[globalPuzzle]; drLC0[]; -- reserve K 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 drRVADD[topDst, topSrc, rK]; drLRIn[G, gP]; drRRX[c: belowDst, a: belowSrc, b: popSrc]; drJNEBB[1, UseLabel8[testLabel]]; drRADD[c: pushDst, a: rJ, b: rK]; drLIDB[512]; drBNDCK[]; 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]; drRRX[c: topDst, a: topSrc, b: rI]; drLRIn[G, gPiececount]; drADD[]; drRSB[0]; drADDB[1]; drLIB[14]; drBNDCK[]; 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, gMaxTrialDepth]; drRJLEBJ[popLeft: FALSE, right: popSrc, dist: UseLabel8[continueLabel]]; SetLabel[newMaxLabel]; HandCodingPseudos.MakeLabelGlobal["Puzzle.newMaxDepth", newMaxLabel]; drDUP[]; drSRIn[G, gMaxTrialDepth]; drLIB[18]; drRJLEBJ[popLeft: FALSE, right: popSrc, dist: UseLabel8[continueLabel]]; Pause[]; SetLabel[continueLabel]; drDIS[]; }; { body: LoopBodyProc = { drLRIn[G, gClass]; drRRX[c: topDst, a: topSrc, b: rI]; drLRIn[G, gPiececount]; drRRX[c: belowDst, a: belowSrc, b: popSrc]; drJEBB[0, UseLabel8[testLabel]]; drLRn[rI]; drLRn[rJ]; drLFC[UseLabel16[enterFit]]; drJEBB[0, UseLabel8[testLabel]]; { thenLabel: Label = GenLabel[]; elseLabel: Label = GenLabel[]; drLRn[rI]; drLRn[rJ]; drLFC[UseLabel16[enterPlace]]; drSRn[rK]; drLRn[rK]; drLFC[UseLabel16[enterTrial]]; drJEBB[1, UseLabel8[thenLabel]]; drLRn[rK]; drJNEBBJ[0, UseLabel8[elseLabel]]; SetLabel[thenLabel]; drROR[c: rTR, a: const0, b: const1]; drJB[UseLabel8[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]; drRJLEBJ[popLeft: TRUE, right: popSrc, dist: UseLabel8[continueLabel]]; Pause[]; SetLabel[continueLabel]; }; drROR[c: reg0, a: const0, b: rTR]; ProcedureExit[1]; }; GenPuzzleRun: PROC = { G: RegSpec = reg0; ProcedureEntry[enterPuzzleRun, 0]; drLIQB[globalPuzzle]; drLC0[]; drSRIn[G, gTrialDepth]; drLC0[]; drSRIn[G, gMaxTrialDepth]; { body1: LoopBodyProc = { drLRIn[G, gM]; drLRIn[G, gPuzzle]; drADD[]; drLC1[]; drWSB[0]; }; drLC0[]; GenGlobalStaticLoop[G, gM, 511, body1]; }; { body1: LoopBodyProc = { drLC1[]; GenGlobalStaticLoop[G, gJ, 5, body2]; }; body2: LoopBodyProc = { drLC1[]; GenGlobalStaticLoop[G, gK, 5, body3]; }; body3: LoopBodyProc = { drLRIn[G, gK]; drSHL[FieldDescriptorToCard[[shift: 3]]]; -- to mult by 8 drLRIn[G, gJ]; drADD[]; drSHL[FieldDescriptorToCard[[shift: 3]]]; -- to mult by 8 drLRIn[G, gI]; drADD[]; drLIDB[512]; drBNDCK[]; drLRIn[G, gPuzzle]; drADD[]; drLC0[]; drWSB[0]; }; drLC1[]; GenGlobalStaticLoop[G, gI, 5, body1]; }; { body1: LoopBodyProc = { drLC0[]; GenGlobalStaticLoop[G, gM, 511, body2]; }; body2: LoopBodyProc = { drLRIn[G, gI]; drLIB[13]; drBNDCK[]; drSHL[FieldDescriptorToCard[[shift: 9]]]; -- to mult by 512 drLRIn[G, gM]; drADD[]; drLRIn[G, gP]; drADD[]; drLC0[]; drWSB[0]; }; drLC0[]; GenGlobalStaticLoop[G, gI, 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]; drLIB[13]; drWSB[0]; drLRIn[G, gPiececount]; drLIB[3]; drWSB[1]; drLRIn[G, gPiececount]; drLIB[1]; drWSB[2]; drLRIn[G, gPiececount]; drLIB[1]; drWSB[3]; drLIB[1 + D * (1 + D * 1)]; drSRIn[G, gM]; drLC0[]; drSRIn[G, gKount]; { elseLabel: Label = GenLabel[]; fiLabel: Label = GenLabel[]; drLC0[]; drLRIn[G, gM]; drLFC[UseLabel16[enterFit]]; drJNEBB[1, UseLabel8[elseLabel]]; drLC0[]; drLRIn[G, gM]; drLFC[UseLabel16[enterPlace]]; drSRIn[G, gN]; drJB[UseLabel8[fiLabel]]; SetLabel[elseLabel]; Halt[3]; SetLabel[fiLabel]; }; drLRIn[G, gN]; 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 drRXOR[c: topDst, a: topSrc, b: const1]; -- code for NOT Halt[0, TRUE]; -- with either 0 for success, or 1 for failure }; LoopBodyProc: TYPE = PROC [loopLabel, testLabel, exitLabel: Label]; Halt: PROC [code: NAT, noPush: BOOL _ FALSE] = { loopLabel: Label = GenLabelHere[]; IF NOT noPush THEN drLIB[code]; drLFC[UseLabel16[enterHalt]]; }; GenCrap: PROC [G: RegSpec, which, class, iLim, jLim, kLim: NAT] = { body1: LoopBodyProc = { drLC0[]; GenGlobalStaticLoop[G, gJ, jLim, body2]; }; body2: LoopBodyProc = { drLC0[]; GenGlobalStaticLoop[G, gK, kLim, body3]; }; body3: LoopBodyProc = { drLRIn[G, gK]; drSHL[FieldDescriptorToCard[[shift: 3]]]; -- to mult by 8 drLRIn[G, gJ]; drADD[]; drSHL[FieldDescriptorToCard[[shift: 3]]]; -- to mult by 8 drLRIn[G, gI]; drADD[]; drLIDB[512]; drBNDCK[]; drLRIn[G, gP]; drADD[]; IF which # 0 THEN drADDDB[which*512]; drLC1[]; drWSB[0]; }; drLC0[]; GenGlobalStaticLoop[G, gI, iLim, body1]; drLIB[class]; drLRIn[G, gClass]; drWB[which]; drLIB[iLim + D*jLim + D*D*kLim]; drLRIn[G, gPiecemax]; drWB[which]; }; GenStaticLoop: PROC [var: RegSpec, lim: CARDINAL, body: LoopBodyProc, closed: BOOL _ TRUE] = { loopLabel: Label = GenLabel[]; testLabel: Label = GenLabel[]; entryLabel: Label = GenLabel[]; exitLabel: Label = GenLabel[]; drJB[UseLabel8[entryLabel]]; 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[popLeft: TRUE, right: var, dist: UseLabel8[loopLabel]] ELSE drRJGBJ[popLeft: TRUE, right: var, dist: UseLabel8[loopLabel]]; SetLabel[exitLabel]; }; GenGlobalStaticLoop: PROC [gr: RegSpec, var: NAT, lim: CARDINAL, body: LoopBodyProc, closed: BOOL _ TRUE] = { loopLabel: Label = GenLabel[]; testLabel: Label = GenLabel[]; entryLabel: Label = GenLabel[]; exitLabel: Label = GenLabel[]; drJB[UseLabel8[entryLabel]]; SetLabel[loopLabel]; body[loopLabel, testLabel, exitLabel]; SetLabel[testLabel]; drLRIn[gr, var]; drADDB[1]; SetLabel[entryLabel]; drDUP[]; drSRIn[gr, var]; IF lim < 256 THEN drLIB[lim] ELSE drLIDB[lim]; IF closed THEN drRJLEBJ[popLeft: TRUE, right: popSrc, dist: UseLabel8[loopLabel]] ELSE drRJLBJ[popLeft: TRUE, right: popSrc, dist: UseLabel8[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[UseLabel8[entryLabel]]; 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[popLeft: limNeedsPush, right: var, dist: UseLabel8[loopLabel]] ELSE drRJGBJ[popLeft: limNeedsPush, right: var, dist: UseLabel8[loopLabel]]; SetLabel[exitLabel]; }; END.  GenPuzzleBetter.mesa Russ Atkinson, April 5, 1984 6:29:56 pm PST This program takes 3.87 seconds with I/O on a Dorado 3.70 seconds without I/O on a Dorado Total instructions: 1027, Bytes: 1348 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 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"]; }; Little Helpers 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; This procedure generates code based on the variable in question being at some small offset from a register base. We assume that at entry the initial value is one the stack and should be stored into the indirect variable. Κ –12 sp tabStops˜šœ™J™+J™—šΟk ˜ J˜ J˜J˜ J˜J˜J˜—šœœ˜JšœD˜KJšœœœ@˜LJ˜Jšœœ˜$J™—™J™!J™$J™%J™—J™–32 sp tabStopsšœ™J–32 sp tabStopsšœœΟc˜$J–32 sp tabStopsšœ œž˜1J–32 sp tabStopsšœ œžΠckž Ÿž˜HJ–32 sp tabStopsšœœžŸž Ÿž ˜AJ–32 sp tabStopsšœ œžŸž Ÿž ˜BJ–32 sp tabStopsšœ œžŸž Ÿ˜;J–32 sp tabStopsš œœžŸž Ÿž Ÿ˜IJ–32 sp tabStopsšœœž ˜J–32 sp tabStopsšœœž ˜J–32 sp tabStopsšœœž ˜J–32 sp tabStopsšœœž ˜J–32 sp tabStopsšœœž ˜J–32 sp tabStopsšœœžŸ˜J–32 sp tabStopsšœ œžŸ˜J–32 sp tabStopsšœœžŸ˜ J–32 sp tabStopsšœœž˜(J–32 sp tabStops˜—–32 sp tabStopsšœ ™ J–32 sp tabStopsšœœœž˜6J–32 sp tabStopsšœž˜1J–32 sp tabStopsšœœ˜J–32 sp tabStopsšœœ˜J–32 sp tabStopsšœœ˜J–32 sp tabStopsšœœ˜J–32 sp tabStopsšœœ˜J–32 sp tabStopsšœœ˜J–32 sp tabStops˜—–32 sp tabStopsšœ™J–32 sp tabStopsšœœ˜ —J–32 sp tabStops˜šΟnœœ˜Jšœ;™;Jšœ0˜0J˜#J˜Jšœ=˜=J˜Jšœ™JšœQ˜Qšœ,˜,J˜—šœ˜Jšœ#™#J™Jšœ˜J˜J™šœž˜+J˜—Jšœœ˜J˜Jšœ˜J˜šœœœ ˜Jšœ œ˜Jšœ˜—Jšœœ˜J˜ Jšœ œ˜J˜ Jšœ œ ˜J˜ Jšœ œ ˜J˜ Jšœ œ ˜J˜ Jšœ œ˜J˜J˜J˜—Jšœ ™ J˜Jšœ"˜"JšœF˜FJ˜JšœA™AJ˜Jšœ-˜-Jšœ ž˜J˜J˜J˜J™qJ˜Jšœ.˜.Jšœ ž˜J˜J˜J˜—š œœ˜ Jšœ4™4Jšœ0˜0J˜J–32 sp tabStops˜J–32 sp tabStopsšœ˜J–32 sp tabStopsšœ˜J–32 sp tabStopsšœ˜J–32 sp tabStopsšœ˜J–32 sp tabStopsšœ˜J˜Jšœ ž$˜0J˜ J˜ J˜ J˜ J˜J˜šœ™J˜Jšœ5™5Jšœ0˜0Jšœ.˜.J˜Jšœ>™>šœœœ ˜Jšœ1œ˜RJšœ.˜.Jšœ˜——J˜—J™š œœ˜Jšœ5™5J˜J˜J˜J˜J˜J˜J˜ J˜J˜Jšœ:˜:J˜J˜Jšœ˜J˜J˜J™Jšœ œ™J˜J˜$J˜šœ˜š œœœœ™Jšœœœœœœ œœœœœ™5Jšœ™J™—šœ˜Jšœ(™(J™Jš œœœœœ™Jšœ ˜ Jšœ+ž˜˜>J˜Jšœ ž˜Jšœž˜Jšœ ž˜ Jšœ ž ˜J™šœ˜š œœœœ™Jšœœœœœ œœœ™'Jšœ™J™—šœ˜Jšœ(™(Jš œœœœœ™J˜J˜ Jšœ+ž˜˜>J˜Jšœ ž˜Jšœž˜Jšœ ž˜Jšœ ž˜J˜˜Jšœ™Jšœ"˜"J˜#Jšœ ˜ J˜JšœB˜BJ˜Jšœœ-œ˜EJšœœ˜Jšœœ1˜HJ˜Jšœ˜JšœE˜EJ˜Jšœœ˜#Jšœ™J˜ Jšœœ1˜HJ˜J˜J˜J˜J˜J˜—J™šœ˜šœœœ™šœœ™"šœœœ™Jšœ œœ™šœœœœ™Jš œœœœœ™'Jšœ œœ™—J™——Jšœ™J™—šœ˜Jšœ(™(Jšœœ™"J˜Jšœœ ˜J˜#Jšœœ˜J˜+J˜ J˜Jšœœœœ™J™J˜ J˜ J˜J˜ J™˜J˜J˜J˜Jšœ œœ™J˜J˜ J˜ J˜J˜ J˜Jšœœœœ™J˜J˜ J˜Jšœ ˜ J˜ J˜"J˜Jš œœœœœ™'Jšœ˜J˜$J˜J˜Jšœœœ™J˜J˜J˜ J˜ J˜J˜—J˜J˜—J˜#Jšœ˜J˜J˜—Jšœ™J˜J˜$J˜Jšœ ™J˜J˜J˜J™J˜Jšœœ ˜J˜ Jšœœ ˜J˜Jšœ™Jšœœ$œ˜J˜J˜J˜—J™™J™Jš  œœœ*˜CJ˜š  œœœ œœ˜0J˜"Jšœœœ ˜Jšœ˜J˜J˜—š œ˜ Jšœœ+œ˜5šœ˜J˜Jšœœ˜(J˜—šœ˜J˜Jšœœ˜(J˜—šœ˜Jš œ œœœœœ™%Jšœœ˜Jšœ+ž˜:Jšœœ˜J˜Jšœ+ž˜:Jšœœ˜J˜J˜ J˜ Jšœœ˜J˜Jšœ œ˜%J˜J˜ J˜—šœœœ œ™šœœœ œ™šœœœ œ™Jš œ œœœœœ™%Jš™—Jš™—Jšœ™ —J˜Jšœœ˜(J™Jšœ™J™Jšœ ˜ Jšœœ ˜Jšœ ˜ J™Jšœœœœ™-J˜Jšœ œœœ˜ Jšœœ ˜Jšœ ˜ J˜J˜—š  œ˜Jšœœœœ˜JJ˜J˜J˜J˜Jšœ˜J˜J˜Jšœ&˜&J˜J˜Jšœ"˜"J˜Jšœ œ œ ˜.šœ˜ Jšœœ)˜DJšœœ*˜D—J˜J˜J˜J˜—š œ˜Jš œœœœœ˜SJ˜Jšœέ™έJ˜J˜J˜J˜J˜Jšœ˜J˜J˜Jšœ&˜&J˜J˜Jšœ˜J˜ J˜J˜Jšœ˜Jšœ œ œ ˜.šœ˜ Jšœœ,˜GJšœœ-˜G—J˜J˜J˜J˜—š œ˜Jšœ9œœ˜IJ˜J˜J˜J˜Jšœœ˜"J˜Jšœ˜J˜J˜Jšœ&˜&J˜J˜Jšœ"˜"J˜Jšœœ ˜šœ˜ JšœH˜LJšœH˜L—J˜J˜J˜—J˜—Jšœ˜J˜—…—5Rl