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

📄 pgdos32q.gml

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 GML
📖 第 1 页 / 共 4 页
字号:
.chap 32-bit Extended DOS Application Development
.*
.if &e'&dohelp eq 0 .do begin
.section Introduction
.do end
.*
.np
.ix 'DOS extenders' 'common problems'
The purpose of this chapter is to anticipate common programming
questions for 32-bit extended DOS application development. Note that
these programming solutions may be DOS-extender specific and therefore
may not work for other DOS extenders.
.np
The following topics are discussed in this chapter:
.if '&lang' eq 'C' or '&lang' eq 'C/C++' .do begin
.begbull
.bull
How can I write directly to video memory using a DOS extender?
.bull
How do I get information about free memory in the 32-bit environment?
.bull
How do I access the first megabyte in the extended DOS environment?
.bull
How do I spawn a protected-mode application?
.bull
How can I use the mouse interrupt (0x33) with DOS/4GW?
.bull
How do I simulate a real-mode interrupt with DOS/4GW?
.bull
How do you install a bi-modal interrupt handler with DOS/4GW?
.endbull
.do end
.if '&lang' eq 'FORTRAN 77' .do begin
.begbull
.bull
How can I write directly to video memory using DOS/4GW?
.bull
How do I issue interrupts in a DOS/4GW application?
.bull
How do I get information about free memory with DOS/4GW?
.endbull
.do end
.np
.ix 'DPMI specification'
Please refer to the
.book DOS Protected-Mode Interface (DPMI) Specification
for information on DPMI services.
In the past, the DPMI specification could be obtained free of charge
by contacting Intel Literature JP26 at 800-548-4725 or by writing
to the address below.
We have been advised that the DPMI specification is no longer
available in printed form.
.illust begin
Intel Literature JP26
3065 Bowers Avenue
P.O. Box 58065
Santa Clara, California
U.S.A. 95051-8065
.illust end
.np
However, the DPMI 1.0 specification can be obtained from the Intel ftp
site.
Here is the URL.
.code begin
ftp://ftp.intel.com/pub/IAL/software_specs/dpmiv1.zip
.code end
.pc
This ZIP file contains a Postscript version of the DPMI 1.0 specification.
.*
.section How can I write directly to video memory using a DOS extender?
.*
.np
.ix 'video memory'
Many programmers require access to video RAM in order to directly
manipulate data on the screen.
Under DOS, it was standard practice to use a far pointer, with the
segment part of the far pointer set to the screen segment.
Under DOS extenders, this practice is not so standard.
Each DOS extender provides its own method for accessing video memory.
.if '&lang' eq 'FORTRAN 77' .do begin
The following program demonstrates the method used with DOS/4GW.
.code begin
* FSCREEN.FOR
* The following program shows how to access screen memory
* from a FORTRAN program under the DOS/4GW DOS extender.

* Compile & Link: wfl386 -l=dos4g fscreen

      program screen

* Allocatable arrays must be declared by specifying their
* dimensions using colons only (see &company FORTRAN 77
* Language Reference on the ALLOCATE statement for details).

      character*1 screen(:,:)
      integer SCRSIZE, i

      parameter ( SCRSIZE = 80*25 )
.code break

* Under DOS/4GW, the first megabyte of physical memory - the
* real memory - is mapped as a shared linear address space.
* This allows your application to access video RAM using its
* linear address.  The DOS segment:offset of B800:0000
* corresponds to a linear address of B8000.

      allocate( screen(0:1,0:SCRSIZE-1), location='B8000'x )

      do i = 0, SCRSIZE - 1
          screen(0,i) = '*'
      enddo

      end
.code end
.do end
.if '&lang' eq 'C' or '&lang' eq 'C/C++' .do begin
.*
.beglevel
.section Writing to Video Memory under Tenberry Software DOS/4GW
.*
.np
.ix 'video memory' 'using DOS/4GW'
Under DOS/4GW, the first megabyte of physical memory is mapped as a
shared linear address space.
This allows your application to access video RAM using a near pointer
set to the screen's linear address.
The following program demonstrates this method.
.millust begin
/*
    SCREEN.C - This example shows how to write directly
    to screen memory under the DOS/4GW dos-extender.

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

/*
  Under DOS/4GW, the first megabyte of physical memory
  (real-mode memory) is mapped as a shared linear address
  space. This allows your application to access video RAM
  using its linear address.  The DOS segment:offset of
  B800:0000 corresponds to a linear address of B8000.
 */
#define SCREEN_AREA 0xb800
#define SCREEN_LIN_ADDR ((SCREEN_AREA) << 4)
#define SCREEN_SIZE 80*25
.millust break

void main()
{
    char       *ptr;
    int         i;

    /* Set the pointer to the screen's linear address */
    ptr = (char *)SCREEN_LIN_ADDR;
    for( i = 0; i < SCREEN_SIZE - 1; i++ ) {
        *ptr = '*';
        ptr += 2 * sizeof( char );
    }
}
.millust end
.np
Please refer to the chapter entitled :HDREF refid='linexe'. for more
information on how DOS/4GW maps the first megabyte.
.*
.section Writing to Video Memory under the Phar Lap 386|DOS-Extender
.*
.np
.ix 'video memory' 'using Phar Lap'
The Phar Lap DOS extender provides screen access through the special
segment selector 0x1C.
This allows far pointer access to video RAM from a 32-bit program.
The following example illustrates this technique.
.millust begin
/*
    SCREENPL.C - This example shows how to write directly
    to screen memory under the Phar Lap DOS extender.

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

/*
    Phar Lap allows access to screen memory through a
    special selector.  Refer to "Hardware Access" in
    Phar Lap's documentation for details.
 */
#define PL_SCREEN_SELECTOR 0x1c
#define SCREEN_SIZE 80*25
.millust break

void main()
{
    /* Need a far pointer to use the screen selector */
    char far   *ptr;
    int         i;

    /* Make a far pointer to screen memory */
    ptr = MK_FP( PL_SCREEN_SELECTOR, 0 );
    for( i = 0; i < SCREEN_SIZE - 1; i++ ) {
        *ptr = '*';
        ptr += 2 * sizeof( char );
    }
}
.millust end
.np
It is also possible to map screen memory into your near memory using
Phar Lap system calls.
Please refer to the chapter entitled "386|DOS-Extender System Calls"
in Phar Lap's
.book 386|DOS-Extender Reference Manual
for details.
.*
.endlevel
.do end
.*
.if '&lang' eq 'FORTRAN 77' .do begin
.*
.section  How do I issue interrupts in a DOS/4GW application?
.*
.np
.ix 'interrupts' 'using DOS/4GW'
The &cmpname library files contain the FINTR subroutine which allows
the user to perform interrupt calls within a &lang program.
This subroutine is described in the Subprogram Library section of the
.book &product User's Guide.
.np
The following sample program illustrates the use of the FINTR subroutine
to set up the register information required for Interrupt 21h.
The register information is loaded into the regs structure.  This structure
is defined in the DOS.FI file located in the \WATCOM\SRC\FORTRAN\DOS
directory.  Assign values to the register elements according to the
interrupt call requirements.  For example, Interrupt 21h, function 4Eh
needs valid values for the AH, ECX, DS and EDX to set up the registers
for the Interrupt 21h call.  This procedure can be used to perform
any interrupt calls that are supported in protected mode by DOS/4GW.
.*
.code begin
* DTA.FOR
* This program demonstrates the use of the FINTR
* function to list the files of the current directory.
* Interrupt 21 Functions for FIND FIRST, FIND NEXT,
* and GET DTA are used.

* Compile & Link: set finclude=\watcom\src\fortran\dos
*                 wfl386 -l=dos4g dta

*$pragma aux GetDS = "mov ax,ds" value [ax]

        program dta
        implicit integer*2 (i-n)
        integer*2 res
        integer*2 GetDS
        integer*4 dir,addr
        integer*1 dta(:)
        character fname*1(12), fname2*12
        equivalence (fname, fname2)
.code break

* DTA is declared as a FAR array.  When referencing an array
* element, the pointer to the array is a FAR pointer.  With a
* character variable, the result is a pointer to a string
* control block (SCB).  The run-time library expects the SCB
* to contain a near pointer.  To get around the problem, we
* define the DTA as a byte array, then use the CHAR function
* to get the character equivalent for printing a filename.

*$pragma array dta far
.code break

        include 'dos.fi'
*
* Listing of current directory
*
        call fsystem( 'dir/w *.*'//char(0) )
        dir = loc( '*.*'//char(0) )

        i = 0
10      i = i + 1
.code break
        if( i .eq. 1 )then
*
* Find first file
*
            AH = '4E'x
            ECX = 0
            DS = GetDS()
            EDX = dir
        else
*
* Find next file
*
            AH = '4F'x
        endif
        call fintr( '21'x, regs )
        res = AX
.code break

        if( res .eq. 0 )then
*
* Extract filename from DTA
*
            AH = '2F'x
            call fintr( '21'x, regs )

            addr = ISHL( IAND( INT( ES ), '0000FFFF'x ), 16 )
            addr = IOR( addr, IAND( INT( BX ), '0000FFFF'x ) )
            allocate( dta(0:42), location=addr )
            fname2 = ' '
            do j = 30, 41
                if( dta(j) .eq. 0 ) goto 20
                fname(j - 29) = char( dta(j) )
            enddo
20          print *, fname2
            deallocate( dta )
            goto 10
        endif

        end
.code end
.do end
.*
.section How do I get information about free memory in the 32-bit environment?
.*
.np
.ix 'free memory'
Under a virtual memory system, programmers are often interested
in the amount of physical memory they can allocate.
Information about the amount of free memory that is available is always
provided under a DPMI host, however,
the manner in which this information is provided may differ
under various environments.
Keep in mind that in a multi-tasking environment, the information
returned to your task from the DPMI host can easily become obsolete
if other tasks allocate memory independently of your task.
.if '&lang' eq 'FORTRAN 77' .do begin
.np
DOS/4GW provides a DPMI interface through interrupt 0x31.
This allows you to use DPMI service 0x0500 to get free memory
information.
The following program illustrates this procedure.
.code begin
* FMEMORY.FOR
* This example shows how to get information about free
* memory using DPMI call 0500h under DOS/4GW using &company
* FORTRAN 77.  Note that only the first field of the
* structure is guaranteed to contain a valid value; any
* field not returned by DOS/4GW is set to -1 (0FFFFFFFFh).

* Compile & Link:   set finclude=\watcom\src\fortran\dos
*                   wfl386 -l=dos4g fmemory

* Pragma to get the default data segment

*$pragma aux GetDS = "mov ax,ds" value [ax] modify exact [ax]

      program memory
      implicit none
      include 'dos.fi'

      structure /meminfo/
          integer*4 LargestBlockAvail
          integer*4 MaxUnlockedPage
          integer*4 LargestLockablePage
          integer*4 LinAddrSpace
          integer*4 NumFreePagesAvail
          integer*4 NumPhysicalPagesFree
          integer*4 TotalPhysicalPages
          integer*4 FreeLinAddrSpace
          integer*4 SizeOfPageFile
          integer*4 Reserved1
          integer*4 Reserved2
      end structure
.code break

* Set up the register information for the interrupt call

      record /meminfo/ MemInfo
      integer interrupt_no
      integer*2 GetDS

      parameter( interrupt_no='31'x)
      DS = FS = GS = 0
      EAX = '00000500'x

⌨️ 快捷键说明

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