program HostAdap(input,output); {*** Copyright Notice: This source Code belongs to the book "The SCSI Bus and IDE Interface" from Addison-Wesley. It may be used, ported and modified for non-commercial purposes when this copyright notice is included. Authorisation from the publisher is necessary for commercial purposes. } uses CRT, DOS; const PNAM : string='Hostadapter Inquiry V1.0 rev 000e 18.7.94 (fs)'; {ASPI Specific Constants} ASPI_SRB_LENGHT = $7F; DATA_LENGTH = $FF; {Messages} ASPI_CONNECTED ='ASPI loaded'; ASPI_OPEN_ERROR ='Error opening ASPI'; type {Generic Types} MemAdress = record Offset: integer; Segment: integer; end; {ASPI-Types} SRBsize= 0..ASPI_SRB_LENGHT; SRBarray = array[SRBsize] of byte; BufferLength = 0..DATA_LENGTH; DataBufferType = array[BufferLength] of byte; var AspiEntryPoint: MemAdress; {**** Low Level Functions} function FileOpen(FileName:string):integer; const DOS_OPEN_FILE = $3D; var register: registers; begin FileName:=FileName+chr(0); with register do begin ax := DOS_OPEN_FILE shl 8; bx:=0; cx:=0; ds := seg(FileName); dx := ofs(FileName)+1; { because Pascal strings carry their length in byte 0 } end; MSDOS(register); if (register.flags and FCarry) > 0 then FileOpen:=-1 else FileOpen:=register.ax; end; function FileClose(FileHandle:integer):integer; const DOS_CLOSE_FILE = $3E; var register: registers; begin with register do begin ax := DOS_CLOSE_FILE shl 8; bx:=FileHandle; end; MSDOS(register); if (register.flags and FCarry) = 0 then FileClose:=0 else FileClose:=register.ax; end; {**** Miscellanous Generic Functions} {**** SCSI generic functions} function SCSICmdLen(Opcode: byte):byte; begin SCSICmdLen:=0; if Opcode and $E0 = $00 then SCSICmdLen:=6; if Opcode and $E0 = $20 then SCSICmdLen:=10; if Opcode and $E0 = $40 then SCSICmdLen:=10; if Opcode and $E0 = $A0 then SCSICmdLen:=12; end; {**** ASPI-specific functions} procedure GetASPIEntry(FileHandle:integer; var AspiEntry:MemAdress); const ASPI_ENTRY_LENGTH = 4; DOS_IOCTL_READ = $4402; var register: registers; begin with register do begin ax := DOS_IOCTL_READ; bx:=FileHandle; cx:=ASPI_ENTRY_LENGTH; ds := seg(AspiEntry); dx := ofs(AspiEntry); end; MSDOS(register); end; procedure SRBexecute(var SRB: SRBarray); var SRBsegment, SRBoffset: integer; begin SRBsegment:=seg(SRB); SRBoffset:=ofs(SRB); asm mov ax, SRBsegment push ax mov ax, SRBoffset push ax LEA BX, AspiEntryPoint call DWORD PTR [bx] add sp,4 end; end; function InitializeASPI(var AspiEntrypoint:MemAdress): boolean; const ASPI_NAME = 'SCSIMGR$'; var result: integer; AspiFileHandle: integer; begin AspiFileHandle:=FileOpen(ASPI_NAME); if AspiFileHandle>-1 then begin GetASPIEntry(AspiFileHandle,AspiEntryPoint); FileClose(AspiFileHandle); InitializeASPI:=true; end else InitializeASPI:=false; end; Procedure HostInquire; const SRB_COMMAND_CODE = $00; SRB_STATUS = $01; HA_SCSI_ID = $09; ENTRY_LENGTH = $10; MANAGER_NAME = $0A; HA_NAME = $1A; var k: integer; Status: byte; SRB: SRBarray; DataBuffer : DataBufferType; begin for k:=0 to high(SRB) do SRB[k]:=0; SRBexecute(SRB); repeat until SRB[SRB_STATUS]<>0; if SRB[SRB_STATUS] = 1 then begin writeln('SCSI-ID of the host adapter: ',SRB[HA_SCSI_ID]); write ('Name of the host adapter: '); for k:=0 to ENTRY_LENGTH-1 do write(char(SRB[HA_NAME+k])); writeln; end end; begin writeln(PNAM); if InitializeASPI(AspiEntryPoint) then begin writeln(ASPI_CONNECTED); HostInquire; end else writeln(ASPI_OPEN_ERROR); end.