mirror of
https://github.com/rzzzwilson/pymlac.git
synced 2025-06-10 09:32:41 +00:00
109 lines
8.5 KiB
Plaintext
Executable File
109 lines
8.5 KiB
Plaintext
Executable File
1 ; Imlac Program Loader
|
|
2 ;
|
|
3 ; This loader is loaded by the bootstrap program at x7700, where x=0 for
|
|
4 ; a 4K machine, and x=1 for an 8K machine. The first byte of this loader
|
|
5 ; is 002, which is used by the bootstrap as a signal to start loading.
|
|
6 ; This loader checks whether it is running at address 017700 on an 8K machine,
|
|
7 ; which is assumed to support long vectors, and enables a simple display
|
|
8 ; during the load if so.
|
|
9 ;
|
|
10 ; The load format consists of one or more contiguous blocks, with no
|
|
11 ; padding bytes between them. Each block begins with three words:
|
|
12 ;
|
|
13 ; load address
|
|
14 ; negative word count
|
|
15 ; checksum
|
|
16 ;
|
|
17 ; Words are always received high-order byte first. The rest of the block
|
|
18 ; consists of "word count" words, which are loaded starting at "load address".
|
|
19 ; The sum of all the words in the block, including these first three, must be
|
|
20 ; zero (16 bit sum), and the checksum is computed to give that result.
|
|
21 ;
|
|
22 ; The end of the load is signalled by a block with a negative starting address.
|
|
23 ; If that address is -1, the loader simply halts. Otherwise it reads one more
|
|
24 ; word (in the position normally occupied by the negative word count), which
|
|
25 ; will be the value in the AC at the start of the program just loaded. Then
|
|
26 ; it starts the program with an indirect jump through the negative starting
|
|
27 ; address. (For example, to start at 00100, the starting address will be
|
|
28 ; 100100).
|
|
29 ;
|
|
30 ; If a checksum error occurs, the loader goes into a tight loop at
|
|
31 ; CSERR (x7736).
|
|
32 ;
|
|
33 ; As decoded by Howard Palmer (hep@acm.org) from an Imlac wumpus binary.
|
|
34 ; Oct. 6, 2004
|
|
35 ;
|
|
36 ORG 37700
|
|
37700 001032 37 START: RCF ; This is overwritten by the block start address
|
|
37701 037701 38 CNT: JMS CNT ; This instruction overwrites itself!
|
|
37702 063701 39 CKSM: LAC CNT ; This is overwritten by the checksum
|
|
37703 077775 40 SAM LD8K ; Are we loaded at 017700?
|
|
37704 013710 41 JMP NODSP ; Yes, skip display code
|
|
37705 104012 42 LWC 12 ; Get address of display list (DLIST at 037766)
|
|
37706 001003 43 DLA ; Start the display processor
|
|
37707 003100 44 DON
|
|
37710 100011 45 NODSP: CAL ; Initialize checksum to zero
|
|
37711 023702 46 DAC CKSM
|
|
37712 037746 47 JMS RWORD ; Read the load address of the next block
|
|
37713 023700 48 DAC START ; Save it
|
|
37714 002002 49 ASP ; Looking for a negative load address
|
|
37715 013740 50 JMP DONE ; Finished loading blocks if we find it
|
|
37716 037746 51 JMS RWORD ; Read the negative word count
|
|
37717 023701 52 DAC CNT
|
|
37720 037746 53 JMS RWORD ; Read the checksum word
|
|
37721 037746 54 LOAD: JMS RWORD ; Read next word to be loaded
|
|
37722 123700 55 DAC @START ; Store it
|
|
37723 063700 56 LAC START ; Get the current load address
|
|
37724 003063 57 SAR 3 ; Extract the top 10 bits
|
|
37725 047765 58 AND M1777
|
|
37726 053764 59 IOR DLYA ; Use as the Y value in a DLYA instruction
|
|
37727 023766 60 DAC DLIST ; Replace the DLYA in the display list
|
|
37730 163700 61 LAC @START ; Get the word that was just loaded
|
|
37731 033700 62 ISZ START ; Bump the load address
|
|
37732 033701 63 ISZ CNT ; Bump the negative count
|
|
37733 013721 64 JMP LOAD ; Loop until it goes to zero
|
|
37734 067702 65 ADD CKSM ; Finish computing the checksum
|
|
37735 002001 66 ASZ ; Should add up to zero
|
|
37736 013736 67 CSERR: JMP CSERR ; Tight loop if checksum error
|
|
37737 013710 68 JMP NODSP ; Loop back for the next block
|
|
69
|
|
37740 001012 70 DONE: DOF ; Turn off the display processor
|
|
37741 100004 71 IAC ; Increment the negative load address
|
|
37742 102001 72 ASN ; Just stop if it goes to zero
|
|
37743 000000 73 HLT ; Load completed successfully
|
|
37744 037746 74 JMS RWORD ; If not zero, read a starting value for the AC
|
|
37745 113700 75 JMP @START ; And use the negative load address to start
|
|
76
|
|
77 ; This subroutine reads the next word. It is entered with either zero or the
|
|
78 ; last word read in the AC. It adds that value to CKSM.
|
|
79
|
|
37746 000000 80 RWORD: ZZZ ; Subroutine to read a word
|
|
37747 067702 81 ADD CKSM ; Accumulate checksum
|
|
37750 023702 82 DAC CKSM
|
|
37751 100011 83 CAL
|
|
37752 002040 84 WT1: RSF ; Wait for high-order byte
|
|
37753 013752 85 JMP WT1
|
|
37754 001033 86 RRC ; Read it
|
|
37755 003003 87 RAL 3 ; Move it to the high-order AC
|
|
37756 003003 88 RAL 3
|
|
37757 003002 89 RAL 2
|
|
37760 002040 90 WT2: RSF ; Wait for low-order byte
|
|
37761 013760 91 JMP WT2
|
|
37762 001033 92 RRC ; Read it, forming a word
|
|
37763 113746 93 JMP @RWORD ; Return to caller
|
|
37764 020000 94 DLYA: DLYA 0 ; Used to build DLYA instruction
|
|
37765 001777 95 M1777: DATA 1777 ; 10-bit mask
|
|
96
|
|
97 ; Begin display list
|
|
98 ; This must start at location 037766
|
|
99
|
|
37766 020000 100 DLIST: DLYA 0 ; This gets dynamically updated
|
|
37767 010000 101 DLXA 0
|
|
37770 004005 102 DSTS 1 ; Set normal scale
|
|
37771 046000 103 DATA 046000 ; 3-word long vector
|
|
37772 021777 104 DATA 021777 ; x=1777, y=0, beam on
|
|
37773 000000 105 DATA 0
|
|
37774 067766 106 DJMP DLIST ; Run the display processor continuously
|
|
37775 017702 107 LD8K: DATA 017702 ; Used to check for load at 017700
|
|
108 END
|