Annotation of researchv10dc/sys/boot/bb/okbblock.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    SADR,0          # r0 -- overwritten with start addr
                     28:        .set    SR1,1*4         # offsets in save area
                     29:        .set    SR3,3*4
                     30:        .set    SFLGS,4*4       # boot flags -- r5
                     31:        .set    DRIVER,5*4      # where device driver addr gets saved -- r6
                     32:        .set    SVSIZE,7*4
                     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:        tstw    (r9)                    # empty entry?
                    164:        beql    1f                      # yes, skip it
                    165:        cmpc3   $DIRSIZ,2(r9),bootname  # desired name?
                    166:        beql    diryes                  # yep
                    167: 1:     acbw    $FSBSIZE-1,$DIRSIZ+2,r9,0b
                    168:        incl    r12                     # get next block
                    169:        brb     dirblk
                    170: 
                    171: berr:  brb     stask
                    172: 
                    173: #
                    174: # subroutines placed here, out of sequence, to save space
                    175: #
                    176: # copy/convert block numbers
                    177: # out of an i-node
                    178: # r10 points to where we want them
                    179: # r0 points to the i-node
                    180: # for now, only the direct blocks
                    181: #
                    182: # r0 is destroyed
                    183: #
                    184: 
                    185: addrcpy:
                    186:        movl    r10,r1                  # make a volatile copy
                    187:        addl2   $I_ADDR,r0              # point to addresses
                    188:        clrl    r2
                    189: 0:
                    190:        movw    (r0)+,(r1)+
                    191:        movb    (r0)+,(r1)+
                    192:        clrb    (r1)+
                    193:        aoblss  $NDIREC+1,r2,0b
                    194:        rsb
                    195: 
                    196: #
                    197: # fetch an i-node
                    198: # r0 has the i-number
                    199: # on exit, r0 points to the i-node in core
                    200: # address 0 is used as a buffer
                    201: #
                    202: 
                    203: iget:
                    204:        decl    r0                      # i-numbers are 1 based
                    205:        clrl    r1                      # make a quadword
                    206:        ediv    $INOPB,r0,r8,-(sp)      # r8 == block; (sp) == offset
                    207:        addl2   $ILBLK*FSBSIZE/BSIZE,r8
                    208:        clrl    r5                      # into address 0
                    209:        bsbb    bread
                    210:        ashl    $ISHIFT,(sp)+,r0        # point to i-node
                    211:        rsb
                    212: 
                    213: #
                    214: # read a BSIZE block from the disk
                    215: # using the rom subroutine
                    216: # block number in r8;
                    217: # buffer address in r5
                    218: # no return if it failed
                    219: #
                    220: # hack: if we would read atop the boot roms, don't;
                    221: # read into a safe place instead, and remember
                    222: # for the purposes of the hack, it's assumed that
                    223: # reads are aligned in memory conveniently
                    224: #
                    225: 
                    226: bread:
                    227:        subl3   bufaddr,r5,r0
                    228:        blss    0f
                    229:        cmpl    r0,$BUFSIZE
                    230:        bgeq    0f
                    231:         movab  savedata,r5
                    232:         addl2  r0,r5
                    233:         movb   $1,didsave
                    234: 0:
                    235:        pushl   r5              # save real addr
                    236:        movl    bufaddr,r5      # get buffer loc
                    237:        movq    SR1(r11),r1     # device address stuff
                    238:        movl    SR3(r11),r3     # unit number
                    239:        pushl   r5              # duplicate address for driver routine
                    240:        jsb     *DRIVER(r11)    # and call driver
                    241:        blbc    r0,berr # disk error, start over
                    242:        tstl    (sp)+           # fixup stack
                    243:        movc3   $BSIZE,*bufaddr,*(sp)+  # copy data to final resting place
                    244:        rsb
                    245: 
                    246: #
                    247: # back to the main path:
                    248: # found the file
                    249: # fetch its i-node and read it in
                    250: #
                    251: 
                    252: diryes:
                    253:        movzwl  (r9),r0         # i-number
                    254:        bsbb    iget
                    255: ##### check i-node?
                    256:        bsbb    addrcpy
                    257: #
                    258: # indirect blocks
                    259: # only the first 1024 bytes of the first indirect block examined
                    260: #
                    261:        mull3   NDIREC*4(r10),$FSBSIZE/BSIZE,r12 # pick up one indirect block
                    262:        beql    noind
                    263:        movl    r12,r8
                    264:        moval   NDIREC*4(r10),r5
                    265:        bsbb    bread
                    266:        addl3   r12,$1,r8               # 2 sectors == 256 indirections
                    267:        moval   NDIREC*4+BSIZE(r10),r5
                    268:        bsbb    bread
                    269: noind:
                    270:        clrl    r5
                    271:        clrl    r12
                    272: rdloop:
                    273:        ashl    $FSSHIFT,r12,r5
                    274:        bsbb    lread
                    275:        bneq    eof
                    276:        incl    r12
                    277:        brb     rdloop
                    278: #
                    279: # whole file read in
                    280: # check for a.out header and relocate
                    281: #
                    282: eof:
                    283:        blbc    didsave,1f
                    284:         movc3  $BUFSIZE,savedata,*bufaddr
                    285: 1:     clrl    r12
                    286:        movq    A_TEXT(r12),r7  # r7 = text size; r8 = data size
                    287:        extzv   $0,$30,A_ENTRY(r12),SADR(r11)   # starting address
                    288: 2:     casel   A_MAGIC(r12),$0407,$1
                    289: 0:     .word   m0407-0b
                    290:        .word   m0410-0b
                    291:        clrl    SADR(r11)       # no a.out, start at the top
                    292:        brb     done
                    293: m0407:
                    294:        addl2   r8,r7           # text = text + data; no data
                    295:        clrl    r8
                    296: #
                    297: # do copies by longword: simpler and smaller than movc3,
                    298: # which would need to loop anyway
                    299: # longword not quadword because ld rounds sizes to long
                    300: #
                    301: # really should beql after the second div, else when there's no data
                    302: # we copy one extra word to a nonsense place.
                    303: # too bad; we can't spare the code space
                    304: #
                    305: m0410:
                    306:        clrl    r0
                    307:        movzbl  $32,r1
                    308:        addl3   r7,r8,r2
                    309:        divl2   $4,r2
                    310: 1:     movl    (r1)+,(r0)+     # copy down over a.out header
                    311:        sobgtr  r2,1b
                    312:        divl3   $4,r8,r2
                    313:        addl3   r8,r7,r1        # from t + d
                    314:        extzv   $0,$PGSHIFT,r7,r0
                    315:        beql    0f              # don't overround
                    316:         subw3  r0,$PGSIZE,r0
                    317: 0:     addl2   r1,r0           # to t + d + round
                    318: 2:     movl    -(r1),-(r0)     # copy data to start at page boundary
                    319:        sobgtr  r2,2b
                    320: #
                    321: # reset registers and start
                    322: #
                    323: 
                    324: done:
                    325:        movl    r11,sp
                    326:        popr    $REGMASK
                    327:        movl    r5,r11          # put boot flags in stupid bky place
                    328:        jmp     2(r0)           # skip register mask & start it
                    329: 
                    330: #
                    331: # read a (filesystem) block from a file
                    332: # (filesystem) block number in r12
                    333: # buffer address in r5
                    334: # r10 points to the addresses
                    335: # returns status in psw:
                    336: # zero flag set if read a block
                    337: # clear if error or block doesn't exist
                    338: #
                    339: 
                    340: lread:
                    341:        cmpl    r12,$NINDBLK
                    342:        blss    0f
                    343: lerr:
                    344:        bicpsw  $4              # clear zero flag
                    345:        rsb
                    346: 0:
                    347:        movl    (r10)[r12],r8
                    348:        beql    lerr
                    349:        pushl   $FSBSIZE/BSIZE  # count of disk blocks within fs block
                    350:        mull3   $FSBSIZE/BSIZE,r8,-(sp) # fs block to disk block
                    351: 1:
                    352:        movl    (sp),r8
                    353:        movl    r5,r6           # safe place
                    354:        bsbw    bread
                    355:        movab   BSIZE(r6),r5
                    356:        incl    (sp)
                    357:        sobgtr  4(sp),1b
                    358:        clrq    (sp)+           # addl2 $8,sp; set zero bit
                    359:        rsb
                    360: #
                    361: # last address that needs saving
                    362: #
                    363:        .globl end
                    364: end:
                    365: 
                    366: #
                    367: # put uninitialized (not 0) data here
                    368: #
                    369:        .align  2
                    370: savedata:
                    371: #      .space  ROMSIZE

unix.superglobalmegacorp.com

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