Annotation of researchv10no/sys/boot/bb/obblock.s, revision 1.1.1.1

1.1       root        1: #
                      2: # device-independent boot block
                      3: # uses the rom device driver
                      4: # reads an already-de-headered, small file with predetermined name
                      5: # into the beginning of memory
                      6: # and executes it
                      7: #
                      8: # buffering:
                      9: # the ROM driver will only write into the bottom 64K of memory
                     10: # to make things simple, we always read to a fixed place,
                     11: # then copy to the desired place.
                     12: # if we would have read to the fixed place,
                     13: # we copy to a safe buffer, and copy back when we're all done.
                     14: # the same subterfuge is needed to avoid overwriting the in-RAM copy
                     15: # of the boot ROMs, where our device driver lives,
                     16: # so we use the memory just below the ROM copy for the buffer
                     17: #
                     18:        .set    BSIZE,512       # size of a disk block, according to rom driver
                     19:        .set    BSHIFT,9
                     20:        .set    BUFADDR,0xfa00-BSIZE    # where to read stuff
                     21:        .set    BUFSIZE,1024+BSIZE      # sizeof(buffer) + sizeof(roms)
                     22: 
                     23:        .set    NAMELEN,14      # number of chars in name; one element for now
                     24:        .set    HIADDR,0x70000  # high address at which we run
                     25: 
                     26:        .set    REGMASK,0xef    # registers to save for second boot
                     27:        .set    SVSIZE,7*4
                     28:        .set    SADR,0          # r0 -- overwritten with start addr
                     29:        .set    SR1,(1*4)       # offsets in save area
                     30:        .set    SR3,(3*4)
                     31:        .set    SFLGS,(4*4)     # boot flags -- r5
                     32:        .set    DRIVER,(5*4)    # where device driver addr gets saved -- r6
                     33: 
                     34:        .set    A_MAGIC,0       # offset in exec hdr: magic number
                     35:        .set    A_TEXT,4        # text size
                     36:        .set    A_DATA,8        # data size
                     37:        .set    A_ENTRY,20      # start address
                     38: 
                     39:        .set    ISIZE,64        # size of an i-node
                     40:        .set    ISHIFT,6        # same as a shift
                     41:        .set    INOPB,BSIZE/ISIZE
                     42:        .set    ROOTINO,2       # i-number of the root
                     43:        .set    ILBLK,2         # first block of i-list
                     44:        .set    NDIREC,10       # number of direct blocks
                     45:        .set    NINDIR,256      # number of (interesting) indirect blocks
                     46:        .set    NINDBLK,NDIREC+NINDIR
                     47:        .set    I_ADDR,12       # offset to addresses in inode
                     48:        .set    DIRSIZ,14       # chars in filename
                     49: 
                     50:        .set    PGSIZE,1024     # ld's idea of page size -- for 0410 a.out
                     51:        .set    PGSHIFT,10
                     52: 
                     53:        .set    RXCS,32         # console rcv csr
                     54:        .set    RXDB,33         # console rcv data buffer
                     55:        .set    RRDY_B,7        # bit number of ready bit in RXCS
                     56:        .set    TXCS,34         # console xmt csr
                     57:        .set    TXDB,35         # console xmt data buffer
                     58:        .set    TRDY_B,7        # bit number of ready bit in TXCS
                     59: 
                     60: #
                     61: # main code
                     62: # relocate ourselves to high memory
                     63: # read the root directory, and search it for
                     64: # the desired file
                     65: # read that file in
                     66: #
                     67: # start must be at addr 0xc
                     68: #
                     69: 
                     70: beg:
                     71:        brb start;brb start     # 0, 2 valid start addresses
                     72: hiaddr:        .long   HIADDR
                     73: .set didsave,hiaddr+3          # a byte which is 0 when we start
                     74: bufaddr: .long BUFADDR         # handy constant reference
                     75: start:
                     76:        movl    hiaddr,sp       # set up new stack
                     77:        pushr   $REGMASK        # save important boot registers
                     78:        movl    sp,r11          # remember where they are
                     79:        movc3   $end,beg,SVSIZE(sp)     # copy us up
                     80:        jmp     strel+SVSIZE(sp)
                     81: 
                     82: bootname:
                     83:        .byte   'u,'n,'i,'x,0,0,0,0,0,0,0,0,0,0
                     84: 
                     85: 
                     86: #
                     87: # print a character on the console from r1
                     88: #
                     89: 
                     90: putc:
                     91:        mfpr    $TXCS,r2
                     92:        bbc     $TRDY_B,r2,putc
                     93:        mtpr    r1,$TXDB
                     94:        rsb
                     95: 
                     96: #
                     97: # jump here after relocation
                     98: #
                     99: 
                    100: strel:
                    101:        blbs    SFLGS(r11),stask        # boot flag 1 == prompt for filename
                    102:        movab   bootname,r0
                    103: 0:     movzbl  (r0)+,r1
                    104:        beql    prnl
                    105:        bsbb    putc
                    106:        brb     0b
                    107: 
                    108: stask:
                    109:        movl    r11,sp          # in case we loop back
                    110: 
                    111: #
                    112: # read a string from the console into bootname
                    113: # terminated by newline
                    114: #
                    115: 
                    116: getpr:
                    117:        movzbl  $'*,r1          # prompt
                    118:        bsbb    putc
                    119: 
                    120: getname:
                    121:        movab   bootname,r3
                    122:        movzbl  $NAMELEN-1,r0
                    123: 0:     mfpr    $RXCS,r1
                    124:        bbc     $RRDY_B,r1,0b
                    125:        mfpr    $RXDB,r1
                    126:        bicb2   $0200,r1
                    127:        bsbb    putc
                    128:        cmpb    $015,r1
                    129:        beql    8f
                    130:        cmpb    $040,r1         # ignore control chars; thanks, nautilus
                    131:        bgtr    0b
                    132:        decl    r0
                    133:        blss    0b
                    134:        movb    r1,(r3)+
                    135:        brb     0b
                    136: 8:     clrb    (r3)+
                    137:        sobgtr  r0,8b
                    138: prnl:  movzbl  $015,r1
                    139:        bsbb    putc
                    140:        movzbl  $012,r1
                    141:        bsbb    putc    # and return
                    142: 2:
                    143: #
                    144: # get the root i-node
                    145: #
                    146:        movl    $ROOTINO,r0
                    147:        bsbb    iget
                    148: #### check is directory?
                    149:        movab   -NINDBLK*4(sp),sp
                    150:        movl    sp,r10
                    151:        bsbb    addrcpy
                    152: #
                    153: # search the root directory
                    154: #
                    155: 
                    156:        clrl    r12                     # init block pointer
                    157: dirblk:
                    158:        clrl    r5                      # use beginning of mem as buffer
                    159:        bsbw    lread
                    160:        bneq    stask                   # eof, try another file
                    161:        clrl    r9
                    162: 0:
                    163:        movzwl  (r9)+,r0                # empty entry?
                    164:        beql    2f                      # yes, skip it
                    165:        clrl    r1
                    166: 1:     cmpb    (r9)[r1],bootname[r1]   # MicroVAX II doesn't have cmpc
                    167:        bneq    2f
                    168:        aoblss  $DIRSIZ,r1,1b
                    169:        brb     diryes                  # the name we want
                    170: 
                    171: 2:     acbw    $FSBSIZE-1,$DIRSIZ,r9,0b
                    172:        incl    r12                     # get next block
                    173:        brb     dirblk
                    174: 
                    175: berr:  brb     stask
                    176: 
                    177: #
                    178: # subroutines placed here, out of sequence, to save space
                    179: #
                    180: # copy/convert block numbers
                    181: # out of an i-node
                    182: # r10 points to where we want them
                    183: # r0 points to the i-node
                    184: # for now, only the direct blocks
                    185: #
                    186: # r0 is destroyed
                    187: #
                    188: 
                    189: addrcpy:
                    190:        movl    r10,r1                  # make a volatile copy
                    191:        addl2   $I_ADDR,r0              # point to addresses
                    192:        clrl    r2
                    193: 0:
                    194:        movw    (r0)+,(r1)+
                    195:        movzbw  (r0)+,(r1)+
                    196:        aoblss  $NDIREC+1,r2,0b
                    197:        rsb
                    198: 
                    199: #
                    200: # fetch an i-node
                    201: # r0 has the i-number
                    202: # on exit, r0 points to the i-node in core
                    203: # address 0 is used as a buffer
                    204: #
                    205: 
                    206: iget:
                    207:        decl    r0                      # i-numbers are 1 based
                    208:        clrl    r1                      # make a quadword
                    209:        ediv    $INOPB,r0,r8,-(sp)      # r8 == block; (sp) == offset
                    210:        addl2   $ILBLK*FSBSIZE/BSIZE,r8
                    211:        clrl    r5                      # into address 0
                    212:        bsbb    bread
                    213:        ashl    $ISHIFT,(sp)+,r0        # point to i-node
                    214:        rsb
                    215: 
                    216: #
                    217: # read a BSIZE block from the disk
                    218: # using the rom subroutine
                    219: # block number in r8;
                    220: # buffer address in r5
                    221: # no return if it failed
                    222: #
                    223: # hack: if we would read atop the boot roms, don't;
                    224: # read into a safe place instead, and remember
                    225: # for the purposes of the hack, it's assumed that
                    226: # reads are aligned in memory conveniently
                    227: #
                    228: 
                    229: bread:
                    230:        subl3   bufaddr,r5,r0
                    231:        blss    0f
                    232:        cmpl    r0,$BUFSIZE
                    233:        bgeq    0f
                    234:         movab  savedata,r5
                    235:         addl2  r0,r5
                    236:         movb   $1,didsave
                    237: 0:
                    238:        pushl   r5              # save real addr
                    239:        movl    bufaddr,r5      # get buffer loc
                    240:        movq    SR1(r11),r1     # device address stuff
                    241:        movl    SR3(r11),r3     # unit number
                    242:        pushl   r5              # duplicate address for driver routine
                    243:        jsb     *DRIVER(r11)    # and call driver
                    244:        blbc    r0,berr         # disk error, start over
                    245:        tstl    (sp)+           # fixup stack
                    246:        movc3   $BSIZE,*bufaddr,*(sp)+  # copy data to final resting place
                    247:        rsb
                    248: 
                    249: #
                    250: # back to the main path:
                    251: # found the file
                    252: # fetch its i-node and read it in
                    253: # i-number left in r0 for us
                    254: #
                    255: 
                    256: diryes:
                    257:        bsbb    iget
                    258: ##### check i-node?
                    259:        bsbb    addrcpy
                    260: #
                    261: # indirect blocks
                    262: # only the first 1024 bytes of the first indirect block examined
                    263: #
                    264:        mull3   NDIREC*4(r10),$FSBSIZE/BSIZE,r12 # pick up one indirect block
                    265:        beql    noind
                    266:        movl    r12,r8
                    267:        moval   NDIREC*4(r10),r5
                    268:        bsbb    bread
                    269:        addl3   r12,$1,r8               # 2 sectors == 256 indirections
                    270:        moval   NDIREC*4+BSIZE(r10),r5
                    271:        bsbb    bread
                    272: noind:
                    273:        clrl    r5
                    274:        clrl    r12
                    275: rdloop:
                    276:        ashl    $FSSHIFT,r12,r5
                    277:        bsbb    lread
                    278:        bneq    eof
                    279:        incl    r12
                    280:        brb     rdloop
                    281: #
                    282: # whole file read in
                    283: # check for a.out header and relocate
                    284: #
                    285: eof:
                    286:        blbc    didsave,1f
                    287:         movc3  $BUFSIZE,savedata,*bufaddr
                    288: 1:     clrl    r12
                    289:        movq    A_TEXT(r12),r7  # r7 = text size; r8 = data size
                    290:        movl    A_ENTRY(r12),SADR(r11)  # starting address
                    291: 2:     casel   A_MAGIC(r12),$0407,$1
                    292: 0:     .word   m0407-0b
                    293:        .word   m0410-0b
                    294:        clrl    SADR(r11)       # no a.out, start at the top
                    295:        brb     done
                    296: m0407:
                    297:        addl2   r8,r7           # text = text + data; no data
                    298:        clrl    r8
                    299: #
                    300: # do copies by longword: simpler and smaller than movc3,
                    301: # which would need to loop anyway
                    302: # longword not quadword because ld rounds sizes to long
                    303: #
                    304: # really should beql after the second div, else when there's no data
                    305: # we copy one extra word to a nonsense place.
                    306: # too bad; we can't spare the code space
                    307: #
                    308: m0410:
                    309:        clrl    r0
                    310:        movzbl  $32,r1
                    311:        addl3   r7,r8,r2
                    312:        divl2   $4,r2
                    313: 1:     movl    (r1)+,(r0)+     # copy down over a.out header
                    314:        sobgtr  r2,1b
                    315:        divl3   $4,r8,r2
                    316:        addl3   r8,r7,r1        # from t + d
                    317:        extzv   $0,$PGSHIFT,r7,r0
                    318:        beql    0f              # don't overround
                    319:         subw3  r0,$PGSIZE,r0
                    320: 0:     addl2   r1,r0           # to t + d + round
                    321: 2:     movl    -(r1),-(r0)     # copy data to start at page boundary
                    322:        sobgtr  r2,2b
                    323: #
                    324: # reset registers and start
                    325: #
                    326: 
                    327: done:
                    328:        movl    r11,sp
                    329:        popr    $REGMASK
                    330:        movl    r5,r11          # put boot flags in stupid bky place
                    331:        jmp     2(r0)           # skip register mask & start it
                    332: 
                    333: #
                    334: # read a (filesystem) block from a file
                    335: # (filesystem) block number in r12
                    336: # buffer address in r5
                    337: # r10 points to the addresses
                    338: # returns status in psw:
                    339: # zero flag set if read a block
                    340: # clear if error or block doesn't exist
                    341: #
                    342: 
                    343: lread:
                    344:        cmpw    r12,$NINDBLK
                    345:        blss    0f
                    346: lerr:
                    347:        bicpsw  $4              # clear zero flag
                    348:        rsb
                    349: 0:
                    350:        movl    (r10)[r12],r8
                    351:        beql    lerr
                    352:        pushl   $FSBSIZE/BSIZE  # count of disk blocks within fs block
                    353:        mull3   $FSBSIZE/BSIZE,r8,-(sp) # fs block to disk block
                    354: 1:
                    355:        movl    (sp),r8
                    356:        movl    r5,r6           # safe place
                    357:        bsbw    bread
                    358:        movab   BSIZE(r6),r5
                    359:        incl    (sp)
                    360:        sobgtr  4(sp),1b
                    361:        clrq    (sp)+           # addl2 $8,sp; set zero bit
                    362:        rsb
                    363: #
                    364: # last address that needs saving
                    365: #
                    366:        .globl end
                    367: end:
                    368: 
                    369: #
                    370: # put uninitialized (not 0) data here
                    371: #
                    372:        .align  2
                    373: savedata:
                    374: #      .space  ROMSIZE

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.