Annotation of researchv10no/sys/boot/bb/bnot.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    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   'k,0,0,0,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.