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