|
|
1.1 ! root 1: / $Header: /kernel/kersrc/i286/RCS/as2.s,v 1.1 92/07/17 15:21:20 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: / Coherent on the IBM personal computer. ! 20: / ! 21: / $Log: as2.s,v $ ! 22: / Revision 1.1 92/07/17 15:21:20 bin ! 23: / Initial revision ! 24: / ! 25: / Revision 1.3 92/01/21 16:10:37 hal ! 26: / Use read_cmos_ routine. ! 27: / Allows merged 386 C code compatibility. ! 28: / ! 29: / Revision 1.2 91/06/06 18:14:46 norm ! 30: / Get memory size by reading CMOS. ! 31: ! 32: / Revision 1.3 88/08/05 15:37:32 src ! 33: / AMD 286 hardware specific fixes removed - hardware now correct. ! 34: / Virtual Selector F000 initialized to access ROM at F0000. ! 35: / Normal kernel stack now used during initialization. ! 36: / ! 37: / Revision 1.2 88/06/29 19:05:31 src ! 38: / AT Coherent can now come up in real-mode by patching 'realmode' variable. ! 39: / ! 40: / Revision 1.1 88/03/24 17:33:18 src ! 41: / Initial revision ! 42: / ! 43: / 88/03/10 Allan Cornish /usr/src/sys/i8086/ibm_at/as2.s ! 44: / Numerous temporary fixes due to AMD 286 chip being buggy in protected mode. ! 45: / These partial fixes will be removed once all CPU's are replaced. ! 46: / ! 47: / 88/03/07 Allan Cornish /usr/src/sys/i8086/ibm_at/as2.s ! 48: / Obsolete video() function deleted - not used, or usable in protected mode. ! 49: / Auto-increment mode no longer assumed, but enforced on block moves. ! 50: / ! 51: / 88/03/04 Allan Cornish /usr/src/sys/i8086/ibm_at/as2.s ! 52: / Memory sizing now flushes instruction pipeline before read-verify. ! 53: / Otherwise bus capacitance on some machines gives invalid memory indication. ! 54: / plrcopy, prlcopy, pclear, upcopy, kpcopy, pucopy, and pkcopy now ensure ! 55: / registers DS and ES refer to kernel data before calling ptov() or vrelse(). ! 56: / MAXMEM variable added to specify maximum low memory in clicks. ! 57: / ! 58: / 87/11/22 Allan Cornish /usr/src/sys/i8086/ibm_at/as2.s ! 59: / Added check for extended memory in protected mode. ! 60: / ! 61: / 87/11/14 Allan Cornish /usr/src/sys/i8086/ibm_at/as2.s ! 62: / boot() now requests 8042 controller to initiate processor reset. ! 63: / ! 64: / 87/11/05 Allan Cornish /usr/src/sys/i8086/ibm_at/as2.s ! 65: / slrcopy/srlcopy/sclear renamed plrcopy/prlcopy/pclear and moved here. ! 66: / ! 67: / 87/10/27 Allan Cornish /usr/src/sys/i8086/ibm_at/as2.s ! 68: / System stack/data segments now setup here rather than in as1.s ! 69: / System stack/data moved to next 128 byte boundary for protected mode. ! 70: / ! 71: / 87/08/31 Allan Cornish /usr/src/sys/i8086/ibm_at/as2.s ! 72: / Timer channel 1 now reprogrammed for memory refresh. ! 73: / ! 74: / 87/07/08 Allan Cornish /usr/src/sys/i8086/ibm_at/as2.s ! 75: / Timer chip now programmed for 100 hz clock interrupt rather than 20 hz. ! 76: / ! 77: //////// ! 78: ! 79: EFAULT = 14 / Bad argument ! 80: EXTMEML = 0x17 / Ext. mem size (low) offset in CMOS ! 81: EXTMEMH = 0x18 / (high) ! 82: PFLAGS = 0x22 / Offset int PROC. ! 83: PFKERN = 0x80 / Kernel process flag bit. ! 84: PIC = 0x20 / 8259 CSR I/O port. ! 85: PICM = 0x21 / 8259 IMR I/O port. ! 86: PIT = 0x40 / 8253 base I/O port. ! 87: KBDATA = 0x60 / 8042 keyboard mpu data I/O port. ! 88: KBCTRL = 0x64 / 8042 keyboard mpu ctrl I/O port. ! 89: CMOSA = 0x70 / Real-time Clock/CMOS addr I/O port. ! 90: CMOSD = 0x71 / Real-time Clock/CMOS data I/O port. ! 91: SPIC = 0xA0 / Slave 8259 CSR I/O port. ! 92: SPICM = 0xA1 / Slave 8259 IMR I/O port. ! 93: UPASIZE = 1024 / Size of uproc and stack ! 94: ! 95: //////// ! 96: / ! 97: / System entry point. Under PC-DOS, ! 98: / which thinks that Coherent is just a large ! 99: / user program, the code is offset by 0x100 ! 100: / to allow space for the base page. ! 101: / ! 102: //////// ! 103: ! 104: .blkb 0x0100 / PC-DOS base page. | MLK --\ ! 105: call iabios_r_ / Before we go into protected mode, init the abios ! 106: ! 107: cli / No interrupts, please. ! 108: int 0x11 / Obtain int 11 value before printf(). ! 109: mov cs:val11, ax /Use boot block's stack for last time. ! 110: / ! 111: / Enable the A20 address line, which is normally disabled by the ROM BIOS. ! 112: / This line is under the control of the 8042 keyboard interface controller. ! 113: / ! 114: sub cx, cx / ! 115: 0: inb al, KBCTRL / Wait for 8042 input buffer to empty. ! 116: testb al, $2 / ! 117: loopne 0b / ! 118: jmp .+2 / DELAY / ! 119: / ! 120: movb al, $0xD1 / Request next output byte to be ! 121: outb KBCTRL, al / sent to the 8042 output port. ! 122: / ! 123: sub cx, cx / ! 124: 0: inb al, KBCTRL / Wait for 8042 input buffer to empty. ! 125: testb al, $2 / ! 126: loopne 0b / ! 127: jmp .+2 / DELAY / ! 128: / ! 129: movb al, $0xDF / Enable A20 address line. ! 130: outb KBDATA, al / See Page 1-44, IBM-AT Tech Ref. ! 131: / ! 132: sub cx, cx / ! 133: 0: inb al, KBCTRL / Wait for 8042 input buffer to empty. ! 134: testb al, $2 / NOTE: A20 not enabled for up to 20 us. ! 135: loopne 0b / ! 136: ! 137: / ! 138: / Reprogram the 8253 timer so that channel 0, ! 139: / which is used as the clock, interrupts at exactly ! 140: / 100 HZ, instead of 18.2 HZ. ! 141: / ! 142: movb al, $0x36 / Timer 0, LSB, MSB, mode 3 ! 143: outb PIT+3, al ! 144: jmp .+2 / DELAY / ! 145: jmp .+2 / DELAY / ! 146: movb al, $0x9C / Lsb of 59659/5 = 11932 ! 147: outb PIT, al ! 148: jmp .+2 / DELAY / ! 149: jmp .+2 / DELAY / ! 150: movb al, $0x2E / Msb of 59659/5 = 11932 ! 151: outb PIT, al ! 152: jmp .+2 / DELAY / ! 153: jmp .+2 / DELAY / ! 154: ! 155: / Reprogram channel 1 on the 8253 timer which is used for memory refresh. ! 156: / movb al, $0x54 / Timer 1, LSB, mode 2 ! 157: / outb PIT+3, al ! 158: / jmp .+2 / DELAY / ! 159: / jmp .+2 / DELAY / ! 160: / movb al, $18 / LSB of 18. ! 161: / outb PIT+1, al ! 162: / jmp .+2 / DELAY / ! 163: / jmp .+2 / DELAY / ! 164: ! 165: / Reprogram the 1st programmable interrupt controller. ! 166: / It's default vector table collides with iAPX 286 protection vectors. ! 167: ! 168: / movb al, $0x11 / ICW1 - edge, master, ICW4 ! 169: movb al, $0x19 / ICW1 - level, master, ICW4 MLK ! 170: outb PIC, al ! 171: jmp .+2 / DELAY / ! 172: jmp .+2 / DELAY / ! 173: movb al, $0x20 / ICW2 - Reserve 1st 32 vectors for 286 ! 174: outb PICM, al ! 175: jmp .+2 / DELAY / ! 176: jmp .+2 / DELAY / ! 177: movb al, $0x04 / ICW3 - master level 2 ! 178: outb PICM, al ! 179: jmp .+2 / DELAY / ! 180: jmp .+2 / DELAY / ! 181: movb al, $0x01 / ICW4 - 8086 mode, master. ! 182: outb PICM, al ! 183: jmp .+2 / DELAY / ! 184: jmp .+2 / DELAY / ! 185: ! 186: movb al, $0xFE / Disable interrupts from master PIC. ! 187: outb PICM, al / (except for clock interrupt). ! 188: ! 189: movb al, $0xFF ! 190: outb SPICM, al / Disable interrupts from slave PIC. ! 191: ! 192: ! 193: / Set up all trap vectors. ! 194: / The machine traps all have their own ! 195: / linkages. We have to steal the clock from ! 196: / the ROM, because the stacks might get switched ! 197: / during the INT 1C, and the EOI would get sent ! 198: / to the 8259 at a strange time. ! 199: ! 200: sub ax, ax / Map DS over the 8088 ! 201: mov ds, ax / vector area. ! 202: ! 203: mov 0x0000, $trap0 / Divide error vector ! 204: mov 0x0002, cs ! 205: mov 0x0004, $trap1 / Single step. ! 206: mov 0x0006, cs ! 207: mov 0x0008, $trap2 / NMI ! 208: mov 0x000A, cs ! 209: mov 0x000C, $trap3 / INT 3 (break) ! 210: mov 0x000E, cs ! 211: mov 0x0010, $trap4 / Overflow. ! 212: mov 0x0012, cs ! 213: mov 0x0014, $trap5 / Bound range exceeded. ! 214: mov 0x0016, cs ! 215: mov 0x0018, $trap6 / Invalid Opcode ! 216: mov 0x001A, cs ! 217: mov 0x001C, $trap7 / Processor extension not available ! 218: mov 0x001E, cs ! 219: mov 0x0020, $trap8 / Double exception detected. ! 220: mov 0x0022, cs ! 221: mov 0x0024, $trap9 / Processor extension segment overrun. ! 222: mov 0x0026, cs ! 223: mov 0x0028, $trap10 / Invalid task state segment. ! 224: mov 0x002A, cs ! 225: mov 0x002C, $trap11 / Segment not present. ! 226: mov 0x002E, cs ! 227: mov 0x0030, $trap12 / Stack segment overrun or not present. ! 228: mov 0x0032, cs ! 229: mov 0x0034, $trap13 / General protection. ! 230: mov 0x0036, cs ! 231: ! 232: mov 0x0080, $clk_ps / Clock for PS2 MLK ! 233: / mov 0x0080, $clk / Clock. ! 234: mov 0x0082, cs ! 235: mov 0x0084, $dev1 / Device 1 ! 236: mov 0x0086, cs ! 237: mov 0x0088, $dev9 / Device 2 maps into Device 9 ! 238: mov 0x008A, cs ! 239: mov 0x008C, $dev3 / Device 3 ! 240: mov 0x008E, cs ! 241: mov 0x0090, $dev4 / Device 4 ! 242: mov 0x0092, cs ! 243: mov 0x0094, $dev5 / Device 5 ! 244: mov 0x0096, cs ! 245: mov 0x0098, $dev6 / Device 6 ! 246: mov 0x009A, cs ! 247: mov 0x009C, $dev7 / Device 7 ! 248: mov 0x009E, cs ! 249: ! 250: mov 0x01C0, $dev8 / Device 8 ! 251: mov 0x01C2, cs ! 252: mov 0x01C4, $dev9 / Device 9 ! 253: mov 0x01C6, cs ! 254: mov 0x01C8, $dev10 / Device 10 ! 255: mov 0x01CA, cs ! 256: mov 0x01CC, $dev11 / Device 11 ! 257: mov 0x01CE, cs ! 258: mov 0x01D0, $dev12 / Device 12 ! 259: mov 0x01D2, cs ! 260: mov 0x01D4, $dev13 / Device 13 ! 261: mov 0x01D6, cs ! 262: mov 0x01D8, $dev14 / Device 14 ! 263: mov 0x01DA, cs ! 264: mov 0x01DC, $dev15 / Device 15 ! 265: mov 0x01DE, cs ! 266: ! 267: mov bx, $0x0200 / INT 80 (sys 0) ! 268: 0: mov (bx), $syc / Set up the system call ! 269: mov 2(bx), cs / trap vector. ! 270: add bx, $4 / Move to next vector and ! 271: cmp bx, $0x0400 / loop until all ! 272: jb 0b / vectors are reset. ! 273: ! 274: / Set up the system stack and data segments, by looking at the size of ! 275: / the text and adding this to the base address already in the CS. ! 276: / Relocate the stack and data to a 128 byte boundary. ! 277: ! 278: mov ax, $etext_+15 / End of text segment ! 279: shr ax, $4 / Convert to paragraphs. ! 280: mov cx, cs / Get code segment base. ! 281: add ax, cx / ! 282: mov ds, ax / Current data segment ! 283: add ax, $31 / Allow virtual-physical alignment ! 284: and ax, $~31 / [use 512 byte, need 128 byte] ! 285: / ! 286: cmp realmode_, $0 / Virtual Addressing enabled? ! 287: jne 0f / ! 288: mov idtsel_, ax / Interrupt descriptor table [2 Kbytes] ! 289: add ax, $0x0080 / 2K >> 4 ! 290: mov gdtsel_, ax / Global descriptor table [64 Kbytes] ! 291: add ax, $0x1000 / 64K >> 4 ! 292: 0: / ! 293: mov es, ax / ! 294: mov si, $edata_-1 / Copy data to new location, backwards. ! 295: mov di, $edata_-1 / ! 296: mov cx, $edata_ / ! 297: std / ! 298: rep / ! 299: movsb / ! 300: / ! 301: mov ds, ax / Update data segment, ! 302: mov ss, ax / and stack segment. ! 303: mov sp, $u_+UPASIZE-32 / Set up initial stack. ! 304: mov scs_, cs / Save code segment and ! 305: mov sds_, ds / data segment bases. ! 306: mov cs:cds, ds / For interrupts. ! 307: ! 308: / Size up memory, starting just above the system. ! 309: / The memory is cleared, because somebody has to do a write ! 310: / to set up the parity bits. ! 311: ! 312: mov di, $edata_ / Clear at edata... ! 313: mov cx, $512 / for 1 Kbyte ! 314: sub ax, ax ! 315: cld ! 316: rep ! 317: stosw ! 318: ! 319: mov bp, $edata_+1023 / Compute base. ! 320: shr bp, $4 ! 321: add bp, sds_ ! 322: shr bp, $6 / Round down to a Kbyte boundary ! 323: shl bp, $6 / so's we're in sync. ! 324: ! 325: 0: sub di, di / Destination. ! 326: mov es, bp / Set extra segment and ! 327: mov es:(di), ax / clear a word. ! 328: jmp .+2 / FLUSH / ! 329: cmp es:(di), ax / Should be zero now. ! 330: jne 0f / Branch if memory end ! 331: ! 332: mov cx, $512 / 1K bytes, in words. ! 333: cld ! 334: rep ! 335: stosw / Clear this 1K ! 336: add bp, $64 / Move along by 1K ! 337: cmp bp, MAXMEM ! 338: jb 0b / If not at video ram yet ! 339: ! 340: 0: mov es, sds_ / Map extra. ! 341: ! 342: mov ax, bp / Calculate top of low memory. ! 343: rol ax, $4 / ! 344: mov dx, ax / ! 345: and ax, $0xFFF0 / ! 346: xor dx, ax / ! 347: ! 348: cmp realmode_, $0 / Real Addressing Mode? ! 349: je 0f / ! 350: mov coretop_, ax / Yes, Record top of memory, ! 351: mov coretop_+2, dx / ! 352: jmp start / and bring up system. ! 353: 0: ! 354: mov holebot_, ax / Record bottom of I/O memory. ! 355: mov holebot_+2, dx / ! 356: ! 357: mov ax, gdtsel_ / Format global descriptor table map. ! 358: rol ax, $4 / ! 359: mov dx, ax / ! 360: and ax, $0xFFF0 / ! 361: xor dx, ax / ! 362: mov gdtmap_+0, $0xFFFF / Limit: 64K bytes. ! 363: mov gdtmap_+2, ax / ! 364: mov gdtmap_+4, dx / ! 365: / ! 366: sub ax, ax / Erase global descriptor table. ! 367: mov cx, $0x8000 / [32K words = 64K bytes] ! 368: mov es, gdtsel_ / ! 369: sub di, di / ! 370: cld / ! 371: rep / ! 372: stosw / ! 373: / ! 374: mov ax, idtsel_ / Format interrupt descriptor table map ! 375: rol ax, $4 / ! 376: mov dx, ax / ! 377: and ax, $0xFFF0 / ! 378: xor dx, ax / ! 379: mov idtmap_+0, $2047 / Limit: 2K bytes. ! 380: mov idtmap_+2, ax / ! 381: mov idtmap_+4, dx / ! 382: / ! 383: sub ax, ax / Erase interrupt descriptor table. ! 384: mov cx, $1024 / [1K words = 2K bytes] ! 385: mov es, idtsel_ / ! 386: sub di, di / ! 387: cld / ! 388: rep / ! 389: stosw / ! 390: / ! 391: mov es, gdtsel_ / ! 392: mov di, cs / Define kernel code global selector. ! 393: mov ax, $etext_-1 / Limit: etext. ! 394: stosw / ! 395: mov dx, $0x9A00 / Flags: Present, executable. ! 396: mov ax, cs / Base: cs << 4. ! 397: rol ax, $4 / ! 398: xor dx, ax / ! 399: and ax, $0xFFF0 / ! 400: stosw / ! 401: xor ax, dx / ! 402: stosw / ! 403: sub ax, ax / ! 404: stosw / ! 405: / ! 406: mov di, ss / Define kernel data global selector. ! 407: mov ax, $0xFFFF / Limit: 64K bytes. ! 408: stosw / ! 409: mov dx, $0x9200 / Flags: Present, writable. ! 410: mov ax, ss / Base: ss << 4. ! 411: rol ax, $4 / ! 412: xor dx, ax / ! 413: and ax, $0xFFF0 / ! 414: stosw / ! 415: xor ax, dx / ! 416: stosw / ! 417: sub ax, ax / ! 418: stosw / ! 419: / ! 420: mov di, $8 / Define task state segment selector[8] ! 421: mov ax, $43 / Limit: 44 bytes. ! 422: stosw / ! 423: mov dx, $0x8100 / Flags: Present, avail tss seg. ! 424: mov ax, ss / Base: (ss << 4) + &tss. ! 425: rol ax, $4 / ! 426: xor dx, ax / ! 427: and ax, $0xFFF0 / ! 428: xor dx, ax / ! 429: add ax, $tss_ / ! 430: adc dx, $0 / ! 431: stosw / ! 432: mov ax, dx / ! 433: stosw / ! 434: sub ax, ax / ! 435: stosw / ! 436: / ! 437: mov di, gdtsel_ / Define gdt access global selector. ! 438: mov ax, $0xFFFF / Limit: 64K bytes. ! 439: stosw / ! 440: mov dx, $0x9200 / Flags: Present, writable. ! 441: mov ax, gdtsel_ / Base: gdtsel << 4. ! 442: rol ax, $4 / ! 443: xor dx, ax / ! 444: and ax, $0xFFF0 / ! 445: stosw / ! 446: xor ax, dx / ! 447: stosw / ! 448: sub ax, ax / ! 449: stosw / ! 450: / ! 451: mov di, idtsel_ / Define idt access global selector. ! 452: mov ax, $2047 / Limit: 2K bytes. ! 453: stosw / ! 454: mov dx, $0x9200 / Flags: Present, writable. ! 455: mov ax, idtsel_ / Base: idtsel << 4. ! 456: rol ax, $4 / ! 457: xor dx, ax / ! 458: and ax, $0xFFF0 / ! 459: stosw / ! 460: xor ax, dx / ! 461: stosw / ! 462: sub ax, ax / ! 463: stosw / ! 464: / ! 465: mov di, $0xB000 / Define video access global selector. ! 466: mov ax, $0xFFFF / Limit: 64K bytes. ! 467: stosw / ! 468: mov dx, $0x9200 / Flags: Present, writable. ! 469: mov ax, $0xB000 / Base: 0xB000 << 4. ! 470: rol ax, $4 / ! 471: xor dx, ax / ! 472: and ax, $0xFFF0 / ! 473: stosw / ! 474: xor ax, dx / ! 475: stosw / ! 476: sub ax, ax / ! 477: stosw / ! 478: / ! 479: mov di, $0xB800 / Define video access global selector. ! 480: mov ax, $0x7FFF / Limit: 32 Kbytes. ! 481: stosw / ! 482: mov dx, $0x9200 / Flags: Present, writable. ! 483: mov ax, $0xB800 / Base: 0xB800 << 4. ! 484: rol ax, $4 / ! 485: xor dx, ax / ! 486: and ax, $0xFFF0 / ! 487: stosw / ! 488: xor ax, dx / ! 489: stosw / ! 490: sub ax, ax / ! 491: stosw / ! 492: ! 493: mov di, $0xF000 / Define ROM access global selector. ! 494: mov ax, $0xFFFF / Limit: 64 Kbytes. ! 495: stosw / ! 496: mov dx, $0x9000 / Flags: Present, read only. ! 497: mov ax, $0xF000 / Base: 0xF000 << 4. ! 498: rol ax, $4 / ! 499: xor dx, ax / ! 500: and ax, $0xFFF0 / ! 501: stosw / ! 502: xor ax, dx / ! 503: stosw / ! 504: sub ax, ax / ! 505: stosw / ! 506: ! 507: mov es, idtsel_ / Map ES over the intr descr table. ! 508: sub ax, ax / Map DS over the 8088 vector area. ! 509: mov ds, ax / ! 510: sub si, si / ! 511: sub di, di / ! 512: mov bx, cs / Make CS available for comparison. ! 513: mov cx, $256 / Install 256 interrupt descriptors. ! 514: / ! 515: 0: lodsw / Copy interrupt IP ! 516: stosw / ! 517: lodsw / Copy interrupt CS ! 518: stosw / ! 519: / ! 520: cmp ax, bx / Coherent interrupt handler? ! 521: mov ax, $0x8600 / ! 522: je 1f / ! 523: sub ax, ax / No, clear flags. ! 524: / ! 525: 1: stosw / Define IDT flags. ! 526: sub ax, ax / Reserved IDT word. ! 527: stosw / ! 528: loop 0b / Repeat for all 256 entries. ! 529: / ! 530: mov ax, ss / Restore data and extra segments. ! 531: mov ds, ax / ! 532: mov es, ax / ! 533: / ! 534: clts / Clear task switched flag. ! 535: lgdt gdtmap_ / Load global descriptor table map. ! 536: lidt idtmap_ / Load interrupt descriptor table map. ! 537: / ! 538: smsw ax / Enter protected mode. ! 539: or ax, $1 / ! 540: lmsw ax / ! 541: jmp .+2 / Clear pipeline. ! 542: / ! 543: mov ax, $0x0008 / Load task state segment register. ! 544: ltr ax / ! 545: sub ax, ax / Load local descriptor table register. ! 546: lldt ax / ! 547: / ! 548: / ! 549: / Register usage: ! 550: / DX:AX = extended mem physical addr. ! 551: / BX = scratch, then 0. ! 552: / SI = selector into extended memory. ! 553: / ES = selector into extended memory. ! 554: / DS = selector into global descr table ! 555: / ! 556: push $EXTMEMH / high byte of pair ! 557: call read_cmos_ / result in ax ! 558: add sp, $2 / pop argument ! 559: movb bl, al / save al to bl ! 560: push $EXTMEML / low byte of pair ! 561: call read_cmos_ / result in ax ! 562: add sp, $2 / pop argument ! 563: movb ah, bl / restore high byte to ah ! 564: shr ax, $6 / K -> 64K conversion ! 565: add ax, $0x0010 / bias up to 1MB ! 566: mov CMOSmax_, ax / save count of 64K hunks ! 567: sub ax, ax / ! 568: mov dx, $0x0010 / Initial 64 Kbyte bank of extended mem. ! 569: mov holetop_, ax / Recorded extended memory bot in bytes. ! 570: mov holetop_+2, dx / ! 571: / ! 572: mov ds, gdtsel_ / Map DS onto global descr table. ! 573: mov si, $0xFFF8 / Define scratch access global selector. ! 574: mov 0(si), $0xFFFF / Limit: 64K bytes. ! 575: mov 2(si), $0x0000 / Base: 1 Mbyte. ! 576: mov 4(si), $0x9210 / Flags: Present, writable. ! 577: mov 6(si), $0x0000 / ! 578: / ! 579: sub bx, bx / ! 580: 0: sub di, di / Destination. ! 581: mov cx, $0x8000 / 64K bytes, in words. ! 582: mov 2(si), ax / Adjust gdt to desired DX:AX mem locn. ! 583: movb 4(si), dl / ! 584: mov es, si / Map ES onto 64K bank of extended mem. ! 585: mov es:(di), bx / Write word of extended memory. ! 586: jmp .+2 / FLUSH / ! 587: cmp es:(di), bx / Verify word was correctly written. ! 588: jne 0f / Branch if memory end. ! 589: / ! 590: cld / ! 591: rep / ! 592: stosw / Clear this 64K of extended memory. ! 593: / ! 594: inc dx / Step to next 64K bank. ! 595: cmp dx, ss:CMOSmax_ / See if we're beyond what the CMOS ! 596: jge 0f / says we have. ! 597: cmp dx, $0x00F0 / Stop at 15 Mbyte boundary; the last ! 598: jl 0b / Mbyte is a dup of the 1st Mbyte. ! 599: / ! 600: 0: movb 5(si), $0 / Free the scratch selector. ! 601: / ! 602: mov bx, ss / Restore data and extra segments. ! 603: mov ds, bx / NOTE: Do not modify DX:AX. ! 604: mov es, bx / ! 605: / ! 606: mov coretop_, ax / Recorded top of extended core memory. ! 607: mov coretop_+2, dx / ! 608: jmp start / Bring up system. ! 609: ! 610: //////// ! 611: / ! 612: / Trap an interrupt linkage. ! 613: / Each of the machine traps has a special little ! 614: / linkage, that sets up the type code and sends ! 615: / control off to the common trap processor. Device ! 616: / interrupts, other than the clock (IR0), are ! 617: / done here. ! 618: / ! 619: //////// ! 620: ! 621: trap0: ! 622: call tsave ! 623: mov 16(bx), $0x0000 / Divide error. ! 624: jmp trap_ ! 625: ! 626: trap1: ! 627: call tsave ! 628: mov 16(bx), $0x0100 / Single step. ! 629: jmp trap_ ! 630: ! 631: trap2: ! 632: call tsave ! 633: mov 16(bx), $0x0200 / Non-maskable interrupt. ! 634: jmp trap_ ! 635: ! 636: trap3: ! 637: call tsave ! 638: mov 16(bx), $0x0300 / INT 3 (breakpoint). ! 639: jmp trap_ ! 640: ! 641: trap4: ! 642: call tsave ! 643: mov 16(bx), $0x0400 / Overflow. ! 644: jmp trap_ ! 645: ! 646: trap5: ! 647: call tsave ! 648: mov 16(bx), $0x0500 / Bound check. ! 649: jmp trap_ ! 650: ! 651: trap6: ! 652: call tsave ! 653: mov 16(bx), $0x0600 / Invalid opcode. ! 654: jmp trap_ ! 655: ! 656: trap7: ! 657: call tsave ! 658: mov 16(bx), $0x0700 / Processor Extension not available. ! 659: jmp trap_ ! 660: ! 661: trap8: ! 662: pop ax / Get error code from stack [always 0] ! 663: call tsave ! 664: mov 16(bx), $0x0800 / Double Exception detected ! 665: jmp trap_ ! 666: ! 667: trap9: ! 668: call tsave ! 669: mov 16(bx), $0x0900 / Processor extension segment overrun ! 670: jmp trap_ ! 671: ! 672: trap10: ! 673: pop ax / Get error code from stack ! 674: call tsave ! 675: mov 16(bx), $0x0A00 / Invalid task state segment ! 676: jmp trap_ ! 677: ! 678: trap11: ! 679: pop ax / Get error code from stack ! 680: call tsave ! 681: mov 16(bx), $0x0B00 / Segment not present ! 682: jmp trap_ ! 683: ! 684: trap12: ! 685: pop ax / Get error code from stack ! 686: call tsave ! 687: mov 16(bx), $0x0C00 / Stack segment overrun or not present ! 688: jmp trap_ ! 689: ! 690: trap13: ! 691: pop ax / Get error code from stack ! 692: call tsave ! 693: mov 16(bx), $0x0D00 / General protection ! 694: jmp trap_ ! 695: ! 696: .globl syc ! 697: ! 698: syc: ! 699: call tsave ! 700: mov 16(bx), $0x2000 / System calls. ! 701: jmp trap_ ! 702: ! 703: ran: ! 704: call tsave ! 705: mov 16(bx), $0x2100 / Random trap. ! 706: jmp trap_ ! 707: ! 708: dev1: ! 709: call tsave ! 710: mov 16(bx), $0x4001 / Device 1: keyboard ! 711: ijmp vecs_+[2*1] ! 712: ! 713: /dev2: call tsave / Device 2: mapped into device 9 ! 714: / mov 16(bx), $0x4002 ! 715: / ijmp vecs_+[2*2] ! 716: ! 717: dev3: ! 718: call tsave ! 719: mov 16(bx), $0x4003 / Device 3: al1 ! 720: ijmp vecs_+[2*3] ! 721: ! 722: dev4: ! 723: call tsave ! 724: mov 16(bx), $0x4004 / Device 4: al0 ! 725: ijmp vecs_+[2*4] ! 726: ! 727: dev5: ! 728: call tsave ! 729: mov 16(bx), $0x4005 / Device 5: hard disk ! 730: ijmp vecs_+[2*5] ! 731: ! 732: dev6: ! 733: call tsave ! 734: mov 16(bx), $0x4006 / Device 6: floppy ! 735: ijmp vecs_+[2*6] ! 736: ! 737: dev7: ! 738: call tsave ! 739: mov 16(bx), $0x4007 / Device 7: lp ! 740: ijmp vecs_+[2*7] ! 741: ! 742: dev8: ! 743: call tsave ! 744: mov 16(bx), $0x4008 / Device 8: ! 745: ijmp vecs_+[2*8] ! 746: ! 747: dev9: ! 748: call tsave ! 749: mov 16(bx), $0x4009 / Device 9: ! 750: ijmp vecs_+[2*9] ! 751: ! 752: dev10: ! 753: call tsave ! 754: mov 16(bx), $0x400A / Device 10: ! 755: ijmp vecs_+[2*10] ! 756: ! 757: dev11: ! 758: call tsave ! 759: mov 16(bx), $0x400B / Device 11: ! 760: ijmp vecs_+[2*11] ! 761: ! 762: dev12: ! 763: call tsave ! 764: mov 16(bx), $0x400C / Device 12: ! 765: ijmp vecs_+[2*12] ! 766: ! 767: dev13: ! 768: call tsave ! 769: mov 16(bx), $0x400D / Device 13: ! 770: ijmp vecs_+[2*13] ! 771: ! 772: dev14: ! 773: call tsave ! 774: mov 16(bx), $0x400E / Device 14: ! 775: ijmp vecs_+[2*14] ! 776: ! 777: dev15: ! 778: call tsave ! 779: mov 16(bx), $0x400F / Device 15: ! 780: ijmp vecs_+[2*15] ! 781: ! 782: //////// ! 783: / ! 784: / Clock interrupt. ! 785: / The clock interrupt is stolen from the ROM; ! 786: / if you don't do this the EOI sequence for the 8259 ! 787: / may get mangled on context switches. ! 788: / ! 789: //////// ! 790: ! 791: clk_ps: / MLK ! 792: push ax ! 793: inb al, 0x61 / PS/2 8259 needs to be told to ! 794: jmp .+2 / stop interrupting the CPU, or ! 795: jmp .+2 ! 796: orb al,$0x80 / we will hang. ! 797: outb 0x61,al ! 798: pop ax / MLK ! 799: ! 800: clk: ! 801: call tsave / Perform trap save. ! 802: mov 16(bx), $0x4000 ! 803: ! 804: sub ax, ax / Assume system mode, push user flag ! 805: push ax ! 806: push 18(bx) / IP at tick time ! 807: ! 808: cmpb depth_, $0 / Correct ? ! 809: jne 0f / If ne, yes. ! 810: mov bx, cprocp_ / User depth, check if the ! 811: test PFLAGS(bx), $PFKERN / current process is a kernel process. ! 812: jne 0f / If ne, yes. ! 813: mov bx, sp / Load stack index ! 814: inc 2(bx) / and set user mode. ! 815: ! 816: 0: call clock_ / Call common clock and ! 817: add sp, $4 / pop arguments. ! 818: ! 819: ret / Back to "tsave". ! 820: ! 821: //////// ! 822: / ! 823: / This routine is called by "tsave" to dismiss an interrupt. ! 824: / The interrupt code is in "ax". ! 825: / ! 826: //////// ! 827: ! 828: .globl eoi ! 829: ! 830: eoi: ! 831: cmpb al, $8 / Is this on the slave PIC? ! 832: jb 0f / Jump if not. ! 833: movb al, $0x20 / Send a non specific EOI ! 834: outb SPIC, al / to the slave PIC. ! 835: 0: movb al, $0x20 / Send a non specific EOI ! 836: outb PIC, al / to the master PIC. ! 837: ret / Done. ! 838: ! 839: //////// ! 840: / ! 841: / Block I/O to ports. ! 842: / Mainly used to read and write the silo memories in the discs. ! 843: / Delibrately only transfers 1 byte per loop to avoid ! 844: / timing problems on AT I/O chips. ! 845: / ! 846: / void outcopy(port, off, seg, n); ! 847: / int port; /* Port address */ ! 848: / char *off; /* Offset in segment */ ! 849: / unsigned seg; /* Segment register base */ ! 850: / int n; /* Byte count */ ! 851: / ! 852: / void incopy(port, off, seg, n); ! 853: / int port; /* Device */ ! 854: / char *off; /* Offset */ ! 855: / unsigned seg; /* Segment register base */ ! 856: / int n; /* Byte count */ ! 857: / ! 858: //////// ! 859: ! 860: .globl incopy_ ! 861: .globl outcopy_ ! 862: ! 863: incopy_: ! 864: push di ! 865: push es ! 866: push bp ! 867: mov bp, sp ! 868: mov dx, 8(bp) /device port ! 869: les di, 10(bp) /seg,off pair ! 870: mov cx, 14(bp) /n bytes ! 871: jcxz 1f ! 872: ! 873: cld /auto-increment ! 874: 0: inb al, dx ! 875: stosb ! 876: loop 0b ! 877: ! 878: 1: pop bp ! 879: pop es /restore regs ! 880: pop di ! 881: ret ! 882: ! 883: outcopy_: ! 884: push si ! 885: push ds ! 886: push bp ! 887: mov bp, sp ! 888: mov dx, 8(bp) /device port ! 889: lds si, 10(bp) /offset ! 890: mov cx, 14(bp) /count ! 891: jcxz 1f ! 892: ! 893: cld /auto-increment ! 894: 0: lodsb ! 895: outb dx, al ! 896: loop 0b ! 897: ! 898: 1: pop bp ! 899: pop ds ! 900: pop si ! 901: ret ! 902: ! 903: //////// ! 904: / ! 905: / Copy "n" bytes of memory from base "p1" to base "p2". ! 906: / The copy must be done from left to right. ! 907: / ! 908: / plrcopy(p1, p2, n) ! 909: / paddr_t p1, p2; ! 910: / size_t n; ! 911: / ! 912: //////// ! 913: ! 914: .globl plrcopy_ ! 915: ! 916: plrcopy_: ! 917: push si / Save sequence ! 918: push di ! 919: push bp ! 920: mov bp, sp ! 921: ! 922: push ds / Save ds ! 923: push es / Save es ! 924: ! 925: push 18(bp) / Map SI:DI at destination ptov(p2,n). ! 926: push 16(bp) ! 927: push 14(bp) ! 928: push 12(bp) ! 929: call ptov_ ! 930: add sp, $8 ! 931: mov si, dx ! 932: mov di, ax ! 933: ! 934: push 18(bp) / Map DX:AX at source ptov(p1,n); ! 935: push 16(bp) ! 936: push 10(bp) ! 937: push 8(bp) ! 938: call ptov_ ! 939: add sp, $8 ! 940: ! 941: mov es, si / Map ES:DI at destination. ! 942: mov ds, dx / Map DS:SI at source. ! 943: mov si, ax ! 944: ! 945: mov cx, 16(bp) / Transfer count in bytes. ! 946: cld / Auto Increment. ! 947: clc / ! 948: rcr cx, $1 / Word count ! 949: rep / ! 950: movsw / Move words ! 951: rcl cx, $1 / ! 952: rep / ! 953: movsb / Move odd byte ! 954: ! 955: mov si, es / Remember mapped selectors. ! 956: mov di, ds / ! 957: pop es / Restore es ! 958: pop ds / Restore ds ! 959: ! 960: push si / Release mapped selectors. ! 961: push ax / NOTE: Offset is ignored. ! 962: call vrelse_ / ! 963: add sp, $4 / ! 964: / ! 965: push di / ! 966: push ax / ! 967: call vrelse_ / ! 968: add sp, $4 / ! 969: ! 970: pop bp / Standard return ! 971: pop di ! 972: pop si ! 973: ret / Return ! 974: ! 975: //////// ! 976: / ! 977: / Copy "n" bytes of memory from base "p1" to base "p2". ! 978: / The copy must be done from right to left. ! 979: / ! 980: / prlcopy(p1, p2, n) ! 981: / paddr_t p1, p2; ! 982: / size_t n; ! 983: / ! 984: //////// ! 985: ! 986: .globl prlcopy_ ! 987: ! 988: prlcopy_: ! 989: push si / Save sequence ! 990: push di ! 991: push bp ! 992: mov bp, sp ! 993: ! 994: push ds / Save ds ! 995: push es / Save es ! 996: ! 997: push 18(bp) / Map SI:DI at destination ptov(p2,n). ! 998: push 16(bp) ! 999: push 14(bp) ! 1000: push 12(bp) ! 1001: call ptov_ ! 1002: add sp, $8 ! 1003: mov si, dx ! 1004: mov di, ax ! 1005: ! 1006: push 18(bp) / Map DX:AX at source ptov(p1,n); ! 1007: push 16(bp) ! 1008: push 10(bp) ! 1009: push 8(bp) ! 1010: call ptov_ ! 1011: add sp, $8 ! 1012: ! 1013: mov es, si / Map ES:DI at destination. ! 1014: mov ds, dx / Map DS:SI at source. ! 1015: mov si, ax ! 1016: ! 1017: mov cx, 16(bp) / Transfer count in bytes ! 1018: add si, cx / Point DS:SI at the end ! 1019: dec si / of the source. ! 1020: add di, cx / Point ES:DI at the end ! 1021: dec di / of the destination. ! 1022: ! 1023: std / Auto decrement ! 1024: clc / ! 1025: rcr cx, $1 / Word Count ! 1026: rep / ! 1027: movsw / Move words ! 1028: rcl cx, $1 / ! 1029: rep / ! 1030: movsb / Move odd byte ! 1031: cld / Auto increment ! 1032: ! 1033: mov si, es / Remember mapped selectors. ! 1034: mov di, ds / ! 1035: pop es / Restore es ! 1036: pop ds / Restore ds ! 1037: ! 1038: push si / Release mapped selectors. ! 1039: push ax / NOTE: Offset is ignored. ! 1040: call vrelse_ / ! 1041: add sp, $4 / ! 1042: / ! 1043: push di / ! 1044: push ax / ! 1045: call vrelse_ / ! 1046: add sp, $4 / ! 1047: / ! 1048: mov ax, 16(bp) / Return transfer count. ! 1049: pop bp / Standard return ! 1050: pop di ! 1051: pop si ! 1052: ret ! 1053: ! 1054: //////// ! 1055: / ! 1056: / Clear "n" bytes of memory starting at physical address "p". ! 1057: / ! 1058: / pclear( p, n ) ! 1059: / paddr_t p; ! 1060: / size_t n; ! 1061: / ! 1062: / ! 1063: / Notes: At most 64K bytes of memory can be cleared. ! 1064: / ! 1065: //////// ! 1066: ! 1067: .globl pclear_ ! 1068: ! 1069: pclear_: ! 1070: push si / Standard save ! 1071: push di ! 1072: push bp ! 1073: mov bp, sp ! 1074: ! 1075: push es / Save es ! 1076: ! 1077: push 14(bp) / Map ES:DI at ptov(p2,n). ! 1078: push 12(bp) ! 1079: push 10(bp) ! 1080: push 8(bp) ! 1081: call ptov_ ! 1082: add sp, $8 ! 1083: mov es, dx ! 1084: mov di, ax ! 1085: ! 1086: shr 14(bp), $1 / Convert count from bytes to words. ! 1087: rcr 12(bp), $1 ! 1088: mov cx, 12(bp) / Count in words. ! 1089: ! 1090: sub ax, ax / Get a 0. ! 1091: cld / Zero the block. ! 1092: rep ! 1093: stosw ! 1094: ! 1095: mov ax, es / Remember mapped selector. ! 1096: pop es / Restore es. ! 1097: ! 1098: push ax / Release mapped selector. ! 1099: push ax / NOTE: Offset is ignored. ! 1100: call vrelse_ / ! 1101: add sp, $4 / ! 1102: ! 1103: pop bp / Standard return. ! 1104: pop di ! 1105: pop si ! 1106: ret ! 1107: ! 1108: //////// ! 1109: / ! 1110: / Block copy chunks of memory to a physical ! 1111: / location from a location in either the system ! 1112: / or user data space. ! 1113: / ! 1114: / upcopy(u, p, n) ! 1115: / char *u; ! 1116: / paddr_t p; ! 1117: / int n; ! 1118: / ! 1119: / kpcopy(k, p, n); ! 1120: / char *k; ! 1121: / paddr_t p; ! 1122: / int n; ! 1123: / ! 1124: //////// ! 1125: ! 1126: .globl upcopy_ ! 1127: ! 1128: upcopy_: ! 1129: mov bx, sp / Get set for stack index. ! 1130: mov ax, 2(bx) / User address ! 1131: dec ax / Don't wrap too soon ! 1132: add ax, 8(bx) / Count ! 1133: jc kuerr / Out of bounds ! 1134: cmp ax, udl_ / In range? ! 1135: ja kuerr / No ! 1136: push uds_ / Mark transfer ds as being user ds. ! 1137: jmp 1f / Finish in common code. ! 1138: ! 1139: .globl kpcopy_ ! 1140: ! 1141: kpcopy_: ! 1142: push ds / Mark transfer ds as being kernel ds. ! 1143: ! 1144: 1: push si / Standard save ! 1145: push di ! 1146: push bp ! 1147: mov bp, sp ! 1148: ! 1149: push ds / Save ds, es ! 1150: push es ! 1151: ! 1152: sub ax, ax / ES:DI = ptov(p,n). ! 1153: push ax / ! 1154: push 16(bp) / ! 1155: push 14(bp) / ! 1156: push 12(bp) / ! 1157: call ptov_ / ! 1158: add sp, $8 / ! 1159: mov es, dx / ! 1160: mov di, ax / ! 1161: / ! 1162: mov ds, 6(bp) / DS:SI = source address. ! 1163: mov si, 10(bp) / ! 1164: mov cx, 16(bp) / Byte count ! 1165: / ! 1166: cld / Auto Increment ! 1167: clc / ! 1168: rcr cx, $1 / Word count ! 1169: rep / ! 1170: movsw / Move words ! 1171: rcl cx, $1 / Move odd byte ! 1172: rep / ! 1173: movsb / ! 1174: / ! 1175: mov ax, es / Remember mapped selector. ! 1176: pop es / Restore es, ds. ! 1177: pop ds / ! 1178: / ! 1179: push ax / Release mapped selector. ! 1180: push ax / NOTE: Offset is ignored. ! 1181: call vrelse_ / ! 1182: add sp, $4 / ! 1183: / ! 1184: mov ax, 16(bp) / Return transfer count. ! 1185: / ! 1186: pop bp / Standard return. ! 1187: pop di ! 1188: pop si ! 1189: add sp, $2 / Discard marked transfer ds. ! 1190: ret ! 1191: ! 1192: //////// ! 1193: / ! 1194: / Block copy memory from physical address "p" ! 1195: / to either user or system data space. ! 1196: / ! 1197: / pucopy(p, u, n) ! 1198: / paddr_t p; ! 1199: / char *u; ! 1200: / int n; ! 1201: / ! 1202: / pkcopy(p, k, n); ! 1203: / paddr_t p; ! 1204: / char *k; ! 1205: / int n; ! 1206: / ! 1207: //////// ! 1208: ! 1209: .globl pucopy_ ! 1210: ! 1211: pucopy_: ! 1212: mov bx, sp / Stack index ! 1213: mov ax, 6(bx) / User address ! 1214: dec ax / Don't wrap too soon ! 1215: add ax, 8(bx) / Count ! 1216: jc kuerr / Out of bounds ! 1217: cmp ax, udl_ / In range? ! 1218: ja kuerr / No ! 1219: push uds_ / Mark transfer es as being user ds. ! 1220: jmp 1f / Common code ! 1221: ! 1222: .globl pkcopy_ ! 1223: ! 1224: pkcopy_: ! 1225: push ds / Mark transfer es as being kernel ds. ! 1226: ! 1227: 1: push si / Standard save ! 1228: push di ! 1229: push bp ! 1230: mov bp, sp ! 1231: ! 1232: push ds / Save ds, es. ! 1233: push es ! 1234: ! 1235: sub ax, ax / DS:SI = ptov(p,n). ! 1236: push ax ! 1237: push 16(bp) ! 1238: push 12(bp) ! 1239: push 10(bp) ! 1240: call ptov_ ! 1241: add sp, $8 ! 1242: mov ds, dx ! 1243: mov si, ax ! 1244: ! 1245: mov es, 6(bp) / ES:DI = destination. ! 1246: mov di, 14(bp) / ! 1247: mov cx, 16(bp) / Count ! 1248: ! 1249: cld / Incremental move ! 1250: clc / ! 1251: rcr cx, $1 / Word count ! 1252: rep / ! 1253: movsw / Move words. ! 1254: rcl cx, $1 / Move odd byte. ! 1255: rep / ! 1256: movsb / ! 1257: / ! 1258: mov ax, ds / Rememember mapped selector. ! 1259: pop es / Restore es, ds. ! 1260: pop ds / ! 1261: / ! 1262: push ax / Release mapped selector. ! 1263: push ax / NOTE: Offset is ignored. ! 1264: call vrelse_ / ! 1265: add sp, $4 / ! 1266: / ! 1267: mov ax, 16(bp) / Return transfer count. ! 1268: / ! 1269: pop bp / Restore registers. ! 1270: pop di / ! 1271: pop si / ! 1272: add sp, $2 / Discard marked transfer es. ! 1273: ret / Fin ! 1274: ! 1275: //////// ! 1276: / ! 1277: / All of the above copy routines jump to ! 1278: / "kuerr", with the stack untouched, if they detect ! 1279: / a bounds error on a user address. ! 1280: / ! 1281: //////// ! 1282: ! 1283: kuerr: ! 1284: mov bx,$u_ / Pointer to user area ! 1285: movb (bx),$EFAULT / Bad parameter error ! 1286: sub ax,ax / Didn't copy anything ! 1287: ret / Return ! 1288: ! 1289: //////// ! 1290: / Read a byte from the CMOS. Takes one argument--the ! 1291: / CMOS address to read from as an int; returns the ! 1292: / value read in ax. ! 1293: / ! 1294: / int read_cmos(addr) ! 1295: / int addr; ! 1296: / ! 1297: //////// ! 1298: .globl read_cmos_ ! 1299: read_cmos_: ! 1300: push bp ! 1301: mov bp, sp ! 1302: movb al, 4(bp) / Fetch address from stack. ! 1303: outb CMOSA, al / Send address to CMOS. ! 1304: jmp .+2 / DELAY ! 1305: sub ax, ax / Zero out everything we don't want. ! 1306: inb al, CMOSD / Get Value from CMOS into al. ! 1307: pop bp ! 1308: ret / Return from read_cmos(). ! 1309: ! 1310: ! 1311: / Read timer channel 0 into int value. ! 1312: / Clock counts down from 11932 to 0 with each clock tick. ! 1313: .globl read_t0_ ! 1314: read_t0_: ! 1315: pushf ! 1316: cli ! 1317: xor ax,ax / Counter latch timer 0 and clear return val ! 1318: outb PIT+3,al ! 1319: jmp .+2 / DELAY / ! 1320: jmp .+2 / DELAY / ! 1321: inb al,PIT / low byte of counter latch ! 1322: movb ah,al ! 1323: jmp .+2 / DELAY / ! 1324: jmp .+2 / DELAY / ! 1325: inb al,PIT / high byte of counter latch ! 1326: xchgb al,ah ! 1327: jmp .+2 / DELAY / ! 1328: jmp .+2 / DELAY / ! 1329: popf ! 1330: ret ! 1331: ! 1332: / return current contents of psw ! 1333: .globl read_psw_ ! 1334: read_psw_: ! 1335: pushf ! 1336: pop ax ! 1337: ret ! 1338: ! 1339: //////// ! 1340: / ! 1341: / Read the equipment description. Use ! 1342: / the "int 11" interface, so that the IBM ! 1343: / ROM will do all the details. ! 1344: / ! 1345: //////// ! 1346: ! 1347: .globl int11_ ! 1348: ! 1349: int11_: mov ax, cs:val11 / Ask the ROM ! 1350: ret / to put stuff in AX ! 1351: ! 1352: //////// ! 1353: / ! 1354: / Bootstrap. ! 1355: / Called by the keyboard driver on control-alt-del. ! 1356: / Requests the 8042 controller to initiate a processor reset, ! 1357: / which is the only way to terminate protected mode operation. ! 1358: / ! 1359: / Reference: IBM-AT Technical Reference Manual, ! 1360: / Real-time Clock/CMOS RAM [Page 1-45] ! 1361: / Keyboard controller [Page 1-40] ! 1362: / Test 3, Page 5-68. ! 1363: / ! 1364: //////// ! 1365: ! 1366: .globl boot_ ! 1367: boot_: ! 1368: cli / Disable interrupts. ! 1369: / ! 1370: sub cx, cx / ! 1371: 0: inb al, KBCTRL / Wait for 8042 input buffer to empty. ! 1372: testb al, $2 / ! 1373: loopne 0b / ! 1374: jmp .+2 / DELAY / ! 1375: / ! 1376: movb al, $0xFE / Issue a shutdown command ! 1377: outb KBCTRL, al / to the 8042 control port. ! 1378: / ! 1379: 0: hlt / Halt until processor reset occurs. ! 1380: jmp 0b ! 1381: ! 1382: //////// ! 1383: / ! 1384: / Data. ! 1385: / ! 1386: //////// ! 1387: ! 1388: .globl MAXMEM ! 1389: .globl vecs_ ! 1390: .globl realmode_ ! 1391: .globl gdtsel_, gdtmap_ ! 1392: .globl idtsel_, idtmap_ ! 1393: .globl CMOSmax_ ! 1394: ! 1395: .shri ! 1396: val11: .word 0 / Value obtained from int11 [in code]. ! 1397: ! 1398: .prvd ! 1399: MAXMEM: .word 0xA000 / In paragraphs, must be mult. of 64 ! 1400: CMOSmax_:.word 0x0000 / Max extended memory according ... ! 1401: / ... to CMOS bytes 0x17 and 0x18 ... ! 1402: / ... in 64K chunks. ! 1403: realmode_:.word 0 / Virtual Addressing Mode Enabled ! 1404: gdtmap_:.blkw 3 / Global descriptor table definition ! 1405: idtmap_:.blkw 3 / Interrupt descriptor table definition ! 1406: gdtsel_:.word 0 / Global descriptor table selector ! 1407: idtsel_:.word 0 / Interrupt descriptor table selector ! 1408: vecs_: .word vret_ / Interrupt vector table ! 1409: .word vret_ ! 1410: .word vret_ ! 1411: .word vret_ ! 1412: .word vret_ ! 1413: .word vret_ ! 1414: .word vret_ ! 1415: .word vret_ ! 1416: .word vret_ ! 1417: .word vret_ ! 1418: .word vret_ ! 1419: .word vret_ ! 1420: .word vret_ ! 1421: .word vret_ ! 1422: .word vret_ ! 1423: .word vret_ ! 1424: ! 1425: //////// ! 1426: / ! 1427: / Task State Segment - Coherent runs as a single protected mode task. ! 1428: / ! 1429: //////// ! 1430: .globl tss_ ! 1431: ! 1432: .prvd ! 1433: tss_: / Task State Segment. ! 1434: tss_lnk:.word 0 / 0: Back link selector to TSS. ! 1435: tss_sp0:.word 0 / 2: SP for CPL 0. ! 1436: tss_ss0:.word 0 / 4: SS for CPL 0. ! 1437: tss_sp1:.word 0 / 6: SP for CPL 1. ! 1438: tss_ss1:.word 0 / 8: SS for CPL 1. ! 1439: tss_sp2:.word 0 / 10: SP for CPL 2. ! 1440: tss_ss2:.word 0 / 12: SS for CPL 2. ! 1441: tss_ip: .word 0 / 14: IP (Entry point). ! 1442: tss_psw:.word 0 / 16: Flag word. ! 1443: tss_ax: .word 0 / 18: Register AX. ! 1444: tss_cx: .word 0 / 20: Register CX. ! 1445: tss_dx: .word 0 / 22: Register DX. ! 1446: tss_bx: .word 0 / 24: Register BX. ! 1447: tss_bp: .word 0 / 26: Register BP. ! 1448: tss_sp: .word 0 / 28: Register SP. ! 1449: tss_si: .word 0 / 30: Register SI. ! 1450: tss_di: .word 0 / 32: Register DI. ! 1451: tss_es: .word 0 / 34: Register ES. ! 1452: tss_cs: .word 0 / 36: Register CS. ! 1453: tss_ss: .word 0 / 38: Register SS. ! 1454: tss_ds: .word 0 / 40: Register DS. ! 1455: tss_ldt:.word 0 / 42: Task LDT Selector.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.