;	TITLE	BLINKY-10 V2.0
;
;	************************************************************
;	*                                                          *
;	*  BLINKY-10 - Blinkenlights demonstration for the PDP-10  *
;	*                                                          *
;	*  Mike Hill             V1.0                 25-Dec-2018  *
;	*  Mike Hill             V2.0                 31-Dec-2018  *
;	*                                                          *
;	*                                                          *
;	************************************************************
;	*                                                          *
;	*             (c) Copyright 2018 by Mike Hill              *
;	*                                                          *
;	*                     All Rights Reserved                  *
;	*                                                          *
;	************************************************************
;
; Synopsis:-
;
;	BLINKY-10 is a simple demonstration program which runs directly on the
;	PDP-10 hardware without an operating system.  It uses the DATA SWITCHES
;	to make patterns on various lamps on the console front panel.
;
;	If you want to learn about the PDP-10 instruction set, this is the
;	perfect tool.  When dry running (or stepping through) the program, you
;	may notice that there are no backwards jumps or loops.  The ONLY place
;	a backwards jump occurs is within the code generated (and jumped to by
;	'JUMPG 13,1(14)') at the end of the lamp-update code.
;
;	You are encouraged to create your own patterns and link them to the
;	pattern tables.  Make sure to put them in memory at addresses which will
;	not be overwritten by code placed there for the TICK loop (3 words).
;
; Operation:-
;
;    DATA SWITCHES:-
;
;	000 000|000 011|111 111|112 222|222 222|333 333
;	012 345|678 901|234 567|890 123|456 789|012 345
;	hf- ix-|--e|qsr|pad OOO|III PPP|AAA DDD|TTT TTT
;
;	At least one T switch (30-35) must be ON to enable the actions below.
;
;	Setting T to zero will load the default settings (see DSDEF below).
;
;	Any enabled switch state-change will result in all lamp pattern cycles
;	being reset to their initial states with the new settings.
;
;    Action if DATA SWITCH is ON:-
;
;	   00  (h)  HALT before starting the next TICK (to learn how it works)
;	   01  (f)  Select FAST CPU mode (slows the TICKs by 32x)
;	   02  (-)  Reserved
;
;	   03  (i)  Turn off INDIRECT mode in the TICK loop instruction
;	   04  (x)  Turn off INDEXED AC in the TICK loop instruction
;	   05  (-)  Reserved
;
;	   06  (-)  Reserved
;	   07  (-)  Reserved
;	   08  (e)  Set PCNT equal to ADDR (ignore the PCNT table)
;
;	   09  (q)  Set DATA equal to ADDR (ignore the DATA table)
;	   10  (s)  Swap the DATA RHS with LHS
;	   11  (r)  Set the DATA RHS to the same as LHS
;
;	   12  (p)  Complement PCNT lamps
;	   13  (a)  Complement ADDR lamps
;	   14  (d)  Complement DATA lamps
;
;	15-17  (O)  Pattern offset (0-7)
;	18-20  (I)  INST speed relative to T
;	21-23  (P)  PCNT speed relative to T
;	24-26  (A)  ADDR speed relative to T
;	27-29  (D)  DATA speed relative to T
;	30-35  (T)  TICK speed (basic time unit ~1/63s)
;
;	UBITS = 116000000000 (see DSOFF for when to use UBITS)
;
; Suggestion:-
;
;       Start with all switches OFF then turn ON switch 35 followed by 34, 33,
;       32, 31, and 30 until you find a comfortable pattern rotation speed.
;	Then play with the other switches.
;
; Requirements:-
;
;	When starting BLINKY-10 in SIMH with throttling turned on (500k) you
;	may need to wait for up to 30 seconds for SIMH to calibrate.
;
;	The supplied PCNT and ADDR tables use addresses which require at least
;	129KW memory (this is not a typo).  By changing the last word of each
;	of these tables, it would be possible for BLINKY-10 to run on a PDP-10
;	with 128KW of memory.
;
;	A sample ADDR table has been supplied to run in just 1KW of memory.
;	To use this table select pattern option 7 (DS 15-17 = ON).
;
;	If your front-panel console has an 'MI program disable switch', it must
;	be OFF in order to display the DATA lamps.
;
; History:-
;
;	I started looking into the PDP-10 on the 4th December 2018 shortly after
;	visiting the VCF (Vintage Computer Festival) in Zurich, Switzerland.
;
;	I first installed pdp10_realcons along with panelsim to see how it
;	looked.  Then I came to the idea of porting the PDP-11 BLINKY to the
;	PDP-10 on the 13th December 2018.  I wanted to present it to the author
;	of pdp10_realcons and panelsim as a "thank you".
;
;	Firstly, I needed to understand the instruction set of the PDP-10.
;	I read through the PDP-l0 System Reference Manual (DEC-10-HGAA-D) for
;	the KA10 from May 1968 because I wanted the code to run on any PDP-10
;	and not only the KS10 which pdp10_realcons emulates (but with a KI10
;	console front panel).
;
;	The code and memory map were designed to be written (and read) by hand
;	because the program was created entirely at the SIMH prompt without the
;	use of an assembler.  This produced highly readable code but was labour
;	intensive.
;
;	Over the course of five days, the basic structure of BLINKY-10 was
;	ready and working.  The memory map was designed and the use of
;	the accumulators was fairly well fixed.
;
;	The basic clock unit was INST and all other clocks were run from that.
;	6 bits were used for each clock.  There were three subsystems (INST=5,
;	ADDR=6, DATA=7) and the constants were at address 400-477.  There were
;	no variables (other than AC0-AC17).  The patterns for ADDR and DATA were
;	ready too.  Also, an XCT instruction was used to set up the INST loop
;	counter from the second word in the INST table entries.
;
;	Later on the 18th December 2018 I added indirection to the INST loop
;	instructions to get the PC address lamps to align with the ADDR lamps.
;	Variables were also added so the SOJGE instruction in the INST loop
;	could also bounce some lamps.
;
;	On the 21st December 2018 I wrote the SIMH script 'BLINKY_LIST' because
;	the code was getting out of hand.  It was much easier to debug the code
;	that way.  I also moved INST to (4) to add the PCNT subsystem (5).
;	The constants and variables now shared the same address block as the
;	program code (200-377).
;
;	Some clean-up was done on the 22nd December and at that point
;	I [under-] estimated I had spent around three man-days work so far.
;	I also finally got the SIMH environment [script] just about right.
;
;	A code rewrite was done on the 23rd December 2018 to get BLINKY-10
;	ready for packaging.  I also started using a spreadsheet to assist me.
;	This code base was now fairly close to the finished DEMO.
;
;	By the afternoon of the 25th December 2018, the code (V1.0) was ready
;	for release.  Obviously, I used MACRO instructions in my SIMH scripts
;	for code generation, but for the DEMO I decided to provide it in octal.
;	After removing leading-zeros, I sorted by line-length and combined
;	duplicates.  This may have taken around a half-hour, but it was fun.
;	There were 147 DEPOSIT commands in the final script along with commands
;	to set up the emulator and start the program.  And, of course, a bunch
;	of comments on how to use it.  With that, I sent out the script to
;	a few people who are highly active at VCF and interested in the PDP-10.
;
;	Between the 26th and 29th December 2018 I went over the code with a fine
;	tooth comb and ironed out the wrinkles.  I also read through the updated
;	DECsystem-10/DECSYSTEM-20 Processor Reference Manual (AD-H391A-T1) from
;	June 1982.  Here I found that some PDP-10 processors do not support the
;	XCT instruction and I also decided to use indexed instructions in the
;	INST loop (to get a truly bouncing pattern).  Since I was changing the
;	code anyway, I added a separate clock (TICK) so the INST clock could run
;	independently.  I changed the DATA SWITCHES to use only 3 bits for
;	the clocks (except TICK which needs 6 bits).  I also added a few rather
;	nice features like up-to 8 patterns per subsystem and using the high-18
;	bits of the ADDR entries to put onto the DATA lamps.  Also swapping the
;	DATA LHS with the RHS and/or making the DATA LHS the same as the RHS.
;
;	V1.0 was quite sparse, so the V2.0 code still fit in exactly the same
;	address space (200-777).  BLINKY-10 (200-777) is not so sparse any more.
;
;	Between the 30th and 31st December 2018, I cleaned up the code and
;	added a whole bunch of comments (e.g. these).  I adjusted the base TICK
;	speed for a CPU which could process 500k SOJx instructions per second.
;	A final switch was also added to disable indexed mode in INST.
;	I also changed the user-defaults for a more pleasing effect.
;	Finally, I re-scripted it and the result is what you're reading now.
;
; Memory map:-
;
;	000-000  AC0: Reserved to HALT for certain program errors (e.g. a UUO)
;	001-017  AC1-AC17: Indexable accumulators (see below)
;
;	020-037  Reserved
;	040-041  Trap for unimplemented user operations (UUOs)
;	042-057  Priority interrupt (PI) locations
;	060-061  Trap for remaining unimplemented operations
;	062-067  Reserved
;	070-070  KI10 Auto restart
;	071-137  Reserved
;	140-161  Allocated to second processor PI if connected
;	162-177  Reserved
;
;	200-205  Hardware initialization (optional)
;	206-207  Software initialization (one-off)
;	210-375  Main program (entry point for TICK completion)
;	376-376  Holds the flags & PC from ERRORs
;	377-377  HALT instruction
;
;	400-777  Shown in the table below
;		+00 xxxxP is the table pointer table for subsystem xxxx
;		+10 xxxx  is the [pattern] table for subsystem xxxx
;		+70 CONSTants, VARiableS, User CONSTants, ReSerVeD
;
;	+---------------+---------------+---------------+---------------+
;	|      400      |      500      |      600      |      700      |
;	+---------------+---------------+---------------+---------------+
;  +00	|     INSTP     |     PCNTP     |     ADDRP     |     DATAP     |
;	+---------------+---------------+---------------+---------------+
;  +10	|     INST      |     PCNT      |     ADDR      |     DATA      |
;	+---------------+---------------+---------------+---------------+
;  +70	|     CONST     |     VARS      |    UCONST     |     RSVD      |
;	+---------------+---------------+---------------+---------------+
;
; Accumulators:-
;
;	+ = As long as the masked DATA SWITCHES remain unchanged, AC5-AC7
;	    and AC11-AC17 are assumed to have the values described below
;
;	* = AC1, AC2, AC4, and AC10 are reserved for use as the TICK loop
;	    counter, thus have a temporary use ONLY
;
;	AC0    Holds a 'JSR ERROR' as an error catcher
;	AC1   *General purpose
;	AC2   *General purpose
;	AC3    General purpose (often DS related)
;	AC4   *General purpose
;	AC5   +Current value for the PCNT tick counter
;	AC6   +Current value for the ADDR tick counter
;	AC7   +Current value for the DATA tick counter
;	AC10  *General purpose
;	AC11  +Current value for the INST tick counter
;	AC12  +Offset within the table pointer tables (0-7)
;	AC13  +Current settings of the masked DATA SWITCHES	
;	AC14  +Pointer to the current INST table entry
;	AC15  +Pointer to the current PCNT table entry
;	AC16  +Pointer to the current ADDR table entry
;	AC17  +Pointer to the current DATA table entry
;
; Subsystems:-
;
;	4  INST (instruction including AC & INDEX lamps for the TICK loop)
;	5  PCNT (Program Counter lamps)
;	6  ADDR (ADDRESS part of the instruction lamps)
;	7  DATA (PROGRAM DATA lamps)
;
;	Each subsystem tries to use accumulators ending in their own digit
;	(e.g. AC7 and AC17 for DATA).  Where possible, they also reference
;	variables at addresses ending in their own digit (e.g the initial loop
;	counter for INST is at address 574.  The table pointers for each
;	subsystem 's' are at addresses s00-s07 and the tables themselves start
;	at address s10.
;
; User changeable constants:-
;
;	670	DSOFF	Force these bits OFF in the DS	
;	671	DSON	Force these bits ON in the DS
;	672	DSMSK	Load DSDEF if all these bits are OFF
;	673	DSDEF	Default for the DS if all DSMSK bits are OFF
;	674	TMULT	TICK loop counter multiplier
;	675	TSCAL	TICK loop counter scaling (for fast CPUs)
;	676	Unused	Reserved for future use
;	677	Unused	Reserved for future use
;
; Notes for DSOFF:-
;
;	Setting DSOFF to the Unused BITS (UBITS) will ignore unused DS switches
;	You may disable any function by setting the appropriate bit here
;	E.g. set to UBITS+400000000000 to disable the SSTEP switch
;
; Notes for DSON:-
;
;	You may force any function ON by setting the appropriate bit here
;	E.g. set to 004000000000 to set PCNT to ADDR (to ignore PCNTP and PCNT)
;
; Notes for DSMSK:-
;
;	You may define the switches of which at least one is ON to ignore DSDEF
;	Set to 000000000001 to make switch 35 the 'bypass DSDEF' switch
;	Set to 400000000077 to allow the single-step switch to bypass DSDEF
;	Set to 000000000077 to make setting the TICK baseline bypass DSDEF
;
; Notes for DSDEF:-
;
;	You may set the defaults here to use when all DSMSK switches are OFF
;	If DSON is not zero, you might want to set the same bits here too
;	Set to 000000000040 to set the rotation speed to around a 1/2 second
;	Set to 000106022210 for quite a nice display (also a 1/2 second)
;
; Notes for TMULT:-
;
;	A TICK is the heart of timing.  All other times are taken as multiples
;	of a TICK.  A TICK consists of a loop using either AOJx or SOJx.  The
;	effective address (E) of the Jump will always be the address of the
;	instruction itself.  The supplied INST code uses both indirect and
;	indexed addressing for E.  This is the slowest possible combination.
;	For the timer calculation, we assume that a real PDP-10 would take 2uS
;	to execute one TICK iteration.  Thus the calculation uses 500,000
;	instructions per second as the baseline.  In reality, the PDP-10 most
;	likely takes longer than 2uS per TICK iteration.
;
;	Each TICK loop should take around 1/63s to complete.  Setting all of the
;	switches 30-35 ON should cause each TICK to take approximately 1 second.
;
;		TMULT = 500,000 / 63 = 7936(10) = 17400(8).
;
; Notes for TSCAL:-
;
;	If the DS FAST-CPU switch is ON then we want to slow down the TICKs a
;	lot more than with TMULT.  For example, if throttling is turned off in
;	SIMH we need a way to scale the TICK loop.  Assuming a modern CPU can
;	emulate 16,000,000 TICK iterations per second, a suggested setting for
;	this is 32x = 40(8).
;
;-------------------------------------------------------------------------------
set on
if "%1"!="" goto SKIP
echof "Initializing SIMH for BLINKY-10 ..."
set cpu klad,noidle
set throt 500k
reset all
d indmax 1
:SKIP
;-------------------------------------------------------------------------------
echof "Loading BLINKY10 for the PDP-10 ..."
d PC 200
d 0-777 0
d 40-61,140-161 JSR 376
; Almost 300 memory locations are deposited using just over 200 deposit commands
d 675 40
d 672 77
d 401 434
d 402 460
d 403 464
d 501 517
d 502 526
d 503 527
d 601 617
d 602 626
d 603 627
d 701 730
d 702 750
d 703 751
d 517 1400
d 674 17400
d 527 400001
d 507,607 631
d 700,707 710
d 631 1001000
d 730 1400000
d 516,520 2200
d 515,521 4100
d 472 17000000
d 471 20000000
d 514,522 10040
d 513,523 20020
d 512,524 40010
d 673 106022210
d 640 377001774
d 511,525 100004
d 510,526 200002
d 727,731 2200000
d 632,646 3001400
d 726,732 4100000
d 633,645 7001600
d 725,733 10040000
d 634,644 17001700
d 724,734 20020000
d 635,643 37001740
d 723,735 40010000
d 636,642 77001760
d 774 104311000000
d 670 116000000000
d 773 121212120000
d 771 152120000000
d 202 200000000475
d 276 200060000014
d 310 200120000016
d 315 200140000002
d 214 200140000673
d 325 200160000015
d 335 200220000016
d 343 200220000017
d 232 200240000003
d 321 200240000575
d 227 200300000003
d 304 200300000576
d 224 200340000003
d 334 200340000577
d 221 200400000003
d 354 200400000477
d 363 200400000570
d 272 200440000574
d 254 200452000500
d 256 200452000600
d 252 200500000003
d 220 200540000003
d 275 200612000400
d 324 200640000571
d 307 200712000600
d 342 200752000700
d 264 201600000464
d 265 201640000467
d 266 201700000467
d 267 201740000467
d 362 202060000003
d 245 202200000574
d 357 202203000001
d 360 202220000002
d 246 202240000575
d 247 202300000576
d 250 202340000577
d 251 202400000570
d 355 202403000002
d 257 202440000571
d 345 204200000004
d 240 220400000674
d 242 220400000675
d 775 222021300000
d 223 240140777772
d 477 254000000210
d 217 254000000271
d 317 254000000333
d 337 254000000344
d 377 254200000200
d 365 254214000001
d 475 264000000376
d 273 271600000004
d 322 271640000001
d 305 271700000001
d 340 271740000001
d 332 275140000001
d 476 300000000000
d 200 300000425451
d 201 300000565371
d 216 316140000013
d 215 322140000377
d 314 323100000377
d 331 323140000377
d 364 327554000001
d 243 335000000013
d 274 336020000014
d 323 336020000015
d 306 336020000016
d 341 336020000017
d 420 365070000000
d 320 365240000325
d 303 365300000310
d 333 365340000353
d 464 365421000000
d 271 365440000276
d 450 367070000000
d 434 367421000000
d 751 400000000001
d 627 400001400001
d 261 400240000000
d 262 400300000000
d 263 400340000000
d 260 400440000000
d 206 400540000000
d 313 405100777777
d 330 405140777777
d 236 405200000007
d 233 405240000007
d 230 405300000007
d 225 405340000007
d 222 405400000077
d 253 405500000007
d 300 420040000471
d 302 420040000472
d 211 420140000670
d 770 425451565371
d 361 434040000002
d 212 434140000671
d 356 434200000476
d 312 450100000002
d 327 450140000003
d 351 450200000004
d 347 504200000004
d 777 505154540000
d 776 555153450000
d 376 556350515454
d 350 603540000010
d 311 603540000020
d 326 603540000040
d 346 603540000100
d 344 603540000200
d 336 603540000400
d 255 603540001000
d 301 603540020000
d 277 603540040000
d 241 603540200000
d 316 616040000471
d 213 616140000672
d 772 662216200000
d 210 700040000003
d 352 700540000004
d 205 700540000673
d 617 777777001400
d 722,736 100004000
d 637,641 177001770
d 721,737 200002000
d 720,740 400001000
d 717,741 1000000400
d 716,742 2000000200
d 715,743 4000000100
d 500,504,505,705 510
d 714,744 10000000040
d 713,745 20000000020
d 712,746 40000000010
d 711,747 100000000004
d 710,750 200000000002
d 421,451 200040000010
d 235,353 200200000003
d 435,465 200400000010
d 414,424 365124000000
d 410,430 365222000000
d 444,454 367124000000
d 440,460 367222000000
d 436,466 400040000000
d 610,626 600003200002
d 611,625 700007100004
d 612,624 740017040010
d 613,623 760037020020
d 614,622 770077010040
d 615,621 774177004100
d 616,620 776377002200
d 244,422,452 400400000000
d 400,404,405,406,407,704 410
d 506,600,604,605,606,706 610
d 415,425,445,455 200100000010
d 411,431,441,461 200200000010
d 226,231,234,237 240140777775
d 203,204,207,270 255000000000
d 412,432,442,462 400100000000
d 416,426,446,456 400200000000
d 413,417,423,427,433,437,443,447,453,457,463,467 254020000003
;-------------------------------------------------------------
if "%1"!="" goto EOF
echof ""
echof "Console DATA SWITCH definitions (others do nothing) ..."
echof ""
echof "       00  (h)  HALT before starting the next TICK (learning by doing)"
echof "       01  (f)  Select FAST CPU mode (slows the TICKs by 32x)"
;chof "       02  (-)  Reserved"
;chof ""
echof "       03  (i)  Turn off INDIRECT mode in the TICK loop instruction"
echof "       04  (x)  Turn off INDEXED AC in the TICK loop instruction"
;chof "       05  (-)  Reserved"
;chof ""
;chof "       06  (-)  Reserved"
;chof "       07  (-)  Reserved"
echof "       08  (e)  Set PCNT equal to ADDR (ignore the PCNT table)"
;chof ""
echof "       09  (q)  Set DATA equal to ADDR (ignore the DATA table)"
echof "       10  (s)  Swap the DATA RHS with LHS"
echof "       11  (r)  Set the DATA RHS to the same as LHS"
;chof ""
echof "       12  (p)  Complement PCNT lamps"
echof "       13  (a)  Complement ADDR lamps"
echof "       14  (d)  Complement DATA lamps"
;chof ""
echof "    15-17  (O)  Pattern offset (0-7)"
echof "    18-20  (I)  INST speed relative to T"
echof "    21-23  (P)  PCNT speed relative to T"
echof "    24-26  (A)  ADDR speed relative to T"
echof "    27-29  (D)  DATA speed relative to T"
echof "    30-35* (T)  TICK speed (basic time unit ~1/63s)"
echof ""
echof "    *  At least one 'T' switch must be ON to enable the above functions"
echof ""
;chof "       Start with all switches OFF then turn ON switch 35 followed"
;chof "       by 34, 33, 32, 31, and 30 until you find a comfortable speed."
;chof "       Then play with the other switches."
;chof ""
;------------------------------------------------------------------------------
echof "Starting BLINKY-10 for the PDP-10 ..."
echof "    Throttle stabilzation takes up to 30 seconds, please be patient ..."
d 0 0
cont
:EOF
;
; END-OF-FILE
