From d2064e099ec03eb483734e36444cdd1554a2ab59 Mon Sep 17 00:00:00 2001 From: Lars Brinkhoff Date: Tue, 8 Nov 2016 11:22:22 +0100 Subject: [PATCH] Build MTBOOT. --- README.md | 1 + build/build.tcl | 3 + src/kshack/ksdefs.193 | 561 ++++++++++++++++++++++++++++++++ src/kshack/mtboot.176 | 720 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1285 insertions(+) create mode 100755 src/kshack/ksdefs.193 create mode 100755 src/kshack/mtboot.176 diff --git a/README.md b/README.md index 754afa00..3e214e68 100644 --- a/README.md +++ b/README.md @@ -50,5 +50,6 @@ from scratch. - TCTYP and CRTSTY, terminal handling. - PEEK, system monitoring. - ARCDEV, transparent file system access to archive files. + - MTBOOT, make bootable tapes. 6. Finally, the whole file system is dumped to tape. diff --git a/build/build.tcl b/build/build.tcl index 034a1c28..0089b5e2 100644 --- a/build/build.tcl +++ b/build/build.tcl @@ -286,6 +286,9 @@ respond "*" ":link channa; rakash pfthmg,dragon; rakash pfthmg\r" respond "*" ":link sys; ts p,sys; ts peek\r" +respond "*" ":midas kshack;ts mtboot_kshack;mtboot\r" +expect ":KILL" + respond "*" $emulator_escape create_tape "out/output.tape" type ":dump\r" diff --git a/src/kshack/ksdefs.193 b/src/kshack/ksdefs.193 new file mode 100755 index 00000000..d5325fcc --- /dev/null +++ b/src/kshack/ksdefs.193 @@ -0,0 +1,561 @@ +; -*- Midas -*- This is the file AI:KSHACK;KSDEFS > + +;;; "Devices" + +PI==:4 ;Interrupts +PAG==:10 ;Paging + ..D010==:0 ;(For DDT) +.RD.==:20 ;Read various kludges. + ..D020==:0 +.WR.==:24 ;Write various kludges. + ..D024==:0 + +;;; XCTR and paging instructions + +UMOVE=:704^9 ;"BLKI 40," + ;Same as XCTR XR,[MOVE ...] + +UMOVEM=:705^9 ;"BLKI 50," + ;Same as XCTR XW,[MOVEM ...] + +XCTR=:103^9 ;XCT with mapping. +XCTRI=:102^9 ;Same, but page fails cause it to skip. Done by + ;software as on the KL. + ;;XCTR bits for the KS are theoretically the same as those on the KL. + ;;These values were generated by reading the documentation rather + ;;than by copying the bits for XCTR on MC. + XR==:4 + XW==:4 + XRW==:4 + XBYTE==:7 ;On MC-KL this is 5. The manual don't list 5 as a + ;reasonable value at all. The 2 bit causes the EA + ;calculation for the byte pointer to take place in + ;the user's context. Since ITS does the EA + ;calculation for byte pointers it XCTRs ahead of + ;time, perhaps it doesn't matter? + XBR==:1 + XBW==:4 + XBRW==:5 + XEA==:10 ; On MC-KL this is #o16. The processor manual for + ; the KL contains some waffling about how 10 won't + ; work and you should use 14 instead. The KS + ; manual is silent on this point. Seemingly no + ; bits other than 10 can effect an immediate + ; instruction. This option doesn't exist on the KA + ; and is used by ITS in only two places, both in + ; the KL-specific page fail code. One occurance is + ; commented out with the claim that it is buggy. + ; For the moment let us assume that this value will + ; just work on the KS. + +;;; Traditional instructions. + +RDAPR==:CONI 0, ;= 700240,, C(E) <- System flags + ;4.3 - 3.5 Flags enabled + ; (on KL 2.8 says the cache is being swept) + ;2.3 - 1.5 Flags set + ;1.4 Some flag is interrupting + ;1.3 - 1.1 PI level + +WRAPR==:CONO 0, ;= 700200,, System flags <- E + ; (on KL 2.8 Clears all IO devices) + ;2.7 - 2.4 Function to perform on flags: + ; 2.7 Enable + ; 2.6 Disable + ; 2.5 Clear + ; 2.4 Set + ;2.3 - 1.5 Flags to perform function upon: + ; 2.3 "Flag 24" + ; 2.2 KS interrupting the 8080 + ; 2.1 Power failure + ; 1.9 No memory + ; 1.8 Bad memory data + ; 1.7 Corrected memory data + ; 1.6 Interval done + ; 1.5 8080 interrupting the KS + ; (on KL flags are: + ; 2.3 S bus error + ; 2.2 No memory + ; 2.1 IO page failure + ; 1.9 MB parity + ; 1.8 Cache directory parity + ; 1.7 Address parity + ; 1.6 Power failure + ; 1.5 Cache sweep done) + ;1.3 - 1.1 PI level + +80INT==:12000 ;Interrupt 8080 from KS. + +RDPI==:CONI PI, ;= 700640,, C(E) <- PI status + ;3.7 - 3.1 interrupts requested with CONO PI, + ; (on KL 2.9 - 2.7 control parity) + ;2.6 - 1.9 Interrupt in progress + ;1.8 PI system is on + ;1.7 - 1.1 Levels turned on + +WRPI==:CONO PI, ;= 700600,, PI status <- E + ; (on KL 2.9 - 2.7 control parity) + ;2.5 Drop requests on selected levels + ;2.4 Clear PI system + ;2.3 Initiate interrupts on selected levels + ;2.2 Turn on selected levels + ;2.1 Turn off selected levels + ;1.9 Turn off PI system + ;1.8 Turn on PI system + ;1.7 - 1.1 Select level + +;;; More traditional looking instructions, sort of... + +APRID==:BLKI 0, ;= 700000,, C(E) <- Processor ID + ;4.9 - 4.1 Microcode options: + ; 4.5 ITS microcode + ; (on KL options are: + ; 4.9 Tops-20 Paging + ; 4.8 Extended addressing + ; 4.7 Exotic microcode + ; 4.5 ITS microcode) + ;3.9 - 3.1 Microcode version number + ;2.9 - 2.7 Hardware options: + ; None defined. + ; (on KL options are: + ; 2.9 50 Hz line frequency + ; 2.8 Cache + ; 2.7 Channel + ; 2.6 Extended KL10 + ; 2.5 Master Oscillator) + ;2.6 - 1.1 Processor serial number + +RDEBR=:CONI PAG, ;= 701240,, C(E) <- EBR +WREBR=:CONO PAG, ;= 701200,, EBR <- E + ;2.6 Tops-20 style + ;2.5 Enable pager (and traps) + ;2.2 - 1.1 EBR physical DEC page number + ;WREBR resets the cache and page table. + ; + ; In the ITS microcode setting bit 2.6 only effects + ; the style in which MUUOs are trapped. It should + ; never be set. + +RDUBR=:DATAI PAG, ;= 701040,, C(E) <- UBR +WRUBR=:DATAO PAG, ;= 701140,, UBR <- C(E) + ;4.9 Set AC blocks + ;4.7 Set UBR + ;4.3 - 4.1 Current ACs + ;3.9 - 3.7 Previous ACs + ;3.2 - 1.1 UBR physical base address + ;RDUBR always returns a word with 4.9 and 4.7 set. + ;WRUBR resets the cache and page table. + +CLRPT=:BLKO PAG, ;= 701100,, Clear page table entry + ;Invalidate the page table entry for the page + ;referenced by E and reset the cache. + ; + ;In the ITS microcode this will only invalidate the + ;page table entry for half page referenced by E. + +CLRCSH=:BLKI PAG, ;= 701000,, Clear Cache + ;In the ITS microcode only. + ;Resets the cache. + + +;;; Instructions for maintaining the DBRs. LPMR and SPM. + +LDBR1=:BLKI .WR., ;= 702400,, DBR1 <- E +SDBR1=:BLKI .RD., ;= 702000,, C(E) <- DBR1 +LDBR2=:DATAI .WR., ;= 702440,, DBR2 <- E +SDBR2=:DATAI .RD., ;= 702040,, C(E) <- DBR2 +LDBR3=:BLKO .WR., ;= 702500,, DBR3 <- E +SDBR3=:BLKO .RD., ;= 702100,, C(E) <- DBR3 +LDBR4=:DATAO .WR., ;= 702540,, DBR4 <- E +SDBR4=:DATAO .RD., ;= 702140,, C(E) <- DBR4 + ;LDBR1, LDBR2, LDBR3 and LDBR4 all reset the cache + ;and page table. someday they may be careful and + ;not reset the half of the page table they don't + ;effect. + +;;; And there is also the traditional: + +LPMR=:CONSO .WR., ;702740,, DBR1, DBR2, ... <- C(E, E+1, ...) +SPM=:CONSO .RD., ;702340,, C(E, E+1, ...) <- DBR1, DBR2, ... + ;The format of the block read and written by these + ;two instructions is: + ; (E) DBR1 + ; (E+1) DBR2 + ; (E+2) Quantum timer + ; (E+3) U.JPC (If this ucode supports it) + ; (E+4) E.JPC ( " " ) + ;LPMR resets the cache and page table. + +RDTIM=:CONO .RD., ;= 702200,, C(E, E+1) <- Time +WRTIM=:CONO .WR., ;= 702600,, Time <- C(E, E+1) + ; The time is a 71. bit unsigned number. The bottom + ; 12. bits cannot be set. The bottom 2 bits cannot + ; even be read. It increments at 4.1 MHz. The top + ; 59. bits (the ones you can set) thus measure + ; (almost) milliseconds. The top 69. bits (the + ; ones you can read) thus measure "short" + ; microseconds. The time wraps around every 18. + ; million years. To make the top 59. bits actually + ; measure milliseconds, the clock would have to run + ; at 4.096 MHz. However it -really- -does- run at + ; exactly 4.1 MHz! + +RDINT=:CONI .RD., ;= 702240,, C(E) <- Interval +WRINT=:CONI .WR., ;= 702640,, Interval <- C(E) + ;The interval is a 35. bit number in the same units + ;as the time. At the end of every interval the + ;interval done interrupt occurs (CONI APR, bit + ;1.5). The biggest interval you can set is about 2 + ;hours and 20 minutes. In the DEC microcode the + ;interval is effectively rounded up to the next + ;millisecond, so it is really only worth your while + ;to set the top 23. bits. In the ITS microcode all + ;bits of the interval are signifigant. Although + ;the length of a -single- interval cannot be + ;controlled more accurately than under the DEC + ;microcode, the average time between interval done + ;interrupts should converge to the full 35. bit + ;value. + +RDHSB=:CONSZ .RD., ;= 702300,, C(E) <- HSB base address +WRHSB=:CONSZ .WR., ;= 702700,, HSB base address <- C(E) + ;4.9 Base address is invalid. If this is set + ; nothing will be written anywhere when the + ; machine halts. + ;3.1 - 1.1 Physical address of first location in + ; which to store debugging info when the + ; machine halts. + ;In the ITS microcode, the initial HSB base address + ; is #o500. + ;When the machine halts it stores a halt code in + ; physical location 0 and the PC in location 1. + ; Then if 4.9 is not set (and the machine has not + ; just powered on) the contents of the 2901's + ; registers are dumped in the halt status block, + ; followed by the VMA. + +;;; Halt Codes + + ;CODES 0 TO 77 ARE "NORMAL" HALTS +; POWER=0 ;POWER UP +; HALT=1 ;HALT INSTRUCTION +; CSL=2 ;CONSOLE HALT + ;CODES 100 TO 777 ARE SOFTWARE ERRORS +; IOPF=100 ;I/O PAGE FAIL +; ILLII=101 ;ILLEGAL INTERRUPT INSTRUCTION +; ILLINT=102 ;BAD POINTER TO UNIBUS INTERRUPT VECTOR + ;CODES 1000 TO 1777 ARE HARDWARE ERRORS +; BW14=1000 ;ILLEGAL BWRITE FUNCTION (BAD DROM) +; NICOND 5=1004 ;ILLEGAL NICOND DISPATCH +; MULERR=1005 ;VALUE COMPUTED FOR 10**21 WAS WRONG + +;;; Halt Status Block definition + +IFNDEF HSB, HSB==:500 +HSBMAG=:HSB+0 +HSBPC=:HSB+1 +HSBHR=:HSB+2 +HSBAR=:HSB+3 +HSBARX=:HSB+4 +HSBBR=:HSB+5 +HSBBRX=:HSB+6 +HSBONE=:HSB+7 +HSBEBR=:HSB+10 +HSBUBR=:HSB+11 +HSBMASK=:HSB+12 +HSBFLG=:HSB+13 +HSBPI=:HSB+14 +HSBXWD1=:HSB+15 +HSBT0=:HSB+16 +HSBT1=:HSB+17 +HSBVMA=:HSB+20 + +;;; ITS I/O instructions. + +UBAQ==:1 ; QSK is on Unibus #1 +UBAI==:3 ; Everything else is on Unibus #3 + +IORDI=:710^9 ; C(AC) <- IO(UBAI,,E) +IORDQ=:711^9 ; C(AC) <- IO(UBAQ,,E) +IORD=:712^9 ; C(AC) <- IO(C(E)) +IOWR=:713^9 ; IO(C(E)) <- C(AC) +IOWRI=:714^9 ; IO(UBAI,,E) <- C(AC) +IOWRQ=:715^9 ; IO(UBAQ,,E) <- C(AC) + +IORDBI=:720^9 +IORDBQ=:721^9 +IORDB=:722^9 +IOWRB=:723^9 +IOWRBI=:724^9 +IOWRBQ=:725^9 + +;;; Byte packing and unpacking instructions. + +;;; These are new with microcode 262, but came from DEC. +;;; Variations of BLT that the convert format of each word moved. +;;; These are legal in user mode, too. Good thing DECUUO doesn't use them. +BLTBU=:716^9 ;Source 8-bit bytes, Destination Unibus format +BLTUB=:717^9 ;Source Unibus format, Destination 8-bit bytes + +;;; Future byte packing and unpacking instructions + +;;; =:730^9 +;;; =:731^9 +;;; =:732^9 +;;; =:733^9 +;;; =:734^9 +;;; =:735^9 +;;; =:736^9 +;;; =:737^9 + +;;; Format of ITS page fail word: + +%PF==:1,,525252 ;Left handed bits. +%PFUSR==:400000 ;4.9 Indicates user address space. +%PFNXI==:200000 ;4.8 Nonexistent IO register. +%PFNXM==:100000 ;4.7 Nonexistent memory. +%PFPAR==:040000 ;4.6 Uncorrectable memory error. + ; (AC0 in block 7 has the word unless 4.7 is + ; also set.) + ;4.5 +%PFWRT==:010000 ;4.4 Soft fault reference called for writing. +%PF2.9==:004000 ;4.3 - 4.2 Access bits for referenced page in soft +%PF2.8==:002000 ; fault. +%PFPHY==:001000 ;4.1 Address given was physical. + ;3.9 +%PFIO==:000200 ;3.8 Indicates an IO operation. + ;3.7 + ;3.6 +%PFBYT==:000020 ;3.5 Indicates a byte IO operation. + ;3.4 - 1.1 IO address + ; or + ;3.1 - 1.1 Memory address +$PFPNO==:121000 ;2.9 - 2.2 Virtual page number + +;;; Format of ITS page table entry: + + ;2.9 - 2.8 Access bits + ; 00 Inaccessible + ; 01 Read only + ; 10 Read/Write/First + ; 11 Read/Write +PMAGEM==:020000 ;2.5 Age bit +PMCSHM==:010000 ;2.4 Cache enable bit +PMRCM==:001777 ;2.1 - 1.1 Physical page number + ; (The page table supports 20 bit physical + ; addresses.) +PMUNSD==:146000 ;Unused bits + +;;; UPT Offsets +;;; In non-time sharing and at clock level in ITS UPT=EPT. + +UPTTR1==:421 ;Exec mode arith ovfl trap. +UPTTR2==:422 ;Exec mode pdl ov trap. +UPTTR3==:423 ;Exec mode trap 3 in non-one-proceed microcode. + +UPTUUO==:424 ;MUUO stored here. +UPTUPC==:425 ;MUUO old PC stored here. +UPTUCX==:426 ;MUUO context (from RDUBR (= DATAI PAG,)) stored here. + +;;; 427 ;Unused. + +UPTUEN==:430 ;MUUO new PC obtained from here in exec mode when + ;traps are not enabled. (MUUO as a trap + ;instruction for example.) +UPTUET==:431 ;MUUO new PC obtained from here in exec mode when + ;traps are enabled. + +UPT1PO==:432 ;One-proceed old PC stored here in one-proceed + ;microcode. +UPT1PN==:433 ;One-proceed new PC obtained from here in + ;one-proceed microcode. + +UPTUUN==:434 ;MUUO new PC obtained from here in user mode when + ;traps are not enabled. +UPTUUT==:435 ;MUUO new PC obtained from here in user mode when + ;traps are enabled. + +;;; 436 ;Unused. +;;; 437 ;Unused. + +;;; EPT Locations + +IFNDEF EPT, EPT==:0 ;Absolute location of EPT. + +PI0LOC=:EPT+40 ;PI0LOC+2*PICHN = Address of instr pair for PICHN. +IRP I,,[1,2,3,4,5,6,7] +PI!I!LOC=:PI0LOC+<2*I> +TERMIN + +EPTUIT=:EPT+100 ;EPTUIT+I contains address of the interrupt table + ; for unibus adapter I. Only adapters 1 and 3 ever + ; exist. + +EPTTR1=:EPT+421 ;Exec mode arith ovfl trap. +EPTTR2=:EPT+422 ;Exec mode pdl ov trap. +EPTTR3=:EPT+423 ;Exec mode trap 3 (1 proceed?). + +;;; When EPT = UPT the following are useful to have defined: + +EPTUUO=:EPT+UPTUUO +EPTUPC=:EPT+UPTUPC +EPTUCX=:EPT+UPTUCX +EPTUEN=:EPT+UPTUEN +EPTUET=:EPT+UPTUET +EPT1PO=:EPT+UPT1PO +EPT1PN=:EPT+UPT1PN +EPTUUN=:EPT+UPTUUN +EPTUUT=:EPT+UPTUUT + +;;; In the ITS microcode the three words used to deliver a page fail are +;;; determined from the current interrupt level. At level I, the page fail +;;; word is stored in EPTPFW+<3*I>, the old PC is stored in EPTPFO+<3*I>, +;;; and the new PC is obtained from EPTPFN+<3*I>. If no interrupts are in +;;; progress we just use EPTPFW, EPTPFO and EPTPFN. + +EPTPFW=:EPT+440 ;Page fail word stored here. +EPTPFO=:EPT+441 ;Page fail old PC stored here. +EPTPFN=:EPT+442 ;Page fail new PC obtained from here. + +IRP I,,[1,2,3,4,5,6,7] +EPTP!I!W=:EPTPFW+<3*I> +EPTP!I!O=:EPTPFO+<3*I> +EPTP!I!N=:EPTPFN+<3*I> +TERMIN + +;;; 8080 communication area + +8SWIT0=:30 ;Simulated switch 0. Set by 8080 SH command. +8KALIV=:31 ;Keep Alive & Status. +8CTYIN=:32 ;CTY input. +8CTYOT=:33 ;CTY output. +8KLKIN=:34 ;KLINIK user input word (from 8080). +8KLKOT=:35 ;KLINIK user output word (to 8080). +8RHBAS=:36 ;BOOT RH11 base address. +8QNUM=:37 ;BOOT Unit Number. +8BOOTP=:40 ;Magtape Boot Format and Slave Number. + +;;; 8080 front end (FE) filesystem format + +;;; Disk addresses for the 8080 are stored in 36-bit words in "FE format": +;;; (These fields are larger than those given in the DEC document because +;;; the cylinder field given there is too small! These numbers reflect the +;;; way that the 8080 manipulates 8 bit quantities instead.) +%88==:777700,,177400 +%88CYL==:100,, +$88CYL==:301400,, ; 4.9 - 3.7 Cylinder +%88TRK==:400 +$88TRK==:101000,, ; 2.7 - 1.9 Track +%88SEC==:1 +$88SEC==:001000,, ; 1.8 - 1.1 Sector + +;;; The 8080 looks for the "home sector" on cylinder 0, track 0, sector 1. +;;; If it fails to find it there it tries sector 10. The home sector is +;;; recognized by having SIXBIT /HOM/ in location 0. Location 103 of the +;;; home sector contains an FE format address of the first sector of the +;;; "FE directory", which is 1000 words (4 sectors) long. Odd numbered +;;; locations in the FE directory are not looked at by the 8080. Even +;;; numbered locations contain FE format addresses of the first sector of +;;; the various "FE files". The following are apparently the only FE files +;;; used by the 8080: +88RAM==:2 ; Microcode. Always 6 blocks long. + ; The rest are always 1000 words long. (1/2 block) +88BT==:4 ; Bootstrap used by BT command and autoboot. +88BT1==:6 ; Bootstrap used by BT1 command. +88B2==:12 ; Bootstrap used by B2 command. +88FI0==:22 ; First indirect file. Contains a sequence of + ; 8-bit bytes containing ASCII characters packed + ; backwards and right justified: + ; ------------------------------- + ; | 0's | 4th | 3rd | 2nd | 1st | + ; ------------------------------- + ; The 8080 stops on a zero byte (or perhaps 377?). + ; Lines must be no longer than 80 characters. + ; Lines are separated by a single ^M. + ; + ; Additional indirect files follow. FIn either + ; runs the file at 88FI0+n or at 88FI0+2*n, I can't + ; tell which. + +;;; Note that the only thing described here that doesn't fit inside a +;;; single ITS block is the microcode. All we need from the filesystem are +;;; the first 2 blocks (for the home sector and the alternate home sectors) +;;; and 6 contiguous blocks elsewhere (for the microcode). + +;;; External register addresses + +KSECCS==:100000 ;Memory Status Register (Controller 0) +%KE==:1,,520040 ; Left half bits. Right half unnamed. + ; [R=Read, W=Write, C=Cleared by writing a 1] +%KEHLD==:400000 ; 4.9 Error currently being held [R/C] +%KEUNC==:200000 ; 4.8 Uncorrectable error [R] +%KEREF==:100000 ; 4.7 Refresh error [R/C] +%KEPAR==:040000 ; 4.6 Parity error [R/W] +%KEENA==:020000 ; 4.5 ECC enabled [R] +%KEECC==:017700 ; 4.4 - 3.7 ECC bits [R] +%KEPWR==:000040 ; 3.6 Memory backup power is low [R/C] + ; 3.4 - 1.1 Error address [R] + ; 1.8 - 1.2 Force ECC bits if non-zero [W] + ; 1.1 Disable ECC [W] + +;; The 7 ECC bits are decoded as follows: The top bit is a parity bit for +;; the bottom 6. The bottom 6 are decoded: +;; +;; ECC code: Location of failing bit: +;; +;; 01 ECC 01 bit +;; 02 ECC 02 bit +;; 04 ECC 04 bit +;; 10 ECC 10 bit +;; 20 ECC 20 bit +;; 40 ECC 40 bit +;; 11 - 16 4.9 - 4.4 +;; 21 - 26 4.3 - 3.7 +;; 31 - 36 3.6 - 3.1 +;; 41 - 46 2.9 - 2.4 +;; 51 - 56 2.3 - 1.7 +;; 61 - 66 1.6 - 1.1 + +UBAPAG==:763000 ;(to 763077) UBA Paging RAM (One per Unibus) +UBALEN==:64. ;Length of UBA Paging RAM + ;When read: +%UP==:1,,525377 ; Left half bits. +%UPPAR==:020000 ; 4.5 RAM parity bit +%UPRPW==:010000 ; 4.4 Force read-pause-write +%UP16B==:004000 ; 4.3 Disable upper two bits on Unibus transfers +%UPFST==:002000 ; 4.2 Fast mode enable +%UPVAL==:001000 ; 4.1 Entry is valid +%UPPVL==:000400 ; 3.9 Parity is valid +$UPPAG==:121200,, ; 3.2 - 2.2 ITS page number + ; 2.1 ITS half page + ; 3.2 - 2.1 DEC page number + ;When written: +%UQ==:0,,537777 ; Right half bits +%UQRPW==:400000 ; 2.9 Force read-pause-write +%UQ16B==:200000 ; 2.8 Disable upper two bits on Unibus transfers +%UQFST==:100000 ; 2.7 Fast mode enable +%UQVAL==:040000 ; 2.6 Entry is valid + ; 2.2 - 1.2 ITS page number + ; 1.1 ITS half page + ; 2.2 - 1.1 DEC page number + +UBASTA==:763100 ;UBA Status Register (One per Unibus) + ; [R=Read, W=Write, C=Cleared by writing a 1, + ; *=Cleared by any write] +%UB==:0,,525270 ; Right half bits. +%UBTIM==:400000 ; 2.9 Unibus timeout [R/C] +%UBBAD==:200000 ; 2.8 Bad mem data (on NPR transfer) [R/C] + ; (Master will timeout instead if %UBDXF set) +%UBPAR==:100000 ; 2.7 KS10 bus parity error [R/C] +%UBNXD==:040000 ; 2.6 CPU addressed non-ex device [R/C] +%UBHIG==:004000 ; 2.3 Interrupt request on BR7 or BR6 (high) [R] +%UBLOW==:002000 ; 2.2 Interrupt request on BR5 or BR4 (low) [R] +%UBPWR==:001000 ; 2.1 Power low [R/*] +%UBDXF==:000200 ; 1.8 Disable tranfer on uncorrectable data [R/W] +%UBINI==:000100 ; 1.7 Issue Unibus init [W] +%UBPIH==:000070 ; 1.6 - 1.4 PI level for BR7 or BR6 (high) [R/W] +%UBPIL==:000007 ; 1.3 - 1.1 PI level for BR5 or BR4 (low) [R/W] + +UBAMNT==:763101 ;UBA Maintenance (One per Unibus) + ; 1.2 Spare maintenance bit (?) + ; 1.1 Change NPR address (?) diff --git a/src/kshack/mtboot.176 b/src/kshack/mtboot.176 new file mode 100755 index 00000000..315b6a1d --- /dev/null +++ b/src/kshack/mtboot.176 @@ -0,0 +1,720 @@ +; -*- Mode:MIDAS -*- + +TITLE MTBOOT - Create KS10 bootload tape or file. + ;CStacy, 21 July 1984 + ;(Munged by Alan a great deal since then.) + +; The 8080 front-end reads a tape starting with an optional +; microcode file, and EOF, and a 512 word bootload program +; which is loaded at 1000 and started. +; +; MTBOOT writes a file (to be copied onto a KS10 boot tape after the +; microcode file) containing the SBLK-bootstrap loader followed by SBLK +; files concatenated. Usually the first one is DDT and the second is +; some client program. +; +; OR +; +; MTBOOT will directly write a tape containing a microcode and the boot +; file. + +;;; MTBOOT gets DDT from the file DSK:KSHACK;DDT BIN +;;; MTBOOT gets microcode from the file DSK:KSHACK;GOOD RAM + +IFNDEF $$DBG, $$DBG==0 ;Set for debugging version of bootloader. +IFNDEF $$TPDBG, $$TPDBG==0 ;Set for debugging tape handling +IFNDEF $$SBDBG, $$SBDBG==0 ;Set for debugging SBLK stuff + + +SUBTTL Definitions + +X=0 ;Super temporary. +A=1 ;A-E general purpose. +B=2 +C=3 +D=4 +E=5 +BP=6 ;Buffer pointer. +F=7 ;Flags. +RETRY=10 ;Count disk ops. +Q=11 ;Checksum. +T=12 ;Temporary ACs. +TT=13 +P=17 ;Stack pointer. + +; I/O channels for MTBOOT + +DSKI==1 ;Disk input +OUTCH==2 ;Disk or tape output +TYIC==3 ;Typein +TYOC==4 ;Typeout + +CALL==: +RET==: +NOP=: + +;System call macro +DEFINE SYSCAL OP,ARGS + .CALL [ SETZ ? SIXBIT /OP/ ? ARGS ((SETZ)) ] +TERMIN + + +;Canonical information macro. +DEFINE INFORM A,B +IF1,[ PRINTX /A = B +/] +TERMIN + +;Type out an ascii string. +DEFINE TSTYPE &STRING + MOVEI T,<.LENGTH STRING> + MOVE TT,[440700,,[ASCII STRING]] + SYSCAL SIOT,[%CLIMM,,TYOC ? TT ? T] + .LOSE %LSFIL +TERMIN + +;Type string from BP until null encountered. +DEFINE TYPEBP BPTR + MOVE T,BPTR + ILDB TT,T + JUMPE TT,.+3 + .IOT TYOC,TT + JRST .-3 +TERMIN + + +;Decrement ASCII byte pointer. +DEFINE DECBP C ;Decrement byte pointer. + ADD C,[70000,,] ;Back up the byte pointer. + SKIPGE C ;Did we cross a word boundary? + SUB C,[430000,,1] ; then fix it. +TERMIN + + + +SUBTTL Main Program and Data + +SYSLOS: .VALUE [ASCIZ ":Losage."] + JRST .-1 + +POPJ1: AOS (P) ;Canonical Skip +CPOPJ: POPJ P, ;Return. +DIE: .LOGOUT 1, ;JRST here to die. + +MTBOOT: MOVE P,[-PDLLEN,,PDL-1] ;Init our stack. + PUSHJ P,RFN"RMNAME ;Find name of this machine. + SYSCAL OPEN,[%CLBIT,,<.UAO+%TJDIS> ? %CLIMM,,TYOC ? [SIXBIT /TTY/]] + .LOSE %LSFIL + SYSCAL OPEN,[%CLBIT,,.UAI ? %CLIMM,,TYIC ? [SIXBIT /TTY/]] + .LOSE %LSFIL + SYSCAL CNSGET,[%CLIMM,,TYIC ? %CLOUT,,X ? %CLOUT,,X ;Get TTY caps. + %CLOUT,,X ? %CLOUT,,X ? %CLOUT,,TTYOPT] + .LOSE %LSFIL + .SUSET [.RSNAME,,A] + MOVEM A,INFILE+3 + MOVEM A,KSBOOT+3 + TSTYPE "AKS10 ITS Bootload Generator." + SETZM MAGP + TSTYPE "AWrite a tape? " + PUSHJ P,YORNP + JRST NOTAPE + SETOM MAGP + TSTYPE "ARewind tape first? " + PUSHJ P,YORNP + JRST NOWIND + SYSCAL OPEN,[ [.BII,,OUTCH] ; Can only rewind in input mode... + [SIXBIT /MT0/]] + .LOSE %LSFIL + MOVE A,[OUTCH,,[1,,1]] ; rewind once + .MTAPE A, + .LOSE %LSSYS +NOWIND: SYSCAL OPEN,[ [1000+.BIO,,OUTCH] ; 1000 word records + [SIXBIT /MT0/]] + .LOSE %LSFIL + TSTYPE "AWriting microcode from " + MOVEI B,RAMFIL + MOVE D,[440700,,TYPEIN] + PUSHJ P,RFN"PFN + MOVE D,[440700,,TYPEIN] + TYPEBP D + PUSHJ P,COPY + MOVE A,[OUTCH,,[1,,5]] ; EOF once + .MTAPE A, + .LOSE %LSSYS +NOTAPE: TSTYPE "AInclude DDT? " + SETOM DDTP ;Normally we write DDT + SETOM PRGP ;and some other program. + PUSHJ P,YORNP + SETZM DDTP ;Say not to include DDT. + TSTYPE "AInput file (just press Return if none)? " + PUSHJ P,READER ;Read file name string. + CAIA + JRST [ MOVE D,[440700,,TYPEIN] ;Bp to the filename string. + MOVEI B,INFILE ;Ptr to file block. + PUSHJ P,RFN"RFN ;Parse the file name. + JRST MERGE ] + SETZM PRGP + SKIPN DDTP + JRST [ TSTYPE "AWriting just the loader is useless!" + JRST DIE ] +MERGE: SKIPE MAGP + JRST MERGE0 + MOVEI A,KSBOOT ;Open the output file. + SYSCAL OPEN,[%CLBIT,,.BIO ? %CLIMM,,OUTCH ? 0(A) ? 1(A) ? 2(A) ? 3(A)] + .LOSE %LSFIL +MERGE0: TSTYPE "AWriting 512 word bootstrap loader." + MOVE A,[-1000,,PREBOOT] ;Pointer to bootload program. + .IOT OUTCH,A ;Write out 512 words. + SKIPN DDTP + JRST [ CALL MNSBLK + JRST MERGE1] + TSTYPE "AWriting DDT from " + MOVEI B,DDTBIN + MOVE D,[440700,,TYPEIN] + PUSHJ P,RFN"PFN + MOVE D,[440700,,TYPEIN] + TYPEBP D + PUSHJ P,COPY ;Write out DDT. +MERGE1: SKIPN PRGP + JRST [ CALL MNSBLK + JRST MERGE2] + SETOM CLIENP + TSTYPE "AWriting SBLK program from " + MOVEI B,INFILE + MOVE D,[440700,,TYPEIN] + PUSHJ P,RFN"PFN + MOVE D,[440700,,TYPEIN] + TYPEBP D + PUSHJ P,COPY ;Write out program. +MERGE2: SKIPE MAGP + JRST MERGE3 + SYSCAL RFNAME,[%CLIMM,,OUTCH ? %CLOUT,,KSBOOT + %CLOUT,,KSBOOT+1 ? %CLOUT,,KSBOOT+2 ? %CLOUT,,KSBOOT+3] + .LOSE %LSFIL + TSTYPE "AWrote file " + MOVEI B,KSBOOT + MOVE D,[440700,,TYPEIN] + PUSHJ P,RFN"PFN + MOVE D,[440700,,TYPEIN] + TYPEBP D +MERGE3: .CLOSE OUTCH, + JRST DIE + +;;; Open, gobble, and write out the file specified by B. +COPY: PUSH P,A + PUSH P,B + PUSH P,C + SYSCAL OPEN,[%CLBIT,,.BII ? %CLIMM,,DSKI ? 0(B) ? 1(B) ? 2(B) ? 3(B)] + .LOSE %LSFIL + JRST COPY1 + +COPY2: MOVE B,[-1000,,BUFFER] + .IOT OUTCH,B ;Copy out buffer. +COPY1: SETZM BUFFER ;Freshen buffer. + MOVE C,[BUFFER,,BUFFER+1] + BLT C,BUFFER+1000 + MOVE A,[-1000,,BUFFER] ;Pointer to input buffer + .IOT DSKI,A ;Read max 512 words from file. + CAME A,[-1000,,BUFFER] ; Stop at EOF + JRST COPY2 + .CLOSE DSKI, + POP P,C + POP P,B + POP P,A + RET + +;;; Write minimum SBLK file: +MNSBLK: PUSH P,A + MOVE A,[-3,,[ + JRST 1 + JRST 4,17 + JRST 4,17 + ]] + .IOT OUTCH,A + SETZM BUFFER + MOVE A,[BUFFER,,BUFFER+1] + BLT A,BUFFER+1000 + MOVE A,[-775,,BUFFER] + .IOT OUTCH,A + POP P,A + RET + +;;; Read from TYIC with minimal rubout handling (displays only). +;;; Uses TYPEIN buffer and skips if read something; returns count in A. + +READER: MOVE BP,[440700,,TYPEIN] + SETZM TYPEIN ;Clear typein buffer. + MOVE A,[TYPEIN,,TYPEIN+1] + BLT A,TYPEIN+LTYPEI + SETZ A, ;Keep count in A. +READ1: .IOT TYIC,T + CAIN T,177 ;Rubout deletes chars. + JRST RUBOUT + CAIN T,^D ;^D rubs out a line. + JRST RUBALL + CAIE T,^C ;^C and ^M finish input. + CAIN T,^M + JRST [ MOVEI T,0 + IDPB T,BP ;Tie off ASCIZ string. + SKIPE A ;If we read something + AOS (P) ; Skip + POPJ P, ] ; Return. + AOS A ;Keep count of chars read. + CAILE C,LTYPEI*5. ;Avoid overflowing the buffer. + JRST RUBALL + IDPB T,BP ;Stuff it. + CAIGE T,40 ;No random ctl chars allowed! + JRST [ .IOT TYOC,[^G] + JRST RUBOUT ] + JRST READ1 ;Get another. +RUBALL: TSTYPE " XXX?" + JRST READER ;Flush entire line. + +RUBOUT: SKIPN A ;Something to rubout? + JRST [ .IOT TYOC,[^G] ; No, just beep. + JRST READ1 ] + MOVE T,TTYOPT ;Examine terminal. + TLNE T,%TOERS + JRST [ TSTYPE "X" ;If able, erase from screen + JRST RUBOU1 ] + LDB T,BP ;Else just echo deleted char. + .IOT TYOC,T +RUBOU1: DECBP BP + SOS A + JRST READ1 + + +;;; Y-OR-N-P, skips for Yes. +YORNP: TSTYPE / (Y or N) / + .IOT TYIC,T + CAIN T,40 ;A [SPACE] means yes. + JRST POPJ1 + CAIN T,177 ;A [RUBOUT] means no. + POPJ P, + CAIL T,140 + SUBI T,40 ;Y or N mean the obvious. + CAIN T,"Y + JRST POPJ1 + CAIN T,"N + POPJ P, + .IOT TYOC,[^G] + JRST YORNP ;Maybe obvious not to everybody???? + + + +$$RFN==1 +$$PFN==1 +$$MNAME==1 +.INSRT DSK:SYSENG;RFN + +RSIXTP:: ;Filename parser routines. +PSIXTP: POPJ P, ;No special character processing. + + +;;; Data + +PDLLEN==200 +LTYPEI==20. +LBUFFE==1001 + +TTYOPT: 0 ;TTYOPT word. +MAGP: 0 ;-1 if writing a tape. +DDTP: 0 ;-1 if DDT being written too. +PRGP: 0 ;-1 if program to "merge" with DDT. +CLIENP: 0 ;-1 if hacking client now. +MNAME: 0 ;Name of this ITS. + +PDL: BLOCK PDLLEN ;Stack. +BUFFER: BLOCK 1001 ;Disk buffer. +TYPEIN: BLOCK LTYPEI+1 ;Typein buffer. + +;;; File names. + +KSBOOT: SIXBIT /DSK/ + SIXBIT /KSBOOT/ + SIXBIT />/ + 0 + +INFILE: SIXBIT /DSK/ + SIXBIT /FOO/ + SIXBIT /BIN/ + 0 + +DDTBIN: SIXBIT /DSK/ + SIXBIT /DDT/ + SIXBIT /BIN/ + SIXBIT /KSHACK/ + +RAMFIL: SIXBIT /DSK/ + SIXBIT /GOOD/ + SIXBIT /RAM/ + SIXBIT /KSHACK/ + +CONSTANTS + + +SUBTTL SBLK Bootstrap Loader + +.INSRT KSHACK;KSDEFS + +MEMSIZ=1000000 ;The size of memory. +DDT=MEMSIZ-4000 ;Address of DDT. +JOBSYM=DDT-1 ;-1 if following is invalid. +; DDT-2 ;All symbols ptr. +KILC= DDT-3 ;Initial symbols ptr. +STARTA=DDT-4 ;Start address. + +;Print a string +DEFINE TYPE &STRING + MOVEI T,[ASCIZ STRING] + CALL TYPOUT +TERMIN + +;Type a SIXBIT value +DEFINE 6TYPE LOC + MOVEI T,LOC + CALL TYPSIX +TERMIN + +;Type a number. +DEFINE 8TYPE LOC + MOVE T,LOC + CALL OCTPNT +TERMIN + +;Type a CRLF (sugar macro). +DEFINE TYPECR + CALL CRLF +TERMIN + +; Type character immediate. +DEFINE CTYPE CHAR + MOVEI TT,CHAR + CALL TYO +TERMIN + +;Fatal error macro. +DEFINE ERROR &MSG + JRST [ MOVEI T,[ASCIZ MSG] + JSR BARF ] +TERMIN + +; 1000 --- Start Program +; 1001 --- Lossage PC stored here. +; LOSE --- Horrible PC here. + +IFNDEF ORG, ORG==:1000 ;Location of this bootload program in core (PREBOOT). + +PREBOOT: +OFFSET ORG-. + JRST GO ;Go for it!. + +BARF: 0 ;Errors JSR here + TYPECR + CALL TYPOUT + TYPECR + JRST 4,@BARF + +LOSE: 0 ;Really awful errors JSR here. + JRST 4,@LOSE + +IFN 0,[ + IORD X,MTCS1 ;Store some I/O info in 103-113. + MOVEM X,103 ;MTCS1. + IORD X,MTCS2 + MOVEM X,104 ;MTCS2. + IORD X,MTDS + MOVEM X,105 ;MTDS. + IORD X,MTER + MOVEM X,106 ;MTER1. + SETZM 107 ;Not used. + SETZM 110 ;Not used. + IORD X,IOPAGR + MOVEM X,111 ;UBA page RAM loc 0. + IORD X,IOSTAT + MOVEM X,112 ;UBA status register. + MOVE X,VERSUN + MOVEM X,113 ;Version of this bootloader. +];IFN 0 + +GO: ;; Clear core above and below the loader. Be careful about 8RHBAS + ;; through 8BOOTP. + SETZM ORG+1000 + MOVE A,[ORG+1000,,ORG+1001] + BLT A,777677 ; Don't clobber DSKDMP bootstrap + SETZM 8BOOTP+1 + MOVE A,[8BOOTP+1,,8BOOTP+2] + BLT A,ORG-1 + SETZM 20 + MOVE A,[20,,21] + BLT A,8RHBAS-1 + ;; Clear all AC's and select block 0 +CLRACS: WRUBR ACBLK+0 ; A in block 0 contains count. + MOVEI A,7 ; Start with block 7. +CLRACL: WRUBR ACBLK(A) ; Select next block + SETZI 0, + MOVEI 17,1 + BLT 17,17 ; Clears A iff A already contained 0. + WRUBR ACBLK+0 ; Select block 0 again + SOJGE A,CLRACL ; Go do next? + MOVE P,[-LBOOPD,,BOOPDL-1] ;Init our stack. +MAKIOT: SKIPN A,8RHBAS ;Find 19 bit base addr of tape boot device. + ERROR "RH11 base?" + HLLM A,IOPAGR ;UBA pager this bus. + HLLM A,IOSTAT ;UBA status this bus. + MOVE B,[-NIOWDS,,MTCS1] ;AOBJN to IO words. +MAKIO1: MOVEM A,(B) ;Store unibus addr of tape control register. + ADDI A,2 ;Compute next one. + AOBJN B,MAKIO1 ;Go store them all. +HERALD: TYPE "ITS MTBOOT." + 6TYPE VERSUN + SETZI BP, ; Buffer starts empty. + CALL LODCOD + MOVEM A,START + JRST LOAD3 + +LOAD4: CALL LODSKP +LOAD3: CALL MTIOT + JUMPL A,LOAD4 + CAME A,START + ERROR "Start instruction mismatch" + CALL LODCOD + EXCH A,START ; Consider running second program + CAMN A,[JRST 4,17] ; Was first file the minimal SBLK file? + JRST DONE ; Yes: Run second program + EXCH A,START ; OK, so run first program + MOVE B,JOBSYM + CAIE B,DDT-2 ; Does it look like DDT? + JRST DONE ; No: Just go run it + MOVEM A,STARTA ; This must be DDT, set starting address + TLO B,400000 + MOVEM B,JOBSYM ; and mark symbol table as clobbered + JRST LOAD5 + +LOAD6: CALL LODSYM +LOAD5: CALL MTIOT + JUMPL A,LOAD6 + CAME A,STARTA + ERROR "Start instruction mismatch" +DONE: ;; Clear out loader and start him up. + SETZM ORG + MOVE 15,[ORG,,ORG+1] ; Load AC for BLT. + MOVE 16,[BLT 15,ORG+1777] ; This instruction does the work. + MOVE 17,START ; This is the start instruction. + JRST 16 ; Do it. + +;;; Load a symbol table block or other information block. Enter with first +;;; word already in A. +;;; Clobbers A, B, C and Q. +LODSYM: HRRZ C,A ; C: type of block + JUMPN C,LODSKP + HLRE B,A + ADD B,A + ADDB B,@JOBSYM + HLL B,A + JRST LODBK1 + +;;; Skip over an information block. Enter with first word already in A. +;;; Clobbers A, B and Q. +LODSKP: MOVE B,A ; B: aobjn into hyperspace + MOVE Q,A ; Q: checksum +SKPLUP: ROT Q,1 + CALL MTIOT + ADD Q,A + AOBJN B,SKPLUP + JRST CHKSUM + +;;; Load the code from an SBLK file, returns start instruction in A. +;;; Clobbers A, B, C and Q. +LODCOD: CALL MTIOT ; Get a word + CAME A,[JRST 1] ; End of RDIN cruft? + JRST LODCOD ; No: keep looking. + JRST LODCD1 + +LODCD2: CALL LODBLK ; Loop loading SBLKs +LODCD1: CALL MTIOT + JUMPL A,LODCD2 ; Until start instruction + RET + +;;; Load an SBLK into memory. Enter with first word already in A. +;;; Clobbers A, B, C and Q. +LODBLK: MOVE B,A ; B: aobjn into core +LODBK1: MOVE Q,A ; Q: checksum +LODLUP: ROT Q,1 + HRRZ C,B ; C: destination address + CAIL C,8SWIT0 ; Smashing 8080 area? + CAILE C,8QNUM + CAIA + ERROR "Overwriting 8080 area" + CAIGE C,20 ; Smashing ACs? + ERROR "Overwriting ACs" + CAIL C,ORG ; Smashing loader? + CAILE C,ORG+1777 + CAIA + ERROR "Overwriting loader" + CALL MTIOT ;Get word. + MOVEM A,(B) ;Store it. + ADD Q,A ;Do sum checking. + AOBJN B,LODLUP +CHKSUM: CALL MTIOT ;Read checksum. + CAME A,Q ;Match? + ERROR "Checksum error" + RET + +; Get word from tape (or refill buffer) into A. +MTIOT: JUMPL BP,MTIOT1 ;Jump if buffer contains data + IFN $$TPDBG,CTYPE "% + MOVEI RETRY,20. ;Retry count +READ: CALL MTHAK ;Init tape. + MOVEI A,40001+ ;Page after loader, UBA valid. + IOWR A,IOPAGR ;Map Unibus locations 0-1777 to KS10 mem. + SETZ A, + IOWR A,MTBA + MOVNI A,2000 ;2000 18-bit words = 1000 36-bit words. + IOWR A,MTWC + MOVEI A,71 ;Read forward + IOWR A,MTCS1 + CALL IOWAIT + TRNE A,4 ;Premature tape mark? + ERROR "Unexpected EOF" ; Lose. + IORD A,MTER + TRNE A,176777 ;Tape error--retry + JRST [ SOJL RETRY,[ ERROR "Tape err" ] + CALL MTHAK + MOVNI A,1 ;Backspace one record. + IOWR A,MTFC + MOVEI A,33 + IOWR A,MTCS1 + CALL IOWAIT + JRST READ ] + MOVSI BP,-1000 ;Buffer contains data now + IFN $$TPDBG,CTYPE "$ +MTIOT1: MOVE A,2000(BP) ;Get next word from buffer + AOBJN BP,.+1 ;Advance buffer pointer +IFN $$SBDBG,[ + TYPE "... " + 8TYPE A + MOVEI B,40000. ;Pause about 1/4 sec. + SOJG B,. +]; $$SBDBG + RET + +MTHAK: IFN $$TPDBG,CTYPE "# + MOVEI A,40 ;Hack the tape drive. + IOWR A,MTCS2 + MOVE A,8QNUM + IOWR A,MTCS2 + MOVE A,8BOOTP + IOWR A,MTTC + SETZ A, + IOWR A,MTFC + RET + +IOWAIT: IORD A,MTDS ;Wait for IO completion. + TRNN A,20000 ;Wait if positioning in progress + TRNN A,200 ;Wait until drive ready + JRST IOWAIT + RET + +;Hand TT to 8080 for printing. +TYO: ANDI TT,177 ;Remove crap. + TRO TT,400 ;Set CTY-character-pending + MOVEM TT,8CTYOT ;Store in comm area + CONI TT ;Read 8080 + TRO TT,80INT ;Hey you! Get this! + CONO (TT) ;Interrupt 8080 + SKIPE 8CTYOT ;Wait for completion + JRST .-1 + RET + +IFN 0,[ +;Wait for console char TT from the 8080. +TYI: SKIPN TT,8CTYIN ;Chars stored here by 8080. + RET + SETZM 8CTYIN ;Remember to clear it. + ANDI TT,177 ;Remove crap. + RET +]; 0 + +;Type Newline. +CRLF: MOVEI TT,15 + CALL TYO + MOVEI TT,12 + CALL TYO + RET + +;Type SIXBIT from T. +TYPSIX: HRLI T,440600 + MOVEI X,6 +TYPSI1: ILDB TT,T + JUMPE TT,TYPSIZ + ADDI TT,40 + CALL TYO + SOJG X,TYPSI1 +TYPSIZ: RET + +;Type ASCIZ from T. +TYPOUT: HRLI T,440700 +TYPOUL: ILDB TT,T + JUMPE TT,TYPOUZ + CALL TYO + JRST TYPOUL +TYPOUZ: RET + +;Type octal number from T. +OCTPNT: SETZ TT, + LSHC T,-3 ;shift instead of IDIVI, don't forget + LSH TT,-41 ;negative! + PUSH P,TT ;push remainder + SKIPE T ;done? + CALL OCTPNT ;no compute next one +OCTPN1: POP P,TT ;yes, take out in opposite order + ADDI TT,60 ;make ascii + CALL TYO + RET ;and return for the next one. + +;;; WRUBR ACBLK+N selects AC block N as current and previous. +ACBLK: REPEAT 8, <400000+<1100*.RPCNT>>,,0 + +; Data +LBOOPD==20. + +VERSUN: .FNAM2 ; Loader version. +BOOPDL: BLOCK LBOOPD ; The stack. +START: 0 ; Start instruction. + +;;; Table of I/O addresses +MTCS1: 0 +MTWC: 0 +MTBA: 0 +MTFC: 0 +MTCS2: 0 +MTDS: 0 +MTER: 0 +MTAS: 0 +MTCK: 0 +MTDB: 0 +MTMR: 0 +MTDT: 0 +MTSN: 0 +MTTC: 0 +NIOWDS==:.-MTCS1 + +IOPAGR: UBAPAG +IOSTAT: UBASTA + +VARIABLES +CONSTANTS + +IF1,[ PRINTX / +Bootstrap loader / + .TYO6 .FNAM2 ] +INFORM [, length]\.-1000 +IFG .-2000, .FATAL Bootstrap loader doesn't fit in 512 words. + +BLOCK 1000 ;Pad the loader. + -1 ;Force core to exist. + +OFFSET 0 + +END MTBOOT