mirror of
https://github.com/rzzzwilson/pymlac.git
synced 2025-06-10 09:32:41 +00:00
105 lines
10 KiB
NASM
Executable File
105 lines
10 KiB
NASM
Executable File
/* ; Imlac Papertape Program Block 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 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. */
|
|
/* ; */
|
|
/* ; As decoded by Howard Palmer (hep@acm.org) from an Imlac wumpus binary. */
|
|
/* ; Oct. 6, 2004 */
|
|
/* ; Modified by Ross Wilson (wilsonr@iinet.net.au) to load papertape. */
|
|
/* ; */
|
|
/* ORG 37700 ; */
|
|
0100011, /* 037700 BLOCK: CAL ; Initialize checksum to zero */
|
|
0023731, /* 037701 DAC CKSM ; */
|
|
0037732, /* 037702 JMS RWORD ; Read the load address of the next block */
|
|
0023727, /* 037703 DAC START ; Save it */
|
|
0002002, /* 037704 ASP ; Looking for a negative load address */
|
|
0013722, /* 037705 JMP DONE ; Finished loading blocks if we find it */
|
|
0037732, /* 037706 JMS RWORD ; Read the negative word count */
|
|
0023730, /* 037707 DAC CNT ; */
|
|
0037732, /* 037710 JMS RWORD ; Read the checksum word */
|
|
0037732, /* 037711 LOAD: JMS RWORD ; Read next word to be loaded */
|
|
0123727, /* 037712 DAC @START ; Store it */
|
|
0033727, /* 037713 ISZ START ; Bump the load address */
|
|
0033730, /* 037714 ISZ CNT ; Bump the negative count */
|
|
0013711, /* 037715 JMP LOAD ; Loop until it goes to zero */
|
|
0067731, /* 037716 ADD CKSM ; Finish computing the checksum */
|
|
0002001, /* 037717 ASZ ; Should add up to zero */
|
|
0013720, /* 037720 CSERR: JMP CSERR ; Tight loop if checksum error */
|
|
0013700, /* 037721 JMP BLOCK ; Loop back for the next block */
|
|
/* ; */
|
|
0100004, /* 037722 DONE: IAC ; Increment the negative load address */
|
|
0102001, /* 037723 ASN ; Just stop if it goes to zero */
|
|
0000000, /* 037724 HLT ; Load completed successfully */
|
|
0037732, /* 037725 JMS RWORD ; If not zero, read a starting value for the AC */
|
|
0113727, /* 037726 JMP @START ; And use the negative load address to start */
|
|
/* ; */
|
|
0000000, /* 037727 START: WORD 0 ; block start address */
|
|
0000000, /* 037730 CNT: WORD 0 ; block word count */
|
|
0000000, /* 037731 CKSM: WORD 0 ; block checksum */
|
|
/* */
|
|
/* ; 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. */
|
|
/* */
|
|
0000000, /* 037732 RWORD: WORD 0 ; Subroutine to read a word */
|
|
0067731, /* 037733 ADD CKSM ; Accumulate checksum */
|
|
0023731, /* 037734 DAC CKSM ; */
|
|
0100011, /* 037735 CAL ; */
|
|
0102400, /* 037736 WT1: HSN ; Wait for high-order byte */
|
|
0013736, /* 037737 JMP WT1 ; */
|
|
0002400, /* 037740 WT2: HSF ; */
|
|
0013740, /* 037741 JMP WT2 ; */
|
|
0001051, /* 037742 HRB ; Read it */
|
|
0003003, /* 037743 RAL 3 ; Move it to the high-order AC */
|
|
0003003, /* 037744 RAL 3 ; */
|
|
0003002, /* 037745 RAL 2 ; */
|
|
0102400, /* 037746 WT3: HSN ; Wait for low-order byte */
|
|
0013746, /* 037747 JMP WT3 ; */
|
|
0002400, /* 037750 WT4: HSF ; */
|
|
0013750, /* 037751 JMP WT4 ; */
|
|
0001051, /* 037752 HRB ; Read it, forming a word */
|
|
0113732, /* 037753 JMP @RWORD ; Return to caller */
|
|
/* */
|
|
0000000, /* 037754 WORD 0 ; Filler to 076 words */
|
|
0000000, /* 037755 WORD 0 ; Filler to 076 words */
|
|
0000000, /* 037756 WORD 0 ; Filler to 076 words */
|
|
0000000, /* 037757 WORD 0 ; Filler to 076 words */
|
|
0000000, /* 037760 WORD 0 ; Filler to 076 words */
|
|
0000000, /* 037761 WORD 0 ; Filler to 076 words */
|
|
0000000, /* 037762 WORD 0 ; Filler to 076 words */
|
|
0000000, /* 037763 WORD 0 ; Filler to 076 words */
|
|
0000000, /* 037764 WORD 0 ; Filler to 076 words */
|
|
0000000, /* 037765 WORD 0 ; Filler to 076 words */
|
|
0000000, /* 037766 WORD 0 ; Filler to 076 words */
|
|
0000000, /* 037767 WORD 0 ; Filler to 076 words */
|
|
0000000, /* 037770 WORD 0 ; Filler to 076 words */
|
|
0000000, /* 037771 WORD 0 ; Filler to 076 words */
|
|
0000000, /* 037772 WORD 0 ; Filler to 076 words */
|
|
0000000, /* 037773 WORD 0 ; Filler to 076 words */
|
|
0000000, /* 037774 WORD 0 ; Filler to 076 words */
|
|
0000000, /* 037775 WORD 0 ; Filler to 076 words */
|
|
0000000 /* 037776 WORD 0 ; Filler to 076 words */
|
|
/* */
|
|
/* END ; */
|