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

unix.superglobalmegacorp.com

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