;	TITLE	BLINKY-8 V1.0
;
;	**********************************************************
;	*                                                        *
;	*  BLINKY-8 - Blinkenlights demonstration for the PDP-8  *
;	*                                                        *
;	*  Mike Hill            V1.0                09-Feb-2019  *
;	*  Edited                                   10-Feb-2020  *
;	*                                                        *
;	**********************************************************
;	*                                                        *
;	*          (c) Copyright 2019-2020 by Mike Hill          *
;	*                                                        *
;	*                    All Rights Reserved                 *
;	*                                                        *
;	**********************************************************
;
; Synopsis:-
;
;	BLINKY-8 is a simple demonstration program which runs directly on the
;	PDP-8 hardware without an operating system.  It uses the SWITCH REGISTER
;	to make patterns on various lamps on the console front panel.
;
;	If you want to learn about the PDP-8 instruction set, this is the
;	perfect tool.  Almost the entire instruction set is used along with
;	interrupt programming and auto-indexed memory references.
;
;	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.  
;	Addresses 0640-0667 and 0670-0717 may be safely used for this purpose.
;
; Usage:-
;
;	sim> do BLINKY8.txt [ LOAD | LIST | DATA | EXEC ]
;
;		None	Same as EXEC
;		LOAD	Only LOAD the BLINKY-8 code into addresses 0000-0777
;		LIST	LIST the whole BLINKY-8 program currently in memory
;		DATA	List the DATA areas of BLINKY-8 as currently in memory
;		EXEC	Load and EXECute the BLINKY-8 program
;
;	After LOAD/LIST the PC will be set to 0200 (the start/restart address)
;
;	After DATA the PC will point to a HLT instruction.  However, usually
;	when BLINKY-8 has Interrupts ON (ION) you may press CONT after DATA
;
; Front-panel operation:-
;
;    SWITCH REGISTER:-
;
;	000|000|000|011
;	012|345|678|901
;	---+---+---+---
;	PC |MB |AC |MQ
;
;	00*    PC/MA lamp option (0=Bounce, 1=Scan R-L)
;	01-02  PC/MA lamp speed
;
;	03     MB lamp option (0=Full-speed count-up, 1=Bounce)
;	04-05  MB lamp speed  (Ignored when switch 03=0)
;
;	06     AC lamp option (0=Bounce, 1=Complemented MB)
;	07-08  AC lamp speed
;
;	09     MQ lamp option (0=Bounce, 1=Complemented AC)
;	10-11  MQ lamp speed
;
;	*      MA duplicates the pattern in the PC [in this version]
;
;    CONSOLE:-
;
;	Characters typed at the console keyboard will be echoed to the
;	console teletype.
;
; Suggestion:-
;
;       Start with all switches 00-11 OFF except 03 ON then play with some of
;	the speed switches (01-02, 04-05, 07-08, 10-11) until you find a
;	comfortable pattern rotation speed.
;
; You might like to try the following patterns:-
;
;	000|000|000|011
;	012|345|678|901
;	---+---+---+---
;	010|000|100|100
;	111|101|010|000
;	000|111|100|001
;
; Requirements:-
;
;	If your front-panel console has a 'PANEL LOCK', it must be OFF in
;	order to start BLINKY-8.  Once BLINKY-8 is running, you may lock
;	the front-panel if you wish.
;
;	The start/restart address for BLINKY-8 is 0200.  Once BLINKY-8 is
;	in memory; on the front-panel set 000200 in the SWITCH REGISTER then
;	press LOAD-ADD followed by START.
;
;	If you have a physical PDP-8 without a clock module, you will need
;	to NOP out the clock IOT instructions (at 0115 and 0205) and use the
;	keyboard to make the lamps rotate.  You will also want to change the
;	clock speed table (pointed to by 0156).  This pointer should point to
;	five words of speeds (the first of which is not used).  You may use
;	addresses 0770-0774 if you like.  Experiment with values starting at
;	0001 and increasing until you have rotation speeds which work for you.
;
;	For a different clock module to the one used here, you will need to
;	use the correct IOT instructions for that module (at 0115 & 0204-0205).
;
;	BLINKY-8 is set to use a 60Hz clock by default.  If you have a 50Hz
;	clock, you may change address 0156 to point to 0750 instead of 0760.
;
;	If your PDP-8 does not have an MQ register (e.g. if your PDP-8 does not
;	have the EAE option) you may put a NOP at address 0524.
;
; History:-
;
;	After completing BLINKY-10 at the end of 2018, I started looking into
;	creating a "BLINKY-8" for the PDP-8 (specifically for the PiDP-8).
;
;	I started working on BLINKY-8 on the 21st January 2019 and completed
;	V1.0 on the 9th February 2019.
;
;	I first installed pdp8_realcons along with panelsim to see how it
;	looked.  Then I needed to understand the instruction set of the PDP-8.
;	I started by reading the PDP-8 Pocket Reference Card.  Then advancing
;	to the PDP-8 Users Handbook from 05/1966 and the PDP-8/L Users Handbook
;	from 10/1968.  To be really thorough, I also read the PDP-5 Handbook
;	from 1964 and even read the PDP-12 System Reference Manual from 1971.
;
;	Thus armed, I designed a memory-map which would run on the PDP-8, PDP-5,
;	and the PDP-12.  You may notice the PDP-5 legacy by looking at addresses
;	0000-0002.  Because the PDP-8 addressing is split into pages of 0200 (8)
;	words, I made a memory map which would fit into such pages.  Page zero
;	(0000-0177) is special because it can be addressed directly from any
;	page.  Otherwise code on each page may only directly address its own
;	page.  By designing the data structures carefully, it was possible to
;	go through them with a simple auto-indexed reference (address 0010).
;
;	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.  [Although I did use a spreadsheet to assist me.]
;
;	I decided early on that, unlike BLINKY-10, the program needed to be
;	interrupt driven and would not work well with programmed loops (because
;	the PC would be jumping around too much).  Great for the PiDP-8 (which
;	has the SIMH clock) but not so good for a physical PDP-8.
;
;	Every interrupt (clock, keyboard, teletype) would advance the tick
;	counter by one.  So, pressing keys on the console keyboard would speed
;	up the lamp rotation (two interrupts because the character is also
;	echoed to the teletype).
;
;	After getting the clock interrupts working, I started working on the
;	lamps in [what is now] the RETURN FROM INTERRUPT routine (at address
;	0564).  This is the code which makes the lamps display unique values.
;	It was a case of trial and error getting the right instructions (in the
;	right order) to make the lamps independantly unique.  After that, I knew
;	which lamps would need data structures to control them, and what those
;	structures must contain.
;
;	I even reserved space for the MA lamps which cannot be 100% controlled
;	but may, to some extent, be unique from any other lamps.  Although
;	populated, the MA structure does not have any function in this version.
;
;	The clock speed table was used to reduce the number of ticks to a
;	usable [visible] lamp rotation speed.
;
;	I put in as much functionality as I could (e.g. power fail/recovery)
;	and finished up on the 9th February 2019.
;
;	I kind of forgot about BLINKY-8 until the 30th January 2020.  At that
;	time I packaged the octal code into BLINKY8.txt and added the LIST
;	and DATA functions.  I didn't change the code because BLINKY-8 worked
;	just fine.  For example, the 5-word clock speed tables are a legacy
;	[the first word is no longer used] which should be converted to 4-word
;	tables in a future version.
;
;-------------------------------------------------------------------------------
set on
set environment LOAD=T
set environment DATA=F
set environment LIST=F
set environment EXEC=T
if    "%1"==""     goto START
if -i "%1"=="EXEC" goto START
if -i "%1"=="LIST" set environment LIST=T
if -i "%2"=="LIST" set environment LIST=T
set environment DATA=%LIST%
if -i "%1"=="DATA" set environment DATA=T
if -i "%2"=="DATA" set environment DATA=T
if   "%DATA%"=="T" set environment LOAD=F
if not 0777=5660   set environment LOAD=T
if not 0776=2661   set environment LOAD=T
set environment EXEC=F
:START
;-------------------------------------------------------------------------------
if "%EXEC%"=="F" goto NOEXEC
echof "Initializing SIMH for BLINKY-8 ..."
set cpu eae,noidle
dep cpu STOP_INST 1
set tsc disable
set fpp disable
set clk 60HZ
;set realcons host=localhost
;set realcons panel=PDP8I
;set realcons interval=20
set realcons disconnected
set throt 200/1
reset all
:NOEXEC
;-------------------------------------------------------------------------------
if "%LOAD%"=="F" GOTO NOLOAD
echof "Loading BLINKY-8 for the PDP-8 ..."
d 0-777 0
; Just over 300 memory locations are deposited using fewer than 200 deposits
d 222 3
d 754 7
d 4 200
d 6 300
d 5 400
d 764 10
d 753 15
d 752 31
d 762 36
d 751 62
d 761 74
d 31 670
d 3 5404
d 605 140
d 437 151
d 151 177
d 351 222
d 223 223
d 156 760
d 36 1000
d 640 1001
d 103 1003
d 403 1024
d 572 1027
d 414 1034
d 420 1036
d 436 1037
d 454 1054
d 474 1064
d 527 1074
d 567 1077
d 374 1114
d 440 1152
d 353 1156
d 302 1157
d 336 1221
d 342 1223
d 375 1454
d 355 1621
d 731 1777
d 400 2025
d 405 2027
d 425 2033
d 411 2035
d 416 2037
d 456 2053
d 451 2055
d 564 2057
d 513 2063
d 471 2065
d 476 2067
d 545 2073
d 524 2075
d 531 2077
d 104 3000
d 303 3010
d 404 3025
d 433 3033
d 415 3035
d 463 3053
d 455 3055
d 521 3063
d 475 3065
d 553 3073
d 530 3075
d 312 3153
d 441 3437
d 703 4000
d 600 4001
d 211 5002
d 1,2 5100
d 101 5110
d 152 5200
d 417 5222
d 431 5235
d 424 5236
d 412 5242
d 461 5265
d 452 5266
d 450 5271
d 505 5313
d 517 5323
d 334 5340
d 337 5341
d 540 5345
d 551 5355
d 122 5405
d 577 5437
d 373 5610
d 372 5623
d 323 5700
d 364 5724
d 576 6001
d 111 6031
d 202 6032
d 207 6035
d 113 6036
d 114 6046
d 100 6102
d 205 6135
d 115 6136
d 377 6171
d 376 6260
d 345 7006
d 573 7010
d 106 7402
d 571 7421
d 333 7430
d 565 7610
d 157,763 17
d 604,606 220
d 641,661 1002
d 643,657 1010
d 644,656 1020
d 422,432 1032
d 645,655 1040
d 446,462 1052
d 467,507 1057
d 500,520 1062
d 541,575 1067
d 533,552 1072
d 646,654 1100
d 117,314 1153
d 647,653 1200
d 427,434 1433
d 457,464 1453
d 515,522 1463
d 547,554 1473
d 722,740 1600
d 723,737 1700
d 724,736 1740
d 725,735 1760
d 726,734 1770
d 727,733 1774
d 730,732 1776
d 601,611 2002
d 300,324 2312
d 421,435 3037
d 465,470 3057
d 511,523 3067
d 543,555 3077
d 327,354 3221
d 121,210 4406
d 112,371 5115
d 702,704 6000
d 110,203 6042
d 331,350 7004
d 311,315 7041
d 360,466 7240
d 700,706 7400
d 116,306 7604
d 676,710 7700
d 675,711 7740
d 674,712 7760
d 673,713 7770
d 672,714 7774
d 671,715 7776
d 0,107,370 5003
d 30,51,60,70 600
d 335,603,607 410
d 36,651,720 1000
d 352,503,536 7001
d 326,340,362 1410
d 401,406,407 5211
d 472,502,512 5324
d 356,510,542 7040
d 204,206,506 7201
d 26,61,71,670 7777
d 602,610,642,660 1004
d 310,330,344,347 1220
d 650,652,721,741 1400
d 525,535,544,556 5364
d 423,447,501,534 7450
d 304,307,316,332,346 3220
d 341,343,357,361,363 3410
d 301,566,574,677,707 7600
d 305,313,317,320,321,322 4324
d 120,430,460,504,516,537,550,570 7440
d 105,201,442,443,444,477,532,701,705 7000
d 102,325,402,413,426,445,453,473,514,526,546 7200
d 776 2661
d 777 5660
d 200 6002
;---------
d L,ION 0
d AC,MQ,PC 200
:NOLOAD
;-------------------------------------------------------------
if "%DATA%"=="F" goto NOLIST
if "%LIST%"=="T" echof "Listing BLINKY-8 for the PDP-8 ..."
if "%LIST%"=="F" echof "Data of BLINKY-8 for the PDP-8 ..."
if "%LIST%"=="F" e PC
;-------------------------------
echo ;    -- IntVector 0000-0002
e <5003 0000
e -m    0001-0002
echo ;    -- Addresses 0003-0007
e -m 0003
e >0 0004-0007
echo ;    -- Indexes   0010-0017
e >0 0010-0017
;-------------------------------
echo ;    -- LN data   0020-0027
e >0 0020-0027
echo ;    -- PC data   0030-0037
e >0 0030-0037
echo ;    -- MA data   0040-0047
e >0 0040-0047
echo ;    -- MB data   0050-0057
e >0 0050-0057
echo ;    -- AC data   0060-0067
e >0 0060-0067
echo ;    -- MQ data   0070-0077
e >0 0070-0077
;-------------------------------
if "%LIST%"=="F" goto NOINT1
echo ;    -- IntRtn #1 0100-0147
e -m >0 0100-0147
:NOINT1
echo ;    -- Const&Var 0150-0177
e    >0 0150-0151
e -m >0 0152
e    >0 0153-0177
;-------------------------------
if "%LIST%"=="F" goto NOSTART
echo ;    -- Start     0200-0217
e -m >0 0200-0217
:NOSTART
echo ;    -- Var&Const 0220-0277
e    >0 0220-0277
;-------------------------------
d PC 0105
if "%LIST%"=="F" goto NOLIST
;-------------------------------
echo ;    -- SR Change 0300-0323
e -m <1000   0300
e -m >0 0301-0323
echo ;    -- SR Parse  0324-0377
e -m <1000   0324
e -m >0 0325-0367
; -c    0370-0377
;-------------------------------
echo ;    -- IntRtn #2 0400-0563
e -m >0 0400-0563
echo ;    -- RetInt    0564-0577
e -m >0 0564-0577
;-------------------------------
echo ;    -- Pat. A    0600-0637
e >0 0600-0637
;cho ;    -- Pat. A 1K 0640-0667
; >0 0640-0667
echo ;    -- Pat. B    0670-0717
e >0 0670-0717
;cho ;    -- Pat. B 1K 0720-0747
; >0 0720-0747
;-------------------------------
echo ;    -- Clk. 50Hz 0750-0754
e >0 0750-0757
echo ;    -- Clk. 60Hz 0760-0764
e >0 0760-0765
;cho ;    -- Clk. User 0770-0774
e >0 0770-0775
;-------------------------------
echo ;    -- Version   0776-0777
e -c 0776-0777
d PC 0200
:NOLIST
;------------------------
if "%EXEC%"=="F" goto EOF
echof ""
echof "Console SWITCH REGISTER definitions ..."
echof ""
echof "       00     PC/MA lamp option (0=Bounce, 1=Scan R-L)"
echof "       01-02  PC/MA lamp speed"
echof ""
echof "       03     MB lamp option (0=Full-speed count-up, 1=Bounce)"
echof "       04-05  MB lamp speed  (Ignored when switch 03=0)"
echof ""
echof "       06     AC lamp option (0=Bounce, 1=Complemented MB)"
echof "       07-08  AC lamp speed"
echof ""
echof "       09     MQ lamp option (0=Bounce, 1=Complemented AC)"
echof "       10-11  MQ lamp speed"
echof ""
echof "Please note that characters typed at the console will be echoed"
echof ""
;------------------------------------------------------------------------------
echof "Starting BLINKY-8 for the PDP-8 ..."
echof "    Throttle stabilzation takes up to 30 seconds, please be patient ..."
echof ""
set realcons connected
cont
:EOF
;
; END-OF-FILE
