IPL – Initial Program Loader

When I rediscoverd my P1 computer in my attic, the board contained only a single PROM marked “IPL v1.1”. Whereas most 2650-based computers use some sort of monitor program (Pipbug, Binbug, the Central Data monitor program, or even Popmon), the P1 used only a single PROM, which only function was to read the first three tracks of the first floppy disk, dump those sectors into RAM at address 6000, and then jump to that address. In other words, after a hardware reset the P1 would load and start a Disk Operating System.

Like one of my other 82S115 PROMs, the IPL PROM contained bit errors. I found two. Both are corrected in the (reverse-engineerd) source listing below.

The IPL code is cleverly written: it can be run in any memory location! It only uses relative instructions. The only references to absolute addresses are to the start address of DOS (6000) and to some scratch RAM locations at the top of the 17FF memory range. Since relative branches can only jump -64..+63 locations far, longer branches need to be broken into separate hops. The code uses “relative jump areas” between subroutines, areas with unconditional branch instructions in order to bridge larger gaps. See for example the bold areas in the code snippet below.

DDCloop:
		bdrr,r2 DDCReadCurrTrack
		bdrr,r1 DDCReadCurrTrack
		bctr,un WRSetNotRdyb

; Relative jump area
WaitReadyd:
		bctr,un WaitReadyc

;
DDCReadCurrTrack:
		rede,r0 FD1771_INT
		bcfr,lt DDCloop			No data ready
		rede,r0 FD1771_DAT
		strz	r1
		bstr,un WaitReadyc
		andi,r0 H'98'			Not Ready, Track/record/ID not found, CRC error
		retc,gt
		retc,lt
		wrte,r1 FD1771_TRK
DDCDiskready:
		loda,r0 StorTrack
		comi,r0 D'34' 			max track
		bcfr,gt DiskIO
		lodi,r1 H'0B'			error code H'0B' == track overflow (as in CD DOS)
		retc,un


; Relative jump area
IOStatCheckb:
		bctr,un IOStatChecka
WaitReadyc:
		bctr,un WaitReadyb
WRSetNotRdyb:
		bctr,un WRSetNotRdya


; DiskIO: read or write a sector on disk
; In:
;  R0 = the track to seek
;  StorAddressHi/Lo = base address into which to read sector
;  StorCmdKind = operation: negative for write, non-negative for read
;  StorTargetDrive = ???
;  StorSector = sector to read/write
;  StorNumAttempts = number of read-attempts
; Out:
;  R1 = 1
;
DiskIO:
		rede,r1 FD1771_TRK		
		comz	r1
		bctr,eq DoIO

Like with many things I do not know the original source or author of this software. The code seems very similar to the disk I/O subroutines in Central Data DOS.