From 2bc035797cce81158dfcb42638a32d9486bbae64 Mon Sep 17 00:00:00 2001 From: Luiz Rafael Culik Date: Fri, 21 Apr 2000 00:45:04 +0000 Subject: [PATCH] See changelog 20000420 22:00 GMT -3 --- harbour/contrib/nflib/cpmi/alias.asm | 124 ++++++++++++++++ harbour/contrib/nflib/cpmi/allocdos.asm | 85 +++++++++++ harbour/contrib/nflib/cpmi/allocsel.asm | 72 ++++++++++ harbour/contrib/nflib/cpmi/farcall.asm | 182 ++++++++++++++++++++++++ harbour/contrib/nflib/cpmi/freedos.asm | 72 ++++++++++ harbour/contrib/nflib/cpmi/freesel.asm | 76 ++++++++++ harbour/contrib/nflib/cpmi/getbase.asm | 75 ++++++++++ harbour/contrib/nflib/cpmi/getlimit.asm | 72 ++++++++++ harbour/contrib/nflib/cpmi/int86.asm | 180 +++++++++++++++++++++++ harbour/contrib/nflib/cpmi/isprot.asm | 107 ++++++++++++++ harbour/contrib/nflib/cpmi/pmptr.asm | 110 ++++++++++++++ harbour/contrib/nflib/cpmi/resizdos.asm | 78 ++++++++++ harbour/contrib/nflib/cpmi/rmptr.asm | 93 ++++++++++++ harbour/contrib/nflib/cpmi/seg2sel.asm | 83 +++++++++++ harbour/contrib/nflib/cpmi/setbase.asm | 74 ++++++++++ harbour/contrib/nflib/cpmi/setlimit.asm | 75 ++++++++++ harbour/contrib/nflib/cpmi/willgpf.asm | 124 ++++++++++++++++ 17 files changed, 1682 insertions(+) create mode 100644 harbour/contrib/nflib/cpmi/alias.asm create mode 100644 harbour/contrib/nflib/cpmi/allocdos.asm create mode 100644 harbour/contrib/nflib/cpmi/allocsel.asm create mode 100644 harbour/contrib/nflib/cpmi/farcall.asm create mode 100644 harbour/contrib/nflib/cpmi/freedos.asm create mode 100644 harbour/contrib/nflib/cpmi/freesel.asm create mode 100644 harbour/contrib/nflib/cpmi/getbase.asm create mode 100644 harbour/contrib/nflib/cpmi/getlimit.asm create mode 100644 harbour/contrib/nflib/cpmi/int86.asm create mode 100644 harbour/contrib/nflib/cpmi/isprot.asm create mode 100644 harbour/contrib/nflib/cpmi/pmptr.asm create mode 100644 harbour/contrib/nflib/cpmi/resizdos.asm create mode 100644 harbour/contrib/nflib/cpmi/rmptr.asm create mode 100644 harbour/contrib/nflib/cpmi/seg2sel.asm create mode 100644 harbour/contrib/nflib/cpmi/setbase.asm create mode 100644 harbour/contrib/nflib/cpmi/setlimit.asm create mode 100644 harbour/contrib/nflib/cpmi/willgpf.asm diff --git a/harbour/contrib/nflib/cpmi/alias.asm b/harbour/contrib/nflib/cpmi/alias.asm new file mode 100644 index 0000000000..134fc69d80 --- /dev/null +++ b/harbour/contrib/nflib/cpmi/alias.asm @@ -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 diff --git a/harbour/contrib/nflib/cpmi/allocdos.asm b/harbour/contrib/nflib/cpmi/allocdos.asm new file mode 100644 index 0000000000..7e30bb7a2f --- /dev/null +++ b/harbour/contrib/nflib/cpmi/allocdos.asm @@ -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 diff --git a/harbour/contrib/nflib/cpmi/allocsel.asm b/harbour/contrib/nflib/cpmi/allocsel.asm new file mode 100644 index 0000000000..fe20d0826f --- /dev/null +++ b/harbour/contrib/nflib/cpmi/allocsel.asm @@ -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 diff --git a/harbour/contrib/nflib/cpmi/farcall.asm b/harbour/contrib/nflib/cpmi/farcall.asm new file mode 100644 index 0000000000..78ee06f3c5 --- /dev/null +++ b/harbour/contrib/nflib/cpmi/farcall.asm @@ -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 diff --git a/harbour/contrib/nflib/cpmi/freedos.asm b/harbour/contrib/nflib/cpmi/freedos.asm new file mode 100644 index 0000000000..3815385b8e --- /dev/null +++ b/harbour/contrib/nflib/cpmi/freedos.asm @@ -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 diff --git a/harbour/contrib/nflib/cpmi/freesel.asm b/harbour/contrib/nflib/cpmi/freesel.asm new file mode 100644 index 0000000000..fb88517424 --- /dev/null +++ b/harbour/contrib/nflib/cpmi/freesel.asm @@ -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 diff --git a/harbour/contrib/nflib/cpmi/getbase.asm b/harbour/contrib/nflib/cpmi/getbase.asm new file mode 100644 index 0000000000..2fb7be8508 --- /dev/null +++ b/harbour/contrib/nflib/cpmi/getbase.asm @@ -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 diff --git a/harbour/contrib/nflib/cpmi/getlimit.asm b/harbour/contrib/nflib/cpmi/getlimit.asm new file mode 100644 index 0000000000..118dc6052e --- /dev/null +++ b/harbour/contrib/nflib/cpmi/getlimit.asm @@ -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 diff --git a/harbour/contrib/nflib/cpmi/int86.asm b/harbour/contrib/nflib/cpmi/int86.asm new file mode 100644 index 0000000000..facb0ebfe6 --- /dev/null +++ b/harbour/contrib/nflib/cpmi/int86.asm @@ -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 diff --git a/harbour/contrib/nflib/cpmi/isprot.asm b/harbour/contrib/nflib/cpmi/isprot.asm new file mode 100644 index 0000000000..5969071642 --- /dev/null +++ b/harbour/contrib/nflib/cpmi/isprot.asm @@ -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 diff --git a/harbour/contrib/nflib/cpmi/pmptr.asm b/harbour/contrib/nflib/cpmi/pmptr.asm new file mode 100644 index 0000000000..4643579d34 --- /dev/null +++ b/harbour/contrib/nflib/cpmi/pmptr.asm @@ -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 diff --git a/harbour/contrib/nflib/cpmi/resizdos.asm b/harbour/contrib/nflib/cpmi/resizdos.asm new file mode 100644 index 0000000000..92e69514b0 --- /dev/null +++ b/harbour/contrib/nflib/cpmi/resizdos.asm @@ -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 diff --git a/harbour/contrib/nflib/cpmi/rmptr.asm b/harbour/contrib/nflib/cpmi/rmptr.asm new file mode 100644 index 0000000000..ab6db207c2 --- /dev/null +++ b/harbour/contrib/nflib/cpmi/rmptr.asm @@ -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 diff --git a/harbour/contrib/nflib/cpmi/seg2sel.asm b/harbour/contrib/nflib/cpmi/seg2sel.asm new file mode 100644 index 0000000000..9f3d23a835 --- /dev/null +++ b/harbour/contrib/nflib/cpmi/seg2sel.asm @@ -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 diff --git a/harbour/contrib/nflib/cpmi/setbase.asm b/harbour/contrib/nflib/cpmi/setbase.asm new file mode 100644 index 0000000000..d2afaf77b5 --- /dev/null +++ b/harbour/contrib/nflib/cpmi/setbase.asm @@ -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 diff --git a/harbour/contrib/nflib/cpmi/setlimit.asm b/harbour/contrib/nflib/cpmi/setlimit.asm new file mode 100644 index 0000000000..7f5d804996 --- /dev/null +++ b/harbour/contrib/nflib/cpmi/setlimit.asm @@ -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 diff --git a/harbour/contrib/nflib/cpmi/willgpf.asm b/harbour/contrib/nflib/cpmi/willgpf.asm new file mode 100644 index 0000000000..499cff6587 --- /dev/null +++ b/harbour/contrib/nflib/cpmi/willgpf.asm @@ -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