⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgdos32q.gml

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 GML
📖 第 1 页 / 共 4 页
字号:
/*
    Under DOS, the keyboard status byte has a segmented
    address of 0x0040:0x0017.  This corresponds to a
    linear address of 0x417.
 */

.millust break
void main()
{
    /* We require a far pointer to use selector
       for 1st megabyte */
    char far *ptr;
.millust break

    /* Set pointer to segmented address of the first
       status byte */
    ptr = MK_FP( 0x34, 0x417 );
.millust break

    /* Caps lock state is in bit 6 */
    if( *ptr & 0x40 ) {
        puts( "Caps Lock on" );
    }
.millust break
    /* Num lock state is in bit 5 */
    if( *ptr & 0x20 ) {
        puts( "Num Lock on" );
    }
.millust break
    /* Scroll lock state is in bit 4 */
    if( *ptr & 0x10 ) {
        puts( "Scroll Lock on" );
    }
}
.millust end
.np
Please refer to the chapter entitled "Program Environment"
in Phar Lap's
.book 386|DOS-Extender Reference Manual
for more information on segment selectors available to your program.
.*
.endlevel
.*
.section How do I spawn a protected-mode application?
.*
.np
.ix 'spawn'
Sometimes applications need to spawn other programs as part of their
execution.
In the extended DOS environment, spawning tasks is much the same as
under DOS, however it should be noted that the only mode supported is
P_WAIT.
The P_OVERLAY mode is not supported since the DOS extender cannot be
removed from memory by the application (this is also the reason why
the exec() functions are unsupported).
The other modes are for concurrent operating systems only.
.np
Also, unless the application being spawned is bound or stubbed, the
DOS extender must be spawned with the application and its arguments
passed in the parameter list.
.*
.beglevel
.section Spawning Protected-Mode Applications Under Tenberry Software DOS/4GW
.*
.np
.ix 'spawn' 'using DOS/4GW'
In the case of DOS/4GW, some real-mode memory must be set aside at run
time for spawning the DOS extender, otherwise the spawning application
could potentially allocate all of system memory.
The real memory can be reserved from within your program by assigning
the global variable
.mono __minreal
the number of bytes to be set aside.
This variable is referenced in
.mono <stdlib.h>.
The following two programs demonstrate how to spawn a DOS/4GW
application.
.millust begin
/*
    SPWNRD4G.C - The following program demonstrates how to
    spawn another DOS/4GW application.

    Compile and link: wcl386 -l=dos4g spwnrd4g
 */
#include <process.h>
#include <stdio.h>
#include <stdlib.h>

/* DOS/4GW var for WLINK MINREAL option */
unsigned __near __minreal = 100*1024;

.millust break
void main()
{
    int app2_exit_code;

    puts( "Spawning a protected-mode application..."
          "using spawnlp() with P_WAIT" );
    app2_exit_code = spawnlp( P_WAIT, "dos4gw",
                            "dos4gw", "spwndd4g", NULL );
    printf( "Application #2 returned with exit code %d\n",
                            app2_exit_code );
}
.millust end
.millust begin
/*
    SPWNDD4G.C - Will be spawned by the SPWNRD4G program.

    Compile & Link: wcl386 -l=dos4g spwndd4g
 */
#include <stdio.h>
#include <stdlib.h>

.millust break
void main()
{
    puts( "\nApplication #2 spawned\n" );
    /* Send back exit code 59 */
    exit( 59 );
}
.millust end
.*
.section Spawning Protected-Mode Applications Under Phar Lap 386|DOS-Extender
.*
.np
.ix 'spawn' 'using Phar Lap'
In the case of the Phar Lap 386|DOS-Extender, some real-mode memory
must be set aside at link time for spawning the DOS extender,
otherwise the spawning application will be assigned all the system
memory at startup.
This is done at link time by specifying the
.bd runtime minreal
and
.bd runtime maxreal
options, as demonstrated by the following programs.
.millust begin
/*
    SPWNRPLS.C - The following program demonstrates how to
    spawn a Phar Lap application.

    Compile & Link:
    wcl386 -l=pharlap -"runt minr=300K,maxr=400K" spwnrpls
 */
#include <process.h>
#include <stdio.h>

.millust break
void main()
{
    int app2_exit_code;

    puts( "Spawning a protect-mode application..."
          "using spawnlp() with P_WAIT" );
    puts( "Spawning application #2..." );
    app2_exit_code = spawnlp( P_WAIT, "run386",
                            "run386", "spwndpls", NULL );

    printf( "Application #2 returned with exit code %d",
                app2_exit_code );
}
.millust end
.millust begin
/*
    SPWNDPLS.C - Will be spawned by the SPWNRPLS program.

    Compile & Link: wcl386 -l=pharlap spwndpls
 */
#include <stdio.h>
#include <stdlib.h>

void main()
{
    puts( "\nApplication #2 spawned\n" );
    /* Exit with error code 59 */
    exit( 59 );
}
.millust end
.endlevel
.do end
.*
.if '&lang' eq 'C' or '&lang' eq 'C/C++' .do begin
.*
.section How Can I Use the Mouse Interrupt (0x33) with DOS/4GW?
.*
.np
.ix 'INT 33H' 'using DOS/4GW'
.ix 'mouse interrupt' 'using DOS/4GW'
Several commonly used interrupts are automatically supported in
protected mode with DOS/4GW.
The DOS extender handles the switch from protected mode to real mode
and manages any intermediate real-mode data buffers that are required.
To use a supported interrupt, set up the register information as
required for the interrupt and use one of the int386() or int386x()
library functions to execute the interrupt.
For calls that are not supported by DOS/4GW, you can use the DPMI
function, Simulate a Real-Mode Interrupt (0x0300).
This process is described in the next section.
.np
Since the mouse interrupt (0x33) is quite commonly used, DOS/4GW
provides protected-mode support for the interrupt and any mouse data
buffer that is required.
The following example demonstrates how a programmer could use the
Microsoft standard mouse interrupt (0x33) from within a DOS/4GW
application.
.code begin
/*
    MOUSE.C - The following program demonstrates how
    to use the mouse interrupt (0x33) with DOS/4GW.

    Compile and link: wcl386 -l=dos4g mouse
*/
#include <stdio.h>
#include <dos.h>
#include <i86.h>

int right_button = 0;
int mouse_event = 0;
int mouse_code = 0;
int mouse_cx = 0;
int mouse_dx = 0;
.code break

/* Set up data buffer for mouse cursor bitmap */
unsigned short cursor[] =
{
    0x0001, 0x0200, 0x0000, 0x0000,
    0x0001, 0x0200, 0x0000, 0x0000,
    0x0001, 0x0200, 0x0000, 0x0000,
    0x0001, 0x0200, 0x0000, 0x0000,
    0x0001, 0x0200, 0x0000, 0x0000,
    0x0001, 0x0200, 0x0000, 0x0000,
    0x0001, 0x0200, 0x0000, 0x0000,
    0x0001, 0x0200, 0x0000, 0x0000,
    0x0001, 0x0200, 0x0000, 0x0000,
    0x0001, 0x0200, 0x0000, 0x0000,
    0x0001, 0x0200, 0x0000, 0x0000,
    0x0001, 0x0200, 0x0000, 0x0000,
    0x0001, 0x0200, 0x0000, 0x0000,
    0x0001, 0x0200, 0x0000, 0x0000,
    0x0001, 0x0200, 0x0000, 0x0000,
    0x0001, 0x0200, 0x0000, 0x0000
};
.code break

#pragma off (check_stack)
void _loadds far click_handler (int max, int mcx, int mdx)
{
#pragma aux click_handler parm [EAX] [ECX] [EDX]
        mouse_event = 1;
        mouse_code = max;
        mouse_cx = mcx;
        mouse_dx = mdx;
        if( mouse_code & 8 ) right_button = 1;
}
#pragma on (check_stack)
.code break

void main( void )
{
    struct SREGS sregs;
    union REGS inregs, outregs;
    int installed = 0;
    int orig_mode = 0;
    int far *ptr;
    int (far *function_ptr)();

    segread(&sregs);

    /* get original video mode */

    inregs.w.ax = 0x0f00;
    int386( 0x10, &inregs, &outregs );

    printf( "Current Mode = %u\n",
            orig_mode=outregs.h.al );
.code break

    /* check for mouse driver */

    inregs.w.ax = 0;
    int386 (0x33, &inregs, &outregs);
    if( installed = (outregs.w.ax == -1) )
        printf( "Mouse installed...\n" );
    else
        printf( "Mouse NOT installed...\n" );
.code break

    if( installed ) {

        /* goto graphics mode */

        inregs.h.ah = 0x00;
        inregs.h.al = 0x4;
        int386( 0x10, &inregs, &outregs );
.code break

        /* show mouse cursor */

        inregs.w.ax = 0x1;
        int386( 0x33, &inregs, &outregs );
.code break

        /* set mouse cursor form */

        inregs.w.ax = 0x9;
        inregs.w.bx = 0x0;
        inregs.w.cx = 0x0;
        ptr = cursor;
        inregs.x.edx = FP_OFF( ptr );
        sregs.es     = FP_SEG( ptr );
        int386x( 0x33, &inregs, &outregs, &sregs );
.code break

        /* install click watcher */

        inregs.w.ax = 0xC;
        inregs.w.cx = 0x0002 + 0x0008;
        function_ptr = click_handler;
        inregs.x.edx = FP_OFF( function_ptr );
        sregs.es     = FP_SEG( function_ptr );
        int386x( 0x33, &inregs, &outregs, &sregs );
.code break

        while( !right_button ) {
            if( mouse_event ) {
                printf( "Event = %x : CX = %u DX = %u\n",
                         mouse_code, mouse_cx, mouse_dx );
                mouse_event = 0;
            }
        }
    }
.code break

    /* check installation again (to clear watcher) */

    inregs.w.ax = 0;
    int386( 0x33, &inregs, &outregs );
    if( outregs.w.ax == -1 )
        printf( "DONE : Mouse still installed...\n" );
    else
        printf( "DONE : Mouse NOT installed...\n" );
.code break

    inregs.h.ah = 0x00;
    inregs.h.al = orig_mode;
    int386( 0x10, &inregs, &outregs );
}
.code end
.*
.section How Do I Simulate a Real-Mode Interrupt with DOS/4GW?
.*
.np
.ix 'interrupts' 'real-mode simulation'
.ix 'simulating real-mode interrupts'
Some interrupts are not supported in protected mode with DOS/4GW but
they can still be called using the DPMI function, Simulate Real-Mode
Interrupt (0x0300).
Information that needs to be passed down to the real-mode interrupt is
transferred using an information data structure that is allocated in
the protected-mode application.
The address to this protected-mode structure is passed into DPMI
function 0x0300.
DOS/4GW will then use this information to set up the real-mode
registers, switch to real mode and then execute the interrupt in real
mode.
.np
If your protected-mode application needs to pass data down into the
real-mode interrupt, an intermediate real-mode buffer must be used.
This buffer can be created using DPMI function 0x0100 to allocate
real-mode memory.
You can then transfer data from the protected-mode memory to the
real-mode memory using a far pointer as illustrated in the
"SIMULATE.C" example.
.np
The following example illustrates how to allocate some real-mode
memory, transfer a string of characters from protected mode into the
real-mode buffer, then set up and call the Interrupt 0x0021 function
to create a directory.
The string of characters are used to provide the directory name.
This example can be adapted to handle most real-mode interrupt calls
that aren't supported in protected mode.
.code begin
/*
    SIMULATE.C - Shows how to issue a real-mode interrupt
    from protected mode using DPMI call 300h.  Any buffers
    to be passed to DOS must be allocated in DOS memory

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -