diff options
Diffstat (limited to 'util/x86emu/yabel/interrupt.c')
-rw-r--r-- | util/x86emu/yabel/interrupt.c | 677 |
1 files changed, 0 insertions, 677 deletions
diff --git a/util/x86emu/yabel/interrupt.c b/util/x86emu/yabel/interrupt.c deleted file mode 100644 index 9a796005bb..0000000000 --- a/util/x86emu/yabel/interrupt.c +++ /dev/null @@ -1,677 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * Copyright (c) 2008, 2009 Pattrick Hueper <phueper@hueper.net> - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#include <types.h> -#include "compat/rtas.h" - -#include "biosemu.h" -#include "mem.h" -#include "device.h" -#include "debug.h" -#include "pmm.h" -#include "interrupt.h" - -#include <x86emu/x86emu.h> -#include "../x86emu/prim_ops.h" - -#ifdef CONFIG_PCI_OPTION_ROM_RUN_YABEL -#include <device/pci.h> -#include <device/pci_ops.h> -#endif - - -//setup to run the code at the address, that the Interrupt Vector points to... -static void -setupInt(int intNum) -{ - DEBUG_PRINTF_INTR("%s(%x): executing interrupt handler @%08x\n", - __func__, intNum, my_rdl(intNum * 4)); - // push current R_FLG... will be popped by IRET - push_word((u16) M.x86.R_FLG); - CLEAR_FLAG(F_IF); - CLEAR_FLAG(F_TF); - // push current CS:IP to the stack, will be popped by IRET - push_word(M.x86.R_CS); - push_word(M.x86.R_IP); - // set CS:IP to the interrupt handler address... so the next executed instruction will - // be the interrupt handler - M.x86.R_CS = my_rdw(intNum * 4 + 2); - M.x86.R_IP = my_rdw(intNum * 4); -} - -// handle int10 (VGA BIOS Interrupt) -static void -handleInt10(void) -{ - // the data for INT10 is stored in BDA (0000:0400h) offset 49h-66h - // function number in AH - //DEBUG_PRINTF_CS_IP("%s:\n", __func__); - //x86emu_dump_xregs(); - //if ((M.x86.R_IP == 0x32c2) && (M.x86.R_SI == 0x1ce2)){ - //X86EMU_trace_on(); - //M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F; - //} - switch (M.x86.R_AH) { - case 0x00: - // set video mode - // BDA offset 49h is current video mode - my_wrb(0x449, M.x86.R_AL); - if (M.x86.R_AL > 7) - M.x86.R_AL = 0x20; - else if (M.x86.R_AL == 6) - M.x86.R_AL = 0x3f; - else - M.x86.R_AL = 0x30; - break; - case 0x01: - // set cursor shape - // ignore - break; - case 0x02: - // set cursor position - // BH: pagenumber, DX: cursor_pos (DH:row, DL:col) - // BDA offset 50h-60h are 8 cursor position words for - // eight possible video pages - my_wrw(0x450 + (M.x86.R_BH * 2), M.x86.R_DX); - break; - case 0x03: - //get cursor position - // BH: pagenumber - // BDA offset 50h-60h are 8 cursor position words for - // eight possible video pages - M.x86.R_AX = 0; - M.x86.R_CH = 0; // start scan line ??? - M.x86.R_CL = 0; // end scan line ??? - M.x86.R_DX = my_rdw(0x450 + (M.x86.R_BH * 2)); - break; - case 0x05: - // set active page - // BDA offset 62h is current page number - my_wrb(0x462, M.x86.R_AL); - break; - case 0x06: - //scroll up windows - break; - case 0x07: - //scroll down windows - break; - case 0x08: - //read character and attribute at position - M.x86.R_AH = 0x07; // white-on-black - M.x86.R_AL = 0x20; // a space... - break; - case 0x09: - // write character and attribute - //AL: char, BH: page number, BL: attribute, CX: number of times to write - //BDA offset 62h is current page number - CHECK_DBG(DEBUG_PRINT_INT10) { - u32 i = 0; - if (M.x86.R_BH == my_rdb(0x462)) { - for (i = 0; i < M.x86.R_CX; i++) - printf("%c", M.x86.R_AL); - } - } - break; - case 0x0a: - // write character - //AL: char, BH: page number, BL: attribute, CX: number of times to write - //BDA offset 62h is current page number - CHECK_DBG(DEBUG_PRINT_INT10) { - u32 i = 0; - if (M.x86.R_BH == my_rdb(0x462)) { - for (i = 0; i < M.x86.R_CX; i++) - printf("%c", M.x86.R_AL); - } - } - break; - case 0x0e: - // teletype output: write character and advance cursor... - //AL: char, BH: page number, BL: attribute - //BDA offset 62h is current page number - CHECK_DBG(DEBUG_PRINT_INT10) { - // we ignore the pagenumber on this call... - //if (M.x86.R_BH == my_rdb(0x462)) - { - printf("%c", M.x86.R_AL); - // for debugging, to read all lines - //if (M.x86.R_AL == 0xd) // carriage return - // printf("\n"); - } - } - break; - case 0x0f: - // get video mode - // BDA offset 49h is current video mode - // BDA offset 62h is current page number - // BDA offset 4ah is columns on screen - M.x86.R_AH = 80; //number of character columns... we hardcode it to 80 - M.x86.R_AL = my_rdb(0x449); - M.x86.R_BH = my_rdb(0x462); - break; - default: - printf("%s(): unknown function (%x) for int10 handler.\n", - __func__, M.x86.R_AH); - DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", - M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, - M.x86.R_DX); - HALT_SYS(); - break; - } -} - -// this table translates ASCII chars into their XT scan codes: -static u8 keycode_table[256] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 - 7 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 8 - 15 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 16 - 23 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 24 - 31 - 0x39, 0x02, 0x28, 0x04, 0x05, 0x06, 0x08, 0x28, // 32 - 39 - 0x0a, 0x0b, 0x09, 0x2b, 0x33, 0x0d, 0x34, 0x35, // 40 - 47 - 0x0b, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // 48 - 55 - 0x09, 0x0a, 0x27, 0x27, 0x33, 0x2b, 0x34, 0x35, // 56 - 63 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 64 - 71 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 72 - 79 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 80 - 87 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 88 - 95 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 96 - 103 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 104 - 111 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 112 - 119 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 120 - 127 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ... - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -} - -; - -static void -translate_keycode(u64 * keycode) -{ - u8 scan_code = 0; - u8 char_code = 0; - if (*keycode < 256) { - scan_code = keycode_table[*keycode]; - char_code = (u8) * keycode & 0xff; - } else { - switch (*keycode) { - case 0x1b50: - // F1 - scan_code = 0x3b; - char_code = 0x0; - break; - default: - printf("%s(): unknown multibyte keycode: %llx\n", - __func__, *keycode); - break; - } - } - //assemble scan/char code in keycode - *keycode = (u64) ((((u16) scan_code) << 8) | char_code); -} - -// handle int16 (Keyboard BIOS Interrupt) -static void -handleInt16(void) -{ - // keyboard buffer is in BIOS Memory Area: - // offset 0x1a (WORD) pointer to next char in keybuffer - // offset 0x1c (WORD) pointer to next insert slot in keybuffer - // offset 0x1e-0x3e: 16 WORD Ring Buffer - // since we currently always read the char from the FW buffer, - // we misuse the ring buffer, we use it as pointer to a u64 that stores - // multi-byte keys (e.g. special keys in VT100 terminal) - // and as long as a key is available (not 0) we dont read further keys - u64 *keycode = (u64 *) (M.mem_base + 0x41e); - s8 c; - // function number in AH - DEBUG_PRINTF_INTR("%s(): Keyboard Interrupt: function: %x.\n", - __func__, M.x86.R_AH); - DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", M.x86.R_AX, - M.x86.R_BX, M.x86.R_CX, M.x86.R_DX); - switch (M.x86.R_AH) { - case 0x00: - // get keystroke - if (*keycode) { - M.x86.R_AX = (u16) * keycode; - // clear keycode - *keycode = 0; - } else { - M.x86.R_AH = 0x61; // scancode for space key - M.x86.R_AL = 0x20; // a space - } - break; - case 0x01: - // check keystroke - // ZF set = no keystroke - // read first byte of key code - if (*keycode) { - // already read, but not yet taken - CLEAR_FLAG(F_ZF); - M.x86.R_AX = (u16) * keycode; - } else { - /* TODO: we need getchar... */ - c = -1; //getchar(); - if (c == -1) { - // no key available - SET_FLAG(F_ZF); - } else { - *keycode = c; - - // since after an ESC it may take a while to receive the next char, - // we send something that is not shown on the screen, and then try to get - // the next char - // TODO: only after ESC?? what about other multibyte keys - printf("tt%c%c", 0x08, 0x08); // 0x08 == Backspace - - /* TODO: we need getchar... */ - while ((c = -1 /*getchar()*/) != -1) { - *keycode = (*keycode << 8) | c; - DEBUG_PRINTF(" key read: %0llx\n", - *keycode); - } - translate_keycode(keycode); - DEBUG_PRINTF(" translated key: %0llx\n", - *keycode); - if (*keycode == 0) { - //not found - SET_FLAG(F_ZF); - } else { - CLEAR_FLAG(F_ZF); - M.x86.R_AX = (u16) * keycode; - //X86EMU_trace_on(); - //M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F; - } - } - } - break; - default: - printf("%s(): unknown function (%x) for int16 handler.\n", - __func__, M.x86.R_AH); - DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", - M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, - M.x86.R_DX); - HALT_SYS(); - break; - } -} - -// handle int1a (PCI BIOS Interrupt) -static void -handleInt1a(void) -{ - // function number in AX - u8 bus, devfn, offs; - struct device* dev; - switch (M.x86.R_AX) { - case 0xb101: - // Installation check - CLEAR_FLAG(F_CF); // clear CF - M.x86.R_EDX = 0x20494350; // " ICP" endian swapped "PCI " - M.x86.R_AL = 0x1; // Config Space Mechanism 1 supported - M.x86.R_BX = 0x0210; // PCI Interface Level Version 2.10 - M.x86.R_CL = 0xff; // number of last PCI Bus in system TODO: check! - break; - case 0xb102: - // Find PCI Device - // device_id in CX, vendor_id in DX - // device index in SI (i.e. if multiple devices with same vendor/device id - // are connected). We currently only support device index 0 - // - DEBUG_PRINTF_INTR("%s(): function: %x: PCI Find Device\n", - __func__, M.x86.R_AX); - /* FixME: support SI != 0 */ -#if defined(CONFIG_YABEL_PCI_ACCESS_OTHER_DEVICES) && CONFIG_YABEL_PCI_ACCESS_OTHER_DEVICES==1 - dev = dev_find_device(M.x86.R_DX, M.x86.R_CX, 0); - if (dev != 0) { - DEBUG_PRINTF_INTR - ("%s(): function %x: PCI Find Device --> 0x%04x\n", - __func__, M.x86.R_AX, M.x86.R_BX); - - M.x86.R_BH = dev->bus->secondary; - M.x86.R_BL = dev->path.pci.devfn; - M.x86.R_AH = 0x00; // return code: success - CLEAR_FLAG(F_CF); -#else - // only allow the device to find itself... - if ((M.x86.R_CX == bios_device.pci_device_id) - && (M.x86.R_DX == bios_device.pci_vendor_id) - // device index must be 0 - && (M.x86.R_SI == 0)) { - CLEAR_FLAG(F_CF); - M.x86.R_AH = 0x00; // return code: success - M.x86.R_BH = bios_device.bus; - M.x86.R_BL = bios_device.devfn; -#endif - } else { - DEBUG_PRINTF_INTR - ("%s(): function %x: invalid device/vendor/device index! (%04x/%04x/%02x expected: %04x/%04x/00) \n", - __func__, M.x86.R_AX, M.x86.R_CX, M.x86.R_DX, - M.x86.R_SI, bios_device.pci_device_id, - bios_device.pci_vendor_id); - - SET_FLAG(F_CF); - M.x86.R_AH = 0x86; // return code: device not found - } - break; - case 0xb108: //read configuration byte - case 0xb109: //read configuration word - case 0xb10a: //read configuration dword - bus = M.x86.R_BH; - devfn = M.x86.R_BL; - offs = M.x86.R_DI; - DEBUG_PRINTF_INTR("%s(): function: %x: PCI Config Read from device: bus: %02x, devfn: %02x, offset: %02x\n", - __func__, M.x86.R_AX, bus, devfn, offs); -#if defined(CONFIG_YABEL_PCI_ACCESS_OTHER_DEVICES) && CONFIG_YABEL_PCI_ACCESS_OTHER_DEVICES==1 - dev = dev_find_slot(bus, devfn); - DEBUG_PRINTF_INTR("%s(): function: %x: dev_find_slot() returned: %s\n", - __func__, M.x86.R_AX, dev_path(dev)); - if (dev == 0) { - // fail accesses to non-existent devices... -#else - dev = bios_device.dev; - if ((bus != bios_device.bus) - || (devfn != bios_device.devfn)) { - // fail accesses to any device but ours... -#endif - printf - ("%s(): Config read access invalid device! bus: %02x (%02x), devfn: %02x (%02x), offs: %02x\n", - __func__, bus, bios_device.bus, devfn, - bios_device.devfn, offs); - SET_FLAG(F_CF); - M.x86.R_AH = 0x87; //return code: bad pci register - HALT_SYS(); - return; - } else { - switch (M.x86.R_AX) { - case 0xb108: - M.x86.R_CL = -#ifdef CONFIG_PCI_OPTION_ROM_RUN_YABEL - pci_read_config8(dev, offs); -#else - (u8) rtas_pci_config_read(bios_device. - puid, 1, - bus, devfn, - offs); -#endif - DEBUG_PRINTF_INTR - ("%s(): function %x: PCI Config Read @%02x --> 0x%02x\n", - __func__, M.x86.R_AX, offs, - M.x86.R_CL); - break; - case 0xb109: - M.x86.R_CX = -#ifdef CONFIG_PCI_OPTION_ROM_RUN_YABEL - pci_read_config16(dev, offs); -#else - (u16) rtas_pci_config_read(bios_device. - puid, 2, - bus, devfn, - offs); -#endif - DEBUG_PRINTF_INTR - ("%s(): function %x: PCI Config Read @%02x --> 0x%04x\n", - __func__, M.x86.R_AX, offs, - M.x86.R_CX); - break; - case 0xb10a: - M.x86.R_ECX = -#ifdef CONFIG_PCI_OPTION_ROM_RUN_YABEL - pci_read_config32(dev, offs); -#else - (u32) rtas_pci_config_read(bios_device. - puid, 4, - bus, devfn, - offs); -#endif - DEBUG_PRINTF_INTR - ("%s(): function %x: PCI Config Read @%02x --> 0x%08x\n", - __func__, M.x86.R_AX, offs, - M.x86.R_ECX); - break; - } - CLEAR_FLAG(F_CF); - M.x86.R_AH = 0x0; // return code: success - } - break; - case 0xb10b: //write configuration byte - case 0xb10c: //write configuration word - case 0xb10d: //write configuration dword - bus = M.x86.R_BH; - devfn = M.x86.R_BL; - offs = M.x86.R_DI; - if ((bus != bios_device.bus) - || (devfn != bios_device.devfn)) { - // fail accesses to any device but ours... - printf - ("%s(): Config read access invalid! bus: %x (%x), devfn: %x (%x), offs: %x\n", - __func__, bus, bios_device.bus, devfn, - bios_device.devfn, offs); - SET_FLAG(F_CF); - M.x86.R_AH = 0x87; //return code: bad pci register - HALT_SYS(); - return; - } else { - switch (M.x86.R_AX) { - case 0xb10b: -#ifdef CONFIG_PCI_OPTION_ROM_RUN_YABEL - pci_write_config8(bios_device.dev, offs, M.x86.R_CL); -#else - rtas_pci_config_write(bios_device.puid, 1, bus, - devfn, offs, M.x86.R_CL); -#endif - DEBUG_PRINTF_INTR - ("%s(): function %x: PCI Config Write @%02x <-- 0x%02x\n", - __func__, M.x86.R_AX, offs, - M.x86.R_CL); - break; - case 0xb10c: -#ifdef CONFIG_PCI_OPTION_ROM_RUN_YABEL - pci_write_config16(bios_device.dev, offs, M.x86.R_CX); -#else - rtas_pci_config_write(bios_device.puid, 2, bus, - devfn, offs, M.x86.R_CX); -#endif - DEBUG_PRINTF_INTR - ("%s(): function %x: PCI Config Write @%02x <-- 0x%04x\n", - __func__, M.x86.R_AX, offs, - M.x86.R_CX); - break; - case 0xb10d: -#ifdef CONFIG_PCI_OPTION_ROM_RUN_YABEL - pci_write_config32(bios_device.dev, offs, M.x86.R_ECX); -#else - rtas_pci_config_write(bios_device.puid, 4, bus, - devfn, offs, M.x86.R_ECX); -#endif - DEBUG_PRINTF_INTR - ("%s(): function %x: PCI Config Write @%02x <-- 0x%08x\n", - __func__, M.x86.R_AX, offs, - M.x86.R_ECX); - break; - } - CLEAR_FLAG(F_CF); - M.x86.R_AH = 0x0; // return code: success - } - break; - default: - printf("%s(): unknown function (%x) for int1a handler.\n", - __func__, M.x86.R_AX); - DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", - M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, - M.x86.R_DX); - HALT_SYS(); - break; - } -} - -// main Interrupt Handler routine, should be registered as x86emu interrupt handler -void -handleInterrupt(int intNum) -{ - u8 int_handled = 0; -#ifndef DEBUG_PRINT_INT10 - // this printf makes output by int 10 unreadable... - // so we only enable it, if int10 print is disabled - DEBUG_PRINTF_INTR("%s(%x)\n", __func__, intNum); -#endif - - /* check wether this interrupt has a function pointer set in yabel_intFuncArray and run that */ - if (yabel_intFuncArray[intNum]) { - DEBUG_PRINTF_INTR("%s(%x) intHandler overridden, calling it...\n", __func__, intNum); - int_handled = (*yabel_intFuncArray[intNum])(); - } else { - switch (intNum) { - case 0x10: //BIOS video interrupt - case 0x42: // INT 10h relocated by EGA/VGA BIOS - case 0x6d: // INT 10h relocated by VGA BIOS - // get interrupt vector from IDT (4 bytes per Interrupt starting at address 0 - if ((my_rdl(intNum * 4) == 0xF000F065) || //F000:F065 is default BIOS interrupt handler address - (my_rdl(intNum * 4) == 0xF4F4F4F4)) //invalid - { -#if 0 - // ignore interrupt... - DEBUG_PRINTF_INTR - ("%s(%x): invalid interrupt Vector (%08x) found, interrupt ignored...\n", - __func__, intNum, my_rdl(intNum * 4)); - DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", - M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, - M.x86.R_DX); - //HALT_SYS(); -#endif - handleInt10(); - int_handled = 1; - } - break; - case 0x16: - // Keyboard BIOS Interrupt - handleInt16(); - int_handled = 1; - break; - case 0x1a: - // PCI BIOS Interrupt - handleInt1a(); - int_handled = 1; - break; - case PMM_INT_NUM: - /* the selfdefined PMM INT number, this is called by the code in PMM struct, it - * is handled by pmm_handleInt() - */ - pmm_handleInt(); - int_handled = 1; - break; - default: - printf("Interrupt %#x (Vector: %x) not implemented\n", intNum, - my_rdl(intNum * 4)); - DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", - M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, - M.x86.R_DX); - int_handled = 1; - HALT_SYS(); - break; - } - } - // if we did not handle the interrupt, jump to the interrupt vector... - if (!int_handled) { - setupInt(intNum); - } -} - -// prepare and execute Interrupt 10 (VGA Interrupt) -void -runInt10(void) -{ - // Initialize stack and data segment - M.x86.R_SS = STACK_SEGMENT; - M.x86.R_DS = DATA_SEGMENT; - M.x86.R_SP = STACK_START_OFFSET; - - // push a HLT instruction and a pointer to it onto the stack - // any return will pop the pointer and jump to the HLT, thus - // exiting (more or less) cleanly - push_word(0xf4f4); //F4=HLT - //push_word(M.x86.R_SS); - //push_word(M.x86.R_SP + 2); - - // setupInt will push the current CS and IP to the stack to return to it, - // but we want to halt, so set CS:IP to the HLT instruction we just pushed - // to the stack - M.x86.R_CS = M.x86.R_SS; - M.x86.R_IP = M.x86.R_SP; // + 4; - - CHECK_DBG(DEBUG_TRACE_X86EMU) { - X86EMU_trace_on(); - } - CHECK_DBG(DEBUG_JMP) { - M.x86.debug |= DEBUG_TRACEJMP_REGS_F; - M.x86.debug |= DEBUG_TRACEJMP_REGS_F; - M.x86.debug |= DEBUG_TRACECALL_F; - M.x86.debug |= DEBUG_TRACECALL_REGS_F; - } - setupInt(0x10); - DEBUG_PRINTF_INTR("%s(): starting execution of INT10...\n", - __func__); - X86EMU_exec(); - DEBUG_PRINTF_INTR("%s(): execution finished\n", __func__); -} - -// prepare and execute Interrupt 13 (Disk Interrupt) -void -runInt13(void) -{ - // Initialize stack and data segment - M.x86.R_SS = STACK_SEGMENT; - M.x86.R_DS = DATA_SEGMENT; - M.x86.R_SP = STACK_START_OFFSET; - - // push a HLT instruction and a pointer to it onto the stack - // any return will pop the pointer and jump to the HLT, thus - // exiting (more or less) cleanly - push_word(0xf4f4); //F4=HLT - //push_word(M.x86.R_SS); - //push_word(M.x86.R_SP + 2); - - // setupInt will push the current CS and IP to the stack to return to it, - // but we want to halt, so set CS:IP to the HLT instruction we just pushed - // to the stack - M.x86.R_CS = M.x86.R_SS; - M.x86.R_IP = M.x86.R_SP; - - CHECK_DBG(DEBUG_TRACE_X86EMU) { - X86EMU_trace_on(); - } - CHECK_DBG(DEBUG_JMP) { - M.x86.debug |= DEBUG_TRACEJMP_REGS_F; - M.x86.debug |= DEBUG_TRACEJMP_REGS_F; - M.x86.debug |= DEBUG_TRACECALL_F; - M.x86.debug |= DEBUG_TRACECALL_REGS_F; - } - - setupInt(0x13); - DEBUG_PRINTF_INTR("%s(): starting execution of INT13...\n", - __func__); - X86EMU_exec(); - DEBUG_PRINTF_INTR("%s(): execution finished\n", __func__); -} |