Annotation of coherent/d/286_KERNEL/USRSRC/286/as1.s, revision 1.1.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.