Annotation of coherent/d/conf/tboot/refs, revision 1.1

1.1     ! root        1: / Startup.s -- initilization code for any tertiary boot program.
        !             2: /
        !             3: / La Monte H. Yarroll <[email protected]>, September 1991
        !             4: /
        !             5: / RBOOTS is set exactly 128K below the top of 640K.
        !             6: / One day, RBOOTS should be dynamicly determined based on the size of
        !             7: / available memory.
        !             8:        RBOOTS  = 0x8000                / New segement for boot program.
        !             9:        JMPF    = 0xEA                  / jump far, direct
        !            10:        SEGSIZ  = 0xffff                / Size of a whole segment.
        !            11:        NSTK    = 0x2000                / # of bytes of stack.
        !            12:        BLOCK   = 0x200                 / # of bytes in a disk block
        !            13:        DIRSIZE = 14                    / Size of a file name.
        !            14:        SIZEOFSDAT = 23                 / sizeof(seconddat)
        !            15:        SECONDDAT = 0x01E7              / Offset of useful data in secondary boot.
        !            16:        CR      = 0x0d                  / Carriage return
        !            17:        LF      = 0x0a                  / Line Feed
        !            18:        NUL     = 0x00                  / NUL (for terminating strings)
        !            19:        / Interrupts.
        !            20:        MON     = 0x00          / Invoke BIOS monitor.
        !            21:        KEYBD   = 0x16          / Keyboard software interrupt.
        !            22:        REBOOT  = 0x19          / Reboot through BIOS.
        !            23:        
        !            24:        
        !            25:        NTRK    = 40            / Number of tracks on a floppy.
        !            26:        NSPT    = 9             / Number of sectors per track on a floppy.
        !            27:        NHD     = 1             / Number of heads per drive on a floppy.
        !            28:        .bssd
        !            29: stack: .blkb   NSTK    / Local Stack
        !            30:        .shri
        !            31:        .blkb   0x100   / Symbol "begin" must be at offset 0x100 from
        !            32: begin:                 / the beginning of the code segment--secondary
        !            33:                        / boot jumps here.
        !            34:        / Upon entry ds points at the secondary boot data segment,
        !            35:        / si points at the data we want,
        !            36:        / and es points at our data segment.
        !            37:        mov     di, $seconddat
        !            38:        mov     cx, $SIZEOFSDAT
        !            39:        cld
        !            40:        rep
        !            41:        movsb   / Copy disk configuration information to our own segment.
        !            42:        / Create a nice, safe stack.
        !            43:        mov     bp, $stack+NSTK
        !            44:        mov     ax, es
        !            45:        mov     ss, ax
        !            46:        mov     sp, bp
        !            47:        
        !            48:        push    es      / Save location of data segment from secondary boot.
        !            49:        / Move the tertiary boot to high memory.
        !            50:        call    moveme
        !            51:        
        !            52:        add     sp, $2  / Throw away old data segment.
        !            53:        / Set up the new stack.
        !            54:        mov     bp, $stack+NSTK
        !            55:        mov     ax, es
        !            56:        mov     ss, ax
        !            57:        mov     sp, bp
        !            58:        .byte   JMPF            / Jump to the relocated code.
        !            59:        .word   entry
        !            60:        .word   RBOOTS
        !            61: entry: call    main_
        !            62: / Aargh!  main() returned!  Wait for a keystroke and then reboot.
        !            63:        push    $keymsg
        !            64:        call    puts_
        !            65: 0:     movb    ah, $1  /       while (!iskey()) {};
        !            66:        int     KEYBD   /               /* Read the key.  */
        !            67:        movb    ah, $1  /       } while (iskey())
        !            68:        int     KEYBD   /               /* Scan the keyboard for another key. */
        !            69:        jne     1b      /       
        !            70:        int     REBOOT  / Reboot through the BIOS. 
        !            71:        .shrd
        !            72: keymsg:        
        !            73:        .byte   CR
        !            74:        .byte   LF
        !            75:        .ascii  "Press any key to reboot."
        !            76:        .byte   CR
        !            77:        .byte   LF
        !            78:        .byte   NUL
        !            79: ////////
        !            80: /
        !            81: / Move tertiary boot to high memory.
        !            82: / Take one parameter--a word on the stack pointing to the current
        !            83: / data segment.
        !            84: /
        !            85: / As a side effect, this sets ds to the new data segment in high memory.
        !            86: /
        !            87: ////////
        !            88:        .shri
        !            89: moveme:
        !            90:        mov     bp, sp  / For parameter lookups.
        !            91:        / Move the code segment.
        !            92:        push    cs
        !            93:        pop     ds
        !            94:        xor     si, si          / Point ds:si at loaded code segment.
        !            95:        mov     ax, $RBOOTS
        !            96:        mov     es, ax
        !            97:        xor     di, di          / Point es:di at where we want to be.
        !            98:        mov     cx, $SEGSIZ     / Move a maximal segment.
        !            99:        cld
        !           100:        rep
        !           101:        movsb
        !           102:        / Calculate location of new data segment.
        !           103:        mov     ax, 2(bp)
        !           104:        push    cs              / Fetch the code segment.
        !           105:        pop     bx
        !           106:        sub     ax, bx          / Calculate offset to data segment.
        !           107:        add     ax, $RBOOTS     / Calculate the new data segment.
        !           108:        
        !           109:        / Move the data segment.
        !           110:        mov     ds, 2(bp)
        !           111:        xor     si, si          / Point ds:si at loaded data segment
        !           112:        mov     es, ax
        !           113:        xor     di, di          / Point es:di at where we want to be.
        !           114:        mov     cx, $SEGSIZ     / Move a maximal segment.
        !           115:        cld
        !           116:        rep
        !           117:        movsb
        !           118:        / Set the new data segment appropriately.
        !           119:        push    es
        !           120:        pop     ds
        !           121:        mov     myds_, ds
        !           122:        ret     / routine moveme
        !           123: / Shared data segment (initialized)
        !           124:        .shrd
        !           125:        .globl  myds_
        !           126: myds_: .word   0       / Place to communicate ds to C programs.
        !           127: / Variables nbuf, traks, sects, and heads MUST appear in this order.
        !           128:        .globl  seconddat
        !           129: seconddat:     / Data extracted from secondary boot data segment.
        !           130:        .globl  nbuf_
        !           131: nbuf_:
        !           132: nbuf:  .blkb   DIRSIZE
        !           133: / Defaults for all the following parameters match a floppy disk.
        !           134:        .globl  traks
        !           135:        .globl  traks_
        !           136: traks_:
        !           137: traks: .word   NTRK    / Number of cylinders on drive we're booting off of.
        !           138:        .globl  sects
        !           139:        .globl  sects_
        !           140: sects_:
        !           141: sects: .byte   NSPT    / Number of sectors per track for our drive.
        !           142:        .globl  heads
        !           143:        .globl  heads_
        !           144: heads_:
        !           145: heads: .byte   NHD     / Number of heads on drive we're booting off of.
        !           146:        .globl  drive
        !           147:        .globl  drive_
        !           148: drive_:
        !           149: drive: .byte   0       / Drive our partition resides upon.
        !           150:        .globl  first
        !           151:        .globl  first_
        !           152: first_:
        !           153: first: .word   0       / First block of our partition (?)
        !           154:        .word   0
        !           155: /*
        !           156:  * Determine whether or not a given argument exists on the command line
        !           157:  * passed into the kernel.
        !           158:  *
        !           159:  * Takes a pointer to a NUL terminated string that is the name of
        !           160:  * the desired argument.
        !           161:  */
        !           162: extern typed_space boot_gift;
        !           163: int
        !           164: arg_exist(arg)
        !           165: {
        !           166: } /* arg_exist() */
        !           167: /*
        !           168:  * Looks for the string "astring" in the fifo "afifo".
        !           169:  * Returns TRUE if it find the string.
        !           170:  */
        !           171: int
        !           172: fifo_find_str(afifo, astring)
        !           173:        typed_space *afifo;
        !           174:        char *astring;
        !           175: {
        !           176: } /* fifo_find_str() */
        !           177: /*
        !           178:  * bio.c -- buffer handling code.
        !           179:  *
        !           180:  * This code REALLY assumes single-threaded execution.  All locks are
        !           181:  * advisory only and may be revoked without notice.
        !           182:  *
        !           183:  * See also bread() in diskio.c.
        !           184:  */
        !           185: static BUF bufl[NBUF]; /* Buffer structures.  */
        !           186: static char blockp[NBUF * BLOCK];      /* The blocks themselves.  */
        !           187: static int buf_inited = (1==2);                /* Has bufinit been called?  */
        !           188: /*
        !           189:  * Initialise buffer headers.
        !           190:  */
        !           191: void
        !           192: bufinit()
        !           193: {
        !           194: } /* bufinit() */
        !           195: /*
        !           196:  * Claim a buffer for a block.
        !           197:  * Finds the buffer if it has already been accessed, otherwise,
        !           198:  * picks another buffer.
        !           199:  */
        !           200: BUF *
        !           201: bclaim(block)
        !           202:        daddr_t block;
        !           203: {
        !           204: } /* bclaim() */
        !           205: /*
        !           206:  * Pick the next buffer for allocation.
        !           207:  * Uses a round-robin scheme of buffer allocation, skipping over
        !           208:  * locked buffers.  If all buffers are locked, they are forcibly
        !           209:  * unlocked and the first one is picked.
        !           210:  */
        !           211: BUF *
        !           212: bpick()
        !           213: {
        !           214: } /* bpick() */
        !           215: /*
        !           216:  * Release a buffer for a block.
        !           217:  */
        !           218: void
        !           219: brelease(bp)
        !           220:        BUF *bp;
        !           221: {
        !           222: } /* brelease() */
        !           223: /*
        !           224:  * Attempt to lock the gate 'g'.
        !           225:  * Return TRUE on success, FALSE if it was already locked.
        !           226:  */
        !           227: int
        !           228: gate_lock(g)
        !           229:        GATE g;
        !           230: {
        !           231: } /* gate_lock() */
        !           232: /*
        !           233:  * Check to see if the gate 'g' is locked.
        !           234:  */
        !           235: int
        !           236: gate_locked(g)
        !           237:        GATE g;
        !           238: {
        !           239: } /* gate_locked() */
        !           240: /*
        !           241:  * Unlock the gate 'g'.
        !           242:  */
        !           243: void
        !           244: gate_unlock(g)
        !           245:        GATE g;
        !           246: {
        !           247: } /* gate_unlock() */
        !           248: /*
        !           249:  * Sanity checker.
        !           250:  * Prints contents of "message" if something is amiss and dumps you
        !           251:  * into the monitor.
        !           252:  *
        !           253:  * Add tests and messages as needed.
        !           254:  */
        !           255: void
        !           256: sanity_check(message)
        !           257:        char *message;
        !           258: {
        !           259: } /* sanity_check() */
        !           260: ////////
        !           261: /
        !           262: / I/O library for use with boot programs.  Uses the BIOS.
        !           263: /
        !           264: / La Monte H. Yarroll <[email protected]>, September 1991
        !           265: /
        !           266: ////////
        !           267: ////////
        !           268: /
        !           269: / Magic constants.
        !           270: /
        !           271: ////////
        !           272:        RETF    = 0xCB                  / Far return
        !           273:        VIDEO   = 0x10                  / video swi
        !           274:        DISK    = 0x13                  / disk io swi
        !           275:        KEYBD   = 0x16                  / keyboard swi
        !           276:        MON     = 0x00                  / Monitor swi
        !           277:        READ1   = 0x0201                / read 1 sector
        !           278:        
        !           279:        BUFSIZE = 0x200         / Size of a physical disk block.
        !           280:        
        !           281:        NTRK    = 40            / Number of tracks on a floppy.
        !           282:        NSPT    = 9             / Number of sectors per track on a floppy.
        !           283:        NHD     = 1             / Number of heads per drive on a floppy.
        !           284:        FIRST   = 8             / Relative start of partition.
        !           285:        .shri   / Shared code segment, initialized.
        !           286: ////////
        !           287: /
        !           288: / Read a block from disk, relative to the start of the boot partition,
        !           289: / using the code in the IBM firmware.
        !           290: /
        !           291: / It takes two parameters:
        !           292: /      daddr_t blockno;        /* 32 bit block number.  */
        !           293: /      char *buff;     /* Must point to a 512 byte buffer.  */
        !           294: /
        !           295: / The buffer must not cross a 4K boundry.  Disk input should generally
        !           296: / be done through the C routine bread(), which calls _bread() with an
        !           297: / aligned buffer.
        !           298: /
        !           299: ////////
        !           300:        .globl  _bread_
        !           301: _bread_:
        !           302:        push    es                      / Save registers
        !           303:        push    si
        !           304:        push    di
        !           305:        push    bp
        !           306:        push    dx
        !           307:        push    ds
        !           308:        pop     es                      / Set es:bp to address of the buffer.
        !           309:        mov     bp, sp
        !           310:        mov     ax, 12(bp)              / Get low word of block number.
        !           311:        mov     dx, 14(bp)              / Get high word of block number.
        !           312:        mov     bx, 16(bp)              / Get a buffer to put it in.
        !           313:        mov     bp, bx
        !           314:        mov     di, bp                  / Blast the buffer contents.
        !           315:        mov     cx, $BUFSIZE            / For block 0, this fills the buffer
        !           316:        rep                             / with zeros.
        !           317:        stosb
        !           318:        / Block #0 is the sparse block--it means a block of all zeros.
        !           319:        test    ax, ax                  / if block 0, return zeroed buffer
        !           320:        jnz     3f
        !           321:        test    dx, dx
        !           322:        jnz     3f
        !           323:        movb    al, $1                  / Say that we read 1 block.
        !           324:        jmp     2f
        !           325:        / Translate block number into cylinder, head, and sector.
        !           326: 3:     add     ax, first               / add first block
        !           327:        adc     dx, first+2             / add rest
        !           328:        mov     bx, ax                  / save block number
        !           329:        movb    al, heads               / get number of heads
        !           330:        movb    cl, sects               / get number of sectors
        !           331:        mulb    cl                      / calculate sectors per cylinder
        !           332:        xchg    bx,ax                   / swap block/sectors
        !           333:        div     bx                      / calculate track
        !           334:        xchg    dx, ax                  / put track in DX
        !           335:        divb    cl                      / calculate head/sector
        !           336:        movb    cl, ah                  / set sector
        !           337:        inc     cx                      / sectors start at 1 [incb cl]
        !           338:        
        !           339:        cmp     dx, traks               / check for second side
        !           340:        jb      0f
        !           341:        sub     dx, traks               / fold track
        !           342:        inc     ax                      / next head [incb al]
        !           343: 0:     rorb    dh, $1                  / rotate track(low) into
        !           344:        rorb    dh, $1                  /  msbits of DX
        !           345:        orb     cl, dh                  / set track(high)
        !           346:        movb    ch, dl                  / set track(low)
        !           347:        movb    dh, al                  / set head
        !           348:        movb    dl, drive               / set drive
        !           349:        mov     bx, bp                  / set offset [bbuf]
        !           350:        mov     ax, $READ1              / Read, 1 sector.
        !           351:        int     DISK                    / Disk I/O.
        !           352:        jnc     2f                      / Jump if no error.
        !           353:        mov     ax, $READ1              / try again
        !           354:        int     DISK
        !           355:        jc      berror
        !           356: 2:
        !           357:        / al contains the number of blocks read (should be 1).
        !           358:        pop     dx                      / restore registers.
        !           359:        pop     bp
        !           360:        pop     di
        !           361:        pop     si
        !           362:        pop     es
        !           363:        ret                             / return.
        !           364: berror:        / error handling for _bread.
        !           365:        xorb    al, al  / ah contains an error code.
        !           366:        jmp     2b
        !           367: ////////
        !           368: /
        !           369: / Write the character in "al" out to
        !           370: / the display, using routines in the ROM.
        !           371: / Like most calls to the ROM, this routine spends
        !           372: / most of its time saving and restoring the
        !           373: / registers.
        !           374: /
        !           375: ////////
        !           376:        .globl  putchar_
        !           377: putchar_:      push    si                      / Save registers.
        !           378:        push    di
        !           379:        push    bp
        !           380:        mov     bp, sp
        !           381:        mov     ax, 8(bp)               / Fetch the single argument.
        !           382:        mov     bx, $0x0007             / Page 0, white on black
        !           383:        movb    ah, $0x0E               / Write TTY.
        !           384:        int     VIDEO                   / Call video I/O in ROM.
        !           385:        pop     bp                      / Restore registers.
        !           386:        pop     di
        !           387:        pop     si
        !           388:        ret
        !           389: ////////
        !           390: /
        !           391: / Fetch character from keyboard, using
        !           392: / routines in the ROM.
        !           393: /
        !           394: ////////
        !           395:        .globl  getchar_
        !           396: getchar_:
        !           397:        push    si                      / Save registers.
        !           398:        push    di
        !           399:        push    bp
        !           400:        movb    ah, $0x00               / Read keystroke.
        !           401:        int     KEYBD
        !           402:        movb    ah, $0x00
        !           403:        pop     bp                      / Restore registers.
        !           404:        pop     di
        !           405:        pop     si
        !           406:        ret
        !           407: ////////
        !           408: /
        !           409: / Check for a pending keystroke using
        !           410: / routines in the ROM.
        !           411: /
        !           412: ////////
        !           413:        .globl  iskey_
        !           414: iskey_:
        !           415:        push    si                      / Save registers.
        !           416:        push    di
        !           417:        push    bp
        !           418:        movb    ah, $0x01               / Check for keystroke.
        !           419:        int     KEYBD
        !           420:        jne     0f
        !           421:        xor     ax, ax                  / Set false.
        !           422:        jmp     1f
        !           423: 0:     xor     ax, ax
        !           424:        inc     ax                      / Set true.
        !           425: 1:     pop     bp                      / Restore registers.
        !           426:        pop     di
        !           427:        pop     si
        !           428:        ret
        !           429: ////////
        !           430: /
        !           431: / Goto a far address
        !           432: / Takes two integer arguments: an offset, and a segment, in that order.
        !           433: /
        !           434: ////////
        !           435:        .globl gotofar_
        !           436: gotofar_:
        !           437:        add     sp, $2
        !           438:        .byte   RETF
        !           439: ////////
        !           440: /
        !           441: / Goto a kernel.
        !           442: / Takes three integer arguments: an offset, a segment, and a new data segment
        !           443: / in that order.
        !           444: /
        !           445: ////////
        !           446:        .globl gotoker_
        !           447: gotoker_:
        !           448:        mov     bp, sp
        !           449:        mov     es, 6(bp)       / Point es at the new data segment.
        !           450:        mov     si, $seconddat  / Point ds:si at useful data.
        !           451:        add     sp, $2
        !           452:        .byte   RETF
        !           453: ////////
        !           454: /
        !           455: / Initilize hard disk parameters
        !           456: /
        !           457: ////////
        !           458:        .globl  hdinit_
        !           459: hdinit_:
        !           460:        push    si                      / Save registers.
        !           461:        push    di
        !           462:        push    bp
        !           463:        mov     si, bp                  / set si to partition table
        !           464:        movb    dl, (si)                / get drive number
        !           465:        movb    ah, $8                  / get drive parameters
        !           466:        int     DISK
        !           467:        jc      1f                      / abort on error (just return)
        !           468:        movb    al, ch                  / fetch cyl(lo)
        !           469:        movb    ah, cl                  / move cyl(hi), sects
        !           470:        rolb    ah, $1                  / shift cylinder high to
        !           471:        rolb    ah, $1                  / the least sig bits
        !           472:        andb    ah, $3                  / mask out cylinder bits
        !           473:        mov     di, $traks              / point to drive
        !           474:        stosw                           / set number of tracks
        !           475:        movb    al, $0x3F               / sector mask
        !           476:        andb    al, cl                  / mask sector
        !           477:        stosb                           / set sector
        !           478:        movb    al, dh                  / get max head
        !           479:        inc     ax                      / change to # of heads (incb al)
        !           480:        stosb                           / set number of heads
        !           481:        movsb                           / set drive
        !           482:        add     si, $FIRST-1            / point to first block
        !           483:        movsw                           / fetch first block
        !           484:        movsw
        !           485: 1:     pop     bp                      / Restore registers.
        !           486:        pop     di
        !           487:        pop     si
        !           488:        ret
        !           489: ////////
        !           490: /
        !           491: / Invoke the native monitor.
        !           492: / Useful for debugging.
        !           493: /
        !           494: ////////
        !           495:        .globl  intmon_
        !           496: intmon_:
        !           497:        int     MON
        !           498:        ret
        !           499: ////////
        !           500: /
        !           501: / void _ffcopy(from_fp, to_fp, count)
        !           502: / faddr_t from_fp, to_fp;
        !           503: / int count;
        !           504: /
        !           505: / Copy count bytes from from_fp to to_fp.
        !           506: /
        !           507: / Here is the stack after initial "push bp":
        !           508: /
        !           509: /      12(bp)  count
        !           510: /      10(bp)  FP_SEL(to_fp)
        !           511: /      8(bp)   FP_OFF(to_fp)
        !           512: /      6(bp)   FP_SEL(from_fp)
        !           513: /      4(bp)   FP_OFF(from_fp)
        !           514: /      2(bp)   return IP
        !           515: /      0(bp)   old bp
        !           516: /
        !           517: ////////
        !           518:        .globl  _ffcopy_
        !           519: _ffcopy_:
        !           520:        push    bp
        !           521:        mov     bp, sp
        !           522:        push    es
        !           523:        push    di
        !           524:        push    ds
        !           525:        push    si
        !           526:        lds     si, 4(bp)       / from_fp  to DS:SI
        !           527:        les     di, 8(bp)       / to_fp to ES:DI
        !           528:        mov     cx, 12(bp)      / rep count to CX
        !           529:        rep
        !           530:        movsb
        !           531:        pop     si
        !           532:        pop     ds
        !           533:        pop     di
        !           534:        pop     es
        !           535:        pop     bp
        !           536:        ret             / return from _ffcopy()
        !           537: ////////
        !           538: /
        !           539: / Read a block from disk, relative to start of disk,
        !           540: / using the code in the IBM firmware.
        !           541: /
        !           542: / It takes two parameters:
        !           543: /      daddr_t blockno;        /* 32 bit block number.  */
        !           544: /      char *buff;     /* Must point to a 512 byte buffer.  */
        !           545: /
        !           546: / The buffer must not cross a 4K boundry.  Disk input should generally
        !           547: / be done through the C routine xbread(), which calls _xbread() with an
        !           548: / aligned buffer.
        !           549: /
        !           550: ////////
        !           551:        .globl  _xbread_
        !           552: _xbread_:
        !           553:        push    es                      / Save registers
        !           554:        push    si
        !           555:        push    di
        !           556:        push    bp
        !           557:        push    dx
        !           558:        push    ds
        !           559:        pop     es                      / Set es:bp to address of the buffer.
        !           560:        mov     bp, sp
        !           561:        mov     ax, 12(bp)              / Get low word of block number.
        !           562:        mov     dx, 14(bp)              / Get high word of block number.
        !           563:        mov     bx, 16(bp)              / Get a buffer to put it in.
        !           564:        mov     bp, bx
        !           565:        / Translate block number into cylinder, head, and sector.
        !           566: 3:
        !           567:        mov     bx, ax                  / save block number
        !           568:        movb    al, heads               / get number of heads
        !           569:        movb    cl, sects               / get number of sectors
        !           570:        mulb    cl                      / calculate sectors per cylinder
        !           571:        xchg    bx,ax                   / swap block/sectors
        !           572:        div     bx                      / calculate track
        !           573:        xchg    dx, ax                  / put track in DX
        !           574:        divb    cl                      / calculate head/sector
        !           575:        movb    cl, ah                  / set sector
        !           576:        inc     cx                      / sectors start at 1 [incb cl]
        !           577:        
        !           578:        cmp     dx, traks               / check for second side
        !           579:        jb      0f
        !           580:        sub     dx, traks               / fold track
        !           581:        inc     ax                      / next head [incb al]
        !           582: 0:     rorb    dh, $1                  / rotate track(low) into
        !           583:        rorb    dh, $1                  /  msbits of DX
        !           584:        orb     cl, dh                  / set track(high)
        !           585:        movb    ch, dl                  / set track(low)
        !           586:        movb    dh, al                  / set head
        !           587:        movb    dl, drive               / set drive
        !           588:        mov     bx, bp                  / set offset [bbuf]
        !           589:        mov     ax, $READ1              / Read, 1 sector.
        !           590:        int     DISK                    / Disk I/O.
        !           591:        jnc     2f                      / Jump if no error.
        !           592:        mov     ax, $READ1              / try again
        !           593:        int     DISK
        !           594:        jc      berror
        !           595: 2:
        !           596:        / al contains the number of blocks read (should be 1).
        !           597:        pop     dx                      / restore registers.
        !           598:        pop     bp
        !           599:        pop     di
        !           600:        pop     si
        !           601:        pop     es
        !           602:        ret                             / return.
        !           603: /* builtin.c -- builtin routines for tboot.
        !           604:  *
        !           605:  * Add new ones by adding a check for them in interpret().
        !           606:  *
        !           607:  * La Monte H. Yarroll <[email protected]>, September 1991
        !           608:  */
        !           609: extern int slow_flag;  /* Slow down pacifier.  */
        !           610: extern int feet_flag;  /* Enable pacifier footprints.  */
        !           611: /* If possible, execute "command".
        !           612:  * Return "true" if the command exists, "false" otherwise.
        !           613:  */
        !           614: int
        !           615: interpret(command)
        !           616:        char *command;
        !           617: {
        !           618: } /* interpret() */
        !           619: /* Display the BIOS parameters loaded up by the startup code.  */
        !           620: void
        !           621: dpb()
        !           622: {
        !           623: } /* dpb() */
        !           624: /* Ask the BIOS how many drives are attached.  */
        !           625: int get_num_of_drives()
        !           626: {
        !           627: } /* get_num_of_drives() */
        !           628: /* Create a listing of file names in /.  */
        !           629: void
        !           630: dir()
        !           631: {
        !           632: } /* dir() */
        !           633: /* cbootlib.c -- C routines for use by boot programs.
        !           634:  *
        !           635:  * La Monte H. Yarroll <[email protected]>, September 1991
        !           636:  */
        !           637: /* puts() -- put a NUL terminated string.
        !           638:  * Takes one argument--a pointer to a NUL terminated character string.
        !           639:  * Does no error checking.  Calls the assembly language routine putc().
        !           640:  */
        !           641: void
        !           642: puts(s)
        !           643:        register char *s;
        !           644: {
        !           645: } /* puts() */
        !           646: /* gets() -- Read string from keyboard.
        !           647:  * Takes one argument--a pointer to a buffer big enough for the
        !           648:  * expected response.
        !           649:  * It stops reading as soon as it detects a carriage return.  The CR
        !           650:  * is replaced with a NUL.
        !           651:  */
        !           652: char *
        !           653: gets(s)
        !           654:        char *s;
        !           655: {
        !           656: } /* gets() */
        !           657: /* Reverse string s in place.
        !           658:  * Straight from K&R.
        !           659:  */
        !           660: void
        !           661: reverse(s)
        !           662:        char s[];
        !           663: {
        !           664: } /* reverse() */
        !           665: /* Convert n to decimal characters in s.
        !           666:  * Straight from K&R  (with minor sylistic changes.)
        !           667:  */
        !           668: void
        !           669: itoa(n, s)
        !           670:        char s[];
        !           671:        int n;
        !           672: {
        !           673: } /* itoa() */
        !           674: /* Convert n to digits in s, base base.
        !           675:  * Works for any base from 2 to 36.
        !           676:  * Modified itoa() from K&R.
        !           677:  */
        !           678: void
        !           679: itobase(n, s, base)
        !           680:        uint16 n;
        !           681:        char s[];
        !           682:        int base;
        !           683: {
        !           684: } /* itobase() */
        !           685: /* basetoi(char *s, int base)
        !           686:  * Convert a string base "base" to an integer.
        !           687:  * Good through base 36.
        !           688:  * Loosely based on K&R's atoi().
        !           689:  */
        !           690: uint16
        !           691: basetoi(s, base)
        !           692:        char *s;
        !           693:        int base;
        !           694: {
        !           695: } /* basetoi() */
        !           696: /* seginc(uint16 *offset,
        !           697:  *       uint16 *segment,
        !           698:  *       uint16 increment)
        !           699:  * Add an offset to a segment.  We may adjust the segment base
        !           700:  * to make everything fit.
        !           701:  */
        !           702:                                 * segments are PP aligned.
        !           703:                                 */
        !           704:  
        !           705: void
        !           706: seginc(offset, segment, increment)
        !           707:        uint16 *offset;
        !           708:        uint16 *segment;
        !           709:        uint16 increment;
        !           710: {
        !           711: } /* seginc() */
        !           712: /* Pad a string s on the left with character c, to length n.
        !           713:  * The old contents of s are replaced by the padded version.
        !           714:  */
        !           715: char *
        !           716: lpad(s, c, n)
        !           717:        char *s;
        !           718:        char c;
        !           719:        int n;
        !           720: {
        !           721: } /* lpad() */
        !           722: /*
        !           723:  * Print a 32 bit integer in hexadecimal.
        !           724:  */
        !           725: void
        !           726: print32(my_int)
        !           727:        uint32 my_int;
        !           728: {
        !           729: }
        !           730: /*
        !           731:  * Print a 16 bit integer in hexadecimal.
        !           732:  */
        !           733: void
        !           734: print16(my_int)
        !           735:        uint16 my_int;
        !           736: {
        !           737: }
        !           738: /*
        !           739:  * Print an 8 bit integer in hexadecimal.
        !           740:  */
        !           741: void
        !           742: print8(my_int)
        !           743:        uint8 my_int;
        !           744: {
        !           745: }
        !           746: /*
        !           747:  * Wrapper for far-far copy.  Changes the segment so that the requested
        !           748:  * length does not wrap past the end of the segment.
        !           749:  *
        !           750:  * For Intel 8086 Real Mode.
        !           751:  */
        !           752: void
        !           753: ffcopy(to_offset, to_seg, from_offset, from_seg, length)
        !           754:        uint16 to_offset;
        !           755:        uint16 to_seg;
        !           756:        uint16 from_offset;
        !           757:        uint16 from_seg;
        !           758:        uint16 length;
        !           759: {
        !           760: } /* ffcopy() */
        !           761: /*
        !           762:  * Align a far address so that its offset is within a paragraph of
        !           763:  * the start of the segment.
        !           764:  *
        !           765:  * Note that we ignore overflow in the segment, since this is exactly
        !           766:  * what happens when you offset past the end of the highest segment.
        !           767:  *
        !           768:  * WARNING: This routine is destructive to its arguments.
        !           769:  *
        !           770:  * For Intel 8086 Real Mode.
        !           771:  */
        !           772: void
        !           773: seg_align(offset, segment)
        !           774:        uint16 *offset;
        !           775:        uint16 *segment;
        !           776: {
        !           777: } /* seg_align() */
        !           778: /*
        !           779:  * wait_for_keystroke() -- wait for a specific keystroke.
        !           780:  */
        !           781: /* Location of BIOS-run timer.  */
        !           782: /*
        !           783:  * Waits delay ticks for the requested keystroke.  Returns TRUE if
        !           784:  * keystroke came, FALSE if delay runs out.
        !           785:  * If key == -1, accept ANY keystroke.
        !           786:  */
        !           787: int
        !           788: wait_for_keystroke(delay, key)
        !           789:        int delay;
        !           790:        int key;
        !           791: {
        !           792: } /* wait_for_keystrok() */
        !           793: /* coff.c -- rutines for manipulating coff executable files.  */
        !           794: /* Convert COFF to load table.
        !           795:  * Used to generate loading instructions for use by tboot main().
        !           796:  * Returns true on successful translation.
        !           797:  */
        !           798: int
        !           799: coff2load(ip, table, data_seg)
        !           800:        struct inode *ip;               /* input: File to read.         */
        !           801:        struct load_segment table[];    /* output: How to read it.      */
        !           802:        uint16 *data_seg;       /* output: Where to point es.   */
        !           803: {
        !           804: }
        !           805: /*
        !           806:  * Symbol name.
        !           807:  */
        !           808: static char *
        !           809: symName(sym, str_tab, work)
        !           810: SYMENT *sym;
        !           811: char *str_tab, *work;
        !           812: {
        !           813: }
        !           814: /*
        !           815:  * Look up the value of a single data symbol in a coff file,
        !           816:  * relative to the start of the data segment.
        !           817:  *
        !           818:  * We use the symbol "sdata" to find the start of the data segment--
        !           819:  * this works for 386 COHERENT kernels but will not work in general.
        !           820:  * It should really fetch the address of the start of the data segment
        !           821:  * from the data section header.
        !           822:  */
        !           823: uint32
        !           824: wrap_coffnlist(fn, symbol)
        !           825:        char *fn;       /* file name */
        !           826:        char *symbol;   /* symbol to look up */
        !           827: {
        !           828: } /* wrap_coffnlist() */
        !           829: int
        !           830: coffnlist(fn, nlp, names, count)
        !           831: char *fn;      /* file name */
        !           832: SYMENT *nlp;   /* names to look up */
        !           833: char *names;   /* long names */
        !           834: int count;     /* size of passed table */
        !           835: {
        !           836: }
        !           837: main()
        !           838: {
        !           839: }
        !           840: /* diskio.c -- C routines for disk i/o in tertiary boot programs.
        !           841:  *
        !           842:  * La Monte H. Yarroll <[email protected]>, September 1991
        !           843:  */
        !           844: /* Aligning bread.
        !           845:  * Reads 1 block into an arbitrary buffer.  The assembly language
        !           846:  * routine bread() needs a buffer aligned on a 4K boundary.
        !           847:  */
        !           848: char bufspace[FOURK+BLOCK];
        !           849: char *lbuf = NULL;     /* Buffer for bread.  */
        !           850: BUF *
        !           851: bread(blockno)
        !           852:        daddr_t blockno;        /* Block number.  */
        !           853: {
        !           854: } /* bread() */
        !           855: /*
        !           856:  * Inode OPEN: Load the inode for a file into memory.
        !           857:  * iopen(struct inode *ip,
        !           858:  *      ino_t inode_number)
        !           859:  *
        !           860:  */  
        !           861: int
        !           862: iopen(meminode, inode_number)
        !           863:        struct inode *meminode;
        !           864:        ino_t inode_number;
        !           865: {
        !           866: } /* iopen() */
        !           867: /* Convert a filename to an inode number.  Returns inode number 0 on
        !           868:  * failure.
        !           869:  */ 
        !           870: ino_t
        !           871: namei(filename)
        !           872:        char *filename;
        !           873: {
        !           874: } /* namei() */
        !           875: /*
        !           876:  * Inode READ: Load a local buffer from a file.
        !           877:  * iread(struct inode *ip,
        !           878:  *      char *buffer,
        !           879:  *      fsize_t offset,
        !           880:  *      uint16 lenarg);
        !           881:  */
        !           882: void
        !           883: iread(ip, buffer, offset, lenarg)
        !           884:        struct inode *ip;       /* Read from this file,         */
        !           885:        char *buffer;           /* into this buffer,            */
        !           886:        fsize_t offset;         /* from here in the file,       */
        !           887:        uint16 lenarg;  /* for this many bytes.         */
        !           888: {
        !           889: } /* iread() */
        !           890: /*
        !           891:  * Inode to Far READ: Load an arbitrary length from a file into a far address.
        !           892:  * ifread(struct inode *ip,
        !           893:  *       uint16 toseg,
        !           894:  *       uint16 tooffset,
        !           895:  *       fsize_t offset,
        !           896:  *       fsize_t length);
        !           897:  */
        !           898: void
        !           899: ifread(ip, toseg, tooffset, offset, lenarg)
        !           900:        struct inode *ip;       /* Read from this file,         */
        !           901:        uint16 toseg;   /* into this far buffer,        */
        !           902:        uint16 tooffset;
        !           903:        fsize_t offset;         /* from here in the file,       */
        !           904:        fsize_t lenarg;         /* for this many bytes.         */
        !           905: {
        !           906: } /* ifread() */
        !           907: /* Aligning xbread.
        !           908:  * Disk addresses are relative to the start of the disk, rather than
        !           909:  * the start of the partition.
        !           910:  * Reads 1 block into an arbitrary buffer.  The assembly language
        !           911:  * routine xbread() needs a buffer aligned on a 4K boundary.
        !           912:  */
        !           913: BUF *
        !           914: xbread(blockno)
        !           915:        daddr_t blockno;        /* Block number.  */
        !           916: {
        !           917: } /* xbread() */
        !           918: /*
        !           919:  *
        !           920:  * fdisk( fp ) --      Fixed Disk Configuration
        !           921:  * dev_t dev;
        !           922:  * struct fdisk_s *fp;
        !           923:  *
        !           924:  *     Input:  fp  = pointer to memory-resident partition info (to update)
        !           925:  *
        !           926:  *     Action: Read first block from the device.
        !           927:  *             If valid signature present on block,
        !           928:  *                     copy partition information to memory
        !           929:  *
        !           930:  *     Return: 1 = partition information successfully updated
        !           931:  *             0 = failure (could not read block, or bad signature)
        !           932:  */
        !           933: int
        !           934: fdisk( fp )
        !           935: register FDISK_S *fp;
        !           936: {
        !           937: }
        !           938: /*
        !           939:  * fifo_b.c -- Extra routines for handling typed fifos.
        !           940:  * Both fifo_b.c (boot fifo) and fifo_k.c (kernel fifo) are needed by the
        !           941:  * boot code.
        !           942:  */
        !           943: /* How long is an open fifo?  */
        !           944: long
        !           945: fifo_len(ffp)
        !           946:        FIFO *ffp;
        !           947: {
        !           948: } /* fifo_len() */
        !           949: /* Write a typed space into a FIFO.  */
        !           950: typed_space *
        !           951: fifo_write(ffp, space)
        !           952:        FIFO *ffp;
        !           953:        typed_space *space;
        !           954: {
        !           955: } /* fifo_write() */
        !           956: /* Write a chunk of data into an open fifo as a typed space.
        !           957:  * Takes a FIFO to be written to, ffp; a pointer to the data, datum; a
        !           958:  * size for the datum, size; and a type for the new space, type.
        !           959:  *
        !           960:  * Returns a pointer to the newly written space.  Returns NULL if the
        !           961:  * new space could not be written.
        !           962:  *
        !           963:  * Note that while sizes throughout this package refer to TOTAL sizes
        !           964:  * including headers, the size argument here is ONLY for the datum.
        !           965:  *
        !           966:  * Only FIFOs of type T_FIFO_SIC are implimented.
        !           967:  */
        !           968: typed_space *
        !           969: fifo_write_untyped(ffp, datum, size, type)
        !           970:        FIFO *ffp;
        !           971:        char *datum;
        !           972:        long size;
        !           973:        space_type type;
        !           974: {
        !           975: } /* fifo_write_untyped() */
        !           976: /*
        !           977:  * fifo_k.c -- Routines for reading interally typed fifos.
        !           978:  * These are all that need to be included in the kernel.
        !           979:  */
        !           980: /* The input channel from tboot to the kernel.  */
        !           981: TYPED_SPACE(boot_gift, 512, T_FIFO_SIC);
        !           982: /* Read a typed space from a fifo.
        !           983:  * Return a pointer to the next typed space in the fifo ffp.  Returns
        !           984:  * NULL on end of fifo.
        !           985:  *
        !           986:  * This read assumes that ffp->f_space has type T_FIFO_SIC.
        !           987:  */
        !           988: typed_space *
        !           989: fifo_read(ffp)
        !           990:        register FIFO *ffp;
        !           991: {
        !           992: } /* fifo_read() */
        !           993: /* Go back to the start of the fifo.
        !           994:  * Takes a FIFO.  For reading, go back to the first space; for writing
        !           995:  * truncate the FIFO to empty.
        !           996:  * Returns 1 on success, 0 otherwise.
        !           997:  */
        !           998: int
        !           999: fifo_rewind(ffp)
        !          1000:        FIFO *ffp;
        !          1001: {
        !          1002: } /* fifo_rewind() */
        !          1003: /* Finish with using a typed space as a fifo.
        !          1004:  * Free up FIFO structure associated with a typed space.
        !          1005:  * Returns 0 if ffp was not open, 1 otherwise.
        !          1006:  */
        !          1007: int
        !          1008: fifo_close(ffp)
        !          1009:        FIFO *ffp;
        !          1010: {
        !          1011: } /* fifo_close() */
        !          1012: /* Open a typed space as a fifo.
        !          1013:  *
        !          1014:  * Takes a typed_space that is already allocated, and a mode.    The type of
        !          1015:  * the typed space must be a FIFO.  Only T_FIFO_SIC has been implimented
        !          1016:  * (static, in-core fifo).
        !          1017:  *
        !          1018:  * The mode indicates whether to open for reading or writing.
        !          1019:  *  mode == 0 means read only.
        !          1020:  *  mode == 1 means write only.
        !          1021:  *  Other values are illegal.
        !          1022:  *
        !          1023:  * Returns a pointer to an initialized FIFO structure.  FIFO structures are
        !          1024:  * allocated from a pre-allocated array.  Returns F_NULL if it can't open
        !          1025:  * the fifo.
        !          1026:  */
        !          1027: FIFO *
        !          1028: fifo_open(fifo_space, mode)
        !          1029:        typed_space *fifo_space;
        !          1030:        int mode;
        !          1031: {
        !          1032: } /* fifo_open() */
        !          1033: /* This is the typed space we will use for our FIFO operations.  */
        !          1034: TYPED_SPACE(global_space, 128, T_FIFO_SIC);    /* Static In-Core Fifo.  */
        !          1035: int
        !          1036: main()
        !          1037: {
        !          1038: } /* main() */
        !          1039: /* gift.c -- Prepare a gift of information for the program currently loaded.
        !          1040:  *
        !          1041:  * To pass a new data structure into the kernel:
        !          1042:  *
        !          1043:  * 1. Define your new data structure in typed.h.  You will probably want
        !          1044:  *    to define some supporting routines for your data structure.  These
        !          1045:  *    should go in a file by themselves.  Be sure to add the file to the
        !          1046:  *    tboot Makefile.
        !          1047:  * 
        !          1048:  * 2. Write a routine that takes at least an ffp, which will generate your
        !          1049:  *    data structure and write it into the ffp.  The routine should return 0
        !          1050:  *    if it ran out of space in the FIFO.  Other return values are permissible,
        !          1051:  *    but ignored.  Add arguments to prepare_gift() as needed.  It is called
        !          1052:  *    only from the end of main() in tboot.c
        !          1053:  *
        !          1054:  * 3. Add a call to your routine to prepare_gift() in the section marked
        !          1055:  *    FILL THE BOX.  This is an if statement with || seperated calls.  The
        !          1056:  *    most important data structures should be called first, because later
        !          1057:  *    calls will be skipped if the FIFO fills.
        !          1058:  *
        !          1059:  * 4. In the kernel (probably in a driver) you will want to add a loop to
        !          1060:  *    look through the gift for your data structure:
        !          1061:  *
        !          1062:  *    FIFO *ffp;
        !          1063:  *    typed_space *tp;
        !          1064:  *
        !          1065:  *    ffp = fifo_open(&boot_gift, 0);  -- Open gift for reading. 
        !          1066:  * 
        !          1067:  *    if (F_NULL == ffp) {
        !          1068:  *       indicate_error("Could not open boot_gift.");
        !          1069:  *    } else {
        !          1070:  *        while (T_NULL != (tp = fifo_read(ffp))) {    -- While not EOFIFO.
        !          1071:  *           if (T_MYTYPE == tp->ts_type) {    -- Is this my type?
        !          1072:  *               my_handler(tp->ts_data);      -- Process the data.
        !          1073:  *           }
        !          1074:  *        }
        !          1075:  *    }
        !          1076:  *
        !          1077:  *    Be sure to include fifo.c and typed.h into your kernel.
        !          1078:  *       
        !          1079:  */
        !          1080: /* We have to build the gift in the local segment and then copy it in
        !          1081:  * place.  In a better world, the gift could be built in place.
        !          1082:  */
        !          1083: TYPED_SPACE(local_gift, GIFTBOX, T_FIFO_SIC); /* Static In-Core Fifo.  */
        !          1084: /* Prepare a gift of information for the program currently loaded.
        !          1085:  *
        !          1086:  * The gift is a Static In-Core FIFO whose objects are typed spaces.
        !          1087:  *
        !          1088:  * cmd_line is the command line needby by gift_argf().
        !          1089:  *
        !          1090:  * It should be placed in memory at data_seg:offset.
        !          1091:  */
        !          1092: void
        !          1093: prepare_gift(data_seg, offset, cmd_line)
        !          1094:        uint16 data_seg;
        !          1095:        uint16 offset;
        !          1096:        char *cmd_line;
        !          1097: {
        !          1098: } /* prepare_gift() */
        !          1099: /* Load the BIOS parameters loaded up by the startup code.  */
        !          1100: int
        !          1101: gift_drive_params(ffp)
        !          1102:        FIFO *ffp;
        !          1103: {
        !          1104: } /* gift_drive_params() */
        !          1105: /* We'd really rather have a dynamic in-core fifo, but they are not
        !          1106:  * yet implimented.  We'll have to settle for a fixed length argument list.
        !          1107:  */
        !          1108: TYPED_SPACE(argf, BLOCK, T_FIFO_SIC);
        !          1109: /*
        !          1110:  * To read this item from bootgift, use the procedure outlined above in
        !          1111:  * point 4 to find the entry marked T_STR_ARGF.  You must then explicitly
        !          1112:  * recast it with RETYPE(tp->ts_data, T_FIFO_SIC).  Then you can open it
        !          1113:  * as a FIFO, with code modeled on point 4 above.  This scheme seemed
        !          1114:  * the simplest for uniquely identifying the argument FIFO.
        !          1115:  * Each element of the FIFO is a T_STR_STR, so ts_data for these is
        !          1116:  * just a NUL terminated string.  You can a
        !          1117:  */
        !          1118: /* Write an argument fifo into ffp from the command line cmd_line.
        !          1119:  * Returns 0 if it runs out of space, 1 on success, and 2 if something else
        !          1120:  * goes wrong.
        !          1121:  */
        !          1122: int
        !          1123: gift_argf(ffp, cmd_line)
        !          1124:        FIFO *ffp;
        !          1125:        char *cmd_line;
        !          1126: {
        !          1127: } /* gift_argf() */
        !          1128: /* Write a structure describing the boot partition into a fifo.
        !          1129:  * Returns 1 on success, 0 if it runs out of space, or 2 if it
        !          1130:  * can't read the boot block.
        !          1131:  */
        !          1132: int
        !          1133: gift_rootdev(ffp)
        !          1134:        FIFO *ffp;
        !          1135: {
        !          1136: } /* gift_rootdev() */
        !          1137: /* Dump the contents of boot_gift.  */
        !          1138: void
        !          1139: dump_gift()
        !          1140: {
        !          1141: }
        !          1142: /* Dump the contents of a fifo.  */
        !          1143: void
        !          1144: dump_fifo(fifo)
        !          1145:        typed_space *fifo;
        !          1146: {
        !          1147: } /* dump_gift() */
        !          1148: /* Dump a T_BIOS_DISK typed_space.  */
        !          1149: void
        !          1150: dump_bios_disk(a_disk)
        !          1151:        BIOS_DISK *a_disk;
        !          1152: {
        !          1153: } /* dump_bios_disk() */
        !          1154: /* Dump a T_BIOS_ROOTDEV typed_space.  */
        !          1155: void
        !          1156: dump_rootdev(a_rootdev)
        !          1157:        BIOS_ROOTDEV *a_rootdev;
        !          1158: {
        !          1159: } /* dump_rootdev() */
        !          1160: /*
        !          1161:  * Handle the indirections in Unix-style file system.
        !          1162:  *
        !          1163:  * Uses a recursive scheme to follow up indirections.
        !          1164:  *
        !          1165:  * Needs optimization.  A good place to start would be caching of
        !          1166:  * lookup tables.
        !          1167:  *
        !          1168:  * La Monte H. Yarroll <[email protected]>, September 1991
        !          1169:  */
        !          1170: extern BUF *bread();
        !          1171: daddr_t vmap();
        !          1172: daddr_t indirect();
        !          1173: daddr_t ind_lookup();
        !          1174: uint16 ind_index();
        !          1175: /* Convert the given virtual block to a physical block for the given inode.
        !          1176:  * ip points to the in-core inode for a file.
        !          1177:  * vblockno is a block number relative to the start of that file.
        !          1178:  */
        !          1179: daddr_t
        !          1180: vmap(ip, vblockno)
        !          1181:        struct inode *ip;
        !          1182:        daddr_t vblockno;
        !          1183: {
        !          1184: } /* vmap() */
        !          1185: /* indirect(uint16 ind_level, daddr_t ind_table_ptr, daddr_t vblockno)
        !          1186:  * Recursively follow an indirection for a given virtual block number
        !          1187:  * vblockno.
        !          1188:  * ind_level must be the level of indirection still un-resolved.
        !          1189:  * ind_table is the physical block number of the next indirection.
        !          1190:  */
        !          1191: daddr_t
        !          1192: indirect(ind_level, ind_table_ptr, vblockno)
        !          1193:        uint16 ind_level;
        !          1194:        daddr_t ind_table_ptr;
        !          1195:        daddr_t vblockno;
        !          1196: {
        !          1197: } /* indirect() */
        !          1198: /* ind_lookup(uint16 ind_level, daddr_t *ind_table, daddr_t vblockno)
        !          1199:  * Look up the next level of block in table ind_table, for virtual
        !          1200:  * block number vblockno.
        !          1201:  * Note that this table is in DISK CANNONICAL format.  If the local
        !          1202:  * notion of daddr_t is a different size from DISK CANONICAL daddr_t
        !          1203:  */
        !          1204: daddr_t
        !          1205: ind_lookup(ind_level, ind_table, vblockno)
        !          1206:        uint16 ind_level;
        !          1207:        daddr_t *ind_table;
        !          1208:        daddr_t vblockno;
        !          1209: {
        !          1210: }
        !          1211: /* uint16 ind_index(uint16 ind_level, daddr_t vblockno);
        !          1212:  * Calculate the index needed for virtual block vblockno into
        !          1213:  * a table of the given indirection level.
        !          1214:  */
        !          1215:                         * NBN = 128 entries = 7 bit address.
        !          1216:                         */
        !          1217: uint16
        !          1218: ind_index(ind_level, vblockno)
        !          1219:        uint16 ind_level;
        !          1220:        daddr_t vblockno;
        !          1221: {}
        !          1222: //////////
        !          1223: / From MSDOS MWC86 system call interface.
        !          1224: / Interrupt simulation.
        !          1225: / Modified for use with tertiary boot code for COHERENT.
        !          1226: / 
        !          1227: / Modified September 1991 by La Monte H. Yarroll <[email protected]>
        !          1228: /
        !          1229: / DANGER!! THIS IS SELF MODIFYING CODE.  IT WILL ONLY WORK IN A STRICTLY
        !          1230: / SINGLE THREADED ENVIRONMENT.
        !          1231: //////////
        !          1232: //////////
        !          1233: / void
        !          1234: / intcall(src, dest, intnum)
        !          1235: / struct reg *src;             /* All regs are loaded except flags */
        !          1236: / struct reg *dest;            /* All regs are stored here */
        !          1237: / int intnum;                  /* Int number */
        !          1238: //////////
        !          1239: src    =       6+RASIZE
        !          1240: dest   =       src+PTRSIZE
        !          1241: intnum =       dest+PTRSIZE
        !          1242:        .globl  intcall_
        !          1243: intcall_:
        !          1244:        push    si                      / Save register variables.
        !          1245:        push    di
        !          1246:        push    bp
        !          1247:        mov     bp, sp
        !          1248:        movb    al, intnum(bp)          / Get intnum in AL
        !          1249:        movb    cs:myint+1, al          / Modify the code
        !          1250:        Lds     si, src(bp)             / Load DS:SI with src pointer.
        !          1251:        mov     ax, (si)                / Set AX
        !          1252:        mov     bx, 2(si)               / and BX
        !          1253:        mov     cx, 4(si)               / and CX
        !          1254:        mov     dx, 6(si)               / and DX
        !          1255:        mov     di, 10(si)              / and DI,
        !          1256:        push    12(si)                  / save src DS,
        !          1257:        mov     es, 14(si)              / set ES
        !          1258:        mov     si, 8(si)               / and SI
        !          1259:        pop     ds                      / and DS.
        !          1260:                                        / Actually do the interrupt.
        !          1261: myint: int     0                       / This instruction gets modified.
        !          1262: / The interrupt handler preserves SS:SP.
        !          1263: / The iret to the handler pops the handler address and flags pushed above,
        !          1264: / the iret from the handler pops the retint address and flags.
        !          1265: retint:
        !          1266:        mov     bp, sp                  / Restore BP.
        !          1267:        pushf                           / Save result flags
        !          1268:        push    es                      / and ES
        !          1269:        push    ds                      / and DS
        !          1270:        push    si                      / and SI.
        !          1271:        mov     si, ss
        !          1272:        mov     ds, si                  / Restore DS
        !          1273:        mov     es, si                  / and ES.
        !          1274:        Lds     si, dest(bp)            / Get dest in DS:SI.
        !          1275:        mov     (si), ax                / Load dest with returned AX
        !          1276:        mov     2(si), bx               / and BX
        !          1277:        mov     4(si), cx               / and CX
        !          1278:        mov     6(si), dx               / and DX
        !          1279:        pop     8(si)                   / and SI
        !          1280:        mov     10(si), di              / and DI
        !          1281:        pop     12(si)                  / and DS
        !          1282:        pop     14(si)                  / and ES
        !          1283:        pop     16(si)                  / and flags.
        !          1284:        pop     bp
        !          1285:        pop     di
        !          1286:        pop     si
        !          1287:        Gret
        !          1288: / end of intcall.m
        !          1289: /* l.out.c -- routines for manipulating l.out executable files.  */
        !          1290: /* Convert l.out to load table.
        !          1291:  * Used to generate loading instructions for use by tboot main().
        !          1292:  * Returns true on successful translation.
        !          1293:  */
        !          1294: int
        !          1295: lout2load(ip, table, data_seg)
        !          1296:        struct inode *ip;               /* input: File to read.         */
        !          1297:        struct load_segment table[];    /* output: How to read it.      */
        !          1298:        uint16 *data_seg;       /* output: Where to point es.   */
        !          1299: {
        !          1300: }
        !          1301: /*
        !          1302:  * Get entries from l.out name list.
        !          1303:  */
        !          1304: void
        !          1305: l_out_nlist(fn, nlp)
        !          1306: char *fn;
        !          1307: struct nlist *nlp;
        !          1308: {
        !          1309: }
        !          1310: /* Mini-monitor for testing boot code.
        !          1311:  *
        !          1312:  * La Monte H. Yarroll <[email protected]>, September 1991
        !          1313:  */
        !          1314: void
        !          1315: monitor()
        !          1316: {
        !          1317: }
        !          1318: /* objects.c -- routines for handling different object formats.
        !          1319:  * Currently, only COFF and COHERENT l.out are supported.
        !          1320:  */
        !          1321: /* Extract information from an object file that describes how to
        !          1322:  * load an executable.
        !          1323:  * The magic number of the file is in "magic".
        !          1324:  * The object file's inode is in "ip".
        !          1325:  *
        !          1326:  * The information needed is extracted into "table".
        !          1327:  * The value for the data segment is put in "data_seg".
        !          1328:  *
        !          1329:  * Returns TRUE if the needed information could be extracted, FALSE ow.
        !          1330:  */
        !          1331: int
        !          1332: object2load(magic, ip, table, data_seg)
        !          1333:        uint16 magic;
        !          1334:        struct inode *ip;
        !          1335:        struct load_segment table[];
        !          1336:        uint16 *data_seg;
        !          1337: {
        !          1338: } /* object2load() */
        !          1339: /* Look up symbol(s) in an object file. 
        !          1340:  * searches  the name list  (symbol table) of  the load module
        !          1341:  * "filename" for each symbol in the array pointed to by "nlp".
        !          1342:  *
        !          1343:  * nlp points to an array of nlist structures, terminated by a
        !          1344:  * structure with a null string as its n_name member.
        !          1345:  *
        !          1346:  * If "filename" is not a load module or has had its symbol table
        !          1347:  * stripped, all returned n_type and n_value entries will be zero.
        !          1348:  *
        !          1349:  */
        !          1350: uint16
        !          1351: object_nlist(magic, filename, symbol)
        !          1352:        uint16 magic;
        !          1353:        char *filename;
        !          1354:        char *symbol;
        !          1355: {
        !          1356: } /* object_nlist() */
        !          1357: /* Determine the value for sys_base based on the type of the load file.  */
        !          1358: uint16
        !          1359: object_sys_base(magic)
        !          1360:        int magic;
        !          1361: {
        !          1362: } /* object_sys_base() */
        !          1363: main()
        !          1364: {
        !          1365: } /* main () */
        !          1366: /*
        !          1367:  * pacifier.c - state machine for putting something interesting on the screen.
        !          1368:  */
        !          1369: int slow_flag = FALSE;         /* Slow down pacifier.  */
        !          1370: int feet_flag = FALSE;         /* Print footprints?  */
        !          1371: void pac_init();               /* Initialise the state machine.  */
        !          1372: void pac_cleanup();            /* Clean up after the state machine.  */
        !          1373: void pacifier();               /* Run the next step of the state machine.  */
        !          1374: void subliminal();     /* Print a subliminal message.  */
        !          1375: static int pac_inited = FALSE; /* Has pac_init() been called?  */
        !          1376: static int pac_dirty = FALSE;  /* Has pacifier() been called?  */
        !          1377: static int state;
        !          1378: static int substate;
        !          1379: static int count;
        !          1380: void
        !          1381: pacifier()
        !          1382: {
        !          1383: } /* pacifier() */
        !          1384: /*
        !          1385:  * Print a subliminal message on the console.
        !          1386:  * It does this by printing the message, backspacing over it,
        !          1387:  * spacing over it, and the backspacing again.
        !          1388:  */
        !          1389: void
        !          1390: subliminal(msg)
        !          1391:        char *msg;
        !          1392: {
        !          1393: } /* subliminal() */
        !          1394: /*
        !          1395:  * Initialize the pacifier state machine.
        !          1396:  */
        !          1397: void
        !          1398: pac_init()
        !          1399: {
        !          1400: } /* pac_init() */
        !          1401: /*
        !          1402:  * Clean up the screen after the pacifier.
        !          1403:  */
        !          1404: void
        !          1405: pac_cleanup()
        !          1406: {
        !          1407: } /* pac_cleanup() */
        !          1408: /* sys.c -- Simulate kernel calls for file i/o.
        !          1409:  */
        !          1410: int errno;
        !          1411: /* Table of file descriptors.  */
        !          1412: static FD u_filep[NUFILE];
        !          1413: static struct inode ip_table[NUFILE];
        !          1414: static inited = (1==2);
        !          1415: /* Open a file.
        !          1416:  * Takes a file name, file; and a way of opening it, type as follows:
        !          1417:  *     0       Read only
        !          1418:  *     1       Write
        !          1419:  *     2       Read and write
        !          1420:  * Only read is implimented.
        !          1421:  *
        !          1422:  * Returns a file descriptor, or -1 if the open failed.
        !          1423:  */
        !          1424: int
        !          1425: open(file, type)
        !          1426:        char *file;
        !          1427:        int type;
        !          1428: {
        !          1429: } /* open() */
        !          1430: /* Read from a file.
        !          1431:  * Takes a file descriptor, a buffer, and a length to read.
        !          1432:  *
        !          1433:  * Returns the number of characters read, or -1 if an error occurs.
        !          1434:  */
        !          1435: int
        !          1436: read(fd, buffer, n)
        !          1437:        int fd;
        !          1438:        char *buffer;
        !          1439:        int n;
        !          1440: {
        !          1441: } /* read() */
        !          1442: /* Close a file.
        !          1443:  * Takes a file descriptor.
        !          1444:  */
        !          1445: int
        !          1446: close(fd)
        !          1447:        int fd;
        !          1448: {
        !          1449: } /* close() */
        !          1450: /* Set a read/write position.
        !          1451:  * Changes the seek position for file descriptor fd.
        !          1452:  * where and  how describe the  new seek position.   where gives the
        !          1453:  * number of  bytes that you wish  to move the seek  position; it is
        !          1454:  * measured from the beginning of the  file if how is zero, from the
        !          1455:  * current seek position if how is  one, or from the end of the file
        !          1456:  * if how is  two.  A successful call to lseek  returns the new seek
        !          1457:  * position; a failure returns (int32) -1.
        !          1458:  */
        !          1459: long
        !          1460: lseek(fd, where, how)
        !          1461:        int fd;
        !          1462:        long where;
        !          1463:        int how;
        !          1464: {
        !          1465: } /* lseek() */
        !          1466: /* tboot.c -- tertiary boot
        !          1467:  * This is invoked by the secondary boot to do all the things we can't
        !          1468:  * do in just 512 bytes.
        !          1469:  *
        !          1470:  * Includes an interpreter for builtin commands.  Just type "info" or "dir"
        !          1471:  * to get disk information, or a directory listing of "/".
        !          1472:  *
        !          1473:  * Can load an image up to 1 gigabyte in length.  Segments can be as
        !          1474:  * big as the whole file.
        !          1475:  *
        !          1476:  * La Monte H. Yarroll <[email protected]>, September 1991
        !          1477:  */
        !          1478: /* Potentially communicated information from an earlier tboot.  */
        !          1479: TYPED_SPACE(boot_gift, 8192, T_FIFO_SIC);      /* Static In-Core FIFO.  */
        !          1480: main()
        !          1481: {
        !          1482: }

unix.superglobalmegacorp.com

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