PDP7-Unix/cmd/dmabs.s

   " dmabs

	" takes a list of files on command line and punches out each
	" to paper tape with a "hardware read-in" (HRI) bootstrap
	" program in front of them.

	" Bob Supnik says:
	" The PDP-7/9/15 hardware read-in used a simple format where
	" the start address was specified in the address switches, and
	" then 18b words were deposited sequentially in memory. Binary
	" format was distinguished by having the high order bit (0200)
	" in each 8b tape frame set, so that leader (all 0s) could be
	" ignored. A frame with bit 1 set (0100) indicated end of
	" load; the last word was supposed to be either a JMP (to
	" start the program running) or a HLT.

   lac o17
   sys creat; punout		" open paper tape punch
   spa
   sys save			" open failed: dump core
   dac fo
   lac 017777
   tad d1
   dac name			" get pointer to argv[0]
   jms space			" punch 10 inch leader
   100

loop:				" loop for input files
   dzm oldsum			" clear checksum
   lac initcmd
   dac comand			" reset command to "dac"
   lac i 017777			" get arg count
   sad d4			" anything left?
   jmp stop			"  no: stop
   tad dm4			" decrement argc by 4
   dac i 017777
   lac name			" advance arg pointer
   tad d4
   dac name

dump1:		" (label not used)
   lac comand			" get command word
   xor dactra			" transmute dac to jmp
   dac tracmd

dump2:		" (label not used)
   sys open; name: 0; 0		" open file
   spa
   jmp opnerr			" open failed
   dac fi			" save input fd
   -bootsiz			" get length of bootstrap
   dac c1
   law boot-1			" get pointer to boostrap in i8
   dac 8
1:
   lac i 8			" fetch word from bootstrap
   jms put			" write to tape
   isz c1			" done?
   jmp 1b			"  no: loop
   lac bootcmd			" write "jmp" instruction to tape
   lrs 12
   jms put1
   lac bootcmd
   lrs 6
   jms put1
   lac bootcmd
   and o77
   xor o300			" final frame of jmp word: 0100 set
   jms put2

   jms space			" punch three empty frames
   3

dump3:				" block loop
   -1				" reset i8 to buffer
   tad bufp
   dac 8
   -64				" get count
   dac c1
1:
   dzm i 8			" loop zeroing buffer
   isz c1
   jmp 1b
   lac fi
   sys read; bufp: buf; 64	" read block from input file
   sna				" got some?
   jmp done			"  done
   dac count			" save count
   -1
   tad bufp
   dac 8			" point i8 to input buffer
   -64
   dac c1			" reset count
   cla
1:				" loop for 1's complement sum of buffer
   add i 8
   isz c1
   jmp 1b
   sna				" sum non-zero?
   jmp dump4			"  no: is zero: skip this block
   dac newsum			" save as new sum
   lac comand			" get command word
   jms put			" write to tape
   lac count			" get positive count
   jms put			" write to tape
   lac oldsum
   add comand
   add count
   jms put			" write oldsum+command+count
   lac newsum			" copy new sum to old sum
   dac oldsum
   jms space			" write three empty frame
   3
   -1				" reset i8 to input buffer
   tad bufp
   dac 8
   -1
   tad count
   cma
   dac c1			" reset counter
1:				" loop writing block to tape
   lac i 8
   jms put
   isz c1
   jmp 1b
   jms space			" follow with 1 inch trailer
   10

dump4:				" end of block
   lac comand			" advance command word by count
   tad count
   dac comand
   jmp dump3			" loop for another block

done:				" here at end of input file
   lac tracmd			" get transfer command (jmp)
   jms put			" write to tape
   cla				" write a zero word
   jms put
   lac oldsum			" get checksum
   add tracmd			" add in jmp command word
   jms put			" write to tape
   jms space			" write two inch trailer
   20
   lac fi			" close input file
   sys close
   jmp loop			" loop for another input file

stop:
   cla
   jms put			" write a zero binary word to tape
   jms space			" write 10 inch trailer
   100
   sys exit

space: 0			" punch empty frames (count after jms)
   -1
   tad i space
   cma
   dac c1			" store negative count
   isz space			" skip count word
1:
   lac o400			" defeat NUL removal
   jms put2			" write one empty frame
   isz c1			" done?
   jmp 1b			"  no
   jmp i space

put: 0				" write a (binary) word (as three frames)
   dac 1f
   lrs 12
   jms put1
   lac 1f
   lrs 6
   jms put1
   lac 1f
   jms put1
   jmp i put
1:0

put1:0				" write one frame of a binary word
   and o77
   xor o200			" light the high bit
   jms put2
   jmp i put1

put2: 0				" write one frame to tape
   dac 1f
   lac fo
   sys write; 1f; 1
   jmp i put2
1: 0

boot:
   org = 017740
2:
   jms get1-boot+org		" get command word from tape
   dac cmd-boot+org
   jms get1-boot+org		" get count from tape
   cma
   dac cnt-boot+org		" store complemented (incremented below)
   jms get2-boot+org		" get checksum word
   xor sum-boot+org		" clear those bits in sum
   dzm sum-boot+org		" clear out sum
   cla cll sza			" checksum match? & clear AC & LINK
   hlt				"  no: checksum mismatch
   isz cnt-boot+org		" yes: increment count (complete negate)
1:
   jms get1-boot+org		" get data word from tape
cmd: 0				" command word (read from tape)
   isz cmd-boot+org		" increment command instruction
   isz cnt-boot+org		" increment count
   jmp 1b-boot+org		"  not done, keep going
   jmp 2b-boot+org
get1: 0				" get checksummed word from tape
   jms get2-boot+org		" read a word
   dac get2-boot+org		" save (in get2 return addr word!)
   add sum-boot+org		" 1's complement sum
   dac sum-boot+org		" save sum
   lac get2-boot+org		" get word back
   jmp i get1-boot+org		" return
get2: 0				" get unchecksummed word from tape
   iot 0144			" "rsb" ptr select binary mode
1:
   iot 0101			" "rsf" ptr skip if flag set
   jmp 1b-boot+org		"  loop until ready
   iot 0112			" "rrb" ptr clear flag, or in read buffer
   jmp i get2-boot+org
sum: 0
   cnt = sum+1
   bootsiz = .-boot
bootcmd: jmp org

opnerr:
   lac name
   dac 1f
   lac d1
   sys write; 1: 0; 4
   lac d1
   sys write; mes; 2
   jmp loop
mes:
   040;077012			" space, ?, NL

comand: 0
tracmd: 0
   d1: 1
o17777: 017777			" unused?
o77: 077
o200: 0200
o300: 0300
d4: 4
d64: 64
dm4: -4
o400: 0400
punout: <pp>;<to>;<ut>;040040
o17: 017

fi: 0
fo: 0
count: 0
oldsum: 0
newsum: 0
daccmd: dac
dactra: dac jmp
initcmd: dac 0
c1: 0
buf:

iot = 0700000