{ function DetectVirtualRealMode(..) detects virtual real mode
{ function USBdetect(..); detects an PCI USB Controller - done by INIT
{ function USBEnable enables USB Controller PCI-BUS Master
{ function USBGetDeviceIOSpace(..) reads I/O port address
{ function USBSetDeviceIOSpace(..) sets I/O port address
{ function USBReadCommandReg read access IOCommandRegister
{ procedure USBWriteCommandReg write access IOCommandRegister
{
{ Initialization should first check the USB device (test USBdetected),
{ read the I/O address space and if zero set an unused port address space
{ (32 byte), now PIC-BUS Master Control can be enabled by USBenable
function USBReadFrameNumberReg:word;
begin
USBReadFrameNumberReg:=portw[USBIOSpace+6];
end;
function USBReadFrameBaseReg:longint;
begin
asm
mov dx,USBIOSpace
add dx,08h
db 66h; in ax,dx { in dx,eax }
db 66h; mov word ptr FrameListBase,ax { mov ..,eax }
end;
USBReadFrameBaseReg:=FrameListBase;
end;
function USBEnable:boolean;
var okay:boolean;
command:word;
begin
okay:=false;
if usbdetected and (USBIOspace<>0) then
if readPCIRegisterWord($4,USBBusNumber,USBFunctionNumber,command) then
begin
okay:=command and 5=5;
command:=command or 5;
if writePCIRegisterWord($4,USBBusNumber,USBFunctionNumber,command) then
okay:=true;
end;
USBenable:=okay;
end;
function USBGetInterruptNumber(Var IntNo:word;Var active:boolean):boolean;
var okay:boolean;
command:longint;
command2:longint;
begin
okay:=false;
active:=false;
if isadetected then
if readPCIRegisterDWord($60,ISABusNumber,ISAFunctionNumber,command) then
begin
intno:=command shr 24;
active:=intno and 128=0;
intno:=intno and 15;
okay:=true;
end;
USBGetInterruptNumber:=okay;
end;
function USBSetInterruptNumber(IntNo:word;active:boolean):boolean;
var okay:boolean;
command:byte;
command2:word;
dummy:word;
begin
okay:=false;
asm
cli
end;
if isadetected then
if readPCIRegisterByte($63,ISABusNumber,ISAFunctionNumber,command) then
begin
{ Redirect IRQD = Register 63h to ISA-BUS IRQ }
command:=IntNo+ord(not active)*128; { Set interrupt Number to MSB }
command2:=1 shl intno;
if command2>255 then
begin
dummy:=port[$4d1] and (not (command2 shr 8));
port[$4d1]:=port[$4d1] and (not (command2 shr 8));
end else
begin
dummy:=port[$4d0] and (not (command2 shr 8));
port[$4d0]:=port[$4d0] and (not (command2));
end;
dummy:=port[$21];
if writePCIRegisterByte($63,ISABusNumber,ISAFunctionNumber,command) then
begin
dummy:=port[$21];
{ Set Interrupt Sensitive Mode }
okay:=true;
end;
if intno>7 then
begin
asm
in al,0a1h
mov cl,byte ptr intno
sub cl,8
mov dl,1
shl dl,cl
not dl
and al,dl
out 0a1h,al
in al,021h
mov dl,2
not dl
and al,dl
out 021h,al
end;
end else
begin
asm
in al,021h
mov cl,byte ptr intno
mov dl,1
shl dl,cl
not dl
and al,dl
out 021h,al
end;
end;
end;
asm
sti
end;
USBSetInterruptNumber:=okay;
end;
function USBDisable:boolean;
var okay:boolean;
begin
okay:=false;
if usbdetected and (USBIOspace<>0) then
if WritePCIRegisterWord($4,USBBusNumber,USBFunctionNumber,0) then
begin
okay:=true;
end;
USBDisable:=okay;
end;
procedure usbclearframelist;
var i:word;
begin
for i:=0 to 1023 do
FrameListPtr^[i]:= 1; { Set Terminate }
end;
function USBSetDeviceIOSpace(IOSpace:word):boolean;
var okay:boolean;
result:word;
setiospace:word;
begin
okay:=false;
IOSpace:=IOSpace ;
if writePCIRegisterWord($20,USBBusNumber,USBFunctionNumber,IOSpace) then
begin
okay:=true;
USBIOSpace:=IOSpace;
end;
USBSetDeviceIOSpace:=okay;
end;
function USBReadCommandReg:word;
begin
USBReadCommandReg:=portw[USBIOSpace];
end;
function USBReadStatusReg:word;
begin
USBReadStatusReg:=portw[USBIOSpace+2];
end;
function USBReadInterruptReg:word;
begin
USBReadInterruptReg:=portw[USBIOSpace+4];
end;
function USBReadPort0Reg:word;
begin
USBReadPort0Reg:=portw[USBIOSpace+16];
end;
procedure USBWritePort0Reg(value:word);
begin
portw[USBIOSpace+16]:=value;
end;
function USBReadPort1Reg:word;
begin
USBReadPort1Reg:=portw[USBIOSpace+18];
end;
procedure USBWritePort1Reg(value:word);
begin
portw[USBIOSpace+18]:=value;
end;
procedure USBWriteInterruptReg(value:word);
begin
portw[USBIOSpace+4]:=value;
end;
procedure USBWriteStatusReg(value:word);
begin
portw[USBIOSpace+2]:=value;
end;
procedure USBWriteCommandReg(value:word);
begin
portw[USBIOSpace]:=value;
end;
procedure USBWriteFrameNumberReg(value:word);
begin
portw[USBIOSpace+6]:=value;
end;
function USBdetect(Var DeviceID,VendorID:word;VAR BusNumber,FunctionNumber:Byte;var Description:string):boolean;
var i:byte;
error,found:boolean;
begin
BusNumber:=0;FunctionNumber:=0;
USBdetect:=false;
i:=0;
error:=false;
found:=false;
repeat { check different possible USB-PCI devices ... }
case i of
0: begin deviceId:=$7020;vendorId:=$8086; description:='Intel 82371SB USB controller'; end;
1: begin deviceId:=$7112;vendorId:=$8086; description:='Intel PIIX4 USB controller'; end;
2: begin deviceId:=$0571;vendorId:=$1106; description:='VIA AMD-645 USB controller'; end;
3: begin deviceId:=$A0F8;vendorID:=$1045; description:='Opti 82C750 (Vendetta) USB controller'; end;
4: begin deviceId:=$C861;vendorID:=$1045; description:='Opti 82C861/871 (Firelink/FireBlast) USB controller'; end;
end;
inc(i);
found:=detectPCIdevice(deviceId,vendorId,BusNumber,FunctionNumber);
error:=i>4;
until error or found;
USBdetect:=found;
end;
function ISAdetect(Var DeviceID,VendorID:word;VAR BusNumber,FunctionNumber:Byte;var Description:string):boolean;
var i:byte;
error,found:boolean;
begin
BusNumber:=0;FunctionNumber:=0;
ISAdetect:=false;
i:=0;
error:=false;
found:=false;
repeat { check different possible ISA-PCI devices ... }
case i of
0: begin deviceId:=$7000;vendorId:=$8086; description:='Intel 82371SB ISA-PCI controller'; end;
1: begin deviceId:=$7110;vendorId:=$8086; description:='Intel PIIX4 ISA-PCI controller'; end;
{ 2: begin deviceId:=$0571;vendorId:=$1106; description:='VIA AMD-645 USB controller'; end;
3: begin deviceId:=$A0F8;vendorID:=$1045; description:='Opti 82C750 (Vendetta) USB controller'; end;
4: begin deviceId:=$C861;vendorID:=$1045; description:='Opti 82C861/871 (Firelink/FireBlast) USB controller'; end; }
end;
inc(i);
found:=detectPCIdevice(deviceId,vendorId,BusNumber,FunctionNumber);
error:=i>2;
until error or found;
ISAdetect:=found;
end;
function USBGetDeviceIOSpace(var IOSpace:word):boolean;
var okay:boolean;
result:word;
setiospace:word;
begin
okay:=false;
if readPCIRegisterWord($20,USBBusNumber,USBFunctionNumber,result) then
begin
okay:=true;
IOSpace:=result and $FFFE;
USBIOSpace:=IOSpace;
end;
USBGetDeviceIOSpace:=okay;
end;