'===========================================================================
' Subject: HARDWARE & MEMORY I/O ROUTINES     Date: 01-20-98 (16:10)       
'  Author: Dave Navarro, Jr.                  Code: PBDLL                  
'  Origin: dave@powerbasic.com              Packet: PBDLL.ABC
'===========================================================================
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Hardware and Memory I/O Routines for Visual Basic
' Copyright (c) 1996 by PowerBASIC, Inc.
'
' For Visual Basic users who do not own PB/DLL, this file is free for personal
' use only.  It may not be used in a commercial package.  Owners of PB/DLL may
' use it as they see fit.
'
' Requires PB/DLL 1.50 or later to recompile.  You can only access memory
' addresses below the first meg (the DOS memory area).
'
' Visual Basic Declares:
'   Declare Function Peek Lib "PEEKOUT.DLL" (ByVal wSeg As Integer, ByVal wOffs As Integer) As Integer
'   Declare Function Inp Lib "PEEKOUT.DLL" (ByVal Port As Integer) As Integer
'   Declare Sub Poke Lib "PEEKOUT.DLL" (ByVal wSeg As Integer, ByVal wOffs As Integer, ByVal Value As Integer)
'   Declare Sub Out Lib "PEEKOUT.DLL" (ByVal Port As Integer, ByVal Value As Integer)
'
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

$COMPILE DLL

DECLARE FUNCTION FreeSelector LIB "KERNEL" (BYVAL wSelector AS WORD) AS WORD
DECLARE FUNCTION SegToSelector(BYVAL Segm AS WORD) AS DWORD


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' PEEK for Visual Basic
'
' Gets a byte from DOS memory (below 1 meg).
'
' Declare Function Peek Lib "PEEKOUT.DLL" (ByVal wSeg As Integer, ByVal wOffs As Integer) As Integer
'
' wSeg  = DOS Segment to PEEK from
' wOffs = DOS Offset to PEEK from
'
FUNCTION vbPeek ALIAS "PEEK" (BYVAL wSeg AS WORD, BYVAL wOffs AS WORD) EXPORT AS INTEGER

  DIM hSelector AS WORD
  DIM Address   AS DWORD

  hSelector = SegToSelector(wSeg)         ' allocate a new selector

  Address = MAKLNG(wOffs, hSelector)      ' create a 32-bit pointer

  FUNCTION = PEEK(Address)                ' get the byte

  FreeSelector hSelector                  ' don't forget to release the
                                          '   selector
END FUNCTION


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' POKE for Visual Basic
'
' Puts a byte into DOS memory (below 1 meg).
'
' Declare Sub Poke Lib "PEEKOUT.DLL" (ByVal wSeg As Integer, ByVal wOffs As Integer, ByVal Value As Integer)
'
' wSeg  = DOS Segment to POKE into
' wOffs = DOS Offset to POKE into
' value = Value to place into memory
'
SUB vbPoke ALIAS "POKE" (BYVAL wSeg AS WORD, BYVAL wOffs AS WORD, BYVAL value AS INTEGER) EXPORT

  DIM hSelector AS WORD
  DIM Address   AS DWORD

  hSelector = SegToSelector(wSeg)         ' allocate a new selector

  Address = MAKLNG(wOffs, hSelector)      ' create a 32-bit pointer

  POKE Address, Value                     ' put the byte into memory

  FreeSelector hSelector                  ' don't forget to release the
                                          '   selector
END SUB


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' OUT for Visual Basic
'
' Sends a byte out the specified hardware port.
'
' Declare Sub Out Lib "PEEKOUT.DLL" (ByVal Port As Integer, ByVal Value As Integer)
'
' Port  = Hardware port to send byte
' Value = byte to send
'
SUB vbOut ALIAS "OUT" (BYVAL port AS WORD, BYVAL value AS INTEGER) EXPORT

  OUT port, Value

END SUB


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' INP for Visual Basic
'
' Receives a byte from the specified hardware port.
'
' Declare Function Inp Lib "PEEKOUT.DLL" (ByVal Port As Integer) As Integer
'
' Port  = Hardware port to receive byte
'
FUNCTION vbInp ALIAS "INP" (BYVAL port AS WORD) EXPORT AS INTEGER

  FUNCTION = INP(Port)

END FUNCTION


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Convert a real mode DOS segment into a protected mode selector
'
' Note:  Do not call from Visual Basic.  You must release the selector
'        when you are finished with it.
'
FUNCTION SegToSelector(BYVAL Segm AS WORD) AS DWORD

  ! mov  AX, &H1686     ; verify presence of DPMI server
  ! int  &H2F           ;

  ! or   AX, AX         ;
  ! jnz  GotError       ;

  ! mov  BX, Segm       ; put segment in BX
  ! mov  AX, 2          ; convert segment to selector
  ! int  &H31           ;
  ! jc   GotError       ;

  ! mov  FUNCTION, AX   ; return selector
GotError:

END FUNCTION
