| 1 | UNIT PortIO;
|
|---|
| 2 |
|
|---|
| 3 | {**************************************************************************
|
|---|
| 4 | * General Unit for Speed-Pascal/2 *
|
|---|
| 5 | * *
|
|---|
| 6 | * PORT Input/Output Operations (Hope it works) *
|
|---|
| 7 | * *
|
|---|
| 8 | * *
|
|---|
| 9 | * Suggested by Ralf Brandt @ 2:2410/104.3 (28.10.94) *
|
|---|
| 10 | * *
|
|---|
| 11 | **************************************************************************}
|
|---|
| 12 |
|
|---|
| 13 | { 04-Mar-96: Adapted to Speed-Pascal 1.5, added pseudo-arrays Port[]
|
|---|
| 14 | and PortW[] which behave like the ones in Borland Pascal.
|
|---|
| 15 | Implemented using classes and default properties.
|
|---|
| 16 |
|
|---|
| 17 | Caution: Untested! :-) }
|
|---|
| 18 |
|
|---|
| 19 | INTERFACE
|
|---|
| 20 |
|
|---|
| 21 | FUNCTION ReadBytePort(PortAdress:WORD;VAR value:BYTE):BOOLEAN;
|
|---|
| 22 | FUNCTION ReadWordPort(PortAdress:WORD;VAR value:WORD):BOOLEAN;
|
|---|
| 23 | FUNCTION WriteBytePort(PortAdress:WORD;value:BYTE):BOOLEAN;
|
|---|
| 24 | FUNCTION WriteWordPort(PortAdress:WORD;value:Word):BOOLEAN;
|
|---|
| 25 | FUNCTION ReadPhysMemory(Address:LONGWORD;VAR Buf;Count:LONGWORD):BOOLEAN;
|
|---|
| 26 |
|
|---|
| 27 | TYPE
|
|---|
| 28 | { Pseudo-array for byte-wise I/O. Don't create
|
|---|
| 29 | instances of this class. The unit already
|
|---|
| 30 | creates one for you. }
|
|---|
| 31 |
|
|---|
| 32 | TBytePorts = class
|
|---|
| 33 | private
|
|---|
| 34 | function GetByte(PortAddr: Word): Byte;
|
|---|
| 35 | procedure SetByte(PortAddr:Word; Value: Byte);
|
|---|
| 36 | public
|
|---|
| 37 | property IO[PortAddr: Word]: Byte
|
|---|
| 38 | read GetByte write SetByte; default;
|
|---|
| 39 | end;
|
|---|
| 40 |
|
|---|
| 41 | { Pseudo-array for word-wise I/O. Don't create
|
|---|
| 42 | instances of this class. The unit already
|
|---|
| 43 | creates one for you. }
|
|---|
| 44 |
|
|---|
| 45 | TWordPorts = class
|
|---|
| 46 | private
|
|---|
| 47 | function GetWord(PortAddr: Word): Word;
|
|---|
| 48 | procedure SetWord(PortAddr:Word; Value: Word);
|
|---|
| 49 | public
|
|---|
| 50 | property IO[PortAddr: Word]: Word
|
|---|
| 51 | read GetWord write SetWord; default;
|
|---|
| 52 | end;
|
|---|
| 53 |
|
|---|
| 54 | VAR
|
|---|
| 55 | { Use this for byte-wise I/O, just like
|
|---|
| 56 | array PORT[] in Borland Pascal. }
|
|---|
| 57 |
|
|---|
| 58 | Port: TBytePorts;
|
|---|
| 59 |
|
|---|
| 60 | { Use this for word-wise I/O, just like
|
|---|
| 61 | array PORTW[] in Borland Pascal. }
|
|---|
| 62 |
|
|---|
| 63 | PortW: TWordPorts;
|
|---|
| 64 |
|
|---|
| 65 | IMPLEMENTATION
|
|---|
| 66 |
|
|---|
| 67 | USES
|
|---|
| 68 | OS2DEF, BSEDOS;
|
|---|
| 69 |
|
|---|
| 70 | CONST
|
|---|
| 71 | TSTCFG_CAT =$80;
|
|---|
| 72 | TSTCFG_FCN_PHYS =$40;
|
|---|
| 73 | TSTCFG_FCN_INPUT =$41;
|
|---|
| 74 | TSTCFG_FCN_OUTPUT =$42;
|
|---|
| 75 |
|
|---|
| 76 | CONST
|
|---|
| 77 | IODriverName:STRING='TESTCFG$'; {Driver name for Port I/O}
|
|---|
| 78 |
|
|---|
| 79 | VAR
|
|---|
| 80 | IODriverHandle:LONGWORD;
|
|---|
| 81 | IOAction:LONGWORD;
|
|---|
| 82 | IOOldExit:POINTER;
|
|---|
| 83 |
|
|---|
| 84 | TYPE
|
|---|
| 85 | TPortAddr=RECORD
|
|---|
| 86 | ioaddr:WORD;
|
|---|
| 87 | iowidth:WORD;
|
|---|
| 88 | iovalue:WORD;
|
|---|
| 89 | END;
|
|---|
| 90 |
|
|---|
| 91 | TPhysAddr=RECORD
|
|---|
| 92 | Command:LONGWORD;
|
|---|
| 93 | address:LONGWORD;
|
|---|
| 94 | Bytes:LONGWORD;
|
|---|
| 95 | END;
|
|---|
| 96 |
|
|---|
| 97 | FUNCTION ReadBytePort(PortAdress:WORD;VAR value:BYTE):BOOLEAN;
|
|---|
| 98 | VAR
|
|---|
| 99 | PortAddr:TPortAddr;
|
|---|
| 100 | BEGIN
|
|---|
| 101 | PortAddr.IoAddr:=PortAdress;
|
|---|
| 102 | PortAddr.IoWidth:=1;
|
|---|
| 103 | IF DosDevIoCtl(IODriverHandle,TSTCFG_CAT,TSTCFG_FCN_INPUT,PortAddr,
|
|---|
| 104 | SizeOf(TPortAddr),NIL,Value,1,NIL)<>0 THEN
|
|---|
| 105 | ReadBytePort:=FALSE
|
|---|
| 106 | ELSE ReadBytePort:=TRUE;
|
|---|
| 107 | END;
|
|---|
| 108 |
|
|---|
| 109 | FUNCTION ReadWordPort(PortAdress:WORD;VAR value:WORD):BOOLEAN;
|
|---|
| 110 | VAR
|
|---|
| 111 | PortAddr:TPortAddr;
|
|---|
| 112 | BEGIN
|
|---|
| 113 | PortAddr.IoAddr:=PortAdress;
|
|---|
| 114 | PortAddr.IoWidth:=2;
|
|---|
| 115 | IF DosDevIoCtl(IODriverHandle,TSTCFG_CAT,TSTCFG_FCN_INPUT,PortAddr,
|
|---|
| 116 | SizeOf(TPortAddr),NIL,Value,2,NIL)<>0 THEN
|
|---|
| 117 | ReadWordPort:=FALSE
|
|---|
| 118 | ELSE ReadWordPort:=TRUE;
|
|---|
| 119 | END;
|
|---|
| 120 |
|
|---|
| 121 | FUNCTION WriteBytePort(PortAdress:WORD;value:BYTE):BOOLEAN;
|
|---|
| 122 | VAR
|
|---|
| 123 | PortAddr:TPortAddr;
|
|---|
| 124 | BEGIN
|
|---|
| 125 | PortAddr.IoAddr:=PortAdress;
|
|---|
| 126 | PortAddr.IoWidth:=1;
|
|---|
| 127 | PortAddr.IoValue:=value;
|
|---|
| 128 | IF DosDevIoCtl(IoDriverHandle,TSTCFG_CAT,TSTCFG_FCN_OUTPUT,PortAddr,
|
|---|
| 129 | SizeOf(TPortAddr),NIL,Value,1,NIL)<>0 THEN
|
|---|
| 130 | WriteBytePort:=FALSE
|
|---|
| 131 | ELSE WriteBytePort:=TRUE;
|
|---|
| 132 | END;
|
|---|
| 133 |
|
|---|
| 134 | FUNCTION WriteWordPort(PortAdress:WORD;value:Word):BOOLEAN;
|
|---|
| 135 | VAR
|
|---|
| 136 | PortAddr:TPortAddr;
|
|---|
| 137 | BEGIN
|
|---|
| 138 | PortAddr.IoAddr:=PortAdress;
|
|---|
| 139 | PortAddr.IoWidth:=2;
|
|---|
| 140 | PortAddr.IoValue:=value;
|
|---|
| 141 | IF DosDevIoCtl(IoDriverHandle,TSTCFG_CAT,TSTCFG_FCN_OUTPUT,PortAddr,
|
|---|
| 142 | SizeOf(TPortAddr),NIL,Value,2,NIL)<>0 THEN
|
|---|
| 143 | WriteWordPort:=FALSE
|
|---|
| 144 | ELSE WriteWordPort:=TRUE;
|
|---|
| 145 | END;
|
|---|
| 146 |
|
|---|
| 147 |
|
|---|
| 148 | FUNCTION ReadPhysMemory(Address:LONGWORD;VAR Buf;Count:LONGWORD):BOOLEAN;
|
|---|
| 149 | VAR
|
|---|
| 150 | PhysAddr:TPhysAddr;
|
|---|
| 151 | BEGIN
|
|---|
| 152 | PhysAddr.Command:=0;
|
|---|
| 153 | PhysAddr.Address:=Address;
|
|---|
| 154 | PhysAddr.Bytes:=Count;
|
|---|
| 155 | IF DosDevIoCtl(IODriverHandle,TSTCFG_CAT,TSTCFG_FCN_PHYS,PhysAddr,
|
|---|
| 156 | sizeof(TPhysAddr),NIL,Buf,Count,NIL)<>0 THEN
|
|---|
| 157 | ReadPhysMemory:=FALSE
|
|---|
| 158 | ELSE ReadPhysMemory:=TRUE;
|
|---|
| 159 | END;
|
|---|
| 160 |
|
|---|
| 161 | FUNCTION GetBytePort(PortAddress : Word) : Byte; {Substitute for Port[]}
|
|---|
| 162 | VAR
|
|---|
| 163 | PortValue:BYTE;
|
|---|
| 164 | BEGIN
|
|---|
| 165 | ReadBytePort(PortAddress,PortValue);
|
|---|
| 166 | GetBytePort:=PortValue;
|
|---|
| 167 | END;
|
|---|
| 168 |
|
|---|
| 169 | FUNCTION GetWordPort(PortAddress : Word) : Word; {Substitute for PortW[]}
|
|---|
| 170 | VAR
|
|---|
| 171 | PortValue:WORD;
|
|---|
| 172 | BEGIN
|
|---|
| 173 | ReadWordPort(PortAddress,PortValue);
|
|---|
| 174 | GetWordPort:=PortValue;
|
|---|
| 175 | END;
|
|---|
| 176 |
|
|---|
| 177 |
|
|---|
| 178 | PROCEDURE IOExit;
|
|---|
| 179 | BEGIN
|
|---|
| 180 | ExitProc:=IOOldExit;
|
|---|
| 181 | IF IoDriverHandle<>0 THEN DosClose(IoDriverHandle);
|
|---|
| 182 | Port.Destroy;
|
|---|
| 183 | PortW.Destroy;
|
|---|
| 184 | END;
|
|---|
| 185 |
|
|---|
| 186 | function TBytePorts.GetByte(PortAddr: Word): Byte;
|
|---|
| 187 | begin
|
|---|
| 188 | ReadBytePort(PortAddr, Result);
|
|---|
| 189 | end;
|
|---|
| 190 |
|
|---|
| 191 | procedure TBytePorts.SetByte(PortAddr:Word; Value: Byte);
|
|---|
| 192 | begin
|
|---|
| 193 | WriteBytePort(PortAddr, Value);
|
|---|
| 194 | end;
|
|---|
| 195 |
|
|---|
| 196 | function TWordPorts.GetWord(PortAddr: Word): Word;
|
|---|
| 197 | begin
|
|---|
| 198 | ReadWordPort(PortAddr, Result);
|
|---|
| 199 | end;
|
|---|
| 200 |
|
|---|
| 201 | procedure TWordPorts.SetWord(PortAddr:Word; Value: Word);
|
|---|
| 202 | begin
|
|---|
| 203 | WriteWordPort(PortAddr, Value);
|
|---|
| 204 | end;
|
|---|
| 205 |
|
|---|
| 206 | BEGIN
|
|---|
| 207 | IOOldExit:=ExitProc;
|
|---|
| 208 | ExitProc:=@IOExit;
|
|---|
| 209 | DosOpen(IODriverName,IoDriverHandle,IoAction,0,0,1,$40,NIL);
|
|---|
| 210 |
|
|---|
| 211 | Port.Create;
|
|---|
| 212 | PortW.Create;
|
|---|
| 213 | END.
|
|---|