The top half (low memory) puzzle interaction portion of this program's source code should be largely understandable, and the synthesis of an XOR through “carryless addition” is interesting. However, the puzzle setup code beginning at 0200 is rather dense and may be difficult to reverse engineer without the aid of clear descriptions of the algorithms used. Though the code is clearly commented, it wasn't clear how much real interest there would be in understanding the algorithms, so they have not been documented in great detail.
Since most SBC6120/FP6120 owner interest will likely be in equipping systems with this puzzle, you can skip the source and jump down to the "Installing LightsOut into your SCB6120/FP6120" section...
PDP-8 / SBC6120/FP6120 “LightsOut” Source Code
/=============================================================================== / "Lights Out" - A simple switch-register puzzle to turn OUT all of the lights /------------------------------------------------------------------------------- / / During puzzle play, each switch-register switch *changes* the illumination of / exactly two lights and each light is changed by *exactly* two of the switches. / /------------------------------------------------------------------------------- / Operation: 1. With the program loaded, start at location 0026 or 0200. / (0026 is the starting location required by the boot loader.) / 2. Set display knob to anything other than MD (memory data). / (This is required for software to control the data lights.) / 3. Move any switch-register switch to begin new puzzle. / (Upon moving any switch, the randomization stops.) / 4. Now find the combination that turns ALL lights OFF. / 5. If you give up and/or are stumped, press the EXAMine switch. / 6. To begin another puzzle, press the CLEAR switch to start / randomizing then move any data switch to begin a new puzzle. / / Hint #1: If you want to give yourself only a hint, cover up some of the / display lights with one hand when you press EXAMine to see the / correct answer. Then set those switches as shown, leaving them / undisturbed as you solve for the positions of the others. / / Hint #2: Try making a chart of which lights are controlled by each switch. / / Too Simple? The value at location 0060 (Difficulty) specifies the number of / lights that are controlled by each switch. '1' is trivial to / solve ... but '6' will extinguish *YOUR* lights permanently! / / (And difficulty level '11' (octal 13) is simple to solve in / a very different way if you have a pencil and paper to make / a chart of which ONE light is NOT changed by each switch.) / / Final Note: At "difficulty" level '2', there are *two* (very different) / solutions to each puzzle. So don't be alarmed if the solution / you achieve is different from what the EXAM switch shows. / / Requirements: The program will run in 4K and needs no EAE or other add-on. / / Have fun with the front panel of your lovely classic PDP-8 computer! /------------------------------------------------------------------------------- / Contemporary PDP-8 FREEWARE written and placed / into the PUBLIC DOMAIN by Steve Gibson, 2009 /=============================================================================== / Implementation notes - The code below uses two SBC6120/FP6120-specific features / which will not work on a regular PDP-8: As explained below, it takes over the / display of the data lights. This is done because the 30hz sampling of the AC / sometimes catches the AC at a bad time causing the display to flicker annoyingly. / This would NOT be a problem on a real PDP-8, since its AC display is not being / sampled and held. Also, since we're able to read the other front panel function / switches (CLEAR, EXAMine, etc.) we use these in the program (see below). On a / regular PDP-8, the puzzle's solution would be kept in the "MQ" register so the / user could get the result or a hint by briefly displaying the MQ register data. CALLBIOS=6206 / Call SBC6120 BIOS function, function code follows call LIGHTS=12 / BIOS function to take over the display of data lights SETLEDS=6246 / write data LEDs (when ROTSW != MD) / Note that for some reason the SBC system doesn't like / to have its "set lights" function (12) called over and / over to perform that function. So the solution, which / works perfectly, is to call that function exactly ONCE / at the start of the program to stop the automatic 30hz / refresh of the data lights from the user-mode machine / state. Then we subsequently write the data we want / displayed directly to the hardware. RFNS=6434 / read function switches (BOOT, EXAM, DEP, ROTSW, etc) /------------------------------------------------------------------------------+ / Bit definitions for the private Read Function Switches (RFNS) IOT | / 0 1 2 | 3 4 5 | 6 7 8 | 9 10 11 | /+------+------+------+-------+------+------+-----+------+----+----+----+------+ /| BOOT | LADR | LEXT | CLEAR | CONT | EXAM | DEP | HALT | MD | MQ | AC | STAT | /+------+------+------+-------+------+------+-----+------+----+----+----+------+ SAC=7340 / Set AC to all 1's and clear the link - microprogrammed / custom "operate" opcode we use to good purpose below. *0 ShowResult, CLA TAD Result SetLights, SETLEDS / we write directly to the hardware / after declaring our intent only once RFNS / read the various function switches AND ExamSW / check for the EXAM switch active SNA JMP CheckForClear / no EXAM switch, keep checking... CLA / we DO have EXAM, so put the puzzle's TAD PuzzleAnswer / answer into the data display JMP SetLights CheckForClear, RFNS / read the various function switches AND ClearSW / check for the CLEAR switch active SZA / not CLEAR either, show current answer JMP I RestartLoc / restart the app to run another puzzle / the following code is the way we perform an XOR (exclusive OR) / when the system doesn't have one available. Since an XOR is / also a "carryless add", we perform an ADD, then subtract the / carrys that resulted (where both bits were 1's) that works! / -(SwitchMask AND PuzzleAnswer) + SwitchMask + PuzzleAnswer CLA OSR / get the user's current puzzle guess DCA SwitchMask / save the new switch register TAD SwitchMask / and get the new switch reg back AND PuzzleAnswer / find the common bits CLL RAL / double the value of common bits CIA / to subtract them from the sum TAD SwitchMask / add into this one of the terms /-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- SKP / skip over 0026, our startup entry. Our / funky SBC6120 OS/8 boot requires this JMP I StartupLoc / fixed 0026 entrypoint, but it's easily / accommodated with a SKP instruction /-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- TAD PuzzleAnswer / and add in the second of the terms DCA SwitchMask / and update/save new XOR result DCA Result / initialize our XOR accumulator to ZERO TAD BitMasksLoc / point to our first BitMask DCA TargetPtr / setup to process XORing of them XorOneSwitch, CLL / make sure LINK is clear before rotate TAD SwitchMask / get the current (remaining) switchmask SNA / if there are still 1 bits, let's go... JMP ShowResult / we're all done, so setup to wait RAR / rotate low-bit into the LINK DCA SwitchMask / save the updated SwitchMask for next SNL / if that bit was NOT zero, perform XOR JMP NextBit / link=0 if it WAS zero, setup for next TAD Result / link=1 get the current cumulative result AND I TargetPtr / and find the common bits CLL RAL / double the value of common bits CIA / to subtract them from the sum TAD Result / add into this one of the terms TAD I TargetPtr / and add in the second of the terms DCA Result / and update/save new XOR result NextBit, ISZ TargetPtr / bump to the next possible XOR target JMP XorOneSwitch / and go back to check for more work /------------------------ Initialized Constant Values ------------------------- StartupLoc, Start / used for our startup cross-page JMP RestartLoc, NewPuzzle / used for our restart cross-page JMP C7764, 7764 / (-12) Difficulty, 2 / 1-11 puzzle complexity (bits per switch) ClearSW, 0400 / front panel Clear switch bit ExamSW, 0100 / front panel Exam switch bit CRandAdd, 541 / 353 base 10 BitMasksLoc, Masks / pointer to our 12 word Mask array /-------------------------- Uninitialized Variables ---------------------------- Masks, ZBLOCK 14 / our array of 12 bitmask words BitsUsed, 0 / the bits we've reset so far TargetPtr, 0 / indirect reference to bitmask array TargetCtr, 0 / counter for 12 bitmask CandidateBit, 0 / index pointer into our arrays BitsToSet, 0 / counter of bits we're setting LoopCtr, 0 / generic short-term use counter PriorBits, 0 / used to see whether we changed anything LastRand, 0 / our previous random value PuzzleAnswer, 0 / this is what the user is seeking Result, 0 / cumulative XORing result SwitchMask, 0 / switch register shifting mask / Uninitialized software multiplier temporaries used by our unsigned multiply Multiplier, 0 / used to shift and conditionally sum PhaseCount, 0 / used to down-count 12 shift/adds AccumLow, 0 / low 12 bits of multiplication accum AccumHigh, 0 / high 12 bits of mult accumulation *200 /---------------------------- Start at location 0200 --------------------------- Start, CALLBIOS / call SBC6120 BIOS to declare that from LIGHTS / now on, WE will control the data lights 1 / by writing directly to the hardware... NewPuzzle, CLA OSR / we grab the switches at start DCA SwitchMask / and save them to find the first change Randomize, JMS GetRand / start spinning the PRNG to randomize LIGHTS / show that we're in our "randomize" mode CLA OSR / get the switches again CIA / negate them TAD SwitchMask / add the original switchreg state SNA / skip if they have been changed JMP Randomize / no change, so keep randomizing... /--------------------------- Initialize a New Puzzle --------------------------- / / Our overall goal is to create a set of twelve "bitmap" words, one for each / switch register switch, each containing some number (typically 2) of '0' bits / occupying pseudo-random bit locations in each word. Each of the '0' bits in / the bitmap specifies the lights to be inverted by its respective switch reg sw. / / The other goal is to evenly distribute the '0' bits across the lights so that, / for example, we don't wind up with many switches all toggling the same few / lights. This could happen if we didn't globally track the used and unused bits. / / We accomplish this by keeping a master mask (BitsUsed) of bits we have set so / far, and only choosing from those remaining unset as we choose bits for the / individual words. Once "BitsUsed" is all 0's, meaning no bits-to-set remaining, / we reset it to all 1's and continue setting bits into the 12 individual bitmaps. JMS GetRand / pickup a random puzzle answer DCA PuzzleAnswer / save it for this puzzle / Setup the twelve bitmask words with N randomly chosen bits. TAD BitMasksLoc / point to our first BitMask DCA TargetPtr / setup to fill from there TAD C7764 / AC <- (-12) DCA TargetCtr / setup to fill twelve bitmask words CMA / init BitsUsed to all 1's DCA BitsUsed / show NO bits used so far FillOneWord, SAC / set AC to 7777 and clear link DCA I TargetPtr / initialize the target to all bits on TAD Difficulty / get the puzzle complexity (bits/switch) CIA / setup our set bit counter DCA BitsToSet / set the bit set counter ClearOneBit, JMS GetRnd0to11 / AC <- RND(0..11) CMA / AC <- Rand(-1 to -12) DCA LoopCtr / set our bit rotator for random bit TAD I TargetPtr / get the current bitmask DCA PriorBits / save current for comparison SAC / turn all AC bits on and LINK *OFF* (!) SpinBits, RAL / rotate zero link into the AC ISZ LoopCtr / bump our loop counter JMP SpinBits / and do it until we're done DCA CandidateBit / save the bit we're considering TAD CandidateBit / get it back for initial testing AND I TargetPtr / turn OFF all other already OFF bits DCA I TargetPtr / save the result back to our target TAD I TargetPtr / get the new bitmask back CLL CIA / form its negative TAD PriorBits / add our prior bit mask to detect change SNA / if result is nonzero, we did change something JMP ClearOneBit / we already had that bit reset, so choose another CLA TAD CandidateBit / now check our new candidate against AND BitsUsed / see whether we have already used this bit CIA TAD BitsUsed / AC = 0 if bits used WAS NOT changed SZA / not changed, so that bit was not available JMP KeepBit / it was changed, so we can keep it... TAD PriorBits / that bit was not available DCA I TargetPtr / return to the previous bitmap JMP ClearOneBit / and get another candidate KeepBit, CLA / we need to update UsedBits TAD CandidateBit / get the bit we've chosen AND BitsUsed / turn off the bit SNA / skip if we still have bits to use CMA / we ran out, so reset to all available DCA BitsUsed / save the updated BitsUsed mask ISZ BitsToSet / count this bit and check for more JMP ClearOneBit / we're not done yet, so set another TAD I TargetPtr / finally ... invert the bits CMA / flip the few 0's into a few 1's DCA I TargetPtr / and save'em back ISZ TargetPtr / bump to the next target bitmask word ISZ TargetCtr / see whether we might be done? JMP FillOneWord / we're not done... so do another! / The one problem with the approach we took to assigning bits to bitmap masks, / is that the Bits Used are assigned to linearly successive switches, filling / all bits then resetting and refilling. This can render many puzzles trivial / to solve. So we now breakup the local association grouping by performing 12 / swaps between pseudo-randomly chosen pairs of the twelve bitmap masks... TAD C7764 / AC <- (-12) DCA TargetCtr / setup to fill twelve bitmask words SwapRndMasks, JMS GetRnd0to11 / pickup the first index to swap TAD BitMasksLoc / form an index DCA TargetPtr / save the first target pointer JMS GetRnd0to11 / pickup the second index to swap TAD BitMasksLoc / form an index DCA BitsToSet / save the second target pointer TAD I TargetPtr / get the first one DCA BitsUsed TAD I BitsToSet / get the second one DCA I TargetPtr / save into the first one TAD BitsUsed / get back the first one DCA I BitsToSet / save back into the second ISZ TargetCtr / see whether we've done 12 JMP SwapRndMasks / let perform another random swap JMP ShowResult / the puzzle is ready for solving... / GetRand ---------------------------------------------------------------------- / This is the simplest way I know of to generate highly random / looking 12-bit values. It's a Linear Congruential Pseudo Random / Number Generator (LCPRNG). Each time it's called, it evaluates / the expression: NextRand = LastRand * 5545 + 541 (all octal) / GetRnd: returns PRNG (0-4095), / GetRnd0to11: returns (0-11) GetRand, 0 / subroutine return TAD LastRand / get the last PRNG value JMS MUY / multiply by the following constant: 5545 / 2917 base 10 - LCPRNG multiplicand TAD CRandAdd / sum in our LCPRNG addend DCA LastRand / save this for next time TAD LastRand / and return it to our caller JMP I GetRand / return the AC to the caller GetRnd0to11, 0 / (subroutine return) JMS GetRand / get a number (0-7777) JMS MUY / treat it as (0 to .9999999) 14 / and multiply by 12 to generate CLA / a range from 0 to 11 TAD AccumHigh / return our 0-11 value JMP I GetRnd0to11 / return with AC <-- RND (0..11) / MUY -------------------------------------------------------------------------- / This is a full 12x12 multiply, needed because the HD6120 PDP-8 / emulation chip used by the SBC6120 inexplicably lacks the EAE / "Extended Arithmetic Element" multiplier. Annoying as this is, / it does mean that these "ToggleToys" will be usable on ALL real / PDP-8 systems, including those without EAE's. / / On Entry: AC contains Multiplier & the word after the call has Multiplicand / Return: least significant 12-bits in AC, most significant in AccumHigh. MUY, 0 / subroutine return DCA Multiplier / save the multiplier for shifting TAD C7764 / setup our -12 loop counter DCA PhaseCount DCA AccumLow / clear our 24-bit results accumulator DCA AccumHigh MuyShift, TAD Multiplier / get a bit from the multiplier CLL RAL / move the high-bit into LINK DCA Multiplier / put the updated multiplier back SNL / we do need to add-in the multiplicand JMP Iterate / no multiplicand add-in TAD I MUY / add the multiplicand into accumulator TAD AccumLow / this *may* overflow, clearing the LINK DCA AccumLow / either way, put the updated low 12 back SNL / if LINK is still '1', no overflow ISZ AccumHigh / bump the high-half if we carried out Iterate, ISZ PhaseCount / see whether we've done all 12 bits JMP Shift24 / not done, so shift and iterate again CLL CLA / return the lower 12-bits in AC TAD AccumLow ISZ MUY / return to the instruction after multiplier JMP I MUY Shift24, TAD AccumLow / get the lower 12-bit half CLL RAL / shift it left, high bit into LINK DCA AccumLow / put back the new low half TAD AccumHigh / get the upper 12-bit half RAL / shift it left, LINK into low bit DCA AccumHigh / put back the new high half JMP MuyShift /------------------------------------------------------------------------------ $ The assembled listing for this source code, LightsOut.lst, is also available. |
Due to the size of the OS/8 operating system, and the fact that three hours of 9600 baud transfer is required to move it in hex ASCII format from a PC to the SBC6120, I wrote the OS/8 Windows utilities to make that process instantaneous by allowing the SBC6120's IDE drive to be attached through any means available to a Windows system, and to then perform a raw physical transfer of the OS/8 partition data to the SBC's drive.
However, the “DeepThought” and “LightsOut” toggle toys, the custom boot sector, and the sector read/write utilities are all short enough to be feasibly entered through a terminal console. This also means that there is no need for a Windows-centric approach, so Apple Mac and Linux/Unix users will not be disadvantaged.
The following instructions will allow you to deposit the “LightsOut” program in RAM, then write it to any one or more IDE drive partitions of your choosing. Then the modified multi-boot sector will allow you to load and run the program any time you wish using only the front panel switches. This code was developed on SBC6120's having an attached eight gigabyte drive, yielding more than 4300 (octal) partitions. So, for ease of switch register use, the toggle toys were written to partitions 4000 and 4001 (octal). Before proceeding, you should determine where — into which partition(s) — you wish to write these toggle toys. (You should probably have already installed the custom multi-boot sector before installing the “DeepThought” and “LightsOut” toggle toys since their subsequent loading and running requires the multi-boot sector.)
If the SBC6120 is currently running (the front panel RUN light is illuminated), briefly lower and raise the front panel HALT switch to return control to the BIOS and console. Establish communication with the BIOS so that pressing “Enter” on your terminal or terminal emulator returns the BIOS '>' prompt.
Begin by either resetting the SBC6120 or performing a master reset (mr) command to bring the SBC6120 into a known state:
>mrThen clear all of memory. This will take a few seconds, during which the front panel's address register will count all the way up to 77777 as zeroes are being written into the PDP-8's RAM:
>cmYou can verify that memory has been cleared by displaying the first sector's-worth of RAM with the examine memory (e) command. You'll receive a nice block display of zeroes, not shown here:
>e 0-377Now we need to deposit the LightsOut program into RAM. The commands to do this are a series of deposit (d) commands shown below. You can enter each line manually, but terminal emulation programs often understand “copy & paste” semantics which make copying the commands from this page and pasting them into the terminal for sending to the SBC6120 much quicker, easier, and less error prone.
If you are a Windows user, the free, open source, and very nice “Tera Term” terminal emulator can be used. With Tera Term, the keystroke combination “Alt-V” will paste the Windows' clipboard into the terminal window while simultaneously sending it to the SBC6120, exactly as if it had been manually entered. (Here is a locally archived copy in case the file's home site ever disappears: TeraTerm_v2.3.zip.)
The following series of SBC6120 deposit (d) commands will place the LightsOut program into SBC RAM:>d 00000 7200,1112,6246,6434,0062,7450,5012,7200 >d 00010 1111,5002,6434,0061,7440,5456,7604,3113 >d 00020 1113,0111,7104,7041,1113,7410,5455,1111 >d 00030 3113,3112,1064,3102,7100,1113,7450,5000 >d 00040 7010,3113,7420,5053,1112,0502,7104,7041 >d 00050 1112,1502,3112,2102,5034,0200,0203,7764 >d 00060 0002,0400,0100,0541,0065 >d 00200 6206,0012,0001,7604,3113,4324,6246,7604 >d 00210 7041,1113,7450,5205,4324,3111,1064,3102 >d 00220 1057,3103,7040,3101,7340,3502,1060,7041 >d 00230 3105,4334,7040,3106,1502,3107,7340,7004 >d 00240 2106,5237,3104,1104,0502,3502,1502,7141 >d 00250 1107,7450,5231,7200,1104,0101,7041,1101 >d 00260 7440,5265,1107,3502,5231,7200,1104,0101 >d 00270 7450,7040,3101,2105,5231,1502,7040,3502 >d 00300 2102,2103,5224,1057,3103,4334,1064,3102 >d 00310 4334,1064,3105,1502,3101,1505,3502,1101 >d 00320 3505,2103,5305,5000,0000,1110,4343,5545 >d 00330 1063,3110,1110,5724,0000,4324,4343,0014 >d 00340 7200,1117,5734,0000,3114,1057,3115,3116 >d 00350 3117,1114,7104,3114,7420,5363,1743,1116 >d 00360 3116,7420,2117,2115,5371,7300,1116,2343 >d 00370 5743,1116,7104,3116,1117,7004,3117,5351Verify the accuracy of the data you just entered by asking the BIOS to compute the checksum (ck command) of the first two PDP-8 pages of RAM, locations 00000 through 00377:
>ck 0-377You should receive the reply:
Checksum = 7343Next, we need to write these first two pages of PDP-8 RAM to non-volatile storage so that we can reload and run it at any time with just a few flips of our front panel switches. The partition writer (PartWrite) code given below is quite short. Its source code and documentation can be found on the custom OS/8 boot sector page. So, as before, deposit the partition writer into RAM (starting at location 00400) using the following sequence of SBC6120 BIOS deposit (d) commands:
>d 00400 7604,7450,7402,3223,6206,0010,0000,0423 >d 00410 4000,0027,0001,6206,0004,4207,0000,0000 >d 00420 7430,7402,7402With the partition writer code in RAM at location 00400, we're ready to write LightsOut to its own partition. FIRST set the front panel data switches to the address of the target partition. If you have a very large drive, you might use something like 4001, but 0007 or 0010—or whatever—would be fine too). Verify that the front panel's “HALT” switch is UP (not enforcing a halt), then, with the front panel switches set to the target partition, start the partition writer with the BIOS start (st) command:
>st 0400Note that to prevent any chance of inadvertently overwriting partition zero, where most users will have installed the OS/8 operating system, the little partition writer will not write to partition zero. So if the switches were inadvertently set to 0000, you will receive:
?Halted at 00403 PC>0403 PS>1000 AC>0000 MQ>0000 SP1>0000 SP2>0000
(That's NOT what you want.)
With a non-zero partition number set into the switches, you should receive:?Halted at 00423 PC>0423 PS>1000 AC>0000 MQ>0000 SP1>0000 SP2>0000You can (and should) verify that the two-page sector was written to the IDE drive by dumping the target partition's first sector with the following command, where <partition> is replaced with the number of the partition where the sector was written:
>dd <partition> 0 1So, for example, assuming that “LightsOut” had been saved into partition 4001, you would give the following command and receive the following dump:
>dd 4001 0 1 0000.000/ 7200 1112 6246 6434 0062 7450 5012 7200 0000.010/ 1111 5002 6434 0061 7440 5456 7604 3113 0000.020/ 1113 0111 7104 7041 1113 7410 5455 1111 0000.030/ 3113 3112 1064 3102 7100 1113 7450 5000 0000.040/ 7010 3113 7420 5053 1112 0502 7104 7041 0000.050/ 1112 1502 3112 2102 5034 0200 0203 7764 0000.060/ 0002 0400 0100 0541 0065 0000 0000 0000 0000.070/ 0000 0000 0000 0000 0000 0000 0000 0000 0000.100/ 0000 0000 0000 0000 0000 0000 0000 0000 0000.110/ 0000 0000 0000 0000 0000 0000 0000 0000 0000.120/ 0000 0000 0000 0000 0000 0000 0000 0000 0000.130/ 0000 0000 0000 0000 0000 0000 0000 0000 0000.140/ 0000 0000 0000 0000 0000 0000 0000 0000 0000.150/ 0000 0000 0000 0000 0000 0000 0000 0000 0000.160/ 0000 0000 0000 0000 0000 0000 0000 0000 0000.170/ 0000 0000 0000 0000 0000 0000 0000 0000 0000.200/ 6206 0012 0001 7604 3113 4324 6246 7604 0000.210/ 7041 1113 7450 5205 4324 3111 1064 3102 0000.220/ 1057 3103 7040 3101 7340 3502 1060 7041 0000.230/ 3105 4334 7040 3106 1502 3107 7340 7004 0000.240/ 2106 5237 3104 1104 0502 3502 1502 7141 0000.250/ 1107 7450 5231 7200 1104 0101 7041 1101 0000.260/ 7440 5265 1107 3502 5231 7200 1104 0101 0000.270/ 7450 7040 3101 2105 5231 1502 7040 3502 0000.300/ 2102 2103 5224 1057 3103 4334 1064 3102 0000.310/ 4334 1064 3105 1502 3101 1505 3502 1101 0000.320/ 3505 2103 5305 5000 0000 1110 4343 5545 0000.330/ 1063 3110 1110 5724 0000 4324 4343 0014 0000.340/ 7200 1117 5734 0000 3114 1057 3115 3116 0000.350/ 3117 1114 7104 3114 7420 5363 1743 1116 0000.360/ 3116 7420 2117 2115 5371 7300 1116 2343 0000.370/ 5743 1116 7104 3116 1117 7004 3117 5351 4573The “4573” at the end is a checksum of the block just dumped, and it (and everything else) should match what's shown above.
You're all done!
You now have the “LightsOut” program safely written, and verified, to an IDE drive partition of your choosing. If you have already installed the modified FlexBoot sector, you can fire up the “LightsOut” toggle toy by setting the target partition into the switch register then depressing the front panel “BOOT” switch twice in succession.
Good luck turning all of the lights out!
Oh!... and if it's too tame and easy for you . . . the program DOES support the toggling of ANY NUMBER of lights with each switch! As mentioned in the comments at the top of the source code, location '0060' will normally contain '0002' (you can see it in the block of octal above). So you can halt the program, change location '0060' to, say, '0004' and really give yourself a headache. You could even write a succession of programs to successive partitions, each with a different difficulty level. Then you could use the switches to select the difficulty by which version is loaded and started.
This ZIP file (352kb) contains all of the recently-written bits and pieces of SBC6120 & FP6120 PDP-8 code for DeepThought, LightsOut, the custom OS/8 boot sector, and other PDP-8 code snippet utilities I created for this project. |
CLICK HERE to learn how YOU can acquire & build one of these complete PDP-8 systems for yourself !!! |
Gibson Research Corporation is owned and operated by Steve Gibson. The contents of this page are Copyright (c) 2024 Gibson Research Corporation. SpinRite, ShieldsUP, NanoProbe, and any other indicated trademarks are registered trademarks of Gibson Research Corporation, Laguna Hills, CA, USA. GRC's web and customer privacy policy. |
Last Edit: Jan 27, 2016 at 18:11 (3,178.41 days ago) | Viewed 4 times per day |