summaryrefslogtreecommitdiff
path: root/util/x86emu/yabel/interrupt.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/x86emu/yabel/interrupt.c')
-rw-r--r--util/x86emu/yabel/interrupt.c677
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__);
-}