mirror of
https://github.com/rzzzwilson/pymlac.git
synced 2025-06-10 09:32:41 +00:00
114 lines
5.0 KiB
NASM
Executable File
114 lines
5.0 KiB
NASM
Executable File
; Imlac Program Loader
|
|
;
|
|
; This loader is loaded by the bootstrap program at x7700, where x=0 for
|
|
; a 4K machine, and x=1 for an 8K machine. The first byte of this loader
|
|
; is 002, which is used by the bootstrap as a signal to start loading.
|
|
; This loader checks whether it is running at address 017700 on an 8K machine,
|
|
; which is assumed to support long vectors, and enables a simple display
|
|
; during the load if so.
|
|
;
|
|
; The load format consists of one or more contiguous blocks, with no
|
|
; padding bytes between them. Each block begins with three words:
|
|
;
|
|
; load address
|
|
; negative word count
|
|
; checksum
|
|
;
|
|
; Words are always received high-order byte first. The rest of the block
|
|
; consists of "word count" words, which are loaded starting at "load address".
|
|
; The sum of all the words in the block, including these first three, must be
|
|
; zero (16 bit sum), and the checksum is computed to give that result.
|
|
;
|
|
; The end of the load is signalled by a block with a negative starting address.
|
|
; If that address is -1, the loader simply halts. Otherwise it reads one more
|
|
; word (in the position normally occupied by the negative word count), which
|
|
; will be the value in the AC at the start of the program just loaded. Then
|
|
; it starts the program with an indirect jump through the negative starting
|
|
; address. (For example, to start at 00100, the starting address will be
|
|
; 100100).
|
|
;
|
|
; If a checksum error occurs, the loader goes into a tight loop at
|
|
; CSERR (x7736).
|
|
;
|
|
; As decoded by Howard Palmer (hep@acm.org) from an Imlac wumpus binary.
|
|
; Oct. 6, 2004
|
|
;
|
|
ORG 37700
|
|
START: RCF ; This is overwritten by the block start address
|
|
CNT: JMS CNT ; This instruction overwrites itself!
|
|
CKSM: LAC CNT ; This is overwritten by the checksum
|
|
SAM LD8K ; Are we loaded at 017700?
|
|
JMP NODSP ; Yes, skip display code
|
|
LWC 12 ; Get address of display list (DLIST at 037766)
|
|
DLA ; Start the display processor
|
|
DON
|
|
NODSP: CAL ; Initialize checksum to zero
|
|
DAC CKSM
|
|
JMS RWORD ; Read the load address of the next block
|
|
DAC START ; Save it
|
|
ASP ; Looking for a negative load address
|
|
JMP DONE ; Finished loading blocks if we find it
|
|
JMS RWORD ; Read the negative word count
|
|
DAC CNT
|
|
JMS RWORD ; Read the checksum word
|
|
LOAD: JMS RWORD ; Read next word to be loaded
|
|
DAC @START ; Store it
|
|
LAC START ; Get the current load address
|
|
SAR 3 ; Extract the top 10 bits
|
|
AND M1777
|
|
IOR DLYA ; Use as the Y value in a DLYA instruction
|
|
DAC DLIST ; Replace the DLYA in the display list
|
|
LAC @START ; Get the word that was just loaded
|
|
ISZ START ; Bump the load address
|
|
ISZ CNT ; Bump the negative count
|
|
JMP LOAD ; Loop until it goes to zero
|
|
ADD CKSM ; Finish computing the checksum
|
|
ASZ ; Should add up to zero
|
|
CSERR: JMP CSERR ; Tight loop if checksum error
|
|
JMP NODSP ; Loop back for the next block
|
|
|
|
|
|
DONE: DOF ; Turn off the display processor
|
|
IAC ; Increment the negative load address
|
|
ASN ; Just stop if it goes to zero
|
|
HLT ; Load completed successfully
|
|
JMS RWORD ; If not zero, read a starting value for the AC
|
|
JMP @START ; And use the negative load address to start
|
|
|
|
|
|
; This subroutine reads the next word. It is entered with either zero or the
|
|
; last word read in the AC. It adds that value to CKSM.
|
|
|
|
|
|
RWORD: ZZZ ; Subroutine to read a word
|
|
ADD CKSM ; Accumulate checksum
|
|
DAC CKSM
|
|
CAL
|
|
WT1: RSF ; Wait for high-order byte
|
|
JMP WT1
|
|
RRC ; Read it
|
|
RAL 3 ; Move it to the high-order AC
|
|
RAL 3
|
|
RAL 2
|
|
WT2: RSF ; Wait for low-order byte
|
|
JMP WT2
|
|
RRC ; Read it, forming a word
|
|
JMP @RWORD ; Return to caller
|
|
DLYA: DLYA 0 ; Used to build DLYA instruction
|
|
M1777: DATA 1777 ; 10-bit mask
|
|
|
|
|
|
; Begin display list
|
|
; This must start at location 037766
|
|
|
|
|
|
DLIST: DLYA 0 ; This gets dynamically updated
|
|
DLXA 0
|
|
DSTS 1 ; Set normal scale
|
|
DATA 046000 ; 3-word long vector
|
|
DATA 021777 ; x=1777, y=0, beam on
|
|
DATA 0
|
|
DJMP DLIST ; Run the display processor continuously
|
|
LD8K: DATA 017702 ; Used to check for load at 017700
|
|
END
|