aboutsummaryrefslogtreecommitdiffstats
path: root/Game/Code/lib/zlportio/zlportio.pas
diff options
context:
space:
mode:
Diffstat (limited to 'Game/Code/lib/zlportio/zlportio.pas')
-rw-r--r--Game/Code/lib/zlportio/zlportio.pas285
1 files changed, 285 insertions, 0 deletions
diff --git a/Game/Code/lib/zlportio/zlportio.pas b/Game/Code/lib/zlportio/zlportio.pas
new file mode 100644
index 00000000..2cf57334
--- /dev/null
+++ b/Game/Code/lib/zlportio/zlportio.pas
@@ -0,0 +1,285 @@
+{ -----------------------------------------------------------------------------}
+{ Copyright 2000-2001, Zloba Alexander. All Rights Reserved. }
+{ This unit can be freely used and distributed in commercial and private }
+{ environments, provided this notice is not modified in any way. }
+{ -----------------------------------------------------------------------------}
+{ Feel free to contact me if you have any questions, comments or suggestions at}
+{ zal@specosoft.com (Zloba Alexander) }
+{ You can always find the latest version of this unit at: }
+{ http://www.specosoft.com }
+
+{ -----------------------------------------------------------------------------}
+{ Date last modified: 08/10/2001 }
+{ -----------------------------------------------------------------------------}
+{ ZLPortIO driver interface unit v1.20 }
+{ -----------------------------------------------------------------------------}
+{ Description: }
+{ This unit allow your application direct access port input and output under }
+{ all versions of Microsoft Windows® }
+{ Depends: }
+{ zlportio.sys ddkint.pas }
+{ You must distribute zlportio.sys with your application }
+{ Procedures and functions: }
+{ procedure zlioportread( const Port,DataType:dword ):dword; }
+{ procedure zlioportwrite( const Port,DataType,Data:dword ); }
+{ }
+{ function portreadb( const Port:dword ):byte; }
+{ function portreadw( const Port:dword ):word; }
+{ function portreadl( const Port:dword ):dword; }
+{ }
+{ procedure portwriteb( const Port:Dword;const Data:byte ); }
+{ procedure portwritew( const Port:dword;const Data:word ); }
+{ procedure portwritel( const Port,Data:dword ); }
+{ }
+{ Examples: }
+{ // get data bits from LPT port }
+{ databits := portreadb( $378 ) }
+{ // set data bits from LPT port }
+{ portwriteb( $378, databits ) }
+{ // The second parameter determine the databus length for operation }
+{ -----------------------------------------------------------------------------}
+{ Revision History: }
+{ 1.00: + First public release }
+{ 1.10: + Added new functions (portreadX,portwriteX) for convenience of usage }
+{ 1.20: + Added new function (zliosetiopm) for enabling direct access to ports}
+{ 1.30: + added compiler directives for correct compilation }
+{ 1.40: + added opportunity to run multiply instances client to driver }
+{ 1.50: - fixed bug with work under win98 }
+{------------------------------------------------------------------------------}
+
+{$A-,H-}
+unit zlportio;
+
+interface
+
+uses windows,
+ sysutils,
+ ddkint;
+
+Const
+ ZLIO_BYTE = 0;
+ ZLIO_WORD = 1;
+ ZLIO_DWORD = 2;
+
+var
+
+// if TRUE then driver was started
+// in other case something wrong
+// We start driver in initialization section of unit.
+
+ ZlIOStarted:boolean = false;
+
+// if TRUE then we can use asm IN,OUT under NT/2000
+// see zliosetiopm for more details
+ ZlIODirect:boolean = false;
+
+// handle to opened driver
+
+ HZLIO:THandle;
+
+
+function portreadb( const Port:dword ):byte;
+function portreadw( const Port:dword ):word;
+function portreadl( const Port:dword ):dword;
+
+procedure portwriteb( const Port:Dword;const Data:byte );
+procedure portwritew( const Port:dword;const Data:word );
+procedure portwritel( const Port,Data:dword );
+
+
+procedure zlioportwrite( const Port,DataType,Data:dword );
+function zlioportread( const Port,DataType:dword ):dword;
+
+// if you need the best perfomance for your IO operations
+// call zliosetiopm(TRUE). This allow your application
+// to use asm command IN,OUT directly in your code.
+
+procedure zliosetiopm( const Direct:boolean );
+
+// internal
+
+function zliostart:boolean;
+procedure zliostop;
+
+
+implementation
+
+const
+ ZLIODriverName='zlportio';
+
+var
+ IOCTL_ZLUNI_PORT_READ:cardinal;
+ IOCTL_ZLUNI_PORT_WRITE:cardinal;
+ IOCTL_ZLUNI_IOPM_ON:cardinal;
+ IOCTL_ZLUNI_IOPM_OFF:cardinal;
+
+type
+TzlIOData = record
+ Port,DataType,Data:dword;
+end;
+
+
+procedure zlioportwrite( const Port,DataType,Data:dword );
+var resdata:TZLIOData;
+ cBR:cardinal;
+begin
+ if (not ZLIODirect) then begin
+ resdata.Port := Port;
+ resdata.Data := Data;
+ resdata.DataType := DataType;
+ if ZLIOStarted then
+ DeviceIoControl(HZLIO,IOCTL_ZLUNI_PORT_WRITE,@resdata,sizeof(resdata),nil,0,cBR,nil );
+ end
+ else begin
+ Case DataType of
+ ZLIO_BYTE : asm mov edx,Port;mov eax,data;out dx,al; end;
+ ZLIO_WORD : asm mov edx,Port;mov eax,data;out dx,ax; end;
+ ZLIO_DWORD: asm mov edx,Port;mov eax,data;out dx,eax; end;
+ end;
+ end;
+end;
+
+function zlioportread(const Port,DataType:dword):dword;
+var resdata:TZLIOData;
+ cBR:cardinal;i:dword;
+begin
+ if (not ZLIODirect) then begin
+ resdata.Port := Port;
+ resdata.DataType := DataType;
+ if ZLIOStarted then
+ DeviceIoControl(HZLIO,IOCTL_ZLUNI_PORT_READ,@resdata,sizeof(resdata),@i,sizeof(dword),cBR,nil );
+ end
+ else begin
+ Case DataType of
+ ZLIO_BYTE : asm mov edx,Port;xor eax,eax;in al,dx;mov i,eax; end;
+ ZLIO_WORD : asm mov edx,Port;xor eax,eax;in ax,dx;mov i,eax; end;
+ ZLIO_DWORD: asm mov edx,Port;xor eax,eax;in eax,dx;mov i,eax end;
+ end;
+ end;
+ result := i;
+end;
+
+function portreadb( const Port:dword ):byte;
+begin
+ Result := zlioportread(Port,ZLIO_BYTE);
+end;
+
+function portreadw( const Port:dword ):word;
+begin
+ Result := zlioportread(Port,ZLIO_WORD);
+end;
+
+function portreadl( const Port:dword ):dword;
+begin
+ Result := zlioportread(Port,ZLIO_DWORD);
+end;
+
+procedure portwriteb( const Port:Dword;const Data:byte );
+begin
+ zlioportwrite(Port,ZLIO_BYTE,Data);
+end;
+
+procedure portwritew( const Port:dword;const Data:word );
+begin
+ zlioportwrite(Port,ZLIO_WORD,Data);
+end;
+
+procedure portwritel( const Port,Data:dword );
+begin
+ zlioportwrite(Port,ZLIO_DWORD,Data);
+end;
+
+procedure zliosetiopm( const Direct:boolean );
+var cBR:cardinal;
+begin
+ if Win32Platform=VER_PLATFORM_WIN32_NT then
+ if ZLIOStarted then begin
+ if Direct then
+ DeviceIoControl(HZLIO,IOCTL_ZLUNI_IOPM_ON,nil,0,nil,0,cBR,nil )
+ else
+ DeviceIoControl(HZLIO,IOCTL_ZLUNI_IOPM_OFF,nil,0,nil,0,cBR,nil );
+ ZLIODirect := Direct;
+ end
+end;
+
+
+
+
+function zliostart;
+var dir:shortstring;
+begin
+ if Win32Platform<>VER_PLATFORM_WIN32_NT then begin
+ result := true;
+ exit;
+ end;
+// Result := false;
+ zliostop;
+ dir := ExtractFileDir(ParamStr(0))+'\'+ZLIODriverName+'.sys'#0;
+ driverinstall(pchar(@dir[1]),ZLIODriverName+#0);
+ Result := driverstart(ZLIODriverName) = 0;
+end;
+
+procedure zliostop;
+begin
+ if Win32Platform<>VER_PLATFORM_WIN32_NT then
+ exit;
+ driverstop(ZLIODriverName);
+ driverremove(ZLIODriverName);
+end;
+
+function zlioopen( var Handle:thandle):boolean;
+var cERR:integer;
+ s:string;
+begin
+ if Win32Platform<>VER_PLATFORM_WIN32_NT then begin
+ result := true;
+ exit;
+ end;
+ Result := false;
+ Handle := THandle(-1);
+ Handle := createFile('\\.\ZLPORTIO',
+ GENERIC_READ or GENERIC_WRITE,
+ 0,
+ nil,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ 0 );
+ cERR := getlasterror;
+ s := messagestring( cerr);
+ if (cERR = ERROR_ALREADY_EXISTS)or(cERR = ERROR_SUCCESS) then Result := True;
+end;
+
+procedure zlioclose( const Handle:thandle);
+begin
+ if (Win32Platform=VER_PLATFORM_WIN32_NT) then
+ closehandle(Handle);
+end;
+
+
+initialization
+
+IOCTL_ZLUNI_PORT_READ := CTL_CODE(FILE_DEVICE_KRNLDRVR, 1, METHOD_BUFFERED, FILE_ANY_ACCESS);
+IOCTL_ZLUNI_PORT_WRITE := CTL_CODE(FILE_DEVICE_KRNLDRVR, 2, METHOD_BUFFERED, FILE_ANY_ACCESS);
+IOCTL_ZLUNI_IOPM_ON := CTL_CODE(FILE_DEVICE_KRNLDRVR, 3, METHOD_BUFFERED, FILE_ANY_ACCESS);
+IOCTL_ZLUNI_IOPM_OFF := CTL_CODE(FILE_DEVICE_KRNLDRVR, 4, METHOD_BUFFERED, FILE_ANY_ACCESS);
+
+ if Win32Platform<>VER_PLATFORM_WIN32_NT then begin
+ zliostarted := true;
+ zliodirect := true;
+ end
+ else begin
+ if not zlioopen(HZLIO) then begin
+ if zliostart then
+ ZLIOStarted := zlioopen(HZLIO) or (Win32Platform<>VER_PLATFORM_WIN32_NT);
+ end
+ else
+ ZLIOStarted := true;
+ end;
+finalization
+
+if ZLIOStarted then
+ zliostop;
+
+
+
+end.