home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Beijing Paradise BBS Backup
/
PARADISE.ISO
/
software
/
BBSDOORW
/
SHSUCD11.ZIP
/
CDROMS.ADB
< prev
next >
Wrap
Text File
|
1995-06-29
|
7KB
|
189 lines
--************************************************************************
--
-- CDROMS.ADB Version 3.0
--
--
-- A copyright-reserved, free use program.
-- (c)John H. McCoy, 1994, 1995, Sam Houston St. Univ., TX 77341-2206
--************************************************************************
with system;
with text_io; use text_io;
with memory, unchecked_conversion;
with tty;
package body CDRoms is
CDTbl : CDArrayAccess;
procedure GetCDStatus(Drive : integer;
DeviceStatus: out DEV_ReturnCodes;
CDStatus : out DW;
DriverName : out string16;
DriverUnit : out byte;
Label : out string11) is
rh : rhs;
dta : bytesAccess;
CB : CBAccess := new CBs;
begin
CB(1):= Ioctl_GetCDStatus;
Label := (" ");
rh := ( Length => 2+rhXs'size/8,
SubUnit => byte(Drive),
rhX => (DeviceIoctlInput,
(Status => DeviceError,
reserved => (others =>0),
MediaDesc => 0,
CBPtr => SA_to_DW(CB(1)'address),
TransferCount => word_to_W(5),
Start => word_to_W(0),
VolIdPtr => SA_to_DW(0) )) );
CDs.Call(rh);
delay(0.0);
DeviceStatus := rh.rhX.IoctlIn.status;
if rh.rhX.IoctlIn.status = DeviceDone then
CDStatus := CB(2..5);
if (CB(2) AND byte(1) ) = 0 then -- door closed
dta := new bytes(1..2048);
rh := (Length => 2+rhXs'size/8,
SubUnit => byte(Drive),
rhX => (DeviceReadLong,
(Status => DeviceError,
reserved => (others =>0),
AddressMode => 0,
DtaPtr => SA_to_DW(dta(1)'address),
SectorsToRead => word_to_W(1),
StartSector => Long_to_DW(16),
ReadMode => 0,
InterleaveSize => 0,
InterleaveSkip => 0,
filler => (0,0))));
CDs.Call(rh);
delay(0.0);
if rh.rhX.ReadLong.status = DeviceDone then
if dta(2..6) = string_to_bytes("CD001") then
CDTbl(Drive).Label:= bytes_to_string(dta(41..51));
Label := CDTbl(Drive).Label;
CDTbl(Drive).VolSize := dta(81..84);
elsif dta(10..14) = string_to_bytes("CDROM") then
CDTbl(Drive).Label:= bytes_to_string(dta(49..59));
Label := CDTbl(Drive).Label;
CDTbl(Drive).VolSize := dta(89..92);
else -- we don't know where label is, blank it
CDTbl(Drive).Label:= (others=>' ');
end if;
end if;
ZapBytes(dta);
DeviceStatus := rh.rhX.ReadLong.status;
end if;
end if;
ZapCBs(CB);
DriverName :=(others=>' ');
if CDTbl(Drive).EType = CD then
DriverName(1..8) := CDTbl(Drive).Driver.Name(1..8);
else
DriverName := CDTbl(Drive).File.Name(1..16);
end if;
DriverUnit := CDTbl(Drive).Unit;
end GetCDStatus;
task body CDRoms is
Stop : boolean := False;
LastCD : integer := -1;
pkt : pkts;
rh : rhs;
CB : CBAccess := new CBs;
procedure CallCDDriver (rh: in out rhs) is
CDIndex : integer;
begin
CDIndex := integer(rh.SubUnit);
if CDIndex > LastCD then
-- the following is a kludge
-- bytes 5 & 6 in rh are device return code(status) for all subcommands
pkt := Rhs_to_Pkts(rh); -- just convert dont't shift
pkt(5..6) := W(DeviceError OR DeviceDone OR DeviceUnknownUnit);
rh := Pkts_to_Rhs(pkt);
elsif (CDTbl(CDIndex).EType = IMG) then
case rh.rhX.command is
when DeviceReadLong =>
DIo.Set_Index(CDTbl(CDIndex).File.Img_F.all,
DIO.positive_count(DW_to_Long(rh.rhX.ReadLong.StartSector)));
declare
dtaPtr : DW :=rh.rhX.ReadLong.dtaPtr;
begin
for i in 1..W_to_Word(rh.rhX.ReadLong.SectorsToRead) loop
if DIO.End_of_File(CDTbl(CDIndex).File.Img_F.all) then
rh.rhX.ReadLong.SectorsToRead := Word_to_W(i-1);
exit;
end if;
DIO.Read(CDTbl(CDIndex).File.Img_F.all,
DW_to_SectorsAccess(dtaPtr).all);
dtaPtr := Long_to_DW(DW_to_Long(dtaPtr)+long_integer(Sectors'last));
end loop;
end;
rh.rhX.ReadLong.Status := DeviceDone;
when DeviceIoctlInput =>
CB := DW_to_CBAccess(rh.rhX.IoctlIn.CBPtr);
case CB(1) is
when Ioctl_ReadDriveBytes => rh.rhX.IoctlIn.Status := DeviceDone;
when Ioctl_GetCDStatus => CB.all(2..5):= CDTbl(CDIndex).Status;
rh.rhX.IoctlIn.Status := DeviceDone;
when Ioctl_RetSectorSize => CB.all(2) := 0;
CB.all(3..4):= Word_to_W(2048);
rh.rhX.IoctlIn.Status := DeviceDone;
when Ioctl_RetVolSize => CB.all(2..5):= CDTbl(CDIndex).VolSize;
rh.rhX.IoctlIn.Status := DeviceDone;
when Ioctl_MediaChanged => CB.all(2):= 1;
rh.rhX.IoctlIn.Status := DeviceDone;
when others => rh.rhX.IoctlIn.Status := DeviceDone OR
DeviceUnknownCommand OR
DeviceError;
end case;
when DeviceIoctlOutput =>
rh.rhX.IoctlOut.Status := DeviceDone;
when DeviceReadLongPrefetch =>
rh.rhX.ReadLong.Status := DeviceDone;
when DeviceSeek =>
rh.rhX.Seek.Status := DeviceDone;
when Others => rh.rhX.Other.Status := DeviceDone OR
DeviceUnknownCommand OR
DeviceError;
end case;
else
rh.SubUnit := CDTbl(CDIndex).Unit;
pkt := Rhs_to_Pkts(rh);
pkt(3..pkts'last-1) := pkt(4..pkts'last);
CallDriver (rh => pkt(1)'address,
DeviceStrategy => CDTbl(CDIndex).Driver.Strategy,
DeviceInterrupt => CDTbl(CDIndex).Driver.Interrupt);
pkt(4..pkts'last) := pkt(3..pkts'last-1);
pkt(3) := 0;
rh := Pkts_to_Rhs(pkt);
rh.SubUnit := byte(CDIndex);
end if;
end CallCDDriver;
pragma inline(CallCDDriver);
begin
accept SetUp(pCDTbl: CDArrayAccess ) do
CDTbl := pCDTbl;
LastCd := CDTbl.all'last;
end SetUp;
loop
select
accept Call (rh: in out rhs) do
CallCDDriver(rh);
end Call;
or
accept ShutDown do
Stop := True;
end ShutDown;
end select;
exit when Stop;
end loop;
end CDRoms;
end CDRoms;