Annotation of coherent/d/conf/boot/boot.m, revision 1.1.1.1

1.1       root        1: / $Header: /newbits/conf/boot/RCS/boot.m,v 1.4 91/11/08 13:18:38 bin Exp Locker: bin $
                      2: / (lgl-
                      3: /      The information contained herein is a trade secret of Mark Williams
                      4: /      Company, and  is confidential information.  It is provided  under a
                      5: /      license agreement,  and may be  copied or disclosed  only under the
                      6: /      terms of  that agreement.  Any  reproduction or disclosure  of this
                      7: /      material without the express written authorization of Mark Williams
                      8: /      Company or persuant to the license agreement is unlawful.
                      9: /
                     10: /      COHERENT Version 3.2.1
                     11: /      Copyright (c) 1982, 1983, 1984, 1991.
                     12: /      An unpublished work by Mark Williams Company, Chicago.
                     13: /      All rights reserved.
                     14: / -lgl)
                     15: 
                     16: ////////
                     17: /
                     18: / Bootstrap block for the IBM
                     19: / PC. This code, which lives in sector 1,
                     20: / track 0 of the floppy (or sector 1 of a hard disk partition)
                     21: / gets read into location 0x7C00 by the ROM.
                     22: / The code relocates itself to location 0x2060:0x0000
                     23: / (128K above the fixed memory used by the ROM). The system image is read
                     24: / in beginning at paragraph 0x0060.
                     25: /
                     26: / $Log:        boot.m,v $
                     27: / * Revision 1.4  91/11/08  13:18:38  bin
                     28: / * Piggy update for building secondary boot for tboot
                     29: / * 
                     30: /  Revision 1.7  91/11/08  11:31:13  piggy
                     31: /  Attempted to integrate pboot into these sources.  Still not working.
                     32: /  Updated secondary boot for use with tertiary boot code.
                     33: /  
                     34: /  Revision 1.4  91/09/17  10:35:59  piggy
                     35: /  Uses 4 byte disk blocks, so can boot from anywhere on disk.
                     36: /  Points ds:si at useful data for tertiary boot.
                     37: /  Loads /tboot by default.
                     38: /  
                     39: / Revision 1.1 88/03/24  16:44:09      src
                     40: / Initial revision
                     41: / 
                     42: / 87/10/04     Allan Cornish           /usr/src/sys/i8086/boot/boot.s
                     43: / Number of heads now defined by NHD macro.  Should be 1 for f*d*, 2 for f*a*.
                     44: /
                     45: / 85/10/04     Allan Cornish           /usr/src/sys/i8086/boot/boot.s
                     46: / Bootstrap extended to increase max file size from 64 Kbytes to 128 Kbytes.
                     47: / The private code segment is now loaded, where previously it had to be empty.
                     48: / File name editing enhanced to help cursor stay in the 14 char entry field,
                     49: / and to provide a destructive backspace.
                     50: /
                     51: / 85/01/04     Allan Cornish
                     52: / Added backspace editing of file name.
                     53: /
                     54: ////////
                     55: 
                     56: #ifndef        NHD
                     57: #define        NHD     1                       / num of heads per drive [1 for f9d0].
                     58: #endif
                     59: 
                     60: #ifndef        NSPT
                     61: #define        NSPT    9                       / num of sectors per track on floppy.
                     62: #define        NTRK    40                      / num of tracks on floppy.
                     63: #endif
                     64: 
                     65: 
                     66: #ifndef        CNTRL
                     67: #define        CNTRL   8
                     68: #endif
                     69: 
                     70: #ifndef        WPCC
                     71: #define        WPCC    0xFFFF
                     72: #endif
                     73: 
                     74: NSTK   =       256                     / num of bytes of stack.
                     75: BS     =       0x08                    / BS character.
                     76: CR     =       0x0D                    / CR character.
                     77: LF     =       0x0A                    / LF character.
                     78: SP     =       0x20                    / Backspace character.
                     79: BOOTLC =       0x7C00                  / Boot location (ROM).
                     80: BOOTS  =       0                       / boot segment (ROM).
                     81: RBOOTS =       0x2060                  / Relocated boot segment.
                     82: BSHIFT =       9                       / Shift, bytes to blocks.
                     83: ROOTINO =      2                       / Root inode #
                     84: INOORG =       2                       / First inode block.
                     85: IBSHIFT =      3                       / Shift, inode to blocks
                     86: IOSHIFT =      6                       / Shift, inode to bytes
                     87: INOMASK =      0x0007                  / Mask, inode to offset
                     88: DIRSIZE =      14                      / Directory size.
                     89: DIRSIZ2 =      7                       / Directory size / 2.
                     90: BUFSIZE =      512                     / Block size.
                     91: HDRSIZE =      44                      / L.out header size.
                     92: HDRSIZ2 =      22                      / L.out header size / 2.
                     93: BUFMSK2 =      0x00FF                  / Block [word] mask, for reads.
                     94: DISK   =       0x13                    / Disk Interrupt
                     95: KEYBD  =       0x16                    / Keyboard Interrupt
                     96: READ1  =       0x0201                  / read one sector
                     97: DADDR  =       4                       / number of bytes in a disk block number
                     98: ND     =       10                      / num of direct blocks.
                     99: NIND   =       128                     / num of blocks in indirect block.
                    100: NINDX2 =       256                     / NIND * 2 (number of words in indirect)
                    101: ISIZE  =       8                       / Offset of "di_size".
                    102: IADDR  =       12                      / Offset of "di_addr".
                    103: JMPF   =       0xEA                    / Jump far, direct.
                    104: LMAGIC =       0                       / Offset of "l_magic"
                    105: LFLAG  =       2                       / Offset of "l_flag"
                    106: LSHRI  =       10                      / Offset of "l_ssize[SHRI]"
                    107: LPRVI  =       14                      / Offset of "l_ssize[PRVI]"
                    108: LSHRD  =       22                      / Offset of "l_ssize[SHRD]"
                    109: LPRVD  =       26                      / Offset of "l_ssize[PRVD]"
                    110: LBSSD  =       30                      / Offset of "l_ssize[BSSD]"
                    111: LFMAG  =       0x0107                  / Magic number.
                    112: LFSEP  =       0x02                    / Sep I/D flag bit.
                    113: SYSBASE =      0x0060                  / System load base paragraph.
                    114: FIRST  =       8                       / relative start of partition
                    115: 
                    116: / Hard disk controller port addresses.
                    117: HF_REG =       0x3F6
                    118: NSEC_REG=      0x1F2
                    119: SEC_REG        =       0x1F3
                    120: HDRV_REG=      0x1F6
                    121: CSR_REG        =       0x1F7
                    122: BSY_ST =       0x80
                    123: SETPARM_CMD=   0x91
                    124: 
                    125: ////////
                    126: / Overall structure of boot.s (the secondary boot):
                    127: /
                    128: / boot: relocate secondary to high memory (0x2060:0x0000)
                    129: /      if needed, get hard disk parameters from bios
                    130: /      jump far to high memory (RBOOTS:entry)
                    131: / entry: open directory "/"
                    132: / search: while filename not found
                    133: /      walk through "/" looking for filename (in nbuf)
                    134: /      if not found, ask for another name (call input:), and loop to search
                    135: / found: open file that we just found
                    136: /      read the l.out header (verify magic number, get partition sizes)
                    137: /      load the shared and private code segments as one (call load:)
                    138: /      load the initialized data segment (call load:)
                    139: /      jump far to the newly loaded program
                    140: /      
                    141: ////////
                    142: 
                    143: ////////
                    144: /
                    145: / Bootstrap mainline. Relocate the
                    146: / boot to high memory, so it will not be written
                    147: / over by the system. Read in a file name. Look up
                    148: / the file name by following out the directory
                    149: / structure. Read in the image and jump to it.
                    150: /
                    151: ////////
                    152: 
                    153: boot:  xor     di, di
                    154:        mov     ds, di
                    155:        mov     si, $BOOTLC             / Make DS:SI point at the code
                    156: / "mov es, 1f(si)" really means "mov es, $RBOOTS".  Clever Intel... :-(
                    157:        mov     es, 1f(si)              / Make ES:DI point at where it goes
                    158:        mov     cx, $512                / cx = # of bytes to move
                    159:        cld
                    160:        rep                             / Move the bootstrap
                    161:        movsb                           / to high memory.
                    162: 
                    163: / Check to see if we were invoked by mboot.  (That means we are booting
                    164: / off a hard disk and need to load disk parameters.  )
                    165: 
                    166:                                        / mboot sets bx = sp
                    167:        cmp     bx, sp                  / trick to tell
                    168:        jne     0f                      / whether or not xt
                    169: 
                    170: / Assertion: at this point we know we are booting off a hard disk.
                    171:        mov     si, bp                  / set si to partition table
                    172: 
                    173:        movb    dl, (si)                / get drive number
                    174:        movb    ah, $8                  / get drive parameters
                    175:        int     DISK
                    176:        jc      0f                      / abort on error
                    177: 
                    178:        movb    al, ch                  / fetch cyl(lo)
                    179:        movb    ah, cl                  / move cyl(hi), sects
                    180:        rolb    ah, $1                  / shift cylinder high to
                    181:        rolb    ah, $1                  / the least sig bits
                    182:        andb    ah, $3                  / mask out cylinder bits
                    183:        
                    184:        mov     di, $traks              / point to drive
                    185:        stosw                           / set number of tracks
                    186: 
                    187:        movb    al, $0x3F               / sector mask
                    188:        andb    al,cl                   / mask sector
                    189:        stosb                           / set sector
                    190: 
                    191:        movb    al, dh                  / get max head
                    192:        inc     ax                      / change to # of heads [incb al]
                    193:        stosb                           / set number of heads
                    194: 
                    195:        movsb                           / set drive
                    196:        add     si, $FIRST-1            / point to first block
                    197:        movsw
                    198:        movsw                           / fetch first block
                    199: 
                    200: / Set registers.
                    201: 
                    202: 0:     mov     bp, $stack+NSTK         / stack pointer value
                    203:        mov     ax, es
                    204:        mov     ds, ax
                    205:        mov     ss, ax
                    206:        mov     sp, bp
                    207: 
                    208: / Jump to (relocated) boot.
                    209: 
                    210:        .byte   JMPF
                    211:        .word   entry
                    212: 1:     .word   RBOOTS
                    213: 
                    214: ////////
                    215: /
                    216: / This is the equivalent of "open()",
                    217: / but takes an inode instead of a pathname.
                    218: /
                    219: / Read the inode specified by "ax"
                    220: / into the external variable "iaddr".
                    221: /
                    222: / Makes a list of block numbers in "iaddr"
                    223: / consisting of the 10 direct block numbers, the 128
                    224: / block numbers pointed to the singly indirect block,
                    225: / and the first 128 block numbers pointed to by the
                    226: / first doubly indirect block.
                    227: /
                    228: / Note that "iread" can only access the first 256
                    229: / block numbers in this list, so the last 10 are
                    230: / ignored.
                    231: /
                    232: / Note that block numbers are actually 32 bits on disk--
                    233: / this routine only uses the lower 16 bits.
                    234: / In fact, iaddr is loaded with 16 bit numbers, not 32 bit.
                    235: /
                    236: / No checking is done to make sure that
                    237: / the inumber is in range on the filesystem.
                    238: / Sets dx and cx to 0.
                    239: / Mungs si, di, ax.
                    240: /
                    241: ////////
                    242: 
                    243: igrab: dec     ax                      / Make origin 0 and
                    244:        push    ax                      / remember for later use.
                    245: 
                    246:        / We assume that the inode table appears in the first 32 meg of disk.
                    247:        / Look up the inode in the inode table.
                    248:        movb    cl, $IBSHIFT            / Convert to
                    249:        shr     ax, cl                  / inode block number,
                    250:        inc     ax                      / then to physical block number,
                    251:        inc     ax
                    252:        sub     bx, bx                  / Assume inode within first 32 meg.
                    253:        call    bread                   / and read in the data.
                    254: 
                    255:        pop     ax                      / Get i-number back.
                    256:        and     ax, $INOMASK            / Get inode within block
                    257:        movb    cl, $IOSHIFT            / and convert to
                    258:        shl     ax, cl                  / a byte offset in the block.
                    259:        add     si, ax                  / si = inode pointer.
                    260: 
                    261:        / Assertion: si now points at the start of the desired
                    262:        / inode structure (see <sys/inode.h>).
                    263: 
                    264:        / Copy out the direct block numbers to iaddr.
                    265:        add     si, $IADDR              / Point at address field.
                    266:        mov     di, $iaddr              / Copy out area.
                    267: 
                    268:        / The block numbers in the inode on disk are stored as
                    269:        / 3 bytes: msb, lsw.  lsw is lsb, msb.  We want to store them
                    270:        / in memory as msw, lsw, just like the inodes in the indirect
                    271:        / blocks on disk.  So we need to cast msb as msw.
                    272:        movb    cl, $ND                 / cx = # of direct blocks
                    273:        sub     ax, ax                  / cast byte in al to word in ax
                    274: 0:     lodsb                           / al = msb for direct byte
                    275:        stosw                           / store msb cast as a word
                    276:        movsw                           / store lsw.
                    277:        loop    0b
                    278: 
                    279:        lodsb                           / Get the msb for the indirect block.
                    280:        xchg    bx, ax                  / (implicit cast of msb to msw)
                    281:        lodsw                           / Get the lsw for the indirect block.
                    282:        call    bread                   / Read (first) indirect block.
                    283: 
                    284:        / Copy out the singly indirect block numbers to iaddr.
                    285:        / These are stored on disk as 4 byte numbers: msw, lsw
                    286:        / where each word is lsb, msb.  This is how we store them
                    287:        / in memory.
                    288:        mov     cx, $NINDX2
                    289:        rep
                    290:        movsw
                    291: 
                    292: 
                    293:        / Finish by reading the first block of the file into bbuf.
                    294:        sub     dx, dx                  / Set dh to first block number in iaddr.
                    295: /      jmp     iread                   / Done return through iread.
                    296: 
                    297: ////////
                    298: /
                    299: / This routine reads the virtual
                    300: / block iaddr[dh] (the dhth block number
                    301: / in iaddr) into the buffer "bbuf".
                    302: / It uses the mapping data that
                    303: / has been provided by a previous call to igrab
                    304: / On return "si" points at "bbuf".
                    305: / Holes in files (sparse blocks) are correctly done.
                    306: / mungs ax, bx, si.
                    307: / clears cx.
                    308: /
                    309: ///////
                    310: 
                    311: iread:
                    312:        sub     bx, bx                  / Convert from words to blocks.
                    313:        movb    bl, dh                  /
                    314: 
                    315:        / Block numbers are 4 bytes long, stored msw, lsw.
                    316:        shl     bx, $2                  / Compute index into iaddr table.
                    317:        push    iaddr(bx)               / fetch msw
                    318:        inc     bx
                    319:        inc     bx
                    320:        mov     ax, iaddr(bx)           / fetch lsw
                    321:        pop     bx                      / put msw where it belongs
                    322: /      jmp     bread                   / Yes, return through "bread".
                    323: 
                    324: ////////
                    325: /
                    326: / Read a block from the floppy disk,
                    327: / drive A:, using the code in the IBM firmware.
                    328: / The physical block # is in ax and bx.
                    329: / Register bx is the MSW, and ax is the LSW.
                    330: /
                    331: ////////
                    332: 
                    333: bread: push    es                      / Save registers
                    334:        push    di
                    335:        push    dx
                    336: 
                    337:        push    ds
                    338:        pop     es                      / set ES to the address of the buffer
                    339: 
                    340:        mov     di, bp                  / Blast the buffer contents.
                    341:        mov     cx, $BUFSIZE            / For block 0, this fills the buffer
                    342:        rep                             / with zeros.
                    343:        stosb
                    344: 
                    345:        / Block #0 is the sparse block--it means a block of all zeros.
                    346:        test    ax, ax                  / if block 0, return zeroed buffer
                    347:        jnz     3f
                    348:        test    bx, bx
                    349:        jz      2f
                    350: 
                    351:        / Translate block number into cylinder, head, and sector.
                    352: 3:     push    bx
                    353:        pop     dx
                    354: /      xor     dx, dx                  / extend block number
                    355:        add     ax, first               / add first block
                    356:        adc     dx, first+2             / add rest
                    357: 
                    358:        mov     bx, ax                  / save block number
                    359:        movb    al, heads               / get number of heads
                    360:        movb    cl, sects               / get number of sectors
                    361:        mulb    cl                      / calculate sectors per cylinder
                    362:        xchg    bx,ax                   / swap block/sectors
                    363:        div     bx                      / calculate track
                    364:        xchg    dx, ax                  / put track in DX
                    365:        divb    cl                      / calculate head/sector
                    366: 
                    367:        movb    cl, ah                  / set sector
                    368:        inc     cx                      / sectors start at 1 [incb cl]
                    369:        
                    370:        cmp     dx, traks               / check for second side
                    371:        jb      0f
                    372:        sub     dx, traks               / fold track
                    373:        inc     ax                      / next head [incb al]
                    374: 
                    375: 0:     rorb    dh, $1                  / rotate track(low) into
                    376:        rorb    dh, $1                  /  msbits of DX
                    377:        orb     cl, dh                  / set track(high)
                    378:        movb    ch, dl                  / set track(low)
                    379:        movb    dh, al                  / set head
                    380:        movb    dl, drive               / set drive
                    381:        mov     bx, bp                  / set offset [bbuf]
                    382: 
                    383:        mov     ax, $READ1              / Read, 1 sector.
                    384:        int     DISK                    / Disk I/O.
                    385:        jnc     2f                      / Jump if no error.
                    386:        mov     ax, $READ1              / try again
                    387:        int     DISK
                    388:        jc      error
                    389: 
                    390: 2:     mov     si, bp                  / set SI to point to buffer for return
                    391:        sub     cx, cx                  / clear CX here to save space
                    392: 
                    393:        pop     dx                      / restore registers.
                    394:        pop     di
                    395:        pop     es
                    396:        ret                             / return.
                    397: 
                    398: / Prompt with a "?" and read the file name
                    399: / into "nbuf".  No character editing facilites
                    400: / are provided.
                    401: 
                    402: error: mov     sp, bp                  / Reset stack
                    403: 
                    404: input: mov     di, $nbuf               / di=name buffer pointer
                    405:        mov     cx, $DIRSIZE            / cx=size of
                    406: / Preprocessor blows up if we use single-quote question mark.
                    407:        movb    al, $0077               / set prompt to ?.
                    408: 0:     call    putc
                    409: 
                    410: 1:     movb    ah, $0                  / Get ASCII opcode.
                    411:        int     KEYBD                   / Read keyboard ROM call.
                    412: 
                    413: 2:     cmpb    al, $CR                 / CR ?
                    414:        je      3f                      / Yup, do next thing
                    415: 
                    416:        jcxz    1b                      / skip over too big name
                    417:        stosb                           / put it into the buffer,
                    418:        dec     cx                      / adjust char count
                    419:        jmp     0b                      / and continue.
                    420: 
                    421: 3:     movb    al, $CR
                    422:        call    putc
                    423:        movb    al, $LF
                    424:        call    putc
                    425: 
                    426:        movb    al, $0                  / zero out
                    427:        rep
                    428:        stosb                           / rest of name
                    429: 
                    430: ////////
                    431: / This is where we jump after boot has been relocated.
                    432: / 
                    433: / Open "/"; we are going to search for "autoboot".
                    434: ////////
                    435: entry: mov     ax, $ROOTINO            / ax = current inode
                    436:        call    igrab                   / Read in inode and set dx
                    437: 
                    438: ////////
                    439: / Search directory for filename in nbuf.
                    440: / Assume directory size = 64 Kbytes.
                    441: / This assumption works because block numbers
                    442: / from the inode beyond end of file are zero.
                    443: ////////
                    444: 
                    445: search: orb    dl, dl                  / On block boundry ?
                    446:        jnz     0f                      / Nope.
                    447:        call    iread                   / Read block, set si.
                    448: 
                    449: 0:     movb    cl, $DIRSIZE            / cx = count left
                    450:        mov     di, $nbuf               / Point at name buffer and
                    451:        lodsw                           / ax = inumber, this entry.
                    452:        or      ax, ax                  / Empty directory slot ?
                    453:        je      1f                      / Yes, skip.
                    454:        repe                            / compare the
                    455:        cmpsb                           / two file names.
                    456:        je      found                   / If eq, go and get inode.
                    457: 
                    458: 1:     add     si, cx                  / Advance by count remaining.
                    459:        add     dx, $DIRSIZ2+1          / Bump [word] seek pointer
                    460:        jg      search                  / Scan up to 64 Kbytes of directory.
                    461: 
                    462:        jmp     input                   / File not found.
                    463: 
                    464: 
                    465: ////////
                    466: /
                    467: / Found the file so read it in.
                    468: / ax = inode number of file
                    469: /
                    470: ////////
                    471: 
                    472: found: call    igrab                   / read in inode and first block
                    473:        cmp     LMAGIC(si),$LFMAG       / Check the magic number.
                    474:        jne     error                   / not Ok.
                    475: 
                    476: /      push    LBSSD(si)               / Push the uninitialized data size.
                    477: 
                    478:        / Get the total size of shared and private data segments.
                    479:        / They are contigious on disk.  see <l.out.h>
                    480:        mov     ax, LSHRD(si)           / Push the sum
                    481:        add     ax, LPRVD(si)           / of the shared and private
                    482:        push    ax                      / [initialized] data sizes.
                    483:        / If this is not a sep I/D executable, then we
                    484:        / do not want to load the non-existent data segment.
                    485:        andb    LFLAG(si), $LFSEP       / check image flags.
                    486:        pushf                           / Push result of test.
                    487:        mov     ax, LSHRI(si)           / Get the sum of the
                    488:        add     ax, LPRVI(si)           / shared and private code sizes.
                    489: 
                    490:        / Find the start of the first segment on disk.
                    491:        mov     dx, $HDRSIZ2            / Seek after header and
                    492:        add     si, $HDRSIZE            / set buffer pointer appropriately.
                    493:        mov     es, 1f                  / Set ES:DI to point to the load
                    494:        sub     di, di                  / base of the new system.
                    495: 
                    496:        / Load the code segment.
                    497:        call    load                    / Load code.
                    498: 
                    499:        / Skip loading the data segment for non-sep I/D executables.
                    500:        popf                            / Pop sep I/D flag test
                    501:        jz      0f                      / Not sep.
                    502: 
                    503:        / Assertion: at this point we are dealing with a sep I/D
                    504:        / l.out executable.
                    505: 
                    506:        / Calculate load point for data segment.
                    507:        add     di, $15                 / Round up the system code
                    508:        movb    cl, $4                  / size to 16 byte
                    509:        shr     di, cl                  / paragraphs.
                    510:        mov     ax, es                  / fetch program base
                    511:        add     ax, di                  / Compute the data base and
                    512:        mov     es, ax                  / set up ES:DI to point
                    513:        sub     di, di                  / at it.
                    514: 
                    515: 0:     pop     ax                      / Pop off initialized data size and
                    516:        / Load the initialized data segment.
                    517:        call    load                    / load the image.
                    518: 
                    519:        mov     si, $useful             / Point ds:si at the useful data
                    520:                                        / for the tertiary boot.
                    521: 
                    522: /      pop     cx                      / Pop off uninitialized data size and
                    523: /      rep                             / clear it.
                    524: /      stosb
                    525: 
                    526:        / Run the program that we just loaded.
                    527:        .byte   JMPF                    / Jump to offset
                    528:        .word   0x0100                  / 0x0100 (after base) in system
                    529: 1:     .word   SYSBASE                 / code segment.
                    530: 
                    531: ////////
                    532: /
                    533: / Load a segment from an l.out file into memory.
                    534: / The "dx" register holds the
                    535: / seek pointer into the file. The "si" holds
                    536: / a pointer into the "bbuf". The "es:di" pair
                    537: / holds the target address. The "ax" holds
                    538: / the number of bytes to load. On return the
                    539: / "ax" must equal 0 (the caller assumes this
                    540: / and uses "al" to clear the BSS).
                    541: /
                    542: / Note that since the number of bytes to load is
                    543: / stored in a 16 bit register, a segment may be no
                    544: / longer than 64K.  For small model this is just fine.
                    545: ////////
                    546: 
                    547: load:  or      ax, ax                  / Any left ?
                    548:        jz      return                  / Jump if all loaded.
                    549: 
                    550:        mov     cx, $bbuf+BUFSIZE       / Compute the number of bytes
                    551:        sub     cx, si                  / remaining in the block.
                    552:        jnz     0f                      / Jump if some.
                    553: 
                    554:        push    ax                      / Save count registers, then
                    555:        call    iread                   / read the next block
                    556:        pop     ax                      / of the file.
                    557:        mov     cx, $BUFSIZE            / We now have a full block.
                    558: 
                    559: 0:     cmp     cx, ax                  / More than we need ?
                    560:        jbe     1f                      / Nope.
                    561:        mov     cx, ax                  / Only take what we need.
                    562: 
                    563: 1:     sub     ax, cx                  / Fix up the count
                    564:        shr     cx, $1                  /
                    565:        add     dx, cx                  / Fix up the seek [word] address, then
                    566:        rep                             / copy the words from the block
                    567:        movsw                           / buffer to the load point and
                    568:        jmp     load                    / loop until done.
                    569: 
                    570: ////////
                    571: /
                    572: / Write the character in "al" out to
                    573: / the display, using routines in the ROM.
                    574: / Like most calls to the ROM, this routine spends
                    575: / most of its time saving and restoring the
                    576: / registers.
                    577: /
                    578: / Note: The ZF in the PSW word must be preserved.
                    579: /
                    580: ////////
                    581: 
                    582: putc:  push    si                      / Save registers.
                    583:        push    di
                    584:        push    bp
                    585: 
                    586:        mov     bx, $0x0007             / Page 0, white on black
                    587:        movb    ah, $0x0E               / Write TTY.
                    588:        int     0x10                    / Call video I/O in ROM.
                    589: 
                    590:        pop     bp                      / Restore registers.
                    591:        pop     di
                    592:        pop     si
                    593: return: ret                            / Return
                    594: 
                    595: ////////
                    596: /
                    597: / Data. There is some pure data in
                    598: / the "prvd" segment. This data is moved to the
                    599: / new memory when the boot is relocated. All buffers
                    600: / are in the BSS, and are not actually moved, or even
                    601: / saved in the boot block.
                    602: /
                    603: ////////
                    604: 
                    605:        .prvd
                    606: 
                    607: / Do not rearrange ANY of the following variables.  If you
                    608: / need to add variables, they must come BEFORE or AFTER these.
                    609: / If you want to teach the tertiary boot about any variables you
                    610: / add, put them after double word "first".
                    611: 
                    612: 
                    613:        .even
                    614: useful:        / Useful variables for the tertiary boot.
                    615: nbuf:  .ascii  "tboot"                 / Name buffer.
                    616:        .blkb   DIRSIZE-5               / rest of buffer (5=sizeof("tboot"))
                    617: 
                    618: traks: .word   NTRK    / Number of cylinders on drive we are booting off of.
                    619: sects: .byte   NSPT    / Number of sectors per track for our drive.
                    620: heads: .byte   NHD     / Number of heads on drive we are booting off of.
                    621: 
                    622: drive: .byte   0       / Drive our partition resides upon.
                    623: first: .word   0       / First block of our partition (?)
                    624:        .word   0
                    625: cntrl: .byte   CNTRL   / Control byte
                    626: wpcc:  .word   WPCC    / 
                    627: 
                    628: / This magic pair of bytes must be the last two bytes of
                    629: / the sector (address 0x1FE), otherwise mboot will refuse
                    630: / to execute it.
                    631: / If needed, uncomment the .blkb and adjust the number appropriately.
                    632: 
                    633:        .blkb   0x28    / Padding needed to make magic byte line up
                    634: 
                    635:        .byte   0x55,0xAA
                    636: 
                    637:        .bssd
                    638: stack: .blkb   NSTK                    / Local Stack and name buffer
                    639: bbuf:  .blkb   BUFSIZE                 / Block buffer [must follow stack].
                    640: iaddr: .blkw   ND+ND+NIND+NIND         / Inode map words.

unix.superglobalmegacorp.com

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