Annotation of researchv10no/sys/boot/bb/obblock.s, revision 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.