See changelog 20000420 22:00 GMT -3

This commit is contained in:
Luiz Rafael Culik
2000-04-21 00:45:04 +00:00
parent 75eb1fcb3e
commit 2bc035797c
17 changed files with 1682 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
;
; $Id$
;
; File......: ALIAS.ASM
; Author....: Ted Means
; CIS ID....: 73067,3332
;
; This is an original work by Ted Means and is placed in the
; public domain.
;
; Modification history:
; ---------------------
; Rev 1.0 01 Jan 1995 03:01:00 TED
; Initial release
;
; $DOC$
; $FUNCNAME$
; cpmiMakeAlias()
; $CATEGORY$
; CPMI
; $ONELINER$
; Create alias descriptor
; $SYNTAX$
; SELECTOR pascal cpmiMakeAlias( SELECTOR Selector, unsigned int Rights )
; $ARGUMENTS$
; Selector is a selector for which an alias should be created.
;
; Rights is an integer describing the access rights for the selector,
; and should be either AR_READ, AR_WRITE, or AR_EXECUTE. You may
; also combine these attributes with the | operator, although
; you may not mix AR_WRITE and AR_EXECUTE. Note that AR_WRITE and
; AR_EXECUTE both implicitly allow AR_READ rights.
; $RETURNS$
; A selector which maps to the same physical memory as the source
; selector.
; $DESCRIPTION$
; This function duplicates a selector while giving different access
; rights. This is useful for writing to a code segment, making a
; data segment read-only, etc.
;
; When no longer needed, the selector should be freed via a call to
; cpmiFreeSelector().
; $EXAMPLES$
; OldSelector = FP_SEG( SomePointer );
;
; // Create a read / write data selector
;
; NewSelector = cpmiMakeAlias( OldSelector, AR_READ | AR_WRITE )
;
; // You can also make it read-only
;
; NewSelector = cpmiMakeAlias( OldSelector, AR_READ )
;
; cpmiWillGPF( NewSelector, AR_WRITE, 1 ) // Returns INVALID_ACCESS
; $INCLUDE$
; CPMI.H
; $SEEALSO$
; cpmiFreeSelector()
; $END$
;
IDEAL
P286
Public _hb_cpmiMakeAlias
Segment _NanFor Word Public "CODE"
Assume CS:_NanFor
Proc _hb_cpmiMakeAlias Far
Enter 10,0 ; Create stack frame
Push DI ; Save DI
Mov AX,0Ah ; DPMI -- create alias
Mov BX,[Word Ptr BP + 8] ; Load selector
Int 31h ; Call DPMI
JC @@Null ; Bail if error
Mov [Word Ptr BP - 2],AX ; Store selector
Mov BX,AX ; Load selector into BX
Push SS ; Move SS . . .
Pop ES ; . . . to ES
LEA DI,[BP - 10] ; Load offset of buffer
Mov AX,0Bh ; DPMI -- get descriptor
Int 31h ; Call DPMI
JC @@Free ; Bail if error
Mov AX,[Word Ptr BP + 6] ; Load access rights
Mov CL,[Byte BP - 5] ; Load existing rights
Test AX,4 ; Check for code bit
JZ @@Data ; If not set, must be data
Or CL,00001010b ; Set bits for code
And CL,11111010b ; Turn off A & E/C bits
Jmp Short @@Reset ; Set new rights
@@Data: And CL,11110000b ; Set bits for data
And AL,2 ; Isolate write bit
Or CL,AL ; Set / Clear write bit
@@Reset: Mov [Byte Ptr BP - 5],CL ; Store new rights
Push SS ; Move SS . . .
Pop ES ; . . . to ES
LEA DI,[BP - 10] ; Load offset of buffer
Mov AX,0Ch ; DPMI -- set descriptor
Int 31h ; Call DPMI
Mov AX,[Word Ptr BP - 2] ; Load return selector
JNC @@Exit ; If no error, quit
@@Free: Mov AX,1 ; DPMI -- Free selector
Mov BX,[Word Ptr BP - 2] ; Get selector
Int 31h ; Call DPMI
@@Null: Xor AX,AX ; Return NULL selector
@@Exit: Pop DI ; Restore DI
Leave ; Destroy stack frame
RetF 4
Endp _hb_cpmiMakeAlias
Ends _NanFor
End

View File

@@ -0,0 +1,85 @@
;
; $Id$
;
; File......: ALLOCDOS.ASM
; Author....: Ted Means
; CIS ID....: 73067,3332
;
; This is an original work by Ted Means and is placed in the
; public domain.
;
; Modification history:
; ---------------------
; Rev 1.0 01 Jan 1995 03:01:00 TED
; Initial release
;
; $DOC$
; $FUNCNAME$
; cpmiAllocDOSMem()
; $CATEGORY$
; CPMI
; $ONELINER$
; Allocate a DOS memory block from the lower 640K
; $SYNTAX$
; SELECTOR pascal cpmiAllocDOSMem( unsigned int Size )
; $ARGUMENTS$
; Size is the number of bytes to allocate.
; $RETURNS$
; A selector which is guaranteed to map to physical memory in the
; lower 640K.
; $DESCRIPTION$
; This function is useful for allocating memory that needs to exist in
; the DOS memory pool; e.g. buffers used by real-mode interrupts.
;
; Note that only the selector is returned; the offset is always zero.
;
; You can obtain the real mode segment:offset of the selector by calling
; cpmiRealPtr().
;
; When the memory is no longer needed, be sure to call cpmiFreeDOSMem()
; to release it.
; $EXAMPLES$
; char far * buffer;
;
; FP_SEG( buffer ) = cpmiAllocateDOSMem( 48 );
; FP_OFF( buffer ) = 0;
;
; // Do whatever
;
; cpmiFreeDOSMem( FP_SEG( buffer ) );
; $INCLUDE$
; CPMI.H
; $SEEALSO$
; cpmiFreeDOSMem(), cpmiResizeDOSMem(), cpmiRealPtr()
; $END$
;
IDEAL
P286
Public _hb_cpmiAllocateDOSMem
Segment _NanFor Word Public "CODE"
Assume CS:_NanFor
Proc _hb_cpmiAllocateDOSMem Far
Enter 0,0 ; Create stack frame
Mov AX,100h ; DPMI -- alloc DOS memory
Mov BX,[Word Ptr BP + 6] ; Get size in bytes
Add BX,15 ; Round up if necessary
SHR BX,4 ; Convert to paragraphs
Int 31h ; Call DPMI
Mov AX,DX ; Move selector to AX
JNC @@Exit ; If no error, return
@@Null: Xor AX,AX ; Return null selector
@@Exit: Leave ; Destroy stack frame
RetF 2
Endp _hb_cpmiAllocateDOSMem
Ends _NanFor
End

View File

@@ -0,0 +1,72 @@
;
; $Id$
;
; File......: ALLOCSEL.ASM
; Author....: Ted Means
; CIS ID....: 73067,3332
;
; This is an original work by Ted Means and is placed in the
; public domain.
;
; Modification history:
; ---------------------
; Rev 1.0 01 Jan 1995 03:01:00 TED
; Initial release
;
; $DOC$
; $FUNCNAME$
; cpmiAllocateSelector()
; $CATEGORY$
; CPMI
; $ONELINER$
; Allocate a selector
; $SYNTAX$
; SELECTOR pascal cpmiAllocateSelector( void )
; $ARGUMENTS$
; None
; $RETURNS$
; A selector with a base and limit of zero. A null selector is returned
; if the function fails.
; $DESCRIPTION$
; This function is used to create a new selector. It must be
; initialized with other CPMI calls before it will be useful. Be
; sure to free it with cpmiFreeSelector() when it is no longer needed.
; $EXAMPLES$
; auto SELECTOR sel = cpmiAllocateSelector();
;
; cpmiSetBase( sel, 0xB8000 );
;
; cpmiSetLimit( sel, 0x8000 );
; // Do whatever
;
; cpmiFreeSelector( sel );
; $INCLUDE$
; CPMI.H
; $SEEALSO$
; cpmiFreeSelector(), cpmiSetLimit(), cpmiSetBase()
; $END$
;
IDEAL
P286
Public _hb_cpmiAllocateSelector
Segment _NanFor Word Public "CODE"
Assume CS:_NanFor
Proc _hb_cpmiAllocateSelector Far
Xor AX,AX ; DPMI -- alloc selector
Mov CX,1 ; Set selector count
Int 31h ; Call DPMI
JNC @@Exit ; Leave if no error
Xor AX,AX ; Return null selector
@@Exit: RetF
Endp _hb_cpmiAllocateSelector
Ends _NanFor
End

View File

@@ -0,0 +1,182 @@
;
; $Id$
;
; File......: FARCALL.ASM
; Author....: Ted Means
; CIS ID....: 73067,3332
;
; This is an original work by Ted Means and is placed in the
; public domain.
;
; Modification history:
; ---------------------
; Rev 1.0 01 Jan 1995 03:01:00 TED
; Initial release
;
; $DOC$
; $FUNCNAME$
; cpmiFarCallReal()
; $CATEGORY$
; CPMI
; $ONELINER$
; Call a real mode function via pointer.
; $SYNTAX$
; int pascal cpmiFarCallReal( void * FuncAddr, CPUREGS * InRegs,
; CPUREGS * OutRegs )
; $ARGUMENTS$
; FuncAddr is the real mode address of the function to call.
;
; InRegs is a pointer to a CPUREGS structure containing the incoming
; register assignments.
;
; OutRegs is a pointer to a CPUREGS structure where the outgoing
; register contents will be stored.
; $RETURNS$
; SUCCEED if successful, FAIL otherwise
; $DESCRIPTION$
; Use cpmiFarCallReal() to execute a real mode function. This function
; allows you to set real mode segment register values from protected
; mode. A call to cpmiFarCallReal() sets the registers to the values
; you provide in the structure to which InRegs points; then it invokes
; the function at the address specified by FuncAddr. After the call
; has been completed, the register values will be stored in the structure
; pointed to by OutRegs. The structures pointed to by InRegs and OutRegs
; are both of type CPUREGS.
;
; $EXAMPLES$
; auto CPUREGS Regs;
;
; cpmiFarCallReal( ( void * ) 0xF000FFF0, &Regs, &Regs ) // Reboot
; $INCLUDE$
; CPMI.H
; $SEEALSO$
; cpmiAllocDOSMem(), cpmiFreeDOSMem(), cpmiRealPtr(), cpmiInt86()
; $END$
;
IDEAL
P286
Struc CPUREGS
DI DW ?
DIHi DW ?
SI DW ?
SIHi DW ?
BP DW ?
BPHi DW ?
Rsv DW ?
RsvHi DW ?
BX DW ?
BXHi DW ?
DX DW ?
DXHi DW ?
CX DW ?
CXHi DW ?
AX DW ?
AXHi DW ?
Flags DW ?
ES DW ?
DS DW ?
FS DW ?
GS DW ?
IP DW ?
CS DW ?
SP DW ?
SS DW ?
Ends CPUREGS
Public _hb_cpmiFarCallReal
Extrn __bset:Far
Regs EQU (CPUREGS Ptr BP - Size CPUREGS)
Segment _NanFor Word Public "CODE"
Proc _hb_cpmiFarCallReal Far
Enter Size CPUREGS,0 ; Create stack frame
Push DS ; Save DS
Push SI ; Save SI
Push DI ; Save DI
Push BP ; Save BP
LEA AX,[BP - Size CPUREGS] ; Calc offset
Push Size CPUREGS ; Set byte count
Push 0 ; Set fill character
Push SS ; Put segment on stack
Push AX ; Put offset on stack
Call __bset ; Init structure
Add SP,8 ; Realign stack
LES BX,[DWord Ptr BP + 10] ; Load pointer to in regs
Push [Word Ptr ES:BX] ; Put AX value on stack
Push [Word Ptr ES:BX + 2] ; Put BX value on stack
Push [Word Ptr ES:BX + 4] ; Put CX value on stack
Push [Word Ptr ES:BX + 6] ; Put DX value on stack
Push [Word Ptr ES:BX + 8] ; Put SI value on stack
Push [Word Ptr ES:BX + 10] ; Put DI value on stack
Push [Word Ptr ES:BX + 12] ; Put BP value on stack
Push [Word Ptr ES:BX + 14] ; Put DS value on stack
Push [Word Ptr ES:BX + 16] ; Put ES value on stack
Push [Word Ptr ES:BX + 18] ; Put flags value on stack
Pop [Regs.Flags]
Pop [Regs.ES]
Pop [Regs.DS]
Pop [Regs.BP]
Pop [Regs.DI]
Pop [Regs.SI]
Pop [Regs.DX]
Pop [Regs.CX]
Pop [Regs.BX]
Pop [Regs.AX]
Mov AX,[Word Ptr BP + 14]
Mov [Regs.IP],AX
Mov AX,[Word Ptr BP + 16]
Mov [Regs.CS],AX
Mov AX,301h ; DPMI -- real mode call
Xor BX,BX ; Clear BX
Mov CX,BX ; Clear CX
Push SS ; Move SS . . .
Pop ES ; . . . to ES
LEA DI,[BP - Size CPUREGS] ; Load register offset
Int 31h ; Call DPMI
Mov AX,1 ; Default to SUCCEED
SBB AX,0 ; Set to FAIL on error
CLD ; Restore preserved
Pop BP ; registers just in case
Pop DI ; DPMI host is ill-behaved
Pop SI
Pop DS
LES BX,[DWord Ptr BP + 6] ; Load pointer to outregs
Push [Regs.ES] ; Put register values on
Push [Regs.DS] ; stack
Push [Regs.BP]
Push [Regs.DI]
Push [Regs.SI]
Push [Regs.DX]
Push [Regs.CX]
Push [Regs.BX]
Push [Regs.AX]
Pop [Word Ptr ES:BX] ; Get AX value
Pop [Word Ptr ES:BX + 2] ; Get BX value
Pop [Word Ptr ES:BX + 4] ; Get CX value
Pop [Word Ptr ES:BX + 6] ; Get DX value
Pop [Word Ptr ES:BX + 8] ; Get SI value
Pop [Word Ptr ES:BX + 10] ; Get DI value
Pop [Word Ptr ES:BX + 12] ; Get BP value
Pop [Word Ptr ES:BX + 14] ; Get DS value
Pop [Word Ptr ES:BX + 16] ; Get ES value
Pop [Word Ptr ES:BX + 18] ; Get flags value
Leave
RetF 10
Endp _hb_cpmiFarCallReal
Ends _NanFor
End

View File

@@ -0,0 +1,72 @@
;
; $Id$
;
; File......: FREEDOS.ASM
; Author....: Ted Means
; CIS ID....: 73067,3332
;
; This is an original work by Ted Means and is placed in the
; public domain.
;
; Modification history:
; ---------------------
; Rev 1.0 01 Jan 1995 03:01:00 TED
; Initial release
;
; $DOC$
; $FUNCNAME$
; cpmiFreeDOSMem()
; $CATEGORY$
; CPMI
; $ONELINER$
; Free a DOS memory block
; $SYNTAX$
; void pascal cpmiFreeDOSMem( SELECTOR Selector )
; $ARGUMENTS$
; Selector is the previously allocated selector
; $RETURNS$
; SUCCEED if successful, FAIL otherwise
; $DESCRIPTION$
; This function is used to free memory blocks that were allocated
; with the cpmiAllocDOSMem() function.
; $EXAMPLES$
; char far * buffer;
;
; FP_SEG( buffer ) = cpmiAllocDOSMem( 48 );
; FP_OFF( buffer ) = 0;
;
; // Do whatever
;
; cpmiFreeDOSMem( FP_SEG( buffer ) );
; $INCLUDE$
; CPMI.H
; $SEEALSO$
; cpmiAllocDOSMem(), cpmiResizeDOSMem()
; $END$
;
IDEAL
P286
Public _hb_cpmiFreeDOSMem
Segment _NanFor Word Public "CODE"
Assume CS:_NanFor
Proc _hb_cpmiFreeDOSMem Far
Enter 0,0 ; Create stack frame
Mov AX,101h ; DPMI -- free DOS memory
Mov DX,[Word Ptr BP + 6] ; Load selector
Int 31h ; Call DPMI
Mov AX,1 ; Default to SUCCEED
SBB AX,0 ; Set to FAIL on error
Leave ; Destroy stack frame
RetF 2
Endp _hb_cpmiFreeDOSMem
Ends _NanFor
End

View File

@@ -0,0 +1,76 @@
;
; $Id$
;
; File......: FREESEL.ASM
; Author....: Ted Means
; CIS ID....: 73067,3332
;
; This is an original work by Ted Means and is placed in the
; public domain.
;
; Modification history:
; ---------------------
; Rev 1.0 01 Jan 1995 03:01:00 TED
; Initial release
;
; $DOC$
; $FUNCNAME$
; cpmiFreeSelector()
; $CATEGORY$
; CPMI
; $ONELINER$
; Free a selector
; $SYNTAX$
; int pascal cpmiFreeSelector( SELECTOR Selector )
; $ARGUMENTS$
; Selector is the previously allocated selector.
; $RETURNS$
; SUCCEED if successful, FAIL otherwise.
; $DESCRIPTION$
; This function is used to free selectors that were allocated
; with cpmiProtectedPtr(), cpmiMakeAlias(), or cpmiAllocSel().
; $EXAMPLES$
; FP_SEG( buffer ) = cpmiMakeAlias( selector, AR_WRITE );
; FP_OFF( buffer ) = 0;
;
; // Do whatever
;
; cpmiFreeSelector( FP_SEG( buffer ) );
; $INCLUDE$
; CPMI.H
; $SEEALSO$
; cpmiAllocSel(), cpmiProtectedPtr(), cpmiMakeAlias()
; $END$
;
IDEAL
P286
Public _hb_cpmiFreeSelector
Segment _NanFor Word Public "CODE"
Assume CS:_NanFor
Proc _hb_cpmiFreeSelector Far
Enter 0,0 ; Create stack frame
Mov BX,[Word Ptr BP + 6] ; Load selector
Mov AX,ES ; Load ES into AX
Cmp AX,BX ; ES contain selector?
JNE @@Free ; If not, continue
Xor AX,AX ; Clear AX
Mov ES,AX ; Set ES to null selector
@@Free: Mov AX,1 ; DPMI -- Free selector
Int 31h ; Call DPMI
Mov AX,1 ; Default to SUCCEED
SBB AX,0 ; Set to FAIL if carry set
@@Exit: Leave ; Destroy stack frame
RetF 2
Endp _hb_cpmiFreeSelector
Ends _NanFor
End

View File

@@ -0,0 +1,75 @@
;
; $Id$
;
; File......: GETBASE.ASM
; Author....: Ted Means
; CIS ID....: 73067,3332
;
; This is an original work by Ted Means and is placed in the
; public domain.
;
; Modification history:
; ---------------------
; Rev 1.0 01 Jan 1995 03:01:00 TED
; Initial release
;
; $DOC$
; $FUNCNAME$
; cpmiGetBase()
; $CATEGORY$
; CPMI
; $ONELINER$
; Obtain the linear base address associated with a selector.
; $SYNTAX$
; LINEAR pascal cpmiGetBase( SELECTOR selector )
; $ARGUMENTS$
; selector is the selector for which the base address is needed.
; $RETURNS$
; The linear base address of the selector. A null address is returned
; if the function fails.
; $DESCRIPTION$
; This function is useful for determining the actual physical memory
; associated with a selector. Note that it is a linear address and
; not a real mode segment:offset.
; $EXAMPLES$
; auto char * Video;
;
; FP_SEG( Video ) = cpmiSeg2Sel( 0xB800 );
; FP_OFF( Video ) = 0;
;
; cpmiGetBase( FP_SEG( Video ) ); // Will return 0xB8000
; $INCLUDE$
; CPMI.H
; $SEEALSO$
; cpmiSetBase(), cpmiGetLimit(), cpmiSetLimit()
; $END$
;
IDEAL
P286
Public _hb_cpmiGetBase
Segment _NanFor Word Public "CODE"
Assume CS:_NanFor
Proc _hb_cpmiGetBase Far
Enter 0,0 ; Create stack frame
Mov AX,6 ; DPMI -- get base
Mov BX,[Word Ptr BP + 6] ; Get selector
Int 31h ; Call DPMI
Mov AX,DX ; Load low word
Mov DX,CX ; Load high word
JNC @@Exit ; Leave if no error
Xor AX,AX ; Return null
Mov DX,AX
@@Exit: Leave ; Destroy stack frame
RetF 2
Endp _hb_cpmiGetBase
Ends _NanFor
End

View File

@@ -0,0 +1,72 @@
;
; $Id$
;
; File......: GETLIMIT.ASM
; Author....: Ted Means
; CIS ID....: 73067,3332
;
; This is an original work by Ted Means and is placed in the
; public domain.
;
; Modification history:
; ---------------------
; Rev 1.0 01 Jan 1995 03:01:00 TED
; Initial release
;
; $DOC$
; $FUNCNAME$
; cpmiGetLimit()
; $CATEGORY$
; CPMI
; $ONELINER$
; Obtain the limit associated with a selector.
; $SYNTAX$
; int pascal cpmiGetLimit( SELECTOR selector )
; $ARGUMENTS$
; selector is the selector for which the limit is needed.
; $RETURNS$
; The limit (i.e. largest possible offset) of the selector.
; If the function fails (e.g. because of an invalid selector) it
; will return a limit of zero.
; $DESCRIPTION$
; This function is useful for determining the amount of data
; a selector can access. Note that attempting to access an offset
; beyond a selector's limit will cause a GPF.
; $EXAMPLES$
; auto char * Video;
;
; FP_SEG( Video ) = cpmiSeg2Sel( 0xB800 );
; FP_OFF( Video ) = 0;
;
; cpmiGetLimit( FP_SEG( Video ) ); // Will return 0xFFFF
; $INCLUDE$
; CPMI.H
; $SEEALSO$
; cpmiSetLimit(), cpmiGetBase(), cpmiSetBase()
; $END$
;
IDEAL
P286
Public _hb_cpmiGetLimit
Segment _NanFor Word Public "CODE"
Assume CS:_NanFor
Proc _hb_cpmiGetLimit Far
Enter 0,0 ; Create stack frame
Mov AX,[Word Ptr BP + 6] ; Get selector
LSL AX,AX ; Load limit
JZ @@Exit ; Leave if selector valid
Xor AX,AX ; Return zero limit
@@Exit: Leave ; Destroy stack frame
RetF 2
Endp _hb_cpmiGetLimit
Ends _NanFor
End

View File

@@ -0,0 +1,180 @@
;
; $Id$
;
; File......: INT86.ASM
; Author....: Ted Means
; CIS ID....: 73067,3332
;
; This is an original work by Ted Means and is placed in the
; public domain.
;
; Modification history:
; ---------------------
; Rev 1.0 01 Jan 1995 03:01:00 TED
; Initial release
;
; $DOC$
; $FUNCNAME$
; cpmiInt86()
; $CATEGORY$
; CPMI
; $ONELINER$
; Execute a real-mode interrupt
; $SYNTAX$
; int pascal cpmiInt86( unsigned char IntNo, CPUREGS * InRegs,
; CPUREGS * OutRegs )
; $ARGUMENTS$
; IntNo is the interrupt to execute
;
; InRegs is a pointer to a CPUREGS structure containing the incoming
; register assignments.
;
; OutRegs is a pointer to a CPUREGS structure where the outgoing
; register contents will be stored.
; $RETURNS$
; SUCCEED if successful, FAIL otherwise
; $DESCRIPTION$
; Use cpmiInt86() to execute a real mode interrupt. This function
; allows you to set real mode segment register values from protected
; mode. A call to cpmiInt86() sets the registers to the values you
; provide in the structure to which InRegs points; then it invokes
; interrupt IntNo. After the interrupt is processed, the register
; values will be stored in the structure pointed to by OutRegs. The
; structures pointed to by InRegs and OutRegs are both of type CPUREGS.
;
; $EXAMPLES$
; auto CPUREGS Regs;
;
; Regs.Reg.AX = 0x19 << 8; // Get default drive
;
; cpmiInt86( 0x21, &Regs, &Regs ) // Call DOS
; $INCLUDE$
; CPMI.H
; $SEEALSO$
; cpmiAllocDOSMem(), cpmiFreeDOSMem(), cpmiRealPtr(), cpmiFarCallReal()
; $END$
;
IDEAL
P286
Struc CPUREGS
DI DW ?
DIHi DW ?
SI DW ?
SIHi DW ?
BP DW ?
BPHi DW ?
Rsv DW ?
RsvHi DW ?
BX DW ?
BXHi DW ?
DX DW ?
DXHi DW ?
CX DW ?
CXHi DW ?
AX DW ?
AXHi DW ?
Flags DW ?
ES DW ?
DS DW ?
FS DW ?
GS DW ?
IP DW ?
CS DW ?
SP DW ?
SS DW ?
Ends CPUREGS
Public hb_cpmiInt86
Extrn __bset:Far
Regs EQU (CPUREGS Ptr BP - Size CPUREGS)
Segment _NanFor Word Public "CODE"
Proc hb_cpmiInt86 Far
Enter Size CPUREGS,0 ; Create stack frame
Push DS ; Save DS
Push SI ; Save SI
Push DI ; Save DI
Push BP ; Save BP
LEA AX,[BP - Size CPUREGS] ; Calc offset
Push Size CPUREGS ; Set byte count
Push 0 ; Set fill character
Push SS ; Put segment on stack
Push AX ; Put offset on stack
Call __bset ; Init structure
Add SP,8 ; Realign stack
LES BX,[DWord Ptr BP + 10] ; Load pointer to in regs
Push [Word Ptr ES:BX] ; Put AX value on stack
Push [Word Ptr ES:BX + 2] ; Put BX value on stack
Push [Word Ptr ES:BX + 4] ; Put CX value on stack
Push [Word Ptr ES:BX + 6] ; Put DX value on stack
Push [Word Ptr ES:BX + 8] ; Put SI value on stack
Push [Word Ptr ES:BX + 10] ; Put DI value on stack
Push [Word Ptr ES:BX + 12] ; Put BP value on stack
Push [Word Ptr ES:BX + 14] ; Put DS value on stack
Push [Word Ptr ES:BX + 16] ; Put ES value on stack
Push [Word Ptr ES:BX + 18] ; Put flags value on stack
Pop [Regs.Flags]
Pop [Regs.ES]
Pop [Regs.DS]
Pop [Regs.BP]
Pop [Regs.DI]
Pop [Regs.SI]
Pop [Regs.DX]
Pop [Regs.CX]
Pop [Regs.BX]
Pop [Regs.AX]
Mov AX,300h ; DPMI -- real mode int
Mov BL,[Byte Ptr BP + 14] ; Get interrupt number
Mov BH,0 ; Clear BH
Xor CX,CX ; Clear CX
Push SS ; Move SS . . .
Pop ES ; . . . to ES
LEA DI,[BP - Size CPUREGS] ; Load register offset
Int 31h ; Call DPMI
Mov AX,1 ; Default to SUCCEED
SBB AX,0 ; Set to FAIL on error
CLD ; Restore preserved
Pop BP ; registers just in case
Pop DI ; DPMI host is ill-behaved
Pop SI
Pop DS
LES BX,[DWord Ptr BP + 6] ; Load pointer to outregs
Push [Regs.Flags] ; Put register values on
Push [Regs.ES] ; stack
Push [Regs.DS]
Push [Regs.BP]
Push [Regs.DI]
Push [Regs.SI]
Push [Regs.DX]
Push [Regs.CX]
Push [Regs.BX]
Push [Regs.AX]
Pop [Word Ptr ES:BX] ; Get AX value
Pop [Word Ptr ES:BX + 2] ; Get BX value
Pop [Word Ptr ES:BX + 4] ; Get CX value
Pop [Word Ptr ES:BX + 6] ; Get DX value
Pop [Word Ptr ES:BX + 8] ; Get SI value
Pop [Word Ptr ES:BX + 10] ; Get DI value
Pop [Word Ptr ES:BX + 12] ; Get BP value
Pop [Word Ptr ES:BX + 14] ; Get DS value
Pop [Word Ptr ES:BX + 16] ; Get ES value
Pop [Word Ptr ES:BX + 18] ; Get flags value
Leave
RetF 10
Endp hb_cpmiInt86
Ends _NanFor
End

View File

@@ -0,0 +1,107 @@
;
; $Id$
;
; File......: ISPROT.ASM
; Author....: Ted Means
; CIS ID....: 73067,3332
;
; This is an original work by Ted Means and is placed in the
; public domain.
;
; Modification history:
; ---------------------
; Rev 1.1 01 Feb 1995 03:02:00 TED
; Fixed bug in which function would report incorrect mode when run under
; OS/2 Warp.
;
; Rev 1.0 01 Jan 1995 03:01:00 TED
; Initial release
;
; $DOC$
; $FUNCNAME$
; cpmiIsProtected()
; $CATEGORY$
; CPMI
; $ONELINER$
; Determine if the CPU is in protected mode
; $SYNTAX$
; int pascal cpmiIsProtected( void )
; $ARGUMENTS$
; None
; $RETURNS$
; Zero if the CPU is in real mode, or a non-zero value if it is running
; in protected mode.
; $DESCRIPTION$
; This functions is useful for writing bi-modal code since you can take
; different actions depending on the CPU mode.
; $EXAMPLES$
; if ( cpmiIsProtected() )
; {
; // Do protected mode stuff
; }
; else
; {
; // Do real mode stuff
; }
; $INCLUDE$
; CPMI.H
; $SEEALSO$
; $END$
;
IDEAL
P286
Public _hb_cpmiIsProtected
Group DGROUP _DATA
Segment _DATA Word Public "DATA"
ModeFlag DW -1
Ends _DATA
Segment _NanFor Word Public "CODE"
Assume CS:_NanFor,DS:DGROUP
Proc _hb_cpmiIsProtected Far
Mov AX,[ModeFlag] ; Get mode indicator
Cmp AX,-1 ; See if checked already
JNE @@Exit
@@Init: Inc AX ; Default to FALSE
Push SP ; Put SP on stack
Pop DX ; Now get it back
Cmp DX,SP ; If not ==, 8088/8086
JNE @@Done ; Return FALSE
SMSW AX ; Get status word
And AX,1 ; Check for pmode bit
JZ @@Done ; Return FALSE if clear
PushF ; Mov flag word . . .
Pop DX ; . . . to DX
And DH,11001111b ; Set IOPL to zero
Push DX ; Move DX . . .
PopF ; . . . back to flag word
PushF ; Now move flags . . .
Pop DX ; . . . back to DX
Test DH,110000b ; Is IOPL still zero?
JZ @@Done ; If so, return TRUE
Mov AX,1686h ; DPMI -- get CPU mode
Int 2Fh ; Call DPMI
Cmp AX,1 ; Check for return >= 1
Mov AX,0 ; Default to real mode
ADC AX,0 ; CF set means protected
@@Done: Mov [ModeFlag],AX
@@Exit: RetF
Endp _hb_cpmiIsProtected
Ends _NanFor
End

View File

@@ -0,0 +1,110 @@
;
; $Id$
;
; File......: PMPTR.ASM
; Author....: Ted Means
; CIS ID....: 73067,3332
;
; This is an original work by Ted Means and is placed in the
; public domain.
;
; Modification history:
; ---------------------
; Rev 1.0 01 Jan 1995 03:01:00 TED
; Initial release
;
; $DOC$
; $FUNCNAME$
; cpmiProtectedPtr()
; $CATEGORY$
; CPMI
; $ONELINER$
; Generate a protected mode selector from a real mode address
; $SYNTAX$
; SELECTOR pascal cpmiProtectedPtr( void * RMAddr, unsigned int Size )
; $ARGUMENTS$
; RMAddr is a protected mode address (segment:offset)
;
; Size is the number of bytes to which RMAddr points.
; $RETURNS$
; A selector which maps to the same physical memory. A null selector
; is returned if the function fails.
; $DESCRIPTION$
; This function is used to obtain the protected mode equivalent of a
; real mode pointer, which is useful when attempting to access DOS or
; BIOS memory locations.
;
; Note that only the selector is generated; the offset is always zero.
;
; Be sure to free with selector with cpmiFreeSelector() when it is no
; longer needed.
; $EXAMPLES$
; auto long * Timer;
; auto long TickCount;
;
; FP_SEG( Timer ) = cpmiProtectedPtr( ( long * ) 0x0000046C,
; sizeof( long ) );
; FP_OFF( Timer ) = 0;
;
; TickCount = *Timer;
;
; cpmiFreeSelector( FPSEG( Timer ) );
; $INCLUDE$
; CPMI.H
; $SEEALSO$
; cpmiRealPtr(), cpmiFreeSelector()
; $END$
;
IDEAL
P286
Public _hb_cpmiProtectedPtr
Segment _NanFor Word Public "CODE"
Assume CS:_NanFor
Proc _hb_cpmiProtectedPtr Far
Enter 2,0 ; Create stack frame
Xor AX,AX ; DPMI -- allocate selector
Mov CX,1 ; Number of selectors
Int 31h ; Call DPMI
JC @@Null ; Bail if error
Mov [Word Ptr BP - 2],AX ; Store selector
Mov BX,AX ; Move selector to BX
Xor CX,CX ; Clear CX
Mov DX,[Word Ptr BP + 10] ; Load segment value
SHL DX,1 ; Move high bit . . .
RCL CX,1 ; . . . into CX low bit
SHL DX,1 ; Move high bit . . .
RCL CX,1 ; . . . into CX low bit
SHL DX,1 ; Move high bit . . .
RCL CX,1 ; . . . into CX low bit
SHL DX,1 ; Move high bit . . .
RCL CX,1 ; . . . into CX low bit
Add DX,[Word Ptr BP + 8] ; Form linear address
ADC CX,0 ; Carry if necessary
Mov AX,7 ; DPMI -- set base address
Int 31h ; Call DPMI
JC @@Null ; Bail if error
Mov AX,8 ; DPMI -- set segment size
Mov BX,[Word Ptr BP - 2] ; Move selector to BX
Xor CX,CX ; Clear size high word
Mov DX,[Word Ptr BP + 6] ; Get size low word
Int 31h ; Call DPMI
Mov AX,[Word Ptr BP - 2] ; Move selector to AX
JNC @@Exit ; If no error, quit
@@Null: Xor AX,AX ; Create null selector
@@Exit: Leave ; Destroy stack frame
RetF 6
Endp _hb_cpmiProtectedPtr
Ends _NanFor
End

View File

@@ -0,0 +1,78 @@
;
; $Id$
;
; File......: RESIZDOS.ASM
; Author....: Ted Means
; CIS ID....: 73067,3332
;
; This is an original work by Ted Means and is placed in the
; public domain.
;
; Modification history:
; ---------------------
; Rev 1.0 01 Jan 1995 03:01:00 TED
; Initial release
;
;
; $DOC$
; $FUNCNAME$
; cpmiResizeDOSMem()
; $CATEGORY$
; CPMI
; $ONELINER$
; Resize a DOS memory block allocated with cpmiAllocDOSMem()
; $SYNTAX$
; int pascal cpmiAllocDOSMem( SELECTOR selector, unsigned int Size )
; $ARGUMENTS$
; selector identifies the DOS memory block.
;
; size is the new size in bytes.
; $RETURNS$
; SUCCEED if successful, FAIL otherwise.
; $DESCRIPTION$
; This function is useful for resizing buffers that reside in the
; lower 640K; e.g. for DOS interrupts.
; $EXAMPLES$
; char far * buffer;
;
; FP_SEG( buffer ) = cpmiAllocDOSMem( 48 );
; FP_OFF( buffer ) = 0;
;
; // Do whatever
;
; cpmiResizeDOSMem( FP_SEG( buffer ), 128 );
; $INCLUDE$
; CPMI.H
; $SEEALSO$
; cpmiAllocDOSMem(), cpmiFreeDOSMem()
; $END$
;
IDEAL
P286
Public _hb_cpmiResizeDOSMem
Segment _NanFor Word Public "CODE"
Assume CS:_NanFor
Proc _hb_cpmiResizeDOSMem Far
Enter 0,0 ; Create stack frame
Mov AX,102h ; DPMI -- resize DOS memory
Mov BX,[Word Ptr BP + 6] ; Get size in bytes
Add BX,15 ; Round up if necessary
SHR BX,4 ; Convert to paragraphs
Mov DX,[Word Ptr BP + 8] ; Get selector
Int 31h ; Call DPMI
Mov AX,1 ; Default to SUCCEED
SBB AX,0 ; Set to FAIL on error
Leave ; Destroy stack frame
RetF 4
Endp _hb_cpmiResizeDOSMem
Ends _NanFor
End

View File

@@ -0,0 +1,93 @@
;
; $Id$
;
; File......: RMPTR.ASM
; Author....: Ted Means
; CIS ID....: 73067,3332
;
; This is an original work by Ted Means and is placed in the
; public domain.
;
; Modification history:
; ---------------------
; Rev 1.0 01 Jan 1995 03:01:00 TED
; Initial release
;
; $DOC$
; $FUNCNAME$
; cpmiRealPtr()
; $CATEGORY$
; CPMI
; $ONELINER$
; Generate a real mode pointer from a protected mode address
; $SYNTAX$
; void * pascal cpmiRealPtr( void * PMAddr )
; $ARGUMENTS$
; PMAddr is a protected mode address (selector:offset)
; $RETURNS$
; The actual real mode physical address (segment:offset)
; $DESCRIPTION$
; This function is used to obtain the real mode equivalent of a
; protected mode pointer, which is useful when attempting to call
; real mode interrupts.
;
; Note that if the protected mode address falls above the real mode
; address space (1 mb) then a null pointer will be returned.
; $EXAMPLES$
; auto char far * buffer;
;
; FP_SEG( buffer ) = cpmiAllocDOSMem( 128 );
; FP_OFF( buffer ) = 0;
;
; buffer = cpmiRealPtr( buffer );
; $INCLUDE$
; CPMI.H
; $SEEALSO$
; cpmiProtectedPtr(), cpmiAllocDOSMem(), cpmiFreeDOSMem(),
; cpmiResizeDOSMem(), cpmiInt86()
; $END$
;
IDEAL
P286
Public _hb_cpmiRealPtr
Segment _NanFor Word Public "CODE"
Assume CS:_NanFor
Proc _hb_cpmiRealPtr Far
Enter 0,0 ; Create stack frame
Mov AX,6 ; DPMI -- get base address
Mov BX,[Word Ptr BP + 8] ; Load selector
Int 31h ; Call DPMI
JC @@Null ; Bail if error
Add DX,[Word Ptr BP + 6] ; Add offset to address
ADC CX,0 ; Carry into high word
Mov AX,DX ; Load low part of address
And AX,1111b ; Mask off upper bits
SHR CX,1 ; Move CX low bit . . .
RCR DX,1 ; . . . into DX high bit
SHR CX,1 ; Move CX low bit . . .
RCR DX,1 ; . . . into DX high bit
SHR CX,1 ; Move CX low bit . . .
RCR DX,1 ; . . . into DX high bit
SHR CX,1 ; Move CX low bit . . .
RCR DX,1 ; . . . into DX high bit
Or CX,CX ; See if CX is clear
JZ @@Exit ; If so, okay
@@Null: Xor AX,AX ; Clear AX
Mov DX,AX ; Create null pointer
@@Exit: Leave
RetF 4
Endp _hb_cpmiRealPtr
Ends _NanFor
End

View File

@@ -0,0 +1,83 @@
;
; $Id$
;
; File......: SEG2SEL.ASM
; Author....: Ted Means
; CIS ID....: 73067,3332
;
; This is an original work by Ted Means and is placed in the
; public domain.
;
; Modification history:
; ---------------------
; Rev 1.0 01 Jan 1995 03:01:00 TED
; Initial release
;
; $DOC$
; $FUNCNAME$
; cpmiSeg2Sel()
; $CATEGORY$
; CPMI
; $ONELINER$
; Generate a protected mode selector from a real mode segment
; $SYNTAX$
; SELECTOR pascal cpmiSeg2Sel( SEGMENT RMSeg )
; $ARGUMENTS$
; RMSeg is the real mode memory segment address for which a selector
; is needed.
; $RETURNS$
; A selector which maps to the same physical memory. A null selector
; is returned if the function fails.
; $DESCRIPTION$
; This function is similar to cpmiProtectedPtr(), but differs in
; a few important ways:
;
; 1) This function always generates a 64K selector.
;
; 2) Selectors generated by this function can never be modified or
; freed.
;
; 3) Multiple calls to this function with the same segment will
; always return the same selector.
;
; This function should be used sparingly. It is mainly intended
; for use with commonly used real mode memory segments like
; 0xB800 or 0x0040.
; $EXAMPLES$
; auto char * Video;
;
; FP_SEG( Video ) = cpmiSeg2Sel( 0xB800 );
; FP_OFF( Video ) = 0;
;
; $INCLUDE$
; CPMI.H
; $SEEALSO$
; cpmiProtectedPtr()
; $END$
;
IDEAL
P286
Public _hb_cpmiSeg2Sel
Segment _NanFor Word Public "CODE"
Assume CS:_NanFor
Proc _hb_cpmiSeg2Sel Far
Enter 0,0 ; Create stack frame
Mov AX,2 ; DPMI -- Seg to Descriptor
Mov BX,[Word Ptr BP + 6] ; Get segment
Int 31h ; Call DPMI
JNC @@Exit ; Leave if no error
Xor AX,AX ; Return null selector
@@Exit: Leave ; Destroy stack frame
RetF 2
Endp _hb_cpmiSeg2Sel
Ends _NanFor
End

View File

@@ -0,0 +1,74 @@
;
; $Id$
;
; File......: SETBASE.ASM
; Author....: Ted Means
; CIS ID....: 73067,3332
;
; This is an original work by Ted Means and is placed in the
; public domain.
;
; Modification history:
; ---------------------
; Rev 1.0 01 Jan 1995 03:01:00 TED
; Initial release
;
; $DOC$
; $FUNCNAME$
; cpmiSetBase()
; $CATEGORY$
; CPMI
; $ONELINER$
; Set the linear base address associated with a selector.
; $SYNTAX$
; int pascal cpmiSetBase( SELECTOR selector, LINEAR base )
; $ARGUMENTS$
; selector is the selector for which the base address is to be set.
;
; base is the linear base address.
; $RETURNS$
; SUCCEED if successful, FAIL otherwise.
; $DESCRIPTION$
; This function is useful for assigning physical memory to a selector.
; Note that it is a linear address and not a real mode segment:offset.
; $EXAMPLES$
; auto char * Video;
;
; FP_SEG( Video ) = cpmiAllocSelector();
; FP_OFF( Video ) = 0;
;
; cpmiSetBase( FP_SEG( Video ), 0xB8000 );
; $INCLUDE$
; CPMI.H
; $SEEALSO$
; cpmiGetBase(), cpmiGetLimit(), cpmiSetLimit()
; $END$
;
IDEAL
P286
Public cpmiSetBase
Segment _NanFor Word Public "CODE"
Assume CS:_NanFor
Proc cpmiSetBase Far
Enter 0,0 ; Create stack frame
Mov AX,7 ; DPMI -- set base
Mov BX,[Word Ptr BP + 10] ; Get selector
Mov DX,[Word Ptr BP + 6] ; Get low word of address
Mov CX,[Word Ptr BP + 8] ; Get high word of address
Int 31h ; Call DPMI
Mov AX,1 ; Default to SUCCEED
SBB AX,0 ; Set to FAIL on error
@@Exit: Leave ; Destroy stack frame
RetF 6
Endp cpmiSetBase
Ends _NanFor
End

View File

@@ -0,0 +1,75 @@
;
; $Id$
;
; File......: SETLIMIT.ASM
; Author....: Ted Means
; CIS ID....: 73067,3332
;
; This is an original work by Ted Means and is placed in the
; public domain.
;
; Modification history:
; ---------------------
; Rev 1.0 01 Jan 1995 03:01:00 TED
; Initial release
;
; $DOC$
; $FUNCNAME$
; cpmiSetLimit()
; $CATEGORY$
; CPMI
; $ONELINER$
; Set the limit associated with a selector.
; $SYNTAX$
; int pascal cpmiSetLimit( SELECTOR selector, unsigned int Limit )
; $ARGUMENTS$
; selector is the selector for which the limit is to be set.
;
; limit is the selector's new limit in bytes.
; $RETURNS$
; SUCCEED if successful, FAIL otherwise.
; $DESCRIPTION$
; This function is useful for changing a selector's limit, but use
; care when making the limit larger that you do not overlap linear
; memory that you do not own.
; $EXAMPLES$
; auto char * Video;
;
; FP_SEG( Video ) = cpmiAllocSelector();
; FP_OFF( Video ) = 0;
;
; cpmiSetLimit( FP_SEG( Video ), 0x8000 );
; $INCLUDE$
; CPMI.H
; $SEEALSO$
; cpmiGetLimit(), cpmiGetBase(), cpmiSetBase()
; $END$
;
IDEAL
P286
Public _hb_cpmiSetLimit
Segment _NanFor Word Public "CODE"
Assume CS:_NanFor
Proc _hb_cpmiSetLimit Far
Enter 0,0 ; Create stack frame
Mov AX,8 ; DPMI -- set limit
Mov BX,[Word Ptr BP + 8] ; Get selector
Xor CX,CX ; Clear high word
Mov DX,[Word Ptr BP + 6] ; Get limit
Int 31h ; Call DPMI
Mov AX,1 ; Default to succeed
SBB AX,0 ; Set to FAIL on error
@@Exit: Leave ; Destroy stack frame
RetF 4
Endp _hb_cpmiSetLimit
Ends _NanFor
End

View File

@@ -0,0 +1,124 @@
;
; $Id$
;
; File......: WILLGPF.ASM
; Author....: Ted Means
; CIS ID....: 73067,3332
;
; This is an original work by Ted Means and is placed in the
; public domain.
;
; Modification history:
; ---------------------
; Rev 1.0 01 Jan 1995 03:01:00 TED
; Initial release
;
; $DOC$
; $FUNCNAME$
; cpmiWillGPF()
; $CATEGORY$
; CPMI
; $ONELINER$
; Determine if accessing a pointer will cause a GPF.
; $SYNTAX$
; int pascal cpmiWillGPF( void * PMAddr, unsigned int Access,
; unsigned int Bytes )
; $ARGUMENTS$
; PMAddr is the pointer to be tested.
;
; Access indicates the intended use for the pointer, and should be
; either AR_READ, AR_WRITE, or AR_EXECUTE (see CPMI.H). You may
; also combine these attributes with the | operator.
;
; Bytes is the number of bytes you intend to access.
; $RETURNS$
; Zero if the specified pointer access will not result in a GPF,
; otherwise a numeric value indicating the cause of the potential
; protection fault:
;
; INVALID_SELECTOR is returned if the selector portion of the
; pointer is invalid.
;
; INVALID_ACCESS is returned if you specify an access mode that
; is invalid; e.g. AR_WRITE for a code selector, or AR_EXECUTE
; for a data selector.
;
; BEYOND_LIMIT is returned if the specified access will go
; beyond the limit of the selector.
;
; $DESCRIPTION$
; This function can help to avoid GPFs by allowing you to validate
; pointers before attempting to use them.
; $EXAMPLES$
; if ( cpmiWillGPF( thePointer, PA_READ | PA_EXECUTE, 128 ) )
; _gtWriteCon( "GPF will occur.", 15 );
; $INCLUDE$
; CPMI.H
; $SEEALSO$
; $END$
;
IDEAL
P286
Public _hb_cpmiWillGPF
Segment _NanFor Word Public "CODE"
Assume CS:_NanFor
Proc _hb_cpmiWillGPF Far
Enter 0,0 ; Create stack frame
Mov AX,-1 ; Return == bad selector
Mov DX,[Word Ptr BP + 12] ; Load selector
LAR CX,DX ; Load access rights
JNZ @@Exit ; Jump if bad selector
Dec AX ; Return == invalid access
Mov BX,[Word Ptr BP + 8] ; Load requested access
And CX,0F00h ; Mask all but type bits
@@Read: Test BX,1 ; Check read access
JZ @@Write ; If not, check write
Cmp CH,7 ; Check all types that
JBE @@Write ; allow reading
Cmp CH,0Ah
JE @@Write
Cmp CH,0Bh
JE @@Write
Cmp CH,0Eh
JB @@Exit ; Read not allowed
@@Write: Test BX,2 ; Check write access
JZ @@Execute ; If not, check execute
Cmp CH,2 ; Check all types that
JE @@Execute ; allow execution
Cmp CH,3
JE @@Execute
Cmp CH,6
JE @@Execute
Cmp CH,7
JNE @@Exit ; Write not allowed
@@Execute:Test BX,4 ; Check execute access
JZ @@Limit ; If not, check limit
Cmp CH,8 ; Check execution types
JB @@Exit ; Execute not allowed
@@Limit: Dec AX ; Return == beyond limit
LSL CX,DX ; Load limit
Mov DX,[Word Ptr BP + 10] ; Get offset
Add DX,[Word Ptr BP + 6] ; Add byte count
Dec DX ; Adjust for zero origin
Cmp DX,CX ; Compare to limit
JA @@Exit ; Bail if beyond
Xor AX,AX ; Return == okay
@@Exit: Leave ; Destroy stack frame
RetF 8 ; Remove params
Endp _hb_cpmiWillGPF
Ends _NanFor
End