See changelog 20000420 22:00 GMT -3
This commit is contained in:
124
harbour/contrib/nflib/cpmi/alias.asm
Normal file
124
harbour/contrib/nflib/cpmi/alias.asm
Normal 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
|
||||
85
harbour/contrib/nflib/cpmi/allocdos.asm
Normal file
85
harbour/contrib/nflib/cpmi/allocdos.asm
Normal 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
|
||||
72
harbour/contrib/nflib/cpmi/allocsel.asm
Normal file
72
harbour/contrib/nflib/cpmi/allocsel.asm
Normal 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
|
||||
182
harbour/contrib/nflib/cpmi/farcall.asm
Normal file
182
harbour/contrib/nflib/cpmi/farcall.asm
Normal 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
|
||||
72
harbour/contrib/nflib/cpmi/freedos.asm
Normal file
72
harbour/contrib/nflib/cpmi/freedos.asm
Normal 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
|
||||
76
harbour/contrib/nflib/cpmi/freesel.asm
Normal file
76
harbour/contrib/nflib/cpmi/freesel.asm
Normal 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
|
||||
75
harbour/contrib/nflib/cpmi/getbase.asm
Normal file
75
harbour/contrib/nflib/cpmi/getbase.asm
Normal 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
|
||||
72
harbour/contrib/nflib/cpmi/getlimit.asm
Normal file
72
harbour/contrib/nflib/cpmi/getlimit.asm
Normal 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
|
||||
180
harbour/contrib/nflib/cpmi/int86.asm
Normal file
180
harbour/contrib/nflib/cpmi/int86.asm
Normal 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
|
||||
107
harbour/contrib/nflib/cpmi/isprot.asm
Normal file
107
harbour/contrib/nflib/cpmi/isprot.asm
Normal 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
|
||||
110
harbour/contrib/nflib/cpmi/pmptr.asm
Normal file
110
harbour/contrib/nflib/cpmi/pmptr.asm
Normal 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
|
||||
78
harbour/contrib/nflib/cpmi/resizdos.asm
Normal file
78
harbour/contrib/nflib/cpmi/resizdos.asm
Normal 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
|
||||
93
harbour/contrib/nflib/cpmi/rmptr.asm
Normal file
93
harbour/contrib/nflib/cpmi/rmptr.asm
Normal 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
|
||||
83
harbour/contrib/nflib/cpmi/seg2sel.asm
Normal file
83
harbour/contrib/nflib/cpmi/seg2sel.asm
Normal 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
|
||||
74
harbour/contrib/nflib/cpmi/setbase.asm
Normal file
74
harbour/contrib/nflib/cpmi/setbase.asm
Normal 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
|
||||
75
harbour/contrib/nflib/cpmi/setlimit.asm
Normal file
75
harbour/contrib/nflib/cpmi/setlimit.asm
Normal 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
|
||||
124
harbour/contrib/nflib/cpmi/willgpf.asm
Normal file
124
harbour/contrib/nflib/cpmi/willgpf.asm
Normal 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
|
||||
Reference in New Issue
Block a user