mirror of
https://github.com/PDP-10/its.git
synced 2026-01-28 12:59:20 +00:00
Build MTBOOT.
This commit is contained in:
561
src/kshack/ksdefs.193
Executable file
561
src/kshack/ksdefs.193
Executable file
@@ -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 (?)
|
||||
720
src/kshack/mtboot.176
Executable file
720
src/kshack/mtboot.176
Executable file
@@ -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==:<PUSHJ P,>
|
||||
RET==:<POPJ P,>
|
||||
NOP=:<TRN>
|
||||
|
||||
;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+<org/1000> ;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
|
||||
Reference in New Issue
Block a user