<> <> <<>> DIRECTORY DragOpsCross, DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport; GenPuzzleBetter: CEDAR PROGRAM IMPORTS DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport = BEGIN OPEN DragOpsCross, DragOpsCrossUtils, HandCoding, HandCodingPseudos; Area: TYPE = HandCodingSupport.Area; <<>> <> <<3.87 seconds with I/O on a Dorado>> <<3.70 seconds without I/O on a Dorado>> <> <<>> <<>> <> 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 = { <<[I: Piecetype, J: Position] RETURNS [FitResult: BOOL]>> 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 = { <<[loopLabel, testLabel, exitLabel: Label]>> <<>> <> 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]; < 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; 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 = { <<[loopLabel, testLabel, exitLabel: Label]>> <> 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 = { <<[loopLabel, testLabel, exitLabel: Label]>> 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]; < 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; 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 = { <<[loopLabel, testLabel, exitLabel: Label]>> <> 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 = { <<[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, 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 = { <<[loopLabel, testLabel, exitLabel: Label]>> <> 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]; < 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]; 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.