|
|
1.1 ! root 1: /****************************************************************************** ! 2: * Copyright (c) 2004, 2008 IBM Corporation ! 3: * All rights reserved. ! 4: * This program and the accompanying materials ! 5: * are made available under the terms of the BSD License ! 6: * which accompanies this distribution, and is available at ! 7: * http://www.opensource.org/licenses/bsd-license.php ! 8: * ! 9: * Contributors: ! 10: * IBM Corporation - initial implementation ! 11: *****************************************************************************/ ! 12: ! 13: #include <stdio.h> ! 14: ! 15: #include <rtas.h> ! 16: ! 17: #include "biosemu.h" ! 18: #include "mem.h" ! 19: #include "device.h" ! 20: #include "debug.h" ! 21: ! 22: #include <x86emu/x86emu.h> ! 23: #include <x86emu/prim_ops.h> ! 24: ! 25: ! 26: ! 27: //setup to run the code at the address, that the Interrupt Vector points to... ! 28: void ! 29: setupInt(int intNum) ! 30: { ! 31: DEBUG_PRINTF_INTR("%s(%x): executing interrupt handler @%08x\n", ! 32: __FUNCTION__, intNum, my_rdl(intNum * 4)); ! 33: // push current R_FLG... will be popped by IRET ! 34: push_word((u16) M.x86.R_FLG); ! 35: CLEAR_FLAG(F_IF); ! 36: CLEAR_FLAG(F_TF); ! 37: // push current CS:IP to the stack, will be popped by IRET ! 38: push_word(M.x86.R_CS); ! 39: push_word(M.x86.R_IP); ! 40: // set CS:IP to the interrupt handler address... so the next executed instruction will ! 41: // be the interrupt handler ! 42: M.x86.R_CS = my_rdw(intNum * 4 + 2); ! 43: M.x86.R_IP = my_rdw(intNum * 4); ! 44: } ! 45: ! 46: // handle int10 (VGA BIOS Interrupt) ! 47: void ! 48: handleInt10() ! 49: { ! 50: // the data for INT10 is stored in BDA (0000:0400h) offset 49h-66h ! 51: // function number in AH ! 52: //DEBUG_PRINTF_CS_IP("%s:\n", __FUNCTION__); ! 53: //x86emu_dump_xregs(); ! 54: //if ((M.x86.R_IP == 0x32c2) && (M.x86.R_SI == 0x1ce2)){ ! 55: //X86EMU_trace_on(); ! 56: //M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F; ! 57: //} ! 58: switch (M.x86.R_AH) { ! 59: case 0x00: ! 60: // set video mode ! 61: // BDA offset 49h is current video mode ! 62: my_wrb(0x449, M.x86.R_AL); ! 63: if (M.x86.R_AL > 7) ! 64: M.x86.R_AL = 0x20; ! 65: else if (M.x86.R_AL == 6) ! 66: M.x86.R_AL = 0x3f; ! 67: else ! 68: M.x86.R_AL = 0x30; ! 69: break; ! 70: case 0x01: ! 71: // set cursor shape ! 72: // ignore ! 73: break; ! 74: case 0x02: ! 75: // set cursor position ! 76: // BH: pagenumber, DX: cursor_pos (DH:row, DL:col) ! 77: // BDA offset 50h-60h are 8 cursor position words for ! 78: // eight possible video pages ! 79: my_wrw(0x450 + (M.x86.R_BH * 2), M.x86.R_DX); ! 80: break; ! 81: case 0x03: ! 82: //get cursor position ! 83: // BH: pagenumber ! 84: // BDA offset 50h-60h are 8 cursor position words for ! 85: // eight possible video pages ! 86: M.x86.R_AX = 0; ! 87: M.x86.R_CH = 0; // start scan line ??? ! 88: M.x86.R_CL = 0; // end scan line ??? ! 89: M.x86.R_DX = my_rdw(0x450 + (M.x86.R_BH * 2)); ! 90: break; ! 91: case 0x05: ! 92: // set active page ! 93: // BDA offset 62h is current page number ! 94: my_wrb(0x462, M.x86.R_AL); ! 95: break; ! 96: case 0x06: ! 97: //scroll up windows ! 98: break; ! 99: case 0x07: ! 100: //scroll down windows ! 101: break; ! 102: case 0x08: ! 103: //read character and attribute at position ! 104: M.x86.R_AH = 0x07; // white-on-black ! 105: M.x86.R_AL = 0x20; // a space... ! 106: break; ! 107: case 0x09: ! 108: // write character and attribute ! 109: //AL: char, BH: page number, BL: attribute, CX: number of times to write ! 110: //BDA offset 62h is current page number ! 111: CHECK_DBG(DEBUG_PRINT_INT10) { ! 112: uint32_t i = 0; ! 113: if (M.x86.R_BH == my_rdb(0x462)) { ! 114: for (i = 0; i < M.x86.R_CX; i++) ! 115: printf("%c", M.x86.R_AL); ! 116: } ! 117: } ! 118: break; ! 119: case 0x0a: ! 120: // write character ! 121: //AL: char, BH: page number, BL: attribute, CX: number of times to write ! 122: //BDA offset 62h is current page number ! 123: CHECK_DBG(DEBUG_PRINT_INT10) { ! 124: uint32_t i = 0; ! 125: if (M.x86.R_BH == my_rdb(0x462)) { ! 126: for (i = 0; i < M.x86.R_CX; i++) ! 127: printf("%c", M.x86.R_AL); ! 128: } ! 129: } ! 130: break; ! 131: case 0x0e: ! 132: // teletype output: write character and advance cursor... ! 133: //AL: char, BH: page number, BL: attribute ! 134: //BDA offset 62h is current page number ! 135: CHECK_DBG(DEBUG_PRINT_INT10) { ! 136: // we ignore the pagenumber on this call... ! 137: //if (M.x86.R_BH == my_rdb(0x462)) ! 138: { ! 139: printf("%c", M.x86.R_AL); ! 140: // for debugging, to read all lines ! 141: //if (M.x86.R_AL == 0xd) // carriage return ! 142: // printf("\n"); ! 143: } ! 144: } ! 145: break; ! 146: case 0x0f: ! 147: // get video mode ! 148: // BDA offset 49h is current video mode ! 149: // BDA offset 62h is current page number ! 150: // BDA offset 4ah is columns on screen ! 151: M.x86.R_AH = 80; //number of character columns... we hardcode it to 80 ! 152: M.x86.R_AL = my_rdb(0x449); ! 153: M.x86.R_BH = my_rdb(0x462); ! 154: break; ! 155: default: ! 156: printf("%s(): unknown function (%x) for int10 handler.\n", ! 157: __FUNCTION__, M.x86.R_AH); ! 158: DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", ! 159: M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, ! 160: M.x86.R_DX); ! 161: HALT_SYS(); ! 162: break; ! 163: } ! 164: } ! 165: ! 166: // this table translates ASCII chars into their XT scan codes: ! 167: static uint8_t keycode_table[256] = { ! 168: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 - 7 ! 169: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 8 - 15 ! 170: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 16 - 23 ! 171: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 24 - 31 ! 172: 0x39, 0x02, 0x28, 0x04, 0x05, 0x06, 0x08, 0x28, // 32 - 39 ! 173: 0x0a, 0x0b, 0x09, 0x2b, 0x33, 0x0d, 0x34, 0x35, // 40 - 47 ! 174: 0x0b, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // 48 - 55 ! 175: 0x09, 0x0a, 0x27, 0x27, 0x33, 0x2b, 0x34, 0x35, // 56 - 63 ! 176: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 64 - 71 ! 177: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 72 - 79 ! 178: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 80 - 87 ! 179: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 88 - 95 ! 180: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 96 - 103 ! 181: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 104 - 111 ! 182: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 112 - 119 ! 183: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 120 - 127 ! 184: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ... ! 185: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ! 186: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ! 187: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ! 188: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ! 189: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ! 190: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ! 191: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ! 192: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ! 193: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ! 194: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ! 195: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ! 196: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ! 197: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ! 198: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ! 199: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ! 200: } ! 201: ! 202: ; ! 203: ! 204: void ! 205: translate_keycode(uint64_t * keycode) ! 206: { ! 207: uint8_t scan_code = 0; ! 208: uint8_t char_code = 0; ! 209: if (*keycode < 256) { ! 210: scan_code = keycode_table[*keycode]; ! 211: char_code = (uint8_t) * keycode & 0xff; ! 212: } else { ! 213: switch (*keycode) { ! 214: case 0x1b50: ! 215: // F1 ! 216: scan_code = 0x3b; ! 217: char_code = 0x0; ! 218: break; ! 219: default: ! 220: printf("%s(): unknown multibyte keycode: %llx\n", ! 221: __FUNCTION__, *keycode); ! 222: break; ! 223: } ! 224: } ! 225: //assemble scan/char code in keycode ! 226: *keycode = (uint64_t) ((((uint16_t) scan_code) << 8) | char_code); ! 227: } ! 228: ! 229: // handle int16 (Keyboard BIOS Interrupt) ! 230: void ! 231: handleInt16() ! 232: { ! 233: // keyboard buffer is in BIOS Memory Area: ! 234: // offset 0x1a (WORD) pointer to next char in keybuffer ! 235: // offset 0x1c (WORD) pointer to next insert slot in keybuffer ! 236: // offset 0x1e-0x3e: 16 WORD Ring Buffer ! 237: // since we currently always read the char from the FW buffer, ! 238: // we misuse the ring buffer, we use it as pointer to a uint64_t that stores ! 239: // multi-byte keys (e.g. special keys in VT100 terminal) ! 240: // and as long as a key is available (not 0) we dont read further keys ! 241: uint64_t *keycode = (uint64_t *) (M.mem_base + 0x41e); ! 242: int8_t c; ! 243: // function number in AH ! 244: DEBUG_PRINTF_INTR("%s(): Keyboard Interrupt: function: %x.\n", ! 245: __FUNCTION__, M.x86.R_AH); ! 246: DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", M.x86.R_AX, ! 247: M.x86.R_BX, M.x86.R_CX, M.x86.R_DX); ! 248: switch (M.x86.R_AH) { ! 249: case 0x00: ! 250: // get keystroke ! 251: if (*keycode) { ! 252: M.x86.R_AX = (uint16_t) * keycode; ! 253: // clear keycode ! 254: *keycode = 0; ! 255: } else { ! 256: M.x86.R_AH = 0x61; // scancode for space key ! 257: M.x86.R_AL = 0x20; // a space ! 258: } ! 259: break; ! 260: case 0x01: ! 261: // check keystroke ! 262: // ZF set = no keystroke ! 263: // read first byte of key code ! 264: if (*keycode) { ! 265: // already read, but not yet taken ! 266: CLEAR_FLAG(F_ZF); ! 267: M.x86.R_AX = (uint16_t) * keycode; ! 268: } else { ! 269: c = getchar(); ! 270: if (c == -1) { ! 271: // no key available ! 272: SET_FLAG(F_ZF); ! 273: } else { ! 274: *keycode = c; ! 275: ! 276: // since after an ESC it may take a while to receive the next char, ! 277: // we send something that is not shown on the screen, and then try to get ! 278: // the next char ! 279: // TODO: only after ESC?? what about other multibyte keys ! 280: printf("tt%c%c", 0x08, 0x08); // 0x08 == Backspace ! 281: ! 282: while ((c = getchar()) != -1) { ! 283: *keycode = (*keycode << 8) | c; ! 284: DEBUG_PRINTF(" key read: %0llx\n", ! 285: *keycode); ! 286: } ! 287: translate_keycode(keycode); ! 288: DEBUG_PRINTF(" translated key: %0llx\n", ! 289: *keycode); ! 290: if (*keycode == 0) { ! 291: //not found ! 292: SET_FLAG(F_ZF); ! 293: } else { ! 294: CLEAR_FLAG(F_ZF); ! 295: M.x86.R_AX = (uint16_t) * keycode; ! 296: //X86EMU_trace_on(); ! 297: //M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F; ! 298: } ! 299: } ! 300: } ! 301: break; ! 302: default: ! 303: printf("%s(): unknown function (%x) for int16 handler.\n", ! 304: __FUNCTION__, M.x86.R_AH); ! 305: DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", ! 306: M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, ! 307: M.x86.R_DX); ! 308: HALT_SYS(); ! 309: break; ! 310: } ! 311: } ! 312: ! 313: // handle int1a (PCI BIOS Interrupt) ! 314: void ! 315: handleInt1a() ! 316: { ! 317: // function number in AX ! 318: uint8_t bus, devfn, offs; ! 319: switch (M.x86.R_AX) { ! 320: case 0xb101: ! 321: // Installation check ! 322: CLEAR_FLAG(F_CF); // clear CF ! 323: M.x86.R_EDX = 0x20494350; // " ICP" endian swapped "PCI " ! 324: M.x86.R_AL = 0x1; // Config Space Mechanism 1 supported ! 325: M.x86.R_BX = 0x0210; // PCI Interface Level Version 2.10 ! 326: M.x86.R_CL = 0xff; // number of last PCI Bus in system TODO: check! ! 327: break; ! 328: case 0xb102: ! 329: // Find PCI Device ! 330: // NOTE: we currently only allow the device to find itself... ! 331: // it SHOULD be all we ever need... ! 332: // device_id in CX, vendor_id in DX ! 333: // device index in SI (i.e. if multiple devices with same vendor/device id ! 334: // are connected). We currently only support device index 0 ! 335: DEBUG_PRINTF_INTR("%s(): function: %x: PCI Find Device\n", ! 336: __FUNCTION__, M.x86.R_AX); ! 337: if ((M.x86.R_CX == bios_device.pci_device_id) ! 338: && (M.x86.R_DX == bios_device.pci_vendor_id) ! 339: // device index must be 0 ! 340: && (M.x86.R_SI == 0)) { ! 341: CLEAR_FLAG(F_CF); ! 342: M.x86.R_AH = 0x00; // return code: success ! 343: M.x86.R_BH = bios_device.bus; ! 344: M.x86.R_BL = bios_device.devfn; ! 345: DEBUG_PRINTF_INTR ! 346: ("%s(): function %x: PCI Find Device --> 0x%04x\n", ! 347: __FUNCTION__, M.x86.R_AX, M.x86.R_BX); ! 348: } else { ! 349: DEBUG_PRINTF_INTR ! 350: ("%s(): function %x: invalid device/vendor/device index! (%04x/%04x/%02x expected: %04x/%04x/0) \n", ! 351: __FUNCTION__, M.x86.R_AX, M.x86.R_CX, M.x86.R_DX, ! 352: M.x86.R_SI, bios_device.pci_device_id, ! 353: bios_device.pci_vendor_id); ! 354: SET_FLAG(F_CF); ! 355: M.x86.R_AH = 0x86; // return code: device not found ! 356: } ! 357: break; ! 358: case 0xb108: //read configuration byte ! 359: case 0xb109: //read configuration word ! 360: case 0xb10a: //read configuration dword ! 361: bus = M.x86.R_BH; ! 362: devfn = M.x86.R_BL; ! 363: offs = M.x86.R_DI; ! 364: if ((bus != bios_device.bus) ! 365: || (devfn != bios_device.devfn)) { ! 366: // fail accesses to any device but ours... ! 367: printf ! 368: ("%s(): Config read access invalid! bus: %x (%x), devfn: %x (%x), offs: %x\n", ! 369: __FUNCTION__, bus, bios_device.bus, devfn, ! 370: bios_device.devfn, offs); ! 371: SET_FLAG(F_CF); ! 372: M.x86.R_AH = 0x87; //return code: bad pci register ! 373: HALT_SYS(); ! 374: return; ! 375: } else { ! 376: switch (M.x86.R_AX) { ! 377: case 0xb108: ! 378: M.x86.R_CL = ! 379: (uint8_t) rtas_pci_config_read(bios_device. ! 380: puid, 1, ! 381: bus, devfn, ! 382: offs); ! 383: DEBUG_PRINTF_INTR ! 384: ("%s(): function %x: PCI Config Read @%02x --> 0x%02x\n", ! 385: __FUNCTION__, M.x86.R_AX, offs, ! 386: M.x86.R_CL); ! 387: break; ! 388: case 0xb109: ! 389: M.x86.R_CX = ! 390: (uint16_t) rtas_pci_config_read(bios_device. ! 391: puid, 2, ! 392: bus, devfn, ! 393: offs); ! 394: DEBUG_PRINTF_INTR ! 395: ("%s(): function %x: PCI Config Read @%02x --> 0x%04x\n", ! 396: __FUNCTION__, M.x86.R_AX, offs, ! 397: M.x86.R_CX); ! 398: break; ! 399: case 0xb10a: ! 400: M.x86.R_ECX = ! 401: (uint32_t) rtas_pci_config_read(bios_device. ! 402: puid, 4, ! 403: bus, devfn, ! 404: offs); ! 405: DEBUG_PRINTF_INTR ! 406: ("%s(): function %x: PCI Config Read @%02x --> 0x%08x\n", ! 407: __FUNCTION__, M.x86.R_AX, offs, ! 408: M.x86.R_ECX); ! 409: break; ! 410: } ! 411: CLEAR_FLAG(F_CF); ! 412: M.x86.R_AH = 0x0; // return code: success ! 413: } ! 414: break; ! 415: case 0xb10b: //write configuration byte ! 416: case 0xb10c: //write configuration word ! 417: case 0xb10d: //write configuration dword ! 418: bus = M.x86.R_BH; ! 419: devfn = M.x86.R_BL; ! 420: offs = M.x86.R_DI; ! 421: if ((bus != bios_device.bus) ! 422: || (devfn != bios_device.devfn)) { ! 423: // fail accesses to any device but ours... ! 424: printf ! 425: ("%s(): Config read access invalid! bus: %x (%x), devfn: %x (%x), offs: %x\n", ! 426: __FUNCTION__, bus, bios_device.bus, devfn, ! 427: bios_device.devfn, offs); ! 428: SET_FLAG(F_CF); ! 429: M.x86.R_AH = 0x87; //return code: bad pci register ! 430: HALT_SYS(); ! 431: return; ! 432: } else { ! 433: switch (M.x86.R_AX) { ! 434: case 0xb10b: ! 435: rtas_pci_config_write(bios_device.puid, 1, bus, ! 436: devfn, offs, M.x86.R_CL); ! 437: DEBUG_PRINTF_INTR ! 438: ("%s(): function %x: PCI Config Write @%02x <-- 0x%02x\n", ! 439: __FUNCTION__, M.x86.R_AX, offs, ! 440: M.x86.R_CL); ! 441: break; ! 442: case 0xb10c: ! 443: rtas_pci_config_write(bios_device.puid, 2, bus, ! 444: devfn, offs, M.x86.R_CX); ! 445: DEBUG_PRINTF_INTR ! 446: ("%s(): function %x: PCI Config Write @%02x <-- 0x%04x\n", ! 447: __FUNCTION__, M.x86.R_AX, offs, ! 448: M.x86.R_CX); ! 449: break; ! 450: case 0xb10d: ! 451: rtas_pci_config_write(bios_device.puid, 4, bus, ! 452: devfn, offs, M.x86.R_ECX); ! 453: DEBUG_PRINTF_INTR ! 454: ("%s(): function %x: PCI Config Write @%02x <-- 0x%08x\n", ! 455: __FUNCTION__, M.x86.R_AX, offs, ! 456: M.x86.R_ECX); ! 457: break; ! 458: } ! 459: CLEAR_FLAG(F_CF); ! 460: M.x86.R_AH = 0x0; // return code: success ! 461: } ! 462: break; ! 463: default: ! 464: printf("%s(): unknown function (%x) for int1a handler.\n", ! 465: __FUNCTION__, M.x86.R_AX); ! 466: DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", ! 467: M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, ! 468: M.x86.R_DX); ! 469: HALT_SYS(); ! 470: break; ! 471: } ! 472: } ! 473: ! 474: // main Interrupt Handler routine, should be registered as x86emu interrupt handler ! 475: void ! 476: handleInterrupt(int intNum) ! 477: { ! 478: uint8_t int_handled = 0; ! 479: #ifndef DEBUG_PRINT_INT10 ! 480: // this printf makes output by int 10 unreadable... ! 481: // so we only enable it, if int10 print is disabled ! 482: DEBUG_PRINTF_INTR("%s(%x)\n", __FUNCTION__, intNum); ! 483: #endif ! 484: switch (intNum) { ! 485: case 0x10: //BIOS video interrupt ! 486: case 0x42: // INT 10h relocated by EGA/VGA BIOS ! 487: case 0x6d: // INT 10h relocated by VGA BIOS ! 488: // get interrupt vector from IDT (4 bytes per Interrupt starting at address 0 ! 489: if ((my_rdl(intNum * 4) == 0xF000F065) || //F000:F065 is default BIOS interrupt handler address ! 490: (my_rdl(intNum * 4) == 0xF4F4F4F4)) //invalid ! 491: { ! 492: #if 0 ! 493: // ignore interrupt... ! 494: DEBUG_PRINTF_INTR ! 495: ("%s(%x): invalid interrupt Vector (%08x) found, interrupt ignored...\n", ! 496: __FUNCTION__, intNum, my_rdl(intNum * 4)); ! 497: DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", ! 498: M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, ! 499: M.x86.R_DX); ! 500: //HALT_SYS(); ! 501: #endif ! 502: handleInt10(); ! 503: int_handled = 1; ! 504: } ! 505: break; ! 506: case 0x16: ! 507: // Keyboard BIOS Interrupt ! 508: handleInt16(); ! 509: int_handled = 1; ! 510: break; ! 511: case 0x1a: ! 512: // PCI BIOS Interrupt ! 513: handleInt1a(); ! 514: int_handled = 1; ! 515: break; ! 516: default: ! 517: printf("Interrupt %#x (Vector: %x) not implemented\n", intNum, ! 518: my_rdl(intNum * 4)); ! 519: DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", ! 520: M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, ! 521: M.x86.R_DX); ! 522: int_handled = 1; ! 523: HALT_SYS(); ! 524: break; ! 525: } ! 526: // if we did not handle the interrupt, jump to the interrupt vector... ! 527: if (!int_handled) { ! 528: setupInt(intNum); ! 529: } ! 530: } ! 531: ! 532: // prepare and execute Interrupt 10 (VGA Interrupt) ! 533: void ! 534: runInt10() ! 535: { ! 536: // Initialize stack and data segment ! 537: M.x86.R_SS = STACK_SEGMENT; ! 538: M.x86.R_DS = DATA_SEGMENT; ! 539: M.x86.R_SP = STACK_START_OFFSET; ! 540: ! 541: // push a HLT instruction and a pointer to it onto the stack ! 542: // any return will pop the pointer and jump to the HLT, thus ! 543: // exiting (more or less) cleanly ! 544: push_word(0xf4f4); //F4=HLT ! 545: //push_word(M.x86.R_SS); ! 546: //push_word(M.x86.R_SP + 2); ! 547: ! 548: // setupInt will push the current CS and IP to the stack to return to it, ! 549: // but we want to halt, so set CS:IP to the HLT instruction we just pushed ! 550: // to the stack ! 551: M.x86.R_CS = M.x86.R_SS; ! 552: M.x86.R_IP = M.x86.R_SP; // + 4; ! 553: ! 554: CHECK_DBG(DEBUG_TRACE_X86EMU) { ! 555: X86EMU_trace_on(); ! 556: } ! 557: CHECK_DBG(DEBUG_JMP) { ! 558: M.x86.debug |= DEBUG_TRACEJMP_REGS_F; ! 559: M.x86.debug |= DEBUG_TRACEJMP_REGS_F; ! 560: M.x86.debug |= DEBUG_TRACECALL_F; ! 561: M.x86.debug |= DEBUG_TRACECALL_REGS_F; ! 562: } ! 563: setupInt(0x10); ! 564: DEBUG_PRINTF_INTR("%s(): starting execution of INT10...\n", ! 565: __FUNCTION__); ! 566: X86EMU_exec(); ! 567: DEBUG_PRINTF_INTR("%s(): execution finished\n", __FUNCTION__); ! 568: } ! 569: ! 570: // prepare and execute Interrupt 13 (Disk Interrupt) ! 571: void ! 572: runInt13() ! 573: { ! 574: // Initialize stack and data segment ! 575: M.x86.R_SS = STACK_SEGMENT; ! 576: M.x86.R_DS = DATA_SEGMENT; ! 577: M.x86.R_SP = STACK_START_OFFSET; ! 578: ! 579: // push a HLT instruction and a pointer to it onto the stack ! 580: // any return will pop the pointer and jump to the HLT, thus ! 581: // exiting (more or less) cleanly ! 582: push_word(0xf4f4); //F4=HLT ! 583: //push_word(M.x86.R_SS); ! 584: //push_word(M.x86.R_SP + 2); ! 585: ! 586: // setupInt will push the current CS and IP to the stack to return to it, ! 587: // but we want to halt, so set CS:IP to the HLT instruction we just pushed ! 588: // to the stack ! 589: M.x86.R_CS = M.x86.R_SS; ! 590: M.x86.R_IP = M.x86.R_SP; ! 591: ! 592: CHECK_DBG(DEBUG_TRACE_X86EMU) { ! 593: X86EMU_trace_on(); ! 594: } ! 595: CHECK_DBG(DEBUG_JMP) { ! 596: M.x86.debug |= DEBUG_TRACEJMP_REGS_F; ! 597: M.x86.debug |= DEBUG_TRACEJMP_REGS_F; ! 598: M.x86.debug |= DEBUG_TRACECALL_F; ! 599: M.x86.debug |= DEBUG_TRACECALL_REGS_F; ! 600: } ! 601: ! 602: setupInt(0x13); ! 603: DEBUG_PRINTF_INTR("%s(): starting execution of INT13...\n", ! 604: __FUNCTION__); ! 605: X86EMU_exec(); ! 606: DEBUG_PRINTF_INTR("%s(): execution finished\n", __FUNCTION__); ! 607: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.