_intr_v86()

Execute a real-mode software interrupt

Synopsis:

#include <x86/v86.h>

int _intr_v86( int swi,
               struct _v86reg* regs, 
               void* data, 
               int datasize );

Arguments:

swi
The software interrupt that you want to execute.
regs
A pointer to a _v86reg structure that specifies the values you want to use for the registers on entry to real mode; see below.
data
A pointer to the data that you want to copy into memory; see below.
datasize
The size of the data, in bytes.

Library:

libc

Use the -l c option to qcc to link against this library. This library is usually included automatically.

Description:

The _intr_v86() function executes the real-mode software interrupt specified by swi in virtual 8086 mode. This allows access to the ROM BIOS functions that are designed to run in 16-bit real mode. Two common examples are:

Interrupt Description
int 10h Video BIOS
int 1ah PCI

BIOS calls (such as int 13h, disk I/O) that require hardware interrupts to be directed at their code aren't supported.

Upon entry to real mode, the registers are loaded from regs. The segment registers and any pointers should address a 2 KB communication area located at offset 0:800h in real memory. The buffer data of length datasize is copied to this area just before real mode is entered and copied back when the call completes. At this point regs is also updated to contain the values of the real-mode registers.

You should set the DS, ES, FS and GS segment registers to 0. The values in the CS:IP, and SS:SP registers are ignored and are set by the kernel. The stack provided is about 500 bytes in size.

The layout of real mode memory is described by the structure _v86_memory in <x86/v86.h>.

When a thread enters virtual 8086 mode, all threads in the system continue to be scheduled based upon their priority, including the calling thread. While in virtual 8086 mode, full access to IO ports and interrupt enable and disable are allowed. Only one thread may enter virtual 8086 mode at a time.

This function fails if the calling process doesn't have the PROCMGR_AID_V86 enabled. For more information, see procmgr_ability().

Returns:

0
Success.
-1
An error occurred; errno is set.

Errors:

EBADF
The connection to the system process is no longer connected to a channel, or the connection doesn't exist. The channel may have been terminated by the server, or the network manager if it failed to respond to multiple polls.
EFAULT
A fault occurred when accessing the information pointed to by the data or regs arguments.
EINTR
The call was interrupted by a signal.
EOVERFLOW
The sum of the IOV lengths being sent to the system process exceeds INT_MAX.
EPERM
The calling process doesn't have the required permission; see procmgr_ability().
ETIMEDOUT
A kernel timeout unblocked the underlying call to MsgSendvnc(). See TimerTimeout().

Examples:

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#include <x86/v86.h>

struct _v86reg reg;

int main( void ) {
    char buf[4];

    /* Equipment call */
    printf("int 12\n");
    memset(&reg, 0, sizeof(reg));
    _intr_v86(0x12, &reg, NULL, 0);
    printreg();
    sleep(5);

    /* Enter 40 column text mode */
    printf("int 10 ah=00h al=00h\n");
    memset(&reg, 0, sizeof(reg));
    _intr_v86(0x10, &reg, NULL, 0);
    printreg();
    sleep(5);

    /* Enter 80 column text mode */
    printf("int 10 ah=00h al=02h\n");
    memset(&reg, 0, sizeof(reg));
    reg.eax = 2;
    _intr_v86(0x10, &reg, NULL, 0);
    printreg();
    sleep(5);

    /* Write a string from memory */
    printf("int 10 ah=13h al=00h\n");
    strcpy(buf, "Hi!");
    memset(&reg, 0, sizeof(reg));
    reg.eax = 0x1300;
    reg.es = 0;
    reg.ebp = offsetof(struct _v86_memory, userdata);
    reg.ecx = strlen(buf);
    reg.edx = 0;
    reg.ebx = 0x0007;
    _intr_v86(0x10, &reg, buf, strlen(buf));
    printreg();
    sleep(5);

    return EXIT_SUCCESS;
}


printreg() {

    printf("eax=%-8x ebx=%-8x ecx=%-8x edx=%-8x\n",
            reg.eax, reg.ebx, reg.ecx, reg.edx);
    printf("esi=%-8x edi=%-8x ebp=%-8x esp=%-8x\n",
            reg.esi, reg.edi, reg.ebp, reg.esp);
    printf(" ds=%-8x  es=%-8x  fs=%-8x  gs=%-8x\n",
            reg.ds, reg.es, reg.fs, reg.gs);
    printf("efl=%-8x\n\n",
            reg.efl);
}

Classification:

QNX Neutrino (x86 only)

Safety:  
Cancellation point No
Interrupt handler No
Signal handler Yes
Thread Yes