7.4 Functions and Procedures

allocate__ldt__descriptors

Declaration:
Function allocate_ldt_descriptors (count : Word) : Word;
Description:
Allocates a number of new descriptors. Parameters:
count: 
specifies the number of requested unique descriptors.

Return value: The base selector. Notes: The descriptors allocated must be initialized by the application with other function calls. This function returns descriptors with a limit and size value set to zero. If more than one descriptor was requested, the function returns a base selector referencing the first of a contiguous array of descriptors. The selector values for subsequent descriptors in the array can be calculated by adding the value returned by the get__next__selector__increment__value (163) function.

Errors:
Check the int31error variable.
See also:

free__ldt__descriptor (159), get__next__selector__increment__value (163), segment__to__descriptor (178), create__code__segment__alias__descriptor (154), set__segment__limit (181), set__segment__base__address (181)

Listing: go32ex/seldes.pp


{$mode delphi}
uses
        crt,
        go32;

const
        maxx = 80;
        maxy = 25;
        bytespercell = 2;
        screensize = maxx * maxy * bytespercell;

        linB8000 = $B800 * 16;

type
        string80 = string[80];

var
        text_save : array[0..screensize-1] of byte;
        text_oldx, text_oldy : Word;

        text_sel : Word;

procedure status(s : string80);
begin
     gotoxy(1, 1); clreol; write(s); readkey;
end;

procedure selinfo(sel : Word);
begin
     gotoxy(1, 24);
     clreol; writeln('Descriptor base address : $',
        hexstr(get_segment_base_address(sel), 8));
     clreol; write('Descriptor limit : ', get_segment_limit(sel));
end;

function makechar(ch : char; color : byte) : Word;
begin
     result := byte(ch) or (color shl 8);
end;

begin
     seg_move(dosmemselector, linB8000, get_ds, longint(@text_save),
        screensize);
     text_oldx := wherex; text_oldy := wherey;
     seg_fillword(dosmemselector, linB8000, screensize div 2,
        makechar(' ', Black or (Black shl 4)));
     status('Creating selector ''text_sel'' to a part of ' +
        'text screen memory');
     text_sel := allocate_ldt_descriptors(1);
     set_segment_base_address(text_sel,
        linB8000 + bytespercell * maxx * 1);
     set_segment_limit(text_sel, screensize - 1 - bytespercell *
        maxx * 3);
     selinfo(text_sel);

     status('and clearing entire memory selected by ''text_sel''' +
        ' descriptor');
     seg_fillword(text_sel, 0, (get_segment_limit(text_sel)+1) div 2,
        makechar(' ', LightBlue shl 4));

     status('Notice that only the memory described by the' +
        ' descriptor changed, nothing else');

     status('Now reducing it''s limit and base and setting it''s ' +
        'described memory');
     set_segment_base_address(text_sel,
        get_segment_base_address(text_sel) + bytespercell * maxx);
     set_segment_limit(text_sel,
        get_segment_limit(text_sel) - bytespercell * maxx * 2);
     selinfo(text_sel);
     status('Notice that the base addr increased by one line but ' +
        'the limit decreased by 2 lines');
     status('This should give you the hint that the limit is ' +
        'relative to the base');
     seg_fillword(text_sel, 0, (get_segment_limit(text_sel)+1) div 2,
        makechar(#176, LightMagenta or Brown shl 4));

     status('Now let''s get crazy and copy 10 lines of data from ' +
        'the previously saved screen');
     seg_move(get_ds, longint(@text_save), text_sel,
        maxx * bytespercell * 2, maxx * bytespercell * 10);

     status('At last freeing the descriptor and restoring the old '+
        ' screen contents..');
     status('I hope this little program may give you some hints on '+
        'working with descriptors');
     free_ldt_descriptor(text_sel);
     seg_move(get_ds, longint(@text_save), dosmemselector,
        linB8000, screensize);
     gotoxy(text_oldx, text_oldy);
end.

allocate__memory__block

Declaration:
Function allocate_memory_block (size:Longint) : Longint;
Description:
Allocates a block of linear memory. Parameters:
size: 
Size of requested linear memory block in bytes.

Returned values: blockhandle - the memory handle to this memory block. Linear address of the requested memory. Notes: WARNING: According to my DPMI docs this function is not implemented correctly. Normally you should also get a blockhandle to this block after successful operation. This handle can then be used to free the memory block afterwards or use this handle for other purposes. Since the function isn’t implemented correctly, and doesn’t return a blockhandle, the block can’t be deallocated and is hence unusuable ! This function doesn’t allocate any descriptors for this block, it’s the applications resposibility to allocate and initialize for accessing this memory.

Errors:
Check the int31error variable.
See also:
free__memory__block (159)

copyfromdos

Declaration:
Procedure copyfromdos (var addr; len : Longint);
Description:

Copies data from the pre-allocated DOS memory transfer buffer to the heap. Parameters:

addr: 
data to copy to.
len: 
number of bytes to copy to heap.

Notes: Can only be used in conjunction with the DOS memory transfer buffer.

Errors:
Check the int31error variable.
See also:
tb__size (182), transfer__buffer (182), copytodos (154)

copytodos

Declaration:
Procedure copytodos (var addr; len : Longint);
Description:
Copies data from heap to the pre-allocated DOS memory buffer. Parameters:
addr: 
data to copy from.
len: 
number of bytes to copy to DOS memory buffer.

Notes: This function fails if you try to copy more bytes than the transfer buffer is in size. It can only be used in conjunction with the transfer buffer.

Errors:
Check the int31error variable.
See also:
tb__size (182), transfer__buffer (182), copyfromdos (154)

create__code__segment__alias__descriptor

Declaration:
Function create_code_segment_alias_descriptor (seg : Word) : Word;
Description:

Creates a new descriptor that has the same base and limit as the specified descriptor. Parameters:

seg: 
Descriptor.

Return values: The data selector (alias). Notes: In effect, the function returns a copy of the descriptor. The descriptor alias returned by this function will not track changes to the original descriptor. In other words, if an alias is created with this function, and the base or limit of the original segment is then changed, the two descriptors will no longer map the same memory.

Errors:
Check the int31error variable.
See also:

allocate__ldt__descriptors (151), set__segment__limit (181), set__segment__base__address (181)

disable

Declaration:
Procedure disable ;
Description:
Disables all hardware interrupts by execution a CLI instruction. Parameters: None.
Errors:
None.
See also:
enable (158)

dosmemfillchar

Declaration:
Procedure dosmemfillchar (seg, ofs : Word; count : Longint; c : char);
Description:
Sets a region of DOS memory to a specific byte value. Parameters:
seg: 
real mode segment.
ofs: 
real mode offset.
count: 
number of bytes to set.
c: 
value to set memory to.

Notes: No range check is performed.

Errors:
None.
See also:

dosmemput (158), dosmemget (157), dosmemmove (157)dosmemmove, dosmemfillword (156), seg__move (178), seg__fillchar (176), seg__fillword (177)

Listing: go32ex/textmess.pp


uses
        crt,
        go32;

const
        columns = 80;
        rows = 25;
        screensize = rows*columns*2;

        text = '! Hello world !';

var
        textofs : Longint;
        save_screen : array[0..screensize-1] of byte;
    curx, cury : Integer;

begin
        randomize;
        dosmemget($B800, 0, save_screen, screensize);
        curx := wherex; cury := wherey;
        gotoxy(1, 1); Write(text);
        textofs := screensize + length(text)*2;
        dosmemmove($B800, 0, $B800, textofs, length(text)*2);
        dosmemfillchar($B800, 0, screensize, #0);
        while (not keypressed) do begin
                dosmemfillchar($B800, textofs + random(length(text))*2 + 1,
                        1, char(random(255)));
                dosmemmove($B800, textofs, $B800,
                        random(columns)*2+random(rows)*columns*2,
                        length(text)*2);
                delay(1);
        end;
        readkey;
        readkey;
        dosmemput($B800, 0, save_screen, screensize);
        gotoxy(curx, cury);
end.

dosmemfillword

Declaration:
Procedure dosmemfillword (seg,ofs : Word; count : Longint; w : Word);
Description:
Sets a region of DOS memory to a specific word value. Parameters:
seg: 
real mode segment.
ofs: 
real mode offset.
count: 
number of words to set.
w: 
value to set memory to.

Notes: No range check is performed.

Errors:
None.
See also:

dosmemput (158), dosmemget (157), dosmemmove (157), dosmemfillchar (155), seg__move (178), seg__fillchar (176), seg__fillword (177)

dosmemget

Declaration:
Procedure dosmemget (seg : Word; ofs : Word; var data; count : Longint);
Description:
Copies data from the DOS memory onto the heap. Parameters:
seg: 
source real mode segment.
ofs: 
source real mode offset.
data: 
destination.
count: 
number of bytes to copy.

Notes: No range checking is performed.

Errors:
None.
See also:
dosmemput (158), dosmemmove (157), dosmemfillchar (155), dosmemfillword (156), seg__move (178), seg__fillchar (176), seg__fillword (177)

For an example, see global__dos__alloc (169).

dosmemmove

Declaration:
Procedure dosmemmove (sseg, sofs, dseg, dofs : Word; count : Longint);
Description:
Copies count bytes of data between two DOS real mode memory locations. Parameters:
sseg: 
source real mode segment.
sofs: 
source real mode offset.
dseg: 
destination real mode segment.
dofs: 
destination real mode offset.
count: 
number of bytes to copy.

Notes: No range check is performed in any way.

Errors:
None.
See also:
dosmemput (158), dosmemget (157), dosmemfillchar (155), dosmemfillword (156) seg__move (178), seg__fillchar (176), seg__fillword (177)

For an example, see seg__fillchar (176).

dosmemput

Declaration:
Procedure dosmemput (seg : Word; ofs : Word; var data; count : Longint);
Description:
Copies heap data to DOS real mode memory. Parameters:
seg: 
destination real mode segment.
ofs: 
destination real mode offset.
data: 
source.
count: 
number of bytes to copy.

Notes: No range checking is performed.

Errors:
None.
See also:
dosmemget (157), dosmemmove (157), dosmemfillchar (155), dosmemfillword (156), seg__move (178), seg__fillchar (176), seg__fillword (177)

For an example, see global__dos__alloc (169).

enable

Declaration:
Procedure enable ;
Description:

Enables all hardware interrupts by executing a STI instruction. Parameters: None.

Errors:
None.
See also:
disable (155)

free__ldt__descriptor

Declaration:
Function free_ldt_descriptor (des : Word) : boolean;
Description:
Frees a previously allocated descriptor. Parameters:
des: 
The descriptor to be freed.

Return value: True if successful, False otherwise. Notes: After this call this selector is invalid and must not be used for any memory operations anymore. Each descriptor allocated with allocate__ldt__descriptors (151) must be freed individually with this function, even if it was previously allocated as a part of a contiguous array of descriptors.

Errors:
Check the int31error variable.
See also:

allocate__ldt__descriptors (151), get__next__selector__increment__value (163)

For an example, see allocate__ldt__descriptors (151).

free__memory__block

Declaration:
Function free_memory_block (blockhandle : Longint) : boolean;
Description:
Frees a previously allocated memory block. Parameters:
blockhandle: the handle to the memory area to free.

Return value: True if successful, false otherwise. Notes: Frees memory that was previously allocated with allocate__memory__block (153) . This function doesn’t free any descriptors mapped to this block, it’s the application’s responsibility.

Errors:
Check int31error variable.
See also:
allocate__memory__block (153)

free__rm__callback

Declaration:
Function free_rm_callback (var intaddr : tseginfo) : boolean;
Description:

Releases a real mode callback address that was previously allocated with the get__rm__callback (164) function. Parameters:

intaddr: 
real mode address buffer returned by get__rm__callback (164) .

Return values: True if successful, False if not

Errors:
Check the int31error variable.
See also:

set__rm__interrupt (181), get__rm__callback (164)

For an example, see get__rm__callback (164).

get__cs

Declaration:
Function get_cs : Word;
Description:

Returns the cs selector. Parameters: None. Return values: The content of the cs segment register.

Errors:
None.
See also:
get__ds (161), get__ss (169)

For an example, see set__pm__interrupt (179).

get__descriptor__access__rights

Declaration:
Function get_descriptor_access_rights (d : Word) : Longint;
Description:
Gets the access rights of a descriptor. Parameters:
d selector to descriptor.

Return value: Access rights bit field.

Errors:
Check the int31error variable.
See also:

set__descriptor__access__rights (179)

get__ds

Declaration:
Function get_ds : Word;
Description:
Returns the ds selector. Parameters: None. Return values: The content of the ds segment register.
Errors:
None.
See also:
get__cs (160), get__ss (169)

get__linear__addr

Declaration:
Function get_linear_addr (phys_addr : Longint; size : Longint) : Longint;
Description:
Converts a physical address into a linear address. Parameters:
phys__addr: 
physical address of device.
size: 
Size of region to map in bytes.

Return value: Linear address that can be used to access the physical memory. Notes: It’s the applications resposibility to allocate and set up a descriptor for access to the memory. This function shouldn’t be used to map real mode addresses.

Errors:
Check the int31error variable.
See also:

allocate__ldt__descriptors (151), set__segment__limit (181), set__segment__base__address (181)

get__meminfo

Declaration:
Function get_meminfo (var meminfo : tmeminfo) : boolean;
Description:
Returns information about the amount of available physical memory, linear address space, and disk space for page swapping. Parameters:
meminfo: 
buffer to fill memory information into.

Return values: Due to an implementation bug this function always returns False, but it always succeeds. Notes: Only the first field of the returned structure is guaranteed to contain a valid value. Any fields that are not supported by the DPMI host will be set by the host to -1 (0FFFFFFFFH) to indicate that the information is not available. The size of the pages used by the DPMI host can be obtained with the get__page__size (163) function.

Errors:
Check the int31error variable.
See also:
get__page__size (163)

Listing: go32ex/meminfo.pp


uses
        go32;

var
        meminfo : tmeminfo;

begin
        get_meminfo(meminfo);
        if (int31error <> 0)  then begin
                Writeln('Error getting DPMI memory information... Halting');
                Writeln('DPMI error number : ', int31error);
        end else begin
                with meminfo do begin
                        Writeln('Largest available free block : ',
                                available_memory div 1024, ' kbytes');
                        if (available_pages <> -1) then
                                Writeln('Maximum available unlocked pages : ',
                                        available_pages);
                        if (available_lockable_pages <> -1) then
                                Writeln('Maximum lockable available pages : ',
                                        available_lockable_pages);
                        if (linear_space <> -1) then
                                Writeln('Linear address space size : ',
                                        linear_space*get_page_size div 1024, ' kbytes');
                        if (unlocked_pages <> -1) then
                                Writeln('Total number of unlocked pages : ',
                                        unlocked_pages);
                        if (available_physical_pages <> -1) then
                                Writeln('Total number of free pages : ',
                                        available_physical_pages);
                        if (total_physical_pages <> -1) then
                                Writeln('Total number of physical pages : ',
                                        total_physical_pages);
                        if (free_linear_space <> -1) then
                                Writeln('Free linear address space : ',
                                        free_linear_space*get_page_size div 1024,
                                        ' kbytes');
                        if (max_pages_in_paging_file <> -1) then
                                Writeln('Maximum size of paging file : ',
                                        max_pages_in_paging_file*get_page_size div 1024,
                                        ' kbytes');
                end;
        end;
end.

get__next__selector__increment__value

Declaration:
Function get_next_selector_increment_value : Word;
Description:
Returns the selector increment value when allocating multiple subsequent descriptors via allocate__ldt__descriptors (151). Parameters: None. Return value: Selector increment value. Notes: Because allocate__ldt__descriptors (151) only returns the selector for the first descriptor and so the value returned by this function can be used to calculate the selectors for subsequent descriptors in the array.
Errors:
Check the int31error variable.
See also:
allocate__ldt__descriptors (151), free__ldt__descriptor (159)

get__page__size

Declaration:
Function get_page_size : Longint;
Description:
Returns the size of a single memory page. Return value: Size of a single page in bytes. Notes: The returned size is typically 4096 bytes.
Errors:
Check the int31error variable.
See also:
get__meminfo (161)

For an example, see get__meminfo (161).

get__pm__interrupt

Declaration:
Function get_pm_interrupt (vector : byte; var intaddr : tseginfo) : boolean;
Description:
Returns the address of a current protected mode interrupt handler. Parameters:
vector: 
interrupt handler number you want the address to.
intaddr: 
buffer to store address.

Return values: True if successful, False if not. Notes: The returned address is a protected mode selector:offset address.

Errors:
Check the int31error variable.
See also:
set__pm__interrupt (179), set__rm__interrupt (181), get__rm__interrupt (167)

For an example, see set__pm__interrupt (179).

get__rm__callback

Declaration:
Function get_rm_callback (pm_func : pointer; const reg : trealregs; var rmcb: tseginfo) : boolean;
Description:

Returns a unique real mode segment:offset address, known as a ”real mode callback,” that will transfer control from real mode to a protected mode procedure. Parameters:

pm__func: 
pointer to the protected mode callback function.
reg: 
supplied registers structure.
rmcb: 
buffer to real mode address of callback function.

Return values: True if successful, otherwise False. Notes: Callback addresses obtained with this function can be passed by a protected mode program for example to an interrupt handler, device driver, or TSR, so that the real mode program can call procedures within the protected mode program or notify the protected mode program of an event. The contents of the supplied regs structure is not valid after function call, but only at the time of the actual callback.

Errors:
Check the int31error variable.
See also:
free__rm__callback (160)

Listing: go32ex/callback.pp


{$ASMMODE ATT}
{$MODE FPC}

uses
        crt,
        go32;

const
        mouseint = $33;

var
        mouse_regs    : trealregs; external name '___v2prt0_rmcb_regs';
        mouse_seginfo : tseginfo;

var
        mouse_numbuttons : longint;

        mouse_action : word;
        mouse_x, mouse_y : Word;
        mouse_b : Word;

        userproc_installed : Longbool;
        userproc_length : Longint;
        userproc_proc : pointer;

procedure callback_handler; assembler;
asm
   pushw %ds
   pushl %eax
   movw %es, %ax
   movw %ax, %ds

   cmpl $1, USERPROC_INSTALLED
   jne .LNoCallback
   pushal
   movw DOSmemSELECTOR, %ax
   movw %ax, %fs
   call *USERPROC_PROC
   popal
.LNoCallback:

   popl %eax
   popw %ds

   pushl %eax
   movl (%esi), %eax
   movl %eax, %es: 42(%edi)
   addw $4, %es:46(%edi)
   popl %eax
   iret
end;
procedure mouse_dummy; begin end;

procedure textuserproc;
begin
        mouse_b := mouse_regs.bx;
        mouse_x := (mouse_regs.cx shr 3) + 1;
        mouse_y := (mouse_regs.dx shr 3) + 1;
end;

procedure install_mouse(userproc : pointer; userproclen : longint);
var r : trealregs;
begin
        r.eax := $0; realintr(mouseint, r);
        if (r.eax <> $FFFF) then begin
                Writeln('No Microsoft compatible mouse found');
                Writeln('A Microsoft compatible mouse driver is necessary ',
                        'to run this example');
                halt;
        end;
        if (r.bx = $ffff) then mouse_numbuttons := 2
        else mouse_numbuttons := r.bx;
        Writeln(mouse_numbuttons, ' button Microsoft compatible mouse ',
                ' found.');
        if (userproc <> nil) then begin
                userproc_proc := userproc;
                userproc_installed := true;
                userproc_length := userproclen;
                lock_code(userproc_proc, userproc_length);
        end else begin
                userproc_proc := nil;
                userproc_length := 0;
                userproc_installed := false;
        end;
        lock_data(mouse_x, sizeof(mouse_x));
        lock_data(mouse_y, sizeof(mouse_y));
        lock_data(mouse_b, sizeof(mouse_b));
        lock_data(mouse_action, sizeof(mouse_action));

        lock_data(userproc_installed, sizeof(userproc_installed));
        lock_data(userproc_proc, sizeof(userproc_proc));

        lock_data(mouse_regs, sizeof(mouse_regs));
        lock_data(mouse_seginfo, sizeof(mouse_seginfo));
        lock_code(@callback_handler,
                longint(@mouse_dummy)-longint(@callback_handler));
        get_rm_callback(@callback_handler, mouse_regs, mouse_seginfo);
        r.eax := $0c; r.ecx := $7f;
        r.edx := longint(mouse_seginfo.offset);
        r.es := mouse_seginfo.segment;
        realintr(mouseint, r);
        r.eax := $01;
        realintr(mouseint, r);
end;

procedure remove_mouse;
var
        r : trealregs;
begin
        r.eax := $02; realintr(mouseint, r);
        r.eax := $0c; r.ecx := 0; r.edx := 0; r.es := 0;
        realintr(mouseint, r);
        free_rm_callback(mouse_seginfo);
        if (userproc_installed) then begin
                unlock_code(userproc_proc, userproc_length);
                userproc_proc := nil;
                userproc_length := 0;
                userproc_installed := false;
        end;
        unlock_data(mouse_x, sizeof(mouse_x));
        unlock_data(mouse_y, sizeof(mouse_y));
        unlock_data(mouse_b, sizeof(mouse_b));
        unlock_data(mouse_action, sizeof(mouse_action));

        unlock_data(userproc_proc, sizeof(userproc_proc));
        unlock_data(userproc_installed, sizeof(userproc_installed));

        unlock_data(mouse_regs, sizeof(mouse_regs));
        unlock_data(mouse_seginfo, sizeof(mouse_seginfo));
        unlock_code(@callback_handler,
                longint(@mouse_dummy)-longint(@callback_handler));
        fillchar(mouse_seginfo, sizeof(mouse_seginfo), 0);
end;


begin
        install_mouse(@textuserproc, 400);
        Writeln('Press any key to exit...');
        while (not keypressed) do begin
                gotoxy(1, wherey);
                write('MouseX : ', mouse_x:2, ' MouseY : ', mouse_y:2,
                        ' Buttons : ', mouse_b:2);
        end;
        remove_mouse;
end.

get__rm__interrupt

Declaration:
Function get_rm_interrupt (vector : byte; var intaddr : tseginfo) : boolean;
Description:
Returns the contents of the current machine’s real mode interrupt vector for the specified interrupt. Parameters:
vector: 
interrupt vector number.
intaddr: 
buffer to store real mode segment:offset address.

Return values: True if successful, False otherwise. Notes: The returned address is a real mode segment address, which isn’t valid in protected mode.

Errors:
Check the int31error variable.
See also:
set__rm__interrupt (181), set__pm__interrupt (179), get__pm__interrupt (163)

get__run__mode

Declaration:
Function get_run_mode : Word;
Description:
Returns the current mode your application runs with. Return values: One of the constants used by this function.
Errors:
None.
See also:
constants returned by get__run__mode (168)

Listing: go32ex/getrunmd.pp


uses
        go32;

begin
        case (get_run_mode) of
                rm_unknown :
                        Writeln('Unknown environment found');
                rm_raw     :
                        Writeln('You are currently running in raw mode ',
                                '(without HIMEM)');
                rm_xms     :
                        Writeln('You are currently using HIMEM.SYS only');
                rm_vcpi    :
                        Writeln('VCPI server detected. You''re using HIMEM and ',
                                'EMM386');
                rm_dpmi    :
                        Writeln('DPMI detected. You''re using a DPMI host like ',
                                'a windows DOS box or CWSDPMI');
        end;
end.

get__segment__base__address

Declaration:
Function get_segment_base_address (d : Word) : Longint;
Description:
Returns the 32-bit linear base address from the descriptor table for the specified segment. Parameters:
d: 
selector of the descriptor you want the base address of.

Return values: Linear base address of specified descriptor.

Errors:
Check the int31error variable.
See also:

allocate__ldt__descriptors (151), set__segment__base__address (181), allocate__ldt__descriptors (151), set__segment__limit (181), get__segment__limit (169)

For an example, see allocate__ldt__descriptors (151).

get__segment__limit

Declaration:
Function get_segment_limit (d : Word) : Longint;
Description:
Returns a descriptors segment limit. Parameters:
d: 
selector.

Return value: Limit of the descriptor in bytes.

Errors:
Returns zero if descriptor is invalid.
See also:
allocate__ldt__descriptors (151), set__segment__limit (181), set__segment__base__address (181), get__segment__base__address (168),

get__ss

Declaration:
Function get_ss : Word;
Description:

Returns the ss selector. Parameters: None. Return values: The content of the ss segment register.

Errors:
None.
See also:
get__ds (161), get__cs (160)

global__dos__alloc

Declaration:
Function global_dos_alloc (bytes : Longint) : Longint;
Description:
Allocates a block of DOS real mode memory. Parameters:
bytes: 
size of requested real mode memory.

Return values: The low word of the returned value contains the selector to the allocated DOS memory block, the high word the corresponding real mode segment value. The offset value is always zero. This function allocates memory from DOS memory pool, i.e. memory below the 1 MB boundary that is controlled by DOS. Such memory blocks are typically used to exchange data with real mode programs, TSRs, or device drivers. The function returns both the real mode segment base address of the block and one descriptor that can be used by protected mode applications to access the block. This function should only used for temporary buffers to get real mode information (e.g. interrupts that need a data structure in ES:(E)DI), because every single block needs an unique selector. The returned selector should only be freed by a global__dos__free (171) call.

Errors:
Check the int31error variable.
See also:
global__dos__free (171)

Listing: go32ex/buffer.pp


uses
        go32;

procedure dosalloc(var selector : word;
        var segment : word; size : longint);
var
        res : longint;
begin
        res := global_dos_alloc(size);
        selector := word(res);
        segment := word(res shr 16);
end;

procedure dosfree(selector : word);
begin
        global_dos_free(selector);
end;

type
        VBEInfoBuf = packed record
                Signature : array[0..3] of char;
                Version : Word;
                reserved : array[0..505] of byte;
        end;

var
        selector,
        segment : Word;

        r : trealregs;
        infobuf : VBEInfoBuf;

begin
        fillchar(r, sizeof(r), 0);
        fillchar(infobuf, sizeof(VBEInfoBuf), 0);
        dosalloc(selector, segment, sizeof(VBEInfoBuf));
        if (int31error<>0) then begin
                Writeln('Error while allocating real mode memory, halting');
                halt;
        end;
        infobuf.Signature := 'VBE2';
        dosmemput(segment, 0, infobuf, sizeof(infobuf));
        r.ax := $4f00; r.es := segment;
        realintr($10, r);
        dosmemget(segment, 0, infobuf, sizeof(infobuf));
        dosfree(selector);
        if (r.ax <> $4f) then begin
                Writeln('VBE BIOS extension not available, function call ',
                        'failed');
                halt;
        end;
        if (infobuf.signature[0] = 'V') and
                (infobuf.signature[1] = 'E') and
                (infobuf.signature[2] = 'S') and
                (infobuf.signature[3] = 'A') then begin
                Writeln('VBE version ', hi(infobuf.version), '.',
                        lo(infobuf.version), ' detected');
        end;
end.

global__dos__free

Declaration:
Function global_dos_free (selector :Word) : boolean;
Description:
Frees a previously allocated DOS memory block. Parameters:
selector: 
selector to the DOS memory block.

Return value: True if successful, False otherwise. Notes: The descriptor allocated for the memory block is automatically freed and hence invalid for further use. This function should only be used for memory allocated by global__dos__alloc (169).

Errors:
Check the int31error variable.
See also:
global__dos__alloc (169)

For an example, see global__dos__alloc (169).

inportb

Declaration:
Function inportb (port : Word) : byte;
Description:
Reads 1 byte from the selected I/O port. Parameters:
port: 
the I/O port number which is read.

Return values: Current I/O port value.

Errors:
None.
See also:
outportb (174), inportw (172), inportl (172)

inportl

Declaration:
Function inportl (port : Word) : Longint;
Description:

Reads 1 longint from the selected I/O port. Parameters:

port: 
the I/O port number which is read.

Return values: Current I/O port value.

Errors:
None.
See also:
outportb (174), inportb (172), inportw (172)

inportw

Declaration:
Function inportw (port : Word) : Word;
Description:

Reads 1 word from the selected I/O port. Parameters:

port: 
the I/O port number which is read.

Return values: Current I/O port value.

Errors:
None.
See also:
outportw (175) inportb (172), inportl (172)

lock__code

Declaration:
Function lock_code (functionaddr : pointer; size : Longint) : boolean;
Description:
Locks a memory range which is in the code segment selector. Parameters:
functionaddr: 
address of the function to be locked.
size: 
size in bytes to be locked.

Return values: True if successful, False otherwise.

Errors:
Check the int31error variable.
See also:

lock__linear__region (173), lock__data (173), unlock__linear__region (183), unlock__data (183), unlock__code (182)

For an example, see get__rm__callback (164).

lock__data

Declaration:
Function lock_data (var data; size : Longint) : boolean;
Description:
Locks a memory range which resides in the data segment selector. Parameters:
data: 
address of data to be locked.
size: 
length of data to be locked.

Return values: True if successful, False otherwise.

Errors:
Check the int31error variable.
See also:

lock__linear__region (173), lock__code (173), unlock__linear__region (183), unlock__data (183), unlock__code (182)

For an example, see get__rm__callback (164).

lock__linear__region

Declaration:
Function lock_linear_region (linearaddr, size : Longint) : boolean;
Description:
Locks a memory region to prevent swapping of it. Parameters:
linearaddr: 
the linear address of the memory are to be locked.
size: 
size in bytes to be locked.

Return value: True if successful, False otherwise.

Errors:
Check the int31error variable.
See also:

lock__data (173), lock__code (173), unlock__linear__region (183), unlock__data (183), unlock__code (182)

outportb

Declaration:
Procedure outportb (port : Word; data : byte);
Description:
Sends 1 byte of data to the specified I/O port. Parameters:
port: 
the I/O port number to send data to.
data: 
value sent to I/O port.

Return values: None.

Errors:
None.
See also:
inportb (172), outportl (175), outportw (175)

Listing: go32ex/outport.pp


uses
        crt,
        go32;

begin
        outportb($61, $ff);
        delay(50);
        outportb($61, $0);
end.

outportl

Declaration:
Procedure outportl (port : Word; data : Longint);
Description:
Sends 1 longint of data to the specified I/O port. Parameters:
port: 
the I/O port number to send data to.
data: 
value sent to I/O port.

Return values: None.

Errors:
None.
See also:
inportl (172), outportw (175), outportb (174)

For an example, see outportb (174).

outportw

Declaration:
Procedure outportw (port : Word; data : Word);
Description:
Sends 1 word of data to the specified I/O port. Parameters:
port: 
the I/O port number to send data to.
data: 
value sent to I/O port.

Return values: None.

Errors:
None.
See also:
inportw (172), outportl (175), outportb (174)

For an example, see outportb (174).

realintr

Declaration:
Function realintr (intnr: Word; var regs : trealregs) : boolean;
Description:
Simulates an interrupt in real mode. Parameters:
intnr: 
interrupt number to issue in real mode.
regs: 
registers data structure.

Return values: The supplied registers data structure contains the values that were returned by the real mode interrupt. True if successful, False if not. Notes: The function transfers control to the address specified by the real mode interrupt vector of intnr. The real mode handler must return by executing an IRET.

Errors:
Check the int31error variable.
See also:

Listing: go32ex/flags.pp


uses
        go32;

var
        r : trealregs;

begin
        r.ax := $5300;
        r.bx := 0;
        realintr($15, r);
        if ((r.flags and carryflag)=0) then begin
                Writeln('APM v', (r.ah and $f), '.',
                        (r.al shr 4), (r.al and $f), ' detected');
        end else
                Writeln('APM not present');
end.

seg__fillchar

Declaration:
Procedure seg_fillchar (seg : Word; ofs : Longint; count : Longint; c : char);
Description:

Sets a memory area to a specific value. Parameters:

seg: 
selector to memory area.
ofs: 
offset to memory.
count: 
number of bytes to set.
c: 
byte data which is set.

Return values: None. Notes: No range check is done in any way.

Errors:
None.
See also:
seg__move (178), seg__fillword (177), dosmemfillchar (155), dosmemfillword (156), dosmemget (157), dosmemput (158), dosmemmove (157)

Listing: go32ex/vgasel.pp


uses
        go32;

var
        vgasel : Word;
        r : trealregs;

begin
        r.eax := $13; realintr($10, r);
        vgasel := segment_to_descriptor($A000);
        seg_fillchar(vgasel, 0, 64000, #15);
        readln;
        r.eax := $3; realintr($10, r);
end.

seg__fillword

Declaration:
Procedure seg_fillword (seg : Word; ofs : Longint; count : Longint; w :Word);
Description:

Sets a memory area to a specific value. Parameters:

seg: 
selector to memory area.
ofs: 
offset to memory.
count: 
number of words to set.
w: 
word data which is set.

Return values: None. Notes: No range check is done in any way.

Errors:
None.
See also:

seg__move (178), seg__fillchar (176), dosmemfillchar (155), dosmemfillword (156), dosmemget (157), dosmemput (158), dosmemmove (157)

For an example, see allocate__ldt__descriptors (151).

segment__to__descriptor

Declaration:
Function segment_to_descriptor (seg : Word) : Word;
Description:

Maps a real mode segment (paragraph) address onto an descriptor that can be used by a protected mode program to access the same memory. Parameters:

seg: 
the real mode segment you want the descriptor to.

Return values: Descriptor to real mode segment address. Notes: The returned descriptors limit will be set to 64 kB. Multiple calls to this function with the same segment address will return the same selector. Descriptors created by this function can never be modified or freed. Programs which need to examine various real mode addresses using the same selector should use the function allocate__ldt__descriptors (151) and change the base address as necessary.

Errors:
Check the int31error variable.
See also:
allocate__ldt__descriptors (151), free__ldt__descriptor (159), set__segment__base__address (181)

For an example, see seg__fillchar (176).

seg__move

Declaration:
Procedure seg_move (sseg : Word; source : Longint; dseg : Word; dest : Longint; count : Longint);
Description:
Copies data between two memory locations. Parameters:
sseg: 
source selector.
source: 
source offset.
dseg: 
destination selector.
dest: 
destination offset.
count: 
size in bytes to copy.

Return values: None. Notes: Overlapping is only checked if the source selector is equal to the destination selector. No range check is done.

Errors:
None.
See also:

seg__fillchar (176), seg__fillword (177), dosmemfillchar (155), dosmemfillword (156), dosmemget (157), dosmemput (158), dosmemmove (157)

For an example, see allocate__ldt__descriptors (151).

set__descriptor__access__rights

Declaration:
Function set_descriptor_access_rights (d : Word; w : Word) : Longint;
Description:

Sets the access rights of a descriptor. Parameters:

d: 
selector.
w: 
new descriptor access rights.

Return values: This function doesn’t return anything useful.

Errors:
Check the int31error variable.
See also:

get__descriptor__access__rights (160)

set__pm__interrupt

Declaration:
Function set_pm_interrupt (vector : byte; const intaddr : tseginfo) : boolean;
Description:
Sets the address of the protected mode handler for an interrupt. Parameters:
vector: 
number of protected mode interrupt to set.
intaddr: 
selector:offset address to the interrupt vector.

Return values: True if successful, False otherwise. Notes: The address supplied must be a valid selector:offset protected mode address.

Errors:
Check the int31error variable.
See also:
get__pm__interrupt (163), set__rm__interrupt (181), get__rm__interrupt (167)

Listing: go32ex/intpm.pp


uses
        crt,
        go32;

const
        int1c = $1c;

var
        oldint1c : tseginfo;
        newint1c : tseginfo;

        int1c_counter : Longint;

        int1c_ds : Word; external name '___v2prt0_ds_alias';

procedure int1c_handler; assembler;
asm
   cli
   pushw %ds
   pushw %ax
   movw %cs:int1c_ds, %ax
   movw %ax, %ds
   incl int1c_counter
   popw %ax
   popw %ds
   sti
   iret
end;

var i : Longint;

begin
     newint1c.offset := @int1c_handler;
     newint1c.segment := get_cs;
     get_pm_interrupt(int1c, oldint1c);
     Writeln('-- Press any key to exit --');
     set_pm_interrupt(int1c, newint1c);
     while (not keypressed) do begin
           gotoxy(1, wherey);
           write('Number of interrupts occured : ', int1c_counter);
     end;
     set_pm_interrupt(int1c, oldint1c);
end.

set__rm__interrupt

Declaration:
Function set_rm_interrupt (vector : byte; const intaddr : tseginfo) : boolean;
Description:
Sets a real mode interrupt handler. Parameters:
vector: 
the interrupt vector number to set.
intaddr: 
address of new interrupt vector.

Return values: True if successful, otherwise False. Notes: The address supplied MUST be a real mode segment address, not a selector:offset address. So the interrupt handler must either reside in DOS memory (below 1 Mb boundary) or the application must allocate a real mode callback address with get__rm__callback (164).

Errors:
Check the int31error variable.
See also:

get__rm__interrupt (167), set__pm__interrupt (179), get__pm__interrupt (163), get__rm__callback (164)

set__segment__base__address

Declaration:
Function set_segment_base_address (d : Word; s : Longint) : boolean;
Description:
Sets the 32-bit linear base address of a descriptor. Parameters:
d: 
selector.
s: 
new base address of the descriptor.
Errors:
Check the int31error variable.
See also:

allocate__ldt__descriptors (151), get__segment__base__address (168), allocate__ldt__descriptors (151), set__segment__limit (181), get__segment__base__address (168), get__segment__limit (169)

set__segment__limit

Declaration:
Function set_segment_limit (d : Word; s : Longint) : boolean;
Description:
Sets the limit of a descriptor. Parameters:
d: 
selector.
s: 
new limit of the descriptor.

Return values: Returns True if successful, else False. Notes: The new limit specified must be the byte length of the segment - 1. Segment limits bigger than or equal to 1MB must be page aligned, they must have the lower 12 bits set.

Errors:
Check the int31error variable.
See also:
allocate__ldt__descriptors (151), set__segment__base__address (181), get__segment__limit (169), set__segment__limit (181)

For an example, see allocate__ldt__descriptors (151).

tb__size

Declaration:
Function tb_size : Longint;
Description:
Returns the size of the pre-allocated DOS memory buffer. Parameters: None. Return values: The size of the pre-allocated DOS memory buffer. Notes: This block always seems to be 16k in size, but don’t rely on this.
Errors:
None.
See also:
transfer__buffer (182), copyfromdos (154) copytodos (154)

transfer__buffer

Declaration:
Function transfer_buffer : Longint;
Description:
transfer_buffer returns the offset of the transfer buffer.
Errors:
None.
See also:
tb__size (182)

unlock__code

Declaration:
Function unlock_code (functionaddr : pointer; size : Longint) : boolean;
Description:
Unlocks a memory range which resides in the code segment selector. Parameters:
functionaddr: 
address of function to be unlocked.
size: 
size bytes to be unlocked.

Return value: True if successful, False otherwise.

Errors:
Check the int31error variable.
See also:
unlock__linear__region (183), unlock__data (183), lock__linear__region (173), lock__data (173), lock__code (173)

For an example, see get__rm__callback (164).

unlock__data

Declaration:
Function unlock_data (var data; size : Longint) : boolean;
Description:
Unlocks a memory range which resides in the data segment selector. Paramters:
data: 
address of memory to be unlocked.
size: 
size bytes to be unlocked.

Return values: True if successful, False otherwise.

Errors:
Check the int31error variable.
See also:
unlock__linear__region (183), unlock__code (182), lock__linear__region (173), lock__data (173), lock__code (173)

For an example, see get__rm__callback (164).

unlock__linear__region

Declaration:
Function unlock_linear_region (linearaddr, size : Longint) : boolean;
Description:
Unlocks a previously locked linear region range to allow it to be swapped out again if needed. Parameters:
linearaddr: 
linear address of the memory to be unlocked.
size: 
size bytes to be unlocked.

Return values: True if successful, False otherwise.

Errors:
Check the int31error variable.
See also:

unlock__data (183), unlock__code (182), lock__linear__region (173), lock__data (173), lock__code (173)