Annotation of coherent/d/286_KERNEL/USRSRC/286/as1.s, revision 1.1

1.1     ! root        1: / $Header: /x/usr/src/sys/i8086/src/RCS/as1.s,v 1.2 91/06/20 14:07:20 hal Exp $
        !             2: 
        !             3: / (lgl-
        !             4: /      The information contained herein is a trade secret of Mark Williams
        !             5: /      Company, and  is confidential information.  It is provided  under a
        !             6: /      license agreement,  and may be  copied or disclosed  only under the
        !             7: /      terms of  that agreement.  Any  reproduction or disclosure  of this
        !             8: /      material without the express written authorization of Mark Williams
        !             9: /      Company or persuant to the license agreement is unlawful.
        !            10: /
        !            11: /      COHERENT Version 2.3.37
        !            12: /      Copyright (c) 1982, 1983, 1984.
        !            13: /      An unpublished work by Mark Williams Company, Chicago.
        !            14: /      All rights reserved.
        !            15: / -lgl)
        !            16: ////////
        !            17: /
        !            18: / Machine language assist for
        !            19: / 8086/8088 Coherent. This contains the parts
        !            20: / that are common to all machines.
        !            21: /
        !            22: / Note that several of the following constants can be invalidated
        !            23: / by changing the contents of ../h/*proc.h among others,
        !            24: / or by changing the number of automatic variables in the functions
        !            25: / called on the paths leading to consave or conrest.  Tread with caution.
        !            26: /
        !            27: / $Log:        as1.s,v $
        !            28: / Revision 1.2  91/06/20  14:07:20  hal
        !            29: / I'm not sure what changed here.
        !            30: 
        !            31: / Revision 1.3 88/08/05  08:32:09      src
        !            32: / Kludges for AMD 286 bug have been removed.
        !            33: / 
        !            34: / Revision 1.2 88/06/24  16:02:08      src
        !            35: / Bug: inb/outb did not work properly in split stack/data operation.
        !            36: / Fix: inb/outb now explicitly reference the stack segment.
        !            37: / 
        !            38: / Revision 1.1 88/03/24  17:39:08      src
        !            39: / Initial revision
        !            40: / 
        !            41: / 88/03/10     Allan Cornish           /usr/src/sys/i8086/src/as1.s
        !            42: / Numerous temporary fixes due to AMD 286 chip being buggy in protected mode.
        !            43: / These partial fixes will be removed once all CPU's are replaced.
        !            44: /
        !            45: / 88/03/04     Allan Cornish           /usr/src/sys/i8086/src/as1.s
        !            46: / tmpcs*/tmpds* temporary variables renamed to sav_*.
        !            47: / usave/conrest/etc now handle odd byte alignment on stack.
        !            48: / envrest/conrest now do interrupt return as last instruction.
        !            49: /
        !            50: / 87/12/21     Allan Cornish           /usr/src/sys/i8086/src/as1.s
        !            51: / fclear(f,n) function added.
        !            52: /
        !            53: / 87/12/04     Allan Cornish           /usr/src/sys/i8086/src/as1.s
        !            54: / kfcopy(k,f,n) and fkcopy(f,k,n) routines added.
        !            55: /
        !            56: / 87/12/03     Allan Cornish           /usr/src/sys/i8086/src/as1.s
        !            57: / popf replaced by 'push cs; mov ax,$0f; push ax; iret; 0:' due to popf int bug.
        !            58: /
        !            59: / 87/11/05     Allan Cornish           /usr/src/sys/i8086/src/as1.s
        !            60: / slrcopy/srlcopy/sclear renamed plrcopy/prlcopy/pclear and moved to ibm*/as2.s
        !            61: /
        !            62: / 87/10/27     Allan Cornish   /usr/src/sys/i8086/src/as1.s
        !            63: / System stack/data segments now setup in ibm/ibm_at as2.s
        !            64: /
        !            65: / 87/02/06     Allan Cornish
        !            66: / Functions ffword and sfword added to fetch and set far memory.
        !            67: /
        !            68: ////////
        !            69: 
        !            70: UPASIZE        =       1024                    / Size of uproc and stack
        !            71: USIZE  =       0x114                   / sizeof(UPROC)
        !            72: USZ1   =       140                     / Word count for usave, uproc size
        !            73: UMCSP  =       0x06                    / offset of sp in u_syscon
        !            74: EFAULT =       14                      / Bad argument
        !            75: PFLAGS =       0x22                    / Offset into PROC.
        !            76: PFKERN =       0x80                    / Kernel process flag bit.
        !            77: SIDEV  =       0x40                    / Device interrupt trap code.
        !            78: 
        !            79: ////////
        !            80: /
        !            81: / After performing machine specific
        !            82: / trap vector setup, the startup code jumps
        !            83: / here. The DS maps the vectors.
        !            84: /
        !            85: ////////
        !            86: 
        !            87:        .globl  start
        !            88: 
        !            89: start:
        !            90: / Call the machine setup code.
        !            91: / Call Coherent main.
        !            92: / On return, send control off to the user
        !            93: / at its entry point.
        !            94: 
        !            95:        mov     sp, $u_+UPASIZE-32      / Stack pointer for init
        !            96:        call    i8086_                  / Do it.
        !            97:        sti                             / Interrupts on, and
        !            98:        call    main_                   / call Coherent mainline.
        !            99:        cli                             / Interrupts off.
        !           100:        incb    depth_                  / Set stack depth to user.
        !           101:        sub     ax, ax                  / User mode IP.
        !           102:        mov     bx, uds_                / User mode DS, ES, SS
        !           103:        mov     cx, ucs_                / User mode CS.
        !           104:        mov     dx, $0x0200             / User mode FL.
        !           105: 
        !           106:        mov     ds, bx                  / Map data segment
        !           107:        mov     es, bx                  / Map extra segment
        !           108:        mov     ss, bx                  / Map stack segment
        !           109: 
        !           110:        mov     sp, $sb-aicodep_        / User's stack
        !           111:        push    dx                      / Flags
        !           112:        push    cx                      / CS
        !           113:        push    ax                      / IP
        !           114:        iret                            / Go to user state.
        !           115: 
        !           116: ////////
        !           117: /
        !           118: / Trap and interrupt save.
        !           119: / These routines will be very familiar to any
        !           120: / RSX-11M hackers out there; it is just the ever
        !           121: / common co-routine call. The caller is called back,
        !           122: / with "bx" pointing to the saved "ax" on the stack,
        !           123: / with interrupts enabled. The called routine must
        !           124: / set 16(bx), which was initially the call back address,
        !           125: / to something non zero in the high byte if it does
        !           126: / not want an EOI sent to the 8259.
        !           127: /
        !           128: / ttsave, tksave, tisave, and tusave could be folded into a single routine
        !           129: / with many tests and branches, but the frequency of passage through
        !           130: / this code warrants a minimally branched execution, and special casing
        !           131: / the interrupted context allows minimal memory references.
        !           132: /
        !           133: ////////
        !           134: 
        !           135:        .globl  tsave
        !           136: 
        !           137: tsave:                         / What level of interrupt ?
        !           138:        push    ds                      / Save current data base
        !           139:        mov     ds, cs:cds              / remap to system data space.
        !           140:        pop     sav_ds                  /
        !           141:        decb    depth_                  / Adjust stack depth.
        !           142:        je      tkusave                 / If e, stack switch may be needed.
        !           143: ttsave:                                / Interrupted within interrupt
        !           144:        cmp     sp,$u_+USIZE+50         / Check for stack
        !           145:        jbe     tabort                  / overflow
        !           146:        push    ss                      / Fake save ss
        !           147:        push    sp                      / Fake save sp
        !           148:        push    sav_ds                  / Save ds
        !           149:        push    bx                      / Save bx
        !           150: 
        !           151:        sti                             / More interrupts ok
        !           152: 
        !           153:        push    ax                      / Save ax
        !           154:        push    dx                      / and remainder
        !           155:        push    cx                      / of machine
        !           156:        push    es                      / state
        !           157:        mov     ax,ds                   / Map es
        !           158:        mov     es,ax                   / to system ds
        !           159:        mov     bx,sp                   / Load index
        !           160:        icall   16(bx)                  / and call the caller
        !           161:        mov     bx,sp                   / Load index
        !           162:        mov     ax,16(bx)               / fetch trap type
        !           163:        cmpb    ah, $SIDEV              / see if eoi
        !           164:        jne     ttkdone                 / can be skipped
        !           165: 
        !           166:        cli                             / don't let eoi swamp us
        !           167:        call    eoi                     / Dismiss interrupt
        !           168: ttkdone:                       / Common ttsave/tksave finish
        !           169:        pop     es                      / Restore
        !           170:        pop     cx                      / the
        !           171:        pop     dx                      / machine state
        !           172:        pop     ax                      / state
        !           173: 
        !           174:        cli                             / No more interrupts
        !           175: 
        !           176:        incb    depth_                  / Reset stack level
        !           177:        pop     bx                      / Restore the
        !           178:        pop     ds                      / last parts
        !           179:        add     sp,$6                   / forget ss, sp, and ra.
        !           180:        iret                            / Done.
        !           181: 
        !           182: tabort:                                / Uarea stack overflowed
        !           183:        add     sp,$300                 / Make room for death.
        !           184:        mov     ax,$oops                / Load
        !           185:        push    ax                      / message
        !           186:        call    panic_                  / and die.
        !           187: 
        !           188: tkusave:                       / Kernel or user process interrupted
        !           189:        mov     sav_bx,bx               / Save bx in temp
        !           190:        mov     bx,cprocp_              / Load proc pointer
        !           191:        test    PFLAGS(bx),$PFKERN      / Kernel process ?
        !           192:        je      tusave                  / Sorry, go do it all.
        !           193: tksave:                                / Kernel process interrupted
        !           194:        push    ss                      / Fake save ss
        !           195:        push    sp                      / Fake save sp
        !           196:        push    sav_ds                  / Save ds
        !           197:        push    sav_bx                  / Save bx
        !           198: 
        !           199:        sti                             / More interrupts ok.
        !           200: 
        !           201:        cmp     bx,iprocp_              / Is this the idle process ?
        !           202:        je      tisave                  / Yes, very easy
        !           203:        push    ax                      / Save the
        !           204:        push    dx                      / rest of
        !           205:        push    cx                      / the machine
        !           206:        push    es                      / state
        !           207:        mov     ax,ds                   / And map
        !           208:        mov     es,ax                   / extra to system data
        !           209:        mov     bx,sp                   / Load index
        !           210:        icall   16(bx)                  / and call the caller back.
        !           211:        mov     bx,sp                   / Load index
        !           212:        mov     ax,16(bx)               / and pull trap type.
        !           213:        cmpb    ah, $SIDEV              / Machine trap?
        !           214:        jne     ttkdone                 / Yes, skip dismiss
        !           215:        call    eoi                     / Dismiss interrupt
        !           216:        jmp     ttkdone                 / Finish above
        !           217: 
        !           218: tisave:                                / Idle process interrupted, nothing to save
        !           219:        sub     sp,$8                   / Push junk
        !           220:        mov     bx,sp                   / Load index
        !           221:        icall   16(bx)                  / and call the caller back.
        !           222:        mov     bx,sp                   / Load index
        !           223:        mov     ax,16(bx)               / and pull trap type.
        !           224:        cmpb    ah, $SIDEV              / Machine trap ?
        !           225:        jne     0f                      / Yes, skip dismiss.
        !           226:        call    eoi                     / Dismiss interrupt
        !           227: 0:
        !           228:        call    stand_                  / Clock, part 2
        !           229:        cli                             / No more interrupts
        !           230: 
        !           231:        add     sp,$18                  / Pop everything
        !           232:        incb    depth_                  / Reset level
        !           233:        iret                            / Done
        !           234: 
        !           235: tusave:                                / User process interrupted
        !           236:        mov     bx, $u_+UPASIZE         / Get base of user area and
        !           237:        pop     -8(bx)                  / pop the data that
        !           238:        pop     -6(bx)                  / was pushed onto the user
        !           239:        pop     -4(bx)                  / stack onto the new
        !           240:        pop     -2(bx)                  / system stack.
        !           241:        mov     sav_ss, ss              / Save the old stack segment
        !           242:        mov     sav_sp, sp              / and stack pointer, then
        !           243:        mov     ss, sds_                / switch onto the
        !           244:        lea     sp, -8(bx)              / new stack in the user area.
        !           245:        push    sav_ss                  / Push old ss
        !           246:        push    sav_sp                  / Push old sp
        !           247:        push    sav_ds                  / Push old ds and
        !           248:        push    sav_bx                  / push old bx.
        !           249: 
        !           250:        sti                             / Allow more interrupts.
        !           251: 
        !           252:        push    ax                      / Save the
        !           253:        push    dx                      / remainder of
        !           254:        push    cx                      / the machine
        !           255:        push    es                      / state.
        !           256:        mov     ax, ds                  / Map extra
        !           257:        mov     es, ax                  / segment to system data.
        !           258:        mov     bx, sp                  / Load up an index into the stack
        !           259:        icall   16(bx)                  / and call the caller back.
        !           260:        mov     bx, sp                  / Load up stack index.
        !           261:        mov     ax, 16(bx)              / Pull trap type.
        !           262:        cmpb    ah, $SIDEV              / Is this a machine trap ?
        !           263:        jne     0f                      / Yes, skip dismiss.
        !           264:        call    eoi                     / Do the dismiss.
        !           265: 0:     mov     bx, cprocp_             / Have we become kernel?
        !           266:        test    PFLAGS(bx), $PFKERN     / If so, do kernel return.
        !           267:        jne     ttkdone                 /
        !           268: 
        !           269:        call    stand_                  / Clock, part 2
        !           270:        pop     es                      / Restore the
        !           271:        pop     cx                      / easy part of the
        !           272:        pop     dx                      / machine
        !           273:        pop     ax                      / state.
        !           274: 
        !           275:        cli                             / Interrupts off.
        !           276: 
        !           277:        incb    depth_                  / Adjust stack depth and
        !           278:        pop     sav_bx                  / Pop off the old bx and
        !           279:        pop     sav_ds                  / ds into statics, then
        !           280:        pop     bx                      / map DS:BX over top of what
        !           281:        pop     ds                      / was the previous stack.
        !           282:        add     sp, $2                  / Pop ra.
        !           283:        pop     -6(bx)                  / Copy the IP,
        !           284:        pop     -4(bx)                  / the CS and the old
        !           285:        pop     -2(bx)                  / FW onto the user's stack, then
        !           286:        lea     sp, -6(bx)              / switch back
        !           287:        mov     bx, ds                  / to the
        !           288:        mov     ss, bx                  / user's stack.
        !           289:        mov     ds, cs:cds              /
        !           290:        mov     bx, sav_bx              / Reload the bx and the
        !           291:        mov     ds, sav_ds              / ds, then
        !           292:        iret                            / exit interrupt.
        !           293: 
        !           294: ////////
        !           295: /
        !           296: / This dummy routine is put in vector
        !           297: / table slots that are unused. All it does is
        !           298: / return to the caller.
        !           299: /
        !           300: ////////
        !           301: 
        !           302:        .globl  vret_
        !           303: 
        !           304: vret_: ret
        !           305: 
        !           306: ////////
        !           307: /
        !           308: / Fetch a word from the user's data space.
        !           309: /
        !           310: / getuwd(u)
        !           311: / char *u;
        !           312: /
        !           313: ////////
        !           314: 
        !           315:        .globl  getuwd_
        !           316:        .globl  getupd_
        !           317: 
        !           318: getuwd_:
        !           319: getupd_:
        !           320:        mov     bx,sp                   / Base pointer
        !           321:        mov     bx,2(bx)                / Argument
        !           322:        cmp     bx,udl_                 / In range?
        !           323:        ja      kuerr                   / No
        !           324: 
        !           325:        push    es                      / Save extra map and
        !           326:        mov     es, uds_                / remap over the user's data.
        !           327:        mov     ax,es:(bx)              / Get word
        !           328:        pop     es                      / Restore es.
        !           329:        ret                             / Return
        !           330: 
        !           331: ////////
        !           332: /
        !           333: / Fetch a word from the user's code space.
        !           334: /
        !           335: / getuwi(u)
        !           336: / char *u;
        !           337: /
        !           338: ////////
        !           339: 
        !           340:        .globl  getuwi_
        !           341: 
        !           342: getuwi_:
        !           343:        mov     bx,sp                   / Base pointer
        !           344:        mov     bx,2(bx)                / Argument
        !           345:        cmp     bx,ucl_                 / In range?
        !           346:        ja      kuerr                   / No
        !           347: 
        !           348:        push    es                      / Save extra.
        !           349:        mov     es,ucs_                 / Users data segment
        !           350:        mov     ax,es:(bx)              / Get word
        !           351:        pop     es                      / Restore extra.
        !           352:        ret                             / Return
        !           353: 
        !           354: ////////
        !           355: /
        !           356: / Fetch a byte from the user's data space.
        !           357: /
        !           358: / getubd(u)
        !           359: / char *u;
        !           360: /
        !           361: ////////
        !           362: 
        !           363:        .globl  getubd_
        !           364: 
        !           365: getubd_:
        !           366:        mov     bx,sp                   / Base pointer
        !           367:        mov     bx,2(bx)                / Argument
        !           368:        cmp     bx,udl_                 / In range?
        !           369:        ja      kuerr                   / No
        !           370: 
        !           371:        push    es                      / Save es.
        !           372:        mov     es,uds_                 / Users data segment
        !           373:        movb    al,es:(bx)              / Get word
        !           374:        pop     es                      / Restore es.
        !           375:        subb    ah,ah                   / Clear upper half
        !           376:        ret                             / Return
        !           377: 
        !           378: ////////
        !           379: /
        !           380: / Store a word into the user's data space.
        !           381: /
        !           382: / putuwd(u, w)
        !           383: / char *u;
        !           384: / int w;
        !           385: /
        !           386: ////////
        !           387: 
        !           388:        .globl  putuwd_
        !           389: 
        !           390: putuwd_:
        !           391:        mov     bx,sp                   / Base pointer
        !           392:        mov     ax,4(bx)                / New value
        !           393:        mov     bx,2(bx)                / Argument
        !           394:        cmp     bx,udl_                 / In range?
        !           395:        ja      kuerr                   / No
        !           396: 
        !           397:        push    es                      / Save es.
        !           398:        mov     es,uds_                 / Users data segment
        !           399:        mov     es:(bx),ax              / Set value
        !           400:        pop     es                      / Restore es.
        !           401:        sub     ax,ax                   / Succesful
        !           402:        ret                             / Return
        !           403: 
        !           404: ////////
        !           405: /
        !           406: / Store a word into the user's code space.
        !           407: /
        !           408: / putuwi(u, w)
        !           409: / char *u;
        !           410: / int w;
        !           411: /
        !           412: ////////
        !           413: 
        !           414:        .globl  putuwi_
        !           415: 
        !           416: putuwi_:
        !           417:        mov     bx,sp                   / Base pointer
        !           418:        mov     ax,4(bx)                / New value
        !           419:        mov     bx,2(bx)                / Argument
        !           420:        cmp     bx,ucl_                 / In range?
        !           421:        ja      kuerr                   / No
        !           422: 
        !           423:        push    ucs_                    / Get physical address.
        !           424:        sub     ax, ax                  / DX:AX = phy = vtop( ucs:0 );
        !           425:        push    ax                      /
        !           426:        call    vtop_                   /
        !           427:        add     sp, $4                  /
        !           428:                                        /
        !           429:        sub     bx, bx                  / Get writable virtual address.
        !           430:        push    bx                      / DX:AX = fp = ptov( phy, ucl );
        !           431:        push    ucl_                    /
        !           432:        push    dx                      /
        !           433:        push    ax                      /
        !           434:        call    ptov_                   /
        !           435:        add     sp, $8                  /
        !           436:                                        /
        !           437:        mov     bx, sp                  /
        !           438:        mov     ax, 4(bx)               / New value
        !           439:        mov     bx, 2(bx)               / Argument
        !           440:        push    es                      / Save ES
        !           441:        mov     es, dx                  / Users (writable) code segment
        !           442:        mov     es:(bx), ax             / Set value
        !           443:        pop     es                      / Restore es
        !           444:                                        /
        !           445:        push    dx                      / Release writable virtual address.
        !           446:        sub     ax, ax                  / vrelse( fp );
        !           447:        push    ax                      /
        !           448:        call    vrelse_                 /
        !           449:        add     sp, $4                  /
        !           450:                                        /
        !           451:        sub     ax,ax                   / Succesful
        !           452:        ret                             / Return
        !           453: 
        !           454: ////////
        !           455: /
        !           456: / Store a byte into the user's data space.
        !           457: /
        !           458: / putubd(u, w)
        !           459: / char *u;
        !           460: / int w;
        !           461: /
        !           462: ////////
        !           463: 
        !           464:        .globl  putubd_
        !           465: 
        !           466: putubd_:
        !           467:        mov     bx,sp                   / Base pointer
        !           468:        mov     ax,4(bx)                / New value
        !           469:        mov     bx,2(bx)                / Argument
        !           470:        cmp     bx,udl_                 / In range?
        !           471:        ja      kuerr                   / No
        !           472: 
        !           473:        push    es                      / Save es.
        !           474:        mov     es,uds_                 / Users data segment
        !           475:        movb    es:(bx),al              / Set value
        !           476:        pop     es                      / Restore es.
        !           477:        sub     ax,ax                   / Succesful
        !           478:        ret                             / Return
        !           479: 
        !           480: ////////
        !           481: /
        !           482: / Block transfer "n" bytes from location
        !           483: / "k" in the system map to location "u" in the
        !           484: / user's data space. Return the number of bytes
        !           485: / transferred.
        !           486: /
        !           487: / kucopy(k, u, n)
        !           488: / char *k;
        !           489: / char *u;
        !           490: / int n;
        !           491: /
        !           492: ////////
        !           493: 
        !           494:        .globl  kucopy_
        !           495: 
        !           496: kucopy_:
        !           497:        mov     bx,sp                   / Base pointer
        !           498:        mov     ax,4(bx)                / User address
        !           499:        dec     ax                      / Don't wrap too soon
        !           500:        add     ax,6(bx)                / Add count
        !           501:        jc      kuerr                   / Out of bounds
        !           502:        cmp     ax,udl_                 / In range?
        !           503:        ja      kuerr                   / No
        !           504: 
        !           505:        push    si                      / Save si
        !           506:        push    di                      / Save di
        !           507:        push    es                      / Save es.
        !           508: 
        !           509:        mov     si,2(bx)                / Kernel address
        !           510:        mov     di,4(bx)                / User address
        !           511:        mov     cx,6(bx)                / Count
        !           512:        mov     ax,cx                   / Move here to return
        !           513:        mov     es,uds_                 / Map extra segment to user
        !           514: 
        !           515:        cld                             / Auto increment
        !           516:        clc                             /
        !           517:        rcr     cx, $1                  / Calculate Word count
        !           518:        rep                             /
        !           519:        movsw                           / Move words.
        !           520:        rcl     cx, $1
        !           521:        rep
        !           522:        movsb                           / Move odd byte.
        !           523: 
        !           524:        pop     es                      / Restore es.
        !           525:        pop     di                      / Restore di
        !           526:        pop     si                      / Restore si
        !           527:        ret                             / Return
        !           528: 
        !           529: ////////
        !           530: /
        !           531: / Block copy "n" bytes from location "u" in
        !           532: / the user data space to location "k" in the system
        !           533: / data space. Return the actual number of bytes
        !           534: / moved.
        !           535: /
        !           536: / ukcopy(u, k, n)
        !           537: / char *u;
        !           538: / char *k;
        !           539: / int n;
        !           540: /
        !           541: ////////
        !           542: 
        !           543:        .globl  ukcopy_
        !           544: 
        !           545: ukcopy_:
        !           546:        mov     bx,sp                   / Base pointer
        !           547:        mov     ax,2(bx)                / User address
        !           548:        dec     ax                      / Don't wrap too soon
        !           549:        add     ax,6(bx)                / Count
        !           550:        jc      kuerr                   / Out of bounds
        !           551:        cmp     ax,udl_                 / In range?
        !           552:        ja      kuerr                   / No
        !           553: 
        !           554:        push    si                      / Save si
        !           555:        push    di                      / Save di
        !           556:        push    ds                      / Save ds
        !           557: 
        !           558:        mov     si,2(bx)                / User address
        !           559:        mov     di,4(bx)                / Kernel address
        !           560:        mov     cx,6(bx)                / Count
        !           561:        mov     ax,cx                   / Move here to return
        !           562:        mov     bx, uds_                / Map data segment
        !           563:        mov     ds, bx                  / avoiding bug in 8088.
        !           564: 
        !           565:        cld                             / Auto increment
        !           566:        clc                             /
        !           567:        rcr     cx, $1                  / Word count, odd byte in carry.
        !           568:        rep                             /
        !           569:        movsw                           / Move words.
        !           570:        rcl     cx, $1
        !           571:        rep                             / Move odd byte.
        !           572:        movsb
        !           573: 
        !           574:        pop     ds                      / Restore ds
        !           575:        pop     di                      / Restore di
        !           576:        pop     si                      / Restore si
        !           577:        ret                             / Return
        !           578: 
        !           579: ////////
        !           580: /
        !           581: / All of the above copy routines jump to
        !           582: / "kuerr", with the stack untouched, if they detect
        !           583: / a bounds error on a user address.
        !           584: /
        !           585: ////////
        !           586: 
        !           587: kuerr:
        !           588:        mov     bx,$u_                  / Pointer to user area
        !           589:        movb    (bx),$EFAULT            / Bad parameter error
        !           590:        sub     ax,ax                   / Didn't copy anything
        !           591:        ret                             / Return
        !           592: 
        !           593: ////////
        !           594: /
        !           595: / sfbyte( fp, b )      -- set far byte
        !           596: / int far * fp;
        !           597: / int b;
        !           598: /
        !           599: ////////
        !           600: 
        !           601:        .globl  sfbyte_
        !           602: 
        !           603: sfbyte_:push   es              / sfbyte( fp, b )
        !           604:        push    di              / register int far * fp;        /* ES:DI */
        !           605:        push    bp              / register int b;               /* AX */
        !           606:        mov     bp, sp          / {
        !           607:        les     di, 8(bp)       /
        !           608:        mov     ax, 12(bp)      /
        !           609:                                /
        !           610:        movb    es:(di), al     /       *fp = b;
        !           611:                                /
        !           612:        pop     bp              / }
        !           613:        pop     di
        !           614:        pop     es
        !           615:        ret
        !           616: 
        !           617: ////////
        !           618: /
        !           619: / sfword( fp, w )      -- set far word
        !           620: / int far * fp;
        !           621: / int w;
        !           622: /
        !           623: ////////
        !           624: 
        !           625:        .globl  sfword_
        !           626: 
        !           627: sfword_:push   es              / sfword( fp, w )
        !           628:        push    di              / register int far * fp;        /* ES:DI */
        !           629:        push    bp              / register int w;               /* AX */
        !           630:        mov     bp, sp          / {
        !           631:        les     di, 8(bp)       /
        !           632:        mov     ax, 12(bp)      /
        !           633:                                /
        !           634:        mov     es:(di), ax     /       *fp = w;
        !           635:                                /
        !           636:        pop     bp              / }
        !           637:        pop     di
        !           638:        pop     es
        !           639:        ret
        !           640: 
        !           641: ////////
        !           642: /
        !           643: / ffbyte( fp )         -- fetch far byte
        !           644: / int far * fp;
        !           645: /
        !           646: ////////
        !           647: 
        !           648:        .globl  ffbyte_
        !           649: 
        !           650: ffbyte_:push   es              / ffbyte( fp )
        !           651:        push    di              / register int far * fp;        /* ES:DI */
        !           652:        push    bp              / {
        !           653:        mov     bp, sp          /
        !           654:        les     di, 8(bp)       /
        !           655:                                /
        !           656:        sub     ax, ax          /
        !           657:        movb    al, es:(di)     /       return *fp;
        !           658:                                /
        !           659:        pop     bp              / }
        !           660:        pop     di
        !           661:        pop     es
        !           662:        ret
        !           663: 
        !           664: ////////
        !           665: /
        !           666: / ffword( fp )         -- fetch far word
        !           667: / int far * fp;
        !           668: /
        !           669: ////////
        !           670: 
        !           671:        .globl  ffword_
        !           672: 
        !           673: ffword_:push   es              / ffword( fp )
        !           674:        push    di              / register int far * fp;        /* ES:DI */
        !           675:        push    bp              / {
        !           676:        mov     bp, sp          /
        !           677:        les     di, 8(bp)       /
        !           678:                                /
        !           679:        mov     ax, es:(di)     /       return *fp;
        !           680:                                /
        !           681:        pop     bp              / }
        !           682:        pop     di
        !           683:        pop     es
        !           684:        ret
        !           685: 
        !           686: ////////
        !           687: /
        !           688: / Block transfer "n" bytes from location
        !           689: / "k" in the system map to location "f"
        !           690: / in the virtual address space.
        !           691: / Return the number of bytes / transferred.
        !           692: /
        !           693: / kfcopy(k, f, n)
        !           694: / char *k;
        !           695: / faddr_t f;
        !           696: / int n;
        !           697: /
        !           698: ////////
        !           699: 
        !           700:        .globl  kfcopy_
        !           701: 
        !           702: kfcopy_:
        !           703:        push    si                      / Save si
        !           704:        push    di                      / Save di
        !           705:        push    bp                      / Save bp
        !           706:        mov     bp, sp                  / Base pointer
        !           707:        push    es                      / Save es.
        !           708: 
        !           709:        mov     si, 8(bp)               / Kernel address
        !           710:        les     di, 10(bp)              / Far address
        !           711:        mov     cx, 14(bp)              / Count
        !           712:        mov     ax, cx                  / Move here to return
        !           713: 
        !           714:        cld                             / Auto increment
        !           715:        clc                             /
        !           716:        rcr     cx, $1                  / Calculate Word count.
        !           717:        rep                             /
        !           718:        movsw                           / Move words.
        !           719:        rcl     cx, $1                  /
        !           720:        rep                             /
        !           721:        movsb                           / Move odd byte.
        !           722:                                        /
        !           723:        pop     es                      / Restore es.
        !           724:        pop     bp                      / Restore bp.
        !           725:        pop     di                      / Restore di
        !           726:        pop     si                      / Restore si
        !           727:        ret                             / Return
        !           728: 
        !           729: ////////
        !           730: /
        !           731: / Block transfer "n" bytes from location
        !           732: / "f" in the virtual addres sspace to
        !           733: / location "f" in the system map.
        !           734: / Return the number of bytes / transferred.
        !           735: /
        !           736: / fkcopy(f, k, n)
        !           737: / faddr_t f;
        !           738: / char *k;
        !           739: / int n;
        !           740: /
        !           741: ////////
        !           742: 
        !           743:        .globl  fkcopy_
        !           744: 
        !           745: fkcopy_:
        !           746:        push    si                      / Save si
        !           747:        push    di                      / Save di
        !           748:        push    bp                      / Save bp
        !           749:        mov     bp, sp                  / Base pointer
        !           750:        push    ds                      / Save ds.
        !           751: 
        !           752:        lds     si, 8(bp)               / Far address
        !           753:        mov     di, 12(bp)              / Kernel address
        !           754:        mov     cx, 14(bp)              / Count
        !           755:        mov     ax, cx                  / Move here to return
        !           756: 
        !           757:        cld                             / Auto increment
        !           758:        clc                             /
        !           759:        rcr     cx, $1                  / Calculate Word count.
        !           760:        rep                             /
        !           761:        movsw                           / Move words.
        !           762:        rcl     cx, $1                  /
        !           763:        rep                             /
        !           764:        movsb                           / Move odd byte.
        !           765:                                        /
        !           766:        pop     ds                      / Restore ds.
        !           767:        pop     bp                      / Restore bp.
        !           768:        pop     di                      / Restore di
        !           769:        pop     si                      / Restore si
        !           770:        ret                             / Return
        !           771: 
        !           772: ////////
        !           773: /
        !           774: / fclear( fp, n )      - Erase far memory.
        !           775: / faddr_t fp;
        !           776: / unsigned n;
        !           777: /
        !           778: ////////
        !           779: 
        !           780:        .globl  fclear_
        !           781: 
        !           782: fclear_:
        !           783:        push    es                      / Save es
        !           784:        push    di                      / Save di
        !           785:        push    bp                      / Save bp
        !           786:        mov     bp, sp                  / Base pointer
        !           787: 
        !           788:        les     di, 8(bp)               / Far address
        !           789:        mov     cx, 12(bp)              / Count
        !           790:        sub     ax, ax                  /
        !           791: 
        !           792:        cld                             / Auto increment
        !           793:        clc                             /
        !           794:        rcr     cx, $1                  / Calculate Word count.
        !           795:        rep                             /
        !           796:        stosw                           / Clear words.
        !           797:        rcl     cx, $1                  /
        !           798:        rep                             /
        !           799:        stosb                           / Clear odd byte.
        !           800:                                        /
        !           801:        pop     bp                      / Restore bp.
        !           802:        pop     di                      / Restore di.
        !           803:        pop     es                      / Restore es.
        !           804:        ret                             / Return
        !           805: 
        !           806: ////////
        !           807: /
        !           808: / Profile scaling.
        !           809: /
        !           810: ////////
        !           811: 
        !           812:        .globl  pscale_
        !           813: 
        !           814: pscale_:
        !           815:        mov     bx,sp                   / Base pointer
        !           816:        mov     ax,2(bx)                / Multiply
        !           817:        mul     4(bx)                   /
        !           818:        mov     ax,dx                   / Get high half
        !           819:        ret                             / And return
        !           820: 
        !           821: ////////
        !           822: /
        !           823: / Save the environment of a process
        !           824: / envsave(p)
        !           825: / MENV *p;
        !           826: /
        !           827: / Save the context of a process
        !           828: / consave(p)
        !           829: / MCON *p;
        !           830: /
        !           831: ////////
        !           832: 
        !           833:        .globl  consave_
        !           834:        .globl  envsave_
        !           835: 
        !           836: envsave_:
        !           837: consave_:
        !           838:        mov     cx, di                  / Hide di.
        !           839:        mov     bx, sp                  / Point bx at the stack and
        !           840:        mov     di, 2(bx)               / di at the MCON block.
        !           841:        cld                             / Ensure increment.
        !           842:        mov     ax, cx                  / Save di
        !           843:        stosw
        !           844:        mov     ax, si                  / Save si
        !           845:        stosw
        !           846:        mov     ax, bp                  / Save bp
        !           847:        stosw
        !           848:        mov     ax, sp                  / Save sp
        !           849:        stosw
        !           850:        mov     ax, (bx)                / Save ra as pc
        !           851:        stosw
        !           852:        pushf                           / Save fw
        !           853:        pop     ax
        !           854:        stosw
        !           855:        movb    al, depth_              / Save stack depth
        !           856:        cbw
        !           857:        stosw
        !           858:        mov     di, cx                  / Put di back,
        !           859:        sub     ax, ax                  / indicate a state save and
        !           860:        ret                             / return to caller.
        !           861: 
        !           862: ////////
        !           863: /
        !           864: / Restore the environment of a process.
        !           865: / envrest(p)
        !           866: / MENV *p;
        !           867: /
        !           868: ////////
        !           869: 
        !           870:        .globl  envrest_
        !           871: 
        !           872: envrest_:
        !           873:        cli
        !           874:        cld
        !           875:        mov     bx,sp                   / Base pointer
        !           876:        mov     si,2(bx)                / Pointer to context
        !           877:        lodsw                           / Restore di
        !           878:        mov     di,ax                   /
        !           879:        lodsw                           / Restore si
        !           880:        mov     cx,ax                   / Save for later
        !           881:        lodsw                           / Restore bp
        !           882:        mov     bp,ax                   /
        !           883:        lodsw                           / Restore sp
        !           884:        mov     sp,ax                   /
        !           885:        mov     bx,ax                   / Our frame
        !           886:        push    cs                      / Push current CS
        !           887:        lodsw                           / Restore pc
        !           888:        push    ax                      /
        !           889:        lodsw                           / Restore flags
        !           890:        mov     (bx),ax                 / Stack now in form PSW,CS,IP.
        !           891:        lodsw                           / Restore stack depth
        !           892:        cli                             / No more interrupts
        !           893:        movb    depth_, al
        !           894:        mov     si,cx                   / Restore si
        !           895:        mov     ax,$1                   / We are restoring
        !           896:        iret                            / Return through PSW,CS,IP.
        !           897: 
        !           898: ////////
        !           899: /
        !           900: / Restore the context of a process.
        !           901: / Called with interrupts disabled from dispatch.
        !           902: / conrest(u, o)
        !           903: / saddr_t u;
        !           904: /
        !           905: ////////
        !           906: 
        !           907:        .globl  conrest_
        !           908: 
        !           909: conrest_:
        !           910:        decb    depth_                  / Falsify user/system state
        !           911:        sti                             / Interrupts ok here
        !           912:                        / Save current uarea
        !           913:        call    usave_                  / Save the uarea in its segment.
        !           914:                        / Copy in new uarea
        !           915:        mov     bx,sp                   / Base pointer
        !           916:        mov     ax, 2(bx)               / Fetch uarea saddr_t
        !           917:        mov     bx, 4(bx)               / Fetch syscon offset
        !           918:        mov     uasa_, ax               / Save uarea saddr_t
        !           919:        mov     cx,$USZ1                / uproc size
        !           920: /      mov     es,sds_                 / system data segment
        !           921:        mov     di,$u_                  / system data uarea offset
        !           922:        mov     ds,ax                   / uarea segment
        !           923:        sub     si,si                   / uarea offset
        !           924:        mov     sp,UMCSP(bx)            / new stack
        !           925:        cld                             / increment
        !           926:        rep                             / repeat
        !           927:        movsw                           / copy uproc
        !           928:        mov     di,sp                   / stack offset in system data
        !           929:        and     di,$~1                  / ensure word alignment
        !           930:        mov     cx,$u_+UPASIZE          / compute byte
        !           931:        sub     cx,di                   / count
        !           932:        mov     si,$UPASIZE             / compute offset
        !           933:        sub     si,cx                   / in segment
        !           934:        shr     cx,$1                   / make word count
        !           935:        rep                             / repeat
        !           936:        movsw                           / copy stack
        !           937:                        / Clean up
        !           938:        mov     ax, es                  / Restore data
        !           939:        mov     ds, ax                  / segment
        !           940:                        / Now restore context
        !           941:        add     bx, $u_                 / convert to address
        !           942:        mov     si, bx                  / Get source index for restore
        !           943:        lodsw                           / Restore di
        !           944:        mov     di,ax                   /
        !           945:        lodsw                           / Restore si
        !           946:        mov     cx,ax                   / Save for later
        !           947:        lodsw                           / Restore bp
        !           948:        mov     bp,ax                   /
        !           949:        lodsw                           / Restore sp
        !           950:        mov     sp,ax                   /
        !           951:        mov     bx,ax                   / Our frame
        !           952:        push    cs                      / Push current CS
        !           953:        lodsw                           / Restore pc
        !           954:        push    ax                      /
        !           955:        lodsw                           / Restore flags
        !           956:        mov     (bx),ax                 / Stack now in form PSW,CS,IP.
        !           957:        lodsw                           / Restore stack depth
        !           958:        cli                             / No more interrupts
        !           959:        movb    depth_, al
        !           960:        mov     si,cx                   / Restore si
        !           961:        mov     ax,$1                   / We are restoring
        !           962:        iret                            / Return through PSW,CS,IP.
        !           963: 
        !           964: ////////
        !           965: / usave()
        !           966: / Save uarea in segment.
        !           967: / Knowing that ds points to the system data segment
        !           968: / and that es should map there also.
        !           969: / And guaranteed not to step on ax or bx for conrest
        !           970: /
        !           971:        .globl  usave_
        !           972: 0:     ret
        !           973: usave_:
        !           974:        cmp     uasa_, $0               /
        !           975:        je      0b
        !           976:        push    es                      / Save es
        !           977:        push    si                      / Save si
        !           978:        push    di                      / Save di
        !           979:        mov     cx,$USZ1                / count
        !           980:        sub     di,di                   / uarea segment offset
        !           981:        mov     es,uasa_                / uarea segment
        !           982:        mov     si,$u_                  / system data offset
        !           983: /      mov     ds,sds_                 / system data segment
        !           984:        cld                             / increment
        !           985:        rep                             / repeat
        !           986:        movsw                           / copy uproc
        !           987:        mov     si,sp                   / stack offset in system data
        !           988:        and     si,$~1                  / ensure word alignment
        !           989:        mov     cx,$u_+UPASIZE          / compute byte
        !           990:        sub     cx,si                   / count
        !           991:        mov     di,$UPASIZE             / compute offset
        !           992:        sub     di,cx                   / in segment
        !           993:        shr     cx,$1                   / make word count
        !           994:        rep                             / repeat
        !           995:        movsw                           / copy stack
        !           996:        pop     di                      / Restore di
        !           997:        pop     si                      / Restore si
        !           998:        pop     es                      / Restore extra
        !           999:        ret
        !          1000: 
        !          1001: / Save useful registers.
        !          1002: /
        !          1003:        .globl  msysgen_
        !          1004: /
        !          1005: / msysgen(p)
        !          1006: / MGEN *p;
        !          1007: /
        !          1008: msysgen_:
        !          1009:        ret                             / Nothing useful to save
        !          1010: 
        !          1011: / Disable interrupts.  Previous value is returned.
        !          1012: /
        !          1013:        .globl  sphi_
        !          1014: 
        !          1015: sphi_:
        !          1016:        pushf                           / Save flags
        !          1017:        pop     ax                      / Return current value
        !          1018:        cli                             / Disable interrupts
        !          1019:        ret                             / And return
        !          1020: 
        !          1021: / Enable interrupts.  Previous value is returned.
        !          1022: /
        !          1023:        .globl  splo_
        !          1024: 
        !          1025: splo_:
        !          1026:        pushf
        !          1027:        pop     ax
        !          1028:        sti
        !          1029:        ret
        !          1030: 
        !          1031: / Change interrupt flag.  Previous value is returned.
        !          1032: /
        !          1033:        .globl  spl_
        !          1034: 
        !          1035: spl_:
        !          1036:        pop     ax                      / ip
        !          1037:        pop     bx                      / psw
        !          1038:        push    bx
        !          1039:        push    bx                      / push psw, cs, ip for iret
        !          1040:        push    cs
        !          1041:        push    ax
        !          1042:        pushf                           / old psw
        !          1043:        pop     ax
        !          1044:        iret
        !          1045: 
        !          1046: ////////
        !          1047: /
        !          1048: / Idle routine.
        !          1049: / Enable interupts, and wait for something to
        !          1050: / happen. Does not do anything to the 8259, bacause
        !          1051: / this will be set up correctly.
        !          1052: /
        !          1053: ////////
        !          1054: 
        !          1055:        .globl  _idle_
        !          1056: 
        !          1057: _idle_:        sti                             / Interupts on.
        !          1058:        hlt                             / Wait for an interrupt
        !          1059:        ret                             / and return.
        !          1060: 
        !          1061: ////////
        !          1062: /
        !          1063: / The world is indeed grim.
        !          1064: / Halt. Keep the interrupts on so that the
        !          1065: / keyboard can get int.
        !          1066: /
        !          1067: ////////
        !          1068: 
        !          1069:        .globl  halt_
        !          1070: 
        !          1071: halt_: sti                             / Be safe,
        !          1072: 0:
        !          1073:        hlt                             / and halt.
        !          1074:        jmp     0b                      / Paranoid, yes sir.
        !          1075: 
        !          1076: ////////
        !          1077: /
        !          1078: / Basic port level I/O.
        !          1079: /
        !          1080: / int  inb(port);
        !          1081: / int  outb(port, data);
        !          1082: /
        !          1083: ////////
        !          1084: 
        !          1085:        .globl  inb_
        !          1086:        .globl  outb_
        !          1087: 
        !          1088: inb_:  mov     bx, sp
        !          1089:        mov     dx, ss:2(bx)
        !          1090:        sub     ax, ax
        !          1091:        inb     al, dx
        !          1092:        ret
        !          1093: 
        !          1094: outb_: mov     bx, sp
        !          1095:        mov     dx, ss:2(bx)
        !          1096:        mov     ax, ss:4(bx)
        !          1097:        outb    dx, al
        !          1098:        ret
        !          1099: 
        !          1100: ////////
        !          1101: /
        !          1102: / Routines to move data to and from
        !          1103: / the system auxiliary segment.
        !          1104: /
        !          1105: ////////
        !          1106: 
        !          1107:        .globl  ageti_
        !          1108: 
        !          1109: ageti_:
        !          1110:        mov     bx,sp                   / Base pointer
        !          1111:        mov     bx,2(bx)                / Pointer
        !          1112:        push    es                      / Save extra mapping and
        !          1113:        mov     es, sas_                / remap.
        !          1114:        mov     ax,es:(bx)              / Get value
        !          1115:        pop     es                      / Restore es and
        !          1116:        ret                             / Return
        !          1117: 
        !          1118:        .globl  aputp_
        !          1119:        .globl  aputi_
        !          1120: 
        !          1121: aputp_:
        !          1122: aputi_:
        !          1123:        mov     bx,sp                   / Base pointer
        !          1124:        mov     ax,4(bx)                / Value
        !          1125:        mov     bx,2(bx)                / Pointer
        !          1126:        push    es                      / Save extra base and
        !          1127:        mov     es, sas_                / remap.
        !          1128:        mov     es:(bx),ax              / Set value
        !          1129:        pop     es                      / Restore extra base
        !          1130:        ret                             / Return
        !          1131: 
        !          1132:        .globl  aputc_
        !          1133: 
        !          1134: aputc_:
        !          1135:        mov     bx,sp                   / Base pointer
        !          1136:        mov     ax,4(bx)                / Value
        !          1137:        mov     bx,2(bx)                / Pointer
        !          1138:        push    es                      / Save es and
        !          1139:        mov     es, sas_                / remap.
        !          1140:        movb    es:(bx),al              / Set value
        !          1141:        pop     es                      / Restore es and
        !          1142:        ret                             / Return
        !          1143: 
        !          1144: ////////
        !          1145: /
        !          1146: / Data. 
        !          1147: / A small number of variables must be
        !          1148: / in the code segment. All of these variables have
        !          1149: / something to do with the interrupt linkage; when you
        !          1150: / get an interrupt the only thing that is valid is
        !          1151: / the code segment.
        !          1152: /
        !          1153: ////////
        !          1154: 
        !          1155:        .globl  cds
        !          1156: 
        !          1157:        .shri
        !          1158: cds:   .blkw   1                       / Copy of "sds_".
        !          1159: 
        !          1160:        .globl  u_
        !          1161:        .globl  depth_, sas_,   scs_,   sds_,   ucs_
        !          1162:        .globl  ucl_,   uds_,   udl_
        !          1163: 
        !          1164:        .bssd
        !          1165:        .even
        !          1166: u_:    .blkb   UPASIZE
        !          1167: 
        !          1168:        .prvd
        !          1169: oops:  .ascii  "stack overflow"
        !          1170:        .byte   0
        !          1171: 
        !          1172: depth_:        .byte   0                       / System state.
        !          1173: 
        !          1174:        .even
        !          1175: sas_:  .blkw   1                       / System auxiliary segment.
        !          1176: scs_:  .blkw   1                       / System code segment.
        !          1177: sds_:  .blkw   1                       / System data segment.
        !          1178: ucs_:  .blkw   1                       / User code segment.
        !          1179: ucl_:  .blkw   1                       / User code limit.
        !          1180: uds_:  .blkw   1                       / User data segment.
        !          1181: udl_:  .blkw   1                       / User data limit.
        !          1182: sav_ds:        .blkw   1                       / Four scratch words
        !          1183: sav_bx:        .blkw   1
        !          1184: sav_ss:        .blkw   1
        !          1185: sav_sp:        .blkw   1
        !          1186: 
        !          1187: ////////
        !          1188: /
        !          1189: / This is the image of the init process.
        !          1190: / It gets copied into a user segment when the system
        !          1191: / is first brought up. It must be in the data segment, because
        !          1192: / that is how it is used, and it must be dephased in a funny
        !          1193: / way because it is executed at location 0.
        !          1194: /
        !          1195: ////////
        !          1196: 
        !          1197:        .globl  aicodep_                / Position of code.
        !          1198:        .globl  aicodes_                / Size of code.
        !          1199:        .globl  aidatap_                / Position of data.
        !          1200:        .globl  aidatas_                / Size of data.
        !          1201: 
        !          1202:        .shrd
        !          1203: aicodep_:
        !          1204:        sub     ax,ax                   / No environment
        !          1205:        push    ax
        !          1206:        mov     ax,$argl-aidatap_       / Argument list
        !          1207:        push    ax
        !          1208:        mov     ax,$fn-aidatap_         / File name
        !          1209:        push    ax
        !          1210:        sub     sp,$2                   / Dummy word for exec
        !          1211:        sys     11                      / Sys exec
        !          1212:        jmp     .                       / This should not return
        !          1213: aicodes_ = .-aicodep_
        !          1214: 
        !          1215: aidatap_:
        !          1216:        .word   0                       /
        !          1217:        .word   0                       / Errno
        !          1218:        .word   0                       /
        !          1219:        .word   0                       /
        !          1220:        .word   0                       /
        !          1221:        .word   0                       /
        !          1222:        .word   0                       /
        !          1223:        .word   0                       /
        !          1224: argl:  .word   fn-aidatap_             / argv[0] = "/etc/init";
        !          1225:        .word   a1-aidatap_             / argv[1] = "";
        !          1226:        .word   0                       / argv[2] = NULL;
        !          1227: 
        !          1228: fn:    .ascii  "/etc/init\000"
        !          1229: a1:    .byte   0
        !          1230: 
        !          1231:        .even
        !          1232:        .blkb   64
        !          1233: sb:
        !          1234: aidatas_ = .-aidatap_

unix.superglobalmegacorp.com

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