Annotation of coherent/d/PS2_KERNEL/i286/as1.s, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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