|
|
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_
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.