mirror of
https://github.com/wfjm/w11.git
synced 2026-01-13 15:37:43 +00:00
- tools/mcode - *.mac: use call/return - (lp11|pc11)write: check line count after last char is accepted - pc11copy: kw11-p: use 100 kHz/13.; ensure last puncher interrupt - *.scmd: add SimH startup files when reasonable - tools/simh/setup_w11a_(max|min).scmd: enable pclk
361 lines
13 KiB
Plaintext
361 lines
13 KiB
Plaintext
; $Id: bootw11.mac 1275 2022-08-10 08:10:40Z mueller $
|
|
; SPDX-License-Identifier: GPL-3.0-or-later
|
|
; Copyright 2019-2022 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
;
|
|
; Revision History:
|
|
; Date Rev Version Comment
|
|
; 2022-08-09 1275 1.0.2 use call/return
|
|
; 2022-05-14 1237 1.0.1 BUGFIX: proper init of unit number in getnam
|
|
; 2019-05-01 1143 1.0 Initial version
|
|
; 2019-04-19 1133 0.1 First draft
|
|
;
|
|
; current ROM usage
|
|
; low 165000 to 165770 --> 503 bytes base + RK11 + RL11 + RH70
|
|
; high 173000 to 173312 --> 202 bytes TM11 + PC11
|
|
;
|
|
; definitions ----------------------------------------------
|
|
;
|
|
.include |lib/defs_cpu.mac|
|
|
.include |lib/defs_dl.mac|
|
|
|
|
lorom = 165000
|
|
hirom = 173000
|
|
;
|
|
CR = 015
|
|
LF = 012
|
|
;
|
|
; low rom area #############################################
|
|
;
|
|
. = lorom
|
|
|
|
start: spl 7
|
|
mov #160000,sp ; default stack
|
|
mov @#cp.los,r0 ; get memory size in clicks
|
|
cmp r0,#1600 ; > 56k
|
|
bhis 1$ ; if his yes, use 160000
|
|
inc r0 ; otherwise sp=(los+1)<<6
|
|
ash #6,r0
|
|
mov r0,sp
|
|
1$:
|
|
;
|
|
; print prompt
|
|
;
|
|
mov #strpro,r1
|
|
nxtpro: call prtstr
|
|
;
|
|
; read boot device name and unit
|
|
; out r2 device name
|
|
; out r3 unit number
|
|
;
|
|
getnam: call getlet ; get 1st char
|
|
mov r0,r2 ; move into low byte
|
|
call getlet ; get 2nd char
|
|
swab r0
|
|
bis r0,r2 ; move into high byte
|
|
clr r3 ; default unit is 0
|
|
call getchr ; get unit number or <CR>
|
|
cmp #CR,r0 ; is <CR> ?
|
|
beq fnddev ; if eq yes, done
|
|
mov r0,r3
|
|
sub #'0,r3 ; convert ascii to binary
|
|
blt errpro ; below 0, error quit
|
|
cmp r3,#7 ; check 0-7 range
|
|
bgt errpro ; above 7, error quit
|
|
call prtchr ; echo character
|
|
call getchr ; get <CR>
|
|
cmp #CR,r0 ; is <CR> ?
|
|
bne errpro
|
|
;
|
|
; find boot loader
|
|
; in r2 device code
|
|
; in r3 unit number
|
|
; use r0,r1,r4
|
|
;
|
|
fnddev: mov #devtbl,r4
|
|
1$: tst (r4) ; end of list ?
|
|
beq errpro ; if eq yes, error quit
|
|
cmp (r4)+,r2 ; match ?
|
|
beq 2$ ; if eq yes
|
|
cmp (r4)+,(r4)+ ; skip two words
|
|
br 1$ ; and try next device in table
|
|
2$: cmp r3,(r4)+ ; is unit number in range ?
|
|
bgt errpro ; if gt not, error quit
|
|
mov #strnl,r1 ; print <CR><LF>
|
|
call prtstr
|
|
mov r3,r0 ; get unit to r0
|
|
jmp @(r4)+ ; and execute boot code
|
|
|
|
;
|
|
errpro: mov #strerr,r1 ; point to error string
|
|
br nxtpro
|
|
;
|
|
; getlet: read drive name letter ---------------------------
|
|
; out r0 character (only A-Z, other error quit)
|
|
;
|
|
getlet: call getchr
|
|
cmp r0,#'Z ; above Z ?
|
|
ble 1$ ; if le not
|
|
sub #<'a-'A>,r0 ; otherwise convert to upper
|
|
1$: cmp r0,#'A ; below A ?
|
|
blt 2$ ; if lt yes, error quit
|
|
cmp r0,#'Z ; above Z ?
|
|
bgt 2$ ; if gt yes, error quit
|
|
call prtchr ; echo character
|
|
return
|
|
2$: tst (sp)+ ; drop return address
|
|
br errpro ; error quit
|
|
;
|
|
; getchr: read character routine ---------------------------
|
|
; out r0 character
|
|
;
|
|
getchr: tstb @#ti.csr ; wait ti ready
|
|
bpl getchr
|
|
mov @#ti.buf,r0 ; and read character
|
|
return
|
|
;
|
|
; prtstr: print string routine -----------------------------
|
|
; in r1 pointer to zero terminated string
|
|
; use r0
|
|
;
|
|
prtstr: movb (r1)+,r0 ; get next char
|
|
beq prtrts ; if eq return
|
|
call prtchr ; else print char
|
|
br prtstr ; and go for next
|
|
;
|
|
; prtchr: print character routine --------------------------
|
|
; in r0 character to be printed
|
|
;
|
|
prtchr: tstb @#to.csr ; wait to ready
|
|
bpl prtchr
|
|
movb r0,@#to.buf ; and print
|
|
prtrts: return
|
|
;
|
|
; rstoff: reset/restart after unit offline detected --------
|
|
;
|
|
rstoff: reset
|
|
spl 7
|
|
mov #stroff,r1 ; load string pointer
|
|
br nxtpro ; and go for error re-prompt
|
|
;
|
|
stroff: .ascii /off/ ; to print "off?\n@"
|
|
strerr: .ascii /?/ ; to print "?\n@"
|
|
strpro: .asciz <CR><LF>/@/ ; to print "\n@"
|
|
strnl: .asciz <CR><LF> ; to print "\n"
|
|
.even
|
|
;
|
|
; device descriptor table ----------------------------------
|
|
;
|
|
devtbl: .word "DK, 7, bootrk ; "DK --> RK11/RK05 boot
|
|
.word "DL, 3, bootrl ; "DL --> RL11/RL02 boot
|
|
.word "DB, 3, bootrp ; "DB --> RH70/RP06 boot
|
|
.word "MT, 3, boottm ; "MT --> TM11 boot
|
|
.word "PR, 0, bootpc ; "PR --> PC11 boot
|
|
.word 0
|
|
;
|
|
; common boot exit -----------------------------------------
|
|
;
|
|
bootgo: clr r2 ; why ?
|
|
clr r3 ; why ?
|
|
clr r4 ; why ?
|
|
clr r5 ; why ?
|
|
clr pc
|
|
;
|
|
; RK11 boot loader +++++++++++++++++++++++++++++++++++++++++
|
|
; RK boot loader code adapted from simh project
|
|
;
|
|
.include |lib/defs_rk.mac|
|
|
;
|
|
bootrk: mov r0,r3
|
|
ash #13.,r3
|
|
mov r3,@#rk.da ; load da with unit number
|
|
tstb @#rk.ds ; drive ready ?
|
|
bmi 1$ ; if mi, ready
|
|
jmp rstoff ; else offline fail
|
|
1$: clr @#rk.ba ; clear ba
|
|
mov #-512.,@#rk.wc ; set wc (2 blocks)
|
|
mov #rk.cs,r1
|
|
mov #<rk.frd!rk.go>,(r1) ; start read
|
|
2$: tstb (r1) ; wait ready
|
|
bpl 2$
|
|
tst @#rk.er ; did read succeed ?
|
|
beq 3$ ; if eq yes
|
|
halt ; else halt
|
|
3$: clrb (r1)
|
|
jmp bootgo
|
|
;
|
|
; RL11 boot loader +++++++++++++++++++++++++++++++++++++++++
|
|
; RL boot loader code adapted from simh project
|
|
;
|
|
.include |lib/defs_rl.mac|
|
|
;
|
|
bootrl: mov r0,r3
|
|
swab r3
|
|
mov #rl.cs,r1
|
|
mov #13,4(r1) ; clr err
|
|
bis #rl.fgs,r3 ; unit+gstat
|
|
mov r3,(r1) ; issue cmd
|
|
1$: tstb (r1) ; wait
|
|
bpl 1$
|
|
mov 6(r1),r2 ; inspect status
|
|
bit #<rl.dse!rl.co>,r2 ; select error or cover open ?
|
|
beq 2$ ; if eq not
|
|
jmp rstoff ; else offline fail
|
|
2$: clrb r3
|
|
bis #rl.frh,r3 ; unit+rdhdr
|
|
mov r3,(r1) ; issue cmd
|
|
3$: tstb (r1) ; wait
|
|
bpl 3$
|
|
mov 6(r1),r2 ; get hdr
|
|
bic #077,r2 ; clr head+sector
|
|
inc r2 ; magic bit
|
|
mov r2,4(r1) ; seek to 0
|
|
clrb r3
|
|
bis #rl.fse,r3 ; unit+seek
|
|
mov r3,(r1) ; issue cmd
|
|
4$: tstb (r1) ; wait
|
|
bpl 4$
|
|
clr 2(r1) ; clr ba
|
|
clr 4(r1) ; clr da
|
|
mov #-512., 6(r1) ; set wc
|
|
clrb r3
|
|
bis #rl.frd,r3 ; unit+read
|
|
mov r3, (r1) ; issue cmd
|
|
5$: tstb (r1) ; wait
|
|
bpl 5$
|
|
tst (r1) ; did read succeed ?
|
|
bpl 6$ ; if pl yes (cs.err = 0)
|
|
halt ; else halt
|
|
6$: bic #377, (r1)
|
|
jmp bootgo
|
|
;
|
|
; RH70 boot loader +++++++++++++++++++++++++++++++++++++++++
|
|
; RH70 boot loader code adapted from simh project
|
|
;
|
|
.include |lib/defs_rp.mac|
|
|
;
|
|
bootrp: mov #rp.cs1,r1 ;
|
|
mov #rp.clr,@#rp.cs2 ; #CS2_CLR
|
|
mov r0,@#rp.cs2 ; set unit
|
|
tstb @#rp.ds ; check drive ready
|
|
bmi 1$ ; if mi yes
|
|
jmp rstoff ; else offline fail
|
|
1$: mov #<rp.frp!rp.go>,(r1) ; #RIP+GO: pack ack
|
|
mov #rp.f16, @#rp.of ; #FMT16B: 16b mode
|
|
mov #-512., @#rp.wc ; set wc
|
|
clr @#rp.ba ; clr ba
|
|
clr @#rp.da ; clr da
|
|
clr @#rp.dc ; clr cyl
|
|
mov #<rp.frd!rp.go>,(r1) ; read
|
|
2$: tstb (r1) ; wait
|
|
bpl 2$
|
|
tst @#rp.ds ; did read succeed ?
|
|
bpl 3$ ; if pl yes (ds.ata = 0)
|
|
halt ; else halt
|
|
3$: clrb (r1)
|
|
jmp bootgo
|
|
;
|
|
; high rom area ############################################
|
|
;
|
|
. = hirom
|
|
;
|
|
; TM11 boot loader +++++++++++++++++++++++++++++++++++++++++
|
|
; TM boot loader code adapted from simh project
|
|
;
|
|
.include |lib/defs_tm.mac|
|
|
boottm: mov #tm.cr,r1 ; load csr
|
|
mov r0,r2
|
|
swab r2
|
|
mov r2,(r1) ; load unit number to cr
|
|
bit #tm.onl,@#tm.sr ; is unit online ?
|
|
bne 1$ ; if ne yes
|
|
jmp rstoff ; else offline fail
|
|
1$: clr @#tm.ba ; tmba = 0
|
|
mov #-1,@#tm.bc ; tmbc = -1
|
|
bis #<tm.d98!tm.fsf!tm.go>,r2
|
|
mov r2,(r1) ; tmcr = space + go
|
|
2$: tstb (r1) ; test tmcr.rdy
|
|
bpl 2$
|
|
mov r0,r2 ; note: tmbc=0 now
|
|
swab r2
|
|
bis #<tm.d98!tm.frd!tm.go>,r2 ; note: tmbc still = 0!
|
|
mov r2,(r1) ; tmcr = read + go
|
|
3$: tstb (r1) ; test tmcr.rdy
|
|
bpl 3$
|
|
tstb #tm.sr+1 ; check upper 8 error bits
|
|
beq 4$ ; if eq, all fine
|
|
halt ; else error halt
|
|
4$: jmp bootgo
|
|
;
|
|
; PC11 boot loader +++++++++++++++++++++++++++++++++++++++++
|
|
; PC boot loader code adapted pc11boot.mac
|
|
;
|
|
.include |lib/defs_pc.mac|
|
|
;
|
|
; register usage
|
|
; r0 byte
|
|
; r1 word
|
|
; r2 checksum
|
|
; r3 addr
|
|
; r4 count
|
|
; r5 #pr.csr
|
|
;
|
|
bootpc: mov #pr.csr,r5
|
|
tst (r5) ; error bit set ?
|
|
bpl pcrec ; if pl no, continue
|
|
jmp rstoff ; otherwise quit offline
|
|
;
|
|
pcrec: clr r2 ; clear checksum
|
|
1$: call pcbyte ; read 000 prefix or 001
|
|
tstb r0 ; is zero ?
|
|
beq 1$ ; if eq yes, keep trying
|
|
dec r0 ; decrement to test for 001
|
|
bne pcerr1 ; if ne, quit
|
|
call pcbyte ; read 000 after 001
|
|
tstb r0 ; is zero ?
|
|
bne pcerr1 ; if ne fail
|
|
call pcword ; read count
|
|
mov r1,r4 ; store count
|
|
call pcword ; read addr
|
|
mov r1,r3 ; store addr
|
|
sub #6,r4 ; subtract 6 from count
|
|
blt pcerr2 ; if <6 fail
|
|
bgt pcdata ; if >6 read data
|
|
call pcbyte ; read checksum
|
|
tstb r2 ; test checksum
|
|
bne pcerr3 ; if ne bad, fail
|
|
bit #1,r3 ; address odd ?
|
|
beq 2$ ; if eq fine, use address
|
|
mov #200,r3 ; else use default start addres
|
|
2$: jmp (r3) ; and start code
|
|
;
|
|
pcerr1: halt ; halt: bad frame
|
|
pcerr2: halt ; halt: bad count
|
|
pcerr3: halt ; halt: bad checksum
|
|
pcerr4: halt ; halt: error bit set
|
|
;
|
|
pcdata: call pcbyte ; read byte
|
|
movb r0,(r3)+ ; store byte
|
|
sob r4,pcdata ; dec count and loop if >0
|
|
call pcbyte ; get checksum
|
|
tstb r2 ; test checksum
|
|
bne pcerr3 ; if ne bad, fail
|
|
br pcrec ; otherwise next record
|
|
|
|
pcword: call pcbyte ; read low byte
|
|
mov r0,r1 ; low byte to r1
|
|
call pcbyte ; read high byte
|
|
swab r0
|
|
bis r0,r1 ; high byte to r1
|
|
return
|
|
|
|
pcbyte: inc (r5) ; set enable
|
|
1$: tst (r5) ; error set ?
|
|
bmi pcerr4 ; if mi yes, fail
|
|
tstb (r5) ; done set ?
|
|
bpl 1$ ; if pl not yet
|
|
mov 2(r5),r0 ; read byte
|
|
add r0,r2 ; accumulate checksum
|
|
return
|
|
;
|
|
.end start
|