2.11BSD/sys/pdpstand/mtboot.s
/*
* Primary tape boot program to load and execute secondary boot.
*
* 1995/05/31 - unit number changed to be in bits 3-5 of 'bootdev'
*
* This is a universal tape boot which can handle HT, TM, TS and TMSCP
* tapes. This boot is FULL. Some of the more extended error
* checking had to be left out to get all the drivers to fit.
*
* Two copies of the primary boot are stored in the first and second records
* of the first tape file (some boot proms execute the second one when
* booting a tape). The secondary boot is also stored in the first tape
* file, starting at record #3.
*
* Also note that the struct exec header must be removed from this bootstrap.
* This needs to be done so taking the address of the tape read and rewind
* functions will work.
*
* Due to size constraints and the rather destructive way in which
* all the registers are used, this boot does not support the
* "jsr pc,0; br restart" convention.
*/
NEWLOC = [48.*1024.] / we relocate ourselves to this address
OURSIZE = 512. / assume we are up to this size
HT_MAJOR = 0 / major device number from bdevsw[]
TM_MAJOR = 1
TS_MAJOR = 2
TMS_MAJOR = 12.
a_text = 02 / a_text (struct exec) field offset
a_data = 04 / a_data (struct exec) field offset
csr = r5 / saved csr of boot device
tread = r4 / pointer at tread routine
blkcnt = r3 / number of blocks to read
memaddr = r2 / memory location to read into
/ r1 & r0 are junk registers
.. = NEWLOC / so absolute address work ...
start:
nop / DEC boot block standard
br 1f / " " " "
1:
mov $NEWLOC,sp / give ourselves a stack to work with
clr r4
mov sp,r5
mov $OURSIZE\/2,r3 / primary boot size in words
2:
clr OURSIZE(r5) / clear work area (major & TS/MSCP area)
mov (r4)+,(r5)+ / move primary boot to just above
sob r3,2b / the stack
jmp *$3f / bypass the relocation code
3:
mov r0,unit / save unit number
mov r1,csr / save the csr
cmp r1,$172440 / HT is always at this address
beq common / r3 is table index
inc r3 / index for TMSCP
cmp r1,$172522 / is this a TS?
blo common / no - br, likely TMSCP
cmp r1,$172522+[7*4] / is CSR in the TS range?
bhi common / no, is a TMSCP - br
inc r3 / adjust index to TS
mov (r1),r4 / save contents of csr in case of a TM
clr (r1) / poke the controller
/ clr r2 / now we delay
/1:
/ sob r2,1b / time for TS to run diagnostics
2:
tstb (r1) / is controller ready?
bpl 2b / no - br
bit $2000,(r1) / TS "address required" bit
bne common / if a TS - br
mov r4,(r1) / is a TM, restore unit/density select
inc r3 / make TM index
common:
movb table1(r3),major+1 / save major device number to high byte
asl r3 / make a word index
mov table2(r3),tread / fetch read routine address
jsr pc,*table3(r3) / call rewind routine (must preserve r4)
readit:
clr memaddr / load starting at 0
jsr pc,*tread / skip the two copies of this
jsr pc,*tread / program on the tape
clr memaddr / reset memory address
jsr pc,*tread / read first block of boot
mov *$a_text,blkcnt / compute remaining amount to read:
add *$a_data,blkcnt / (a_text + a_data
add $15.,blkcnt / + sizeof(struct exec) + 511
ash $-9.,blkcnt / - 512) [already read one block]
bic $177600,blkcnt / / 512 [[unsigned]]
beq done / already done if == 0 [not likely]
2:
jsr pc,*tread
sob blkcnt,2b
done:
1: / down by sizeof(struct exec)
mov 20(blkcnt),(blkcnt)+ / r3 cleared by loop above
cmp blkcnt,sp
blo 1b
mov csr,r1 / put things where 'boot'
mov unit,r3 / expects them
ash $3,r3 / unit # in bits 3-5
bis major,r3 / the major device to high byte
clr pc / go to location 0 ... no return
/*
* HT tape driver
*/
htcs1 = 0 / offset from base csr
htwc = 2
htba = 4
htfc = 6
htcs2 = 10
htds = 12
hter = 14
httc = 32
RESET = 040
READ = 071
REW = 07
hrrec:
mov memaddr,htba(csr)
mov $-256.,htwc(csr)
mov $READ,(csr) / htcs1
htcmd:
tstb (csr) / controller ready?
bpl htcmd
tst htds(csr) / drive ready?
bpl htcmd
tstb htcs2+1(csr) / any controller errors?
bne ctlerr
bit $!1000,hter(csr) / any drive errors except HTER_FCE?
beq bumpaddr / no, go bump address
ctlerr:
halt
/*
* Rewind tape. This routine is only done once and must preceed any reads.
*/
htrew:
tstb (csr) / controller ready?
bpl htrew / no - go try again
mov htcs2(csr),r1 / boot unit(formatter) number
bic $!7,r1 / only the low bits
mov httc(csr),r0 / save format,slave,density
bic $!3767,r0 / only the bits we're interested in
mov $RESET,htcs2(csr) / reset controller
movb r1,htcs2(csr) / reselect boot unit(formatter)
mov r0,httc(csr) / reselect density/format/slave(drive)
mov $REW,(csr)
br htcmd / join common code
/*
* TM tape driver
*/
tmer = -2 / offset from base csr
tmcs = 0
tmbc = 2
tmba = 4
tmdb = 6
tmrd = 10
tmmr = 12
tmrrec:
mov $-512.,tmbc(csr) / bytecount
mov memaddr,tmba(csr) / bus address
mov $3,r1 / 'read'
tmcmd:
mov (csr),r0
bic $!63400,r0 / save the density and unit
bis r1,r0 / merge in the function code
mov r0,(csr) / tmcs - give command
/1:
/ bit $100,tmer(csr) / unit still selected? (TMER_SELR)
/ beq ctlerr / nope, go halt
/ bit $1,tmer(csr) / unit ready? (TMER_TUR)
/ beq 1b / no, keep waiting
tmtscom:
bit $100200,(csr) / error or ready?
beq tmtscom / neither, keep looking
bmi ctlerr / error - go halt
bumpaddr:
add $512.,memaddr
rts pc
/*
* Rewind tape.
* Side effects:
* just what the first line says ...
*/
tmrew:
mov $17,r1 / 'rewind'
br tmcmd / join common code
/*
* TS tape driver
*/
tsdb = -2 / offset from ROM supplied address
tssr = 0
TSCHAR = 140004
TSREW = 102010
TSREAD = 100001
tsrrec:
mov $tsdbuf+6,r0
mov $512.,(r0)
clr -(r0)
mov memaddr,-(r0)
mov $TSREAD,-(r0)
mov r0,tsdb(csr)
br tmtscom
/*
* Rewind and initialize tape - only done once.
* Side effects:
* just what the first line says ...
*/
tsrew:
mov $tsdbuf,tsdb(csr)
br tmtscom / go join common code
.if [.-start]&2
.blkb 2 / tsdbuf must be on a mod 4 boundary
.endif
tsdbuf:
TSCHAR / command
tsdbuf+10 / buffer address (lo)
0 / buffer address (hi - always 0)
10 / length of command buffer
/ from here on is used only at initialization/rewind time. The Set
/ Charactistics command only looks at the word following the buffer length,
/ part of the TMSCP code is used as the remainder of the characteristics packet.
tsdbuf+10 / buffer address (lo)
0 / buffer address (hi - always 0)
16 / minimum length packet
0 / characteristics to set (lo byte)
/*
* Copyright (c) Digital Equipment Corporation 1984, 1985, 1986.
* All Rights Reserved.
* Reference "/usr/src/COPYRIGHT" for applicable restrictions.
*
* ULTRIX-11 Block Zero Bootstrap for TMSCP Magtape
*
* SCCSID: @(#)tkboot.s 3.0 4/21/86
*
* Chung_wu Lee 2/8/85
*
* sms 4/27/91 - merged into universal tape boot
* sms 4/12/91 - saved some more space. the major device number and unit
* number are now passed to the secondary boot along with the csr of
* the booting controller.
*
* Steven M. Schultz (sms@wlv.imsd.contel.com) Aug 20 1990. Port to 2.11BSD
*/
s1 = 4000
go = 1
/ TK initialization (and rewind) - only done once
tkrew:
clr (csr)+ / start tk init sequence
/ move pointer to tksa register
mov $s1,r0 / set tk state test bit to step 1
mov $cmdtbl,r1 / address of init seq table
2:
tst (csr) / error ?
bmi . / yes, hang - can't restart !!!
bit r0,(csr) / current step done ?
beq 2b / no
mov (r1)+,(csr) / yes, load next step info from table
asl r0 / change state test bit to next step
bpl 2b / if all steps not done, go back
/ r0 now = 100000, TK_OWN bit
mov $400,cmdhdr+2 / tape VCID = 1
mov $36.,cmdhdr / command packet length
/ don't set response packet length,
/ little shakey but it works.
/ unit is already loaded at tkcmd+4
mov $11,tkcmd+8. / on-line command opcode
mov $20000,tkcmd+10. / set clear serious exception
mov $ring,r2 / initialize cmd/rsp ring
mov $tkrsp,(r2)+ / address of response packet
mov r0,(r2)+ / set TK owner
mov $tkcmd,(r2)+ / address of command packet
mov r0,(r2)+ / set TK owner
mov -(csr),r0 / start TK polling
3:
jsr pc,tkready
mov $tkcmd+8.,r0
mov $45,(r0)+ / reposition opcode
mov $20002,(r0)+ / set rewind & clear serious exception
clr (r0)+ / clear record/object count
clr (r0)+ / zzz2
clr (r0)+ / clear tape mark count
tkpoll:
mov $100000,ring+2 / set TK owner of response
mov $100000,ring+6 / set TK owner of command
mov (csr),r0 / start TK polling
tkready:
tst ring+2 / wait for response
bmi tkready
tstb tkrsp+10. / does returned status = SUCCESS ?
bne . / no, hang
rts pc
tkread:
mov $tkcmd+8.,r0
mov $41,(r0)+ / read opcode
mov $20000,(r0)+ / set clear serious exception
mov $512.,(r0)+ / byte count
clr (r0)+ / zzz2
mov memaddr,(r0)+ / buffer address
jsr pc,bumpaddr / bump address
br tkpoll / wait for response
cmdtbl:
100000 / TK_ERR, init step 1
ring / address of ringbase
0 / hi ringbase address
go / TK go bit
table1:
.byte HT_MAJOR
.byte TMS_MAJOR
.byte TS_MAJOR
.byte TM_MAJOR
table2:
hrrec
tkread
tsrrec
tmrrec
table3:
htrew
tkrew
tsrew
tmrew
end:
major = NEWLOC+OURSIZE
cmdint = major+2 / TMSCP stuff
rspint = cmdint+2.
ring = rspint+2.
rsphdr = ring+8.
tkrsp = rsphdr+4.
cmdhdr = tkrsp+48.
tkcmd = cmdhdr+4.
unit = tkcmd+4