Skip to content

Instantly share code, notes, and snippets.

@learosema
Last active August 31, 2020 12:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save learosema/94de225420fd71f16a0442ef9bc163e0 to your computer and use it in GitHub Desktop.
Save learosema/94de225420fd71f16a0442ef9bc163e0 to your computer and use it in GitHub Desktop.
uses crt,playcd;
var cd:record
danz,drive:word;
mintrk,maxtrk,anztrk:byte;
traks:array[0..63] of longint;
len:array[0..63] of longint;
ttyp:array[0..63] of byte;
end;
i:integer; m,s:byte;
zeit:longint;
c:char;
function InitCD:byte;
var status:longint;
l:longint; i:integer;
begin
cd.danz:=DriveAnz(cd.drive);
if cd.danz=0 then
begin
InitCd:=1; {MSCDEX nicht installiert}
exit;
end;
status:=DeviceState(cd.drive) and $a11;
if status<>$210 then begin Initcd:=2; exit; end; {CD-Fehler ignorieren !}
GetCDInfo(cd.drive,cd.mintrk,cd.maxtrk,l);
l:=RedBook2HSG(cd.drive,l);
cd.anztrk:=cd.maxtrk-cd.mintrk+1;
for i:=cd.mintrk to cd.maxtrk do
begin
cd.traks[i]:=Track2Sector(cd.drive,i);
cd.ttyp[i]:=tracktype;
cd.traks[i]:=Redbook2HSG(cd.drive,cd.traks[i]);
end;
if cd.mintrk=1 then cd.traks[1]:=0;
for i:=cd.mintrk to cd.maxtrk do
begin
if i=cd.maxtrk then cd.len[i]:=GetVolSize(cd.drive)-cd.traks[i] else
cd.len[i]:=cd.traks[i+1]-cd.traks[i];
end;
c:=readkey;
{ cd.drive:=4;}
end;
function bin(a:word):string;
var s:string; i:longint;
begin
s:='';
for i:=0 to 15 do if (a and (1 shl i))<>0 then s:=s+'1' else
s:=s+'0';
bin:=s;
end;
procedure DriveInfo(drive:word);
{ devstat_DoorOpen EQU 0001h ; TÅr offen ?
devstat_DoorNotBolted EQU 0002h ; TÅr nicht verriegelt ?
devstat_ReadAndWrite EQU 0008h ; Schreiben mîglich ?
devstat_DataAudioVideo EQU 0010h ; Audio-CD ?
devstat_AudioManipulation EQU 0100h ; Audiomanipulation ?
devstat_HSGAndRedBook EQU 0200h ; RedBook-Modus erlaubt ?
devstat_NoCDInDrive EQU 0800h ; Keine CD im Laufwerk ?}
const stat0:array[0..6] of string=('door open',
'door not bolted',
'cd-writer',
'audioplay possible','audiomanipulation',
'redbook possible','no cd in drive');
stat1:array[0..6] of string=('door closed','door bolted','read only',
'data cd in drive','no audiomanipulation',
'HSG mode only','cd in drive');
stat2:array[0..6] of longint=(1,2,8,$10,$100,$200,$800);
var status:longint; i:integer;
begin
writeln('drive letter : ',chr(65+drive));
status:=DeviceState(drive);
for i:=0 to 6 do if (status and stat2[i])<>0 then writeln(stat0[i]) else
writeln(stat1[i]);
end;
begin
clrscr;
cd.danz:=DriveAnz(cd.drive);
{ cd.drive:=3;}
zeit:=DeviceState(cd.drive);
writeln('Device State :',bin(hi(zeit)),' ',bin(lo(zeit)));
DriveInfo(cd.drive);
c:=readkey;
i:=initcd; i:=0;
case i of
1 : begin
writeln('MSCDEX not installed !!!');
halt;
end;
2 : begin
writeln('Keine CD eingelegt !');
halt;
end;
end;
writeln;
writeln('Tracks:');
for i:=cd.mintrk to cd.maxtrk do
begin
Sect2Time(cd.len[i],m,s);
writeln(i:3,' - ',cd.len[i]:9,' Sektoren',' - Offset ',cd.traks[i]:9,' ',m:2,':',s:2,' Typ:',cd.ttyp[i]);
end;
i:=cd.mintrk;
CDPlay(cd.drive,0,cd.traks[i],cd.len[i]);
zeit:=Sect2PCTimer(cd.len[i]);
Repeat
if (GetTimer>=zeit)or(keypressed) then
begin
c:=readkey;
i:=i+1;
if i<=cd.maxtrk then
begin
CDPlay(cd.drive,0,cd.traks[i],cd.len[i]);
zeit:=Sect2PCTimer(cd.len[i]);
end;
end;
until i>cd.maxtrk;
CDStop(cd.drive);
end.
Unit PlayCD;
INTERFACE
const HSGmode=0;
Redbook=1;
type CDRH=record
Len : byte; {= 13+ (max.128)}
SubUnit : byte;
CmdCode : byte;
Status : word;
Reserved : array[0..7] of byte;
daten : array[0..63] of byte;
IOCtlData: array[0..63] of byte;
end;
cd_info=RECORD {fÅr GetMoreInfo...}
f0:byte;
Track:byte;
Index:byte;
tMin:byte; {Min. in bezug auf den akt. Track}
tSec:byte; {Sec. in bezug auf den akt. Track}
f1:word;
Min:byte;
Sek:byte;
f2:byte;
END;
var tracktype:byte;
procedure ClearHeader(var p:CDRH);
function DriveAnz(var nr:word):word;
{Ausgabe in nr: Buchstabe des 1. CD-Laufwerks (0=A,1=B,2=C,3=D,...) }
function CDVer:word;
function CheckDrive(nr:word):boolean;
function GetCDPos(nr:word;mode:byte):longint;
function GetVolSize(nr:word):longint;
function DeviceState(nr:word):longint;
function Track2Sector(nr:word;track:byte):longint; {redbook only}
function Time2Sector(min,sec:byte):longint; {HSG only}
function HSG2Redbook(nr:word;l:longint):longint;
function Redbook2HSG(nr:word;l:longint):longint;
function Sect2PCTimer(s:longint):longint;
function GetTimer:longint;
procedure CDCall(nr:word;var p:cdrh);
procedure CDPlay(nr:word;mode:byte;Start,len:longint);
procedure CDStop(nr:word);
procedure CDResume(nr:word);
procedure CDSeek(nr:word;mode:byte;start:longint);
procedure IOCTLInput(var p:cdrh;nr:word;bufsize:word);
procedure GetCDInfo(Nr:word;Var min,max:byte;var l:longint);
procedure ResetDrive(Nr:word);
procedure GetMoreInfo(nr:word;var i:cd_info);
procedure Sect2Time(s:longint;var min,sec:byte); {HSG only}
IMPLEMENTATION
function CDVer:word; { MACRO ;; Out: Version Hi.Lo}
var v:word;
begin
asm
push ax
mov ax,150ch
int 2fh
mov v,bx
pop ax
end;
CDVer:=v;
end;
function DriveAnz(var nr:word):word; {nr: 1. Laufwerk}
var anz,n:word;
begin
asm
mov ax,1500h
xor bx,bx
int 2Fh
mov anz,bx
mov n,cx
end;
nr:=n;
driveanz:=anz;
end;
procedure ClearHeader(var p:CDRH);
begin
fillchar(p,sizeof(p),0);
end;
procedure CDCall(nr:word;var p:cdrh);
var s,o:word;
begin
s:=seg(p);
o:=ofs(p);
asm
push es
mov ax,1510h
mov cx,nr
mov bx,s
mov es,bx
mov BX,o
int 2fh
pop es
end;
end;
function CheckDrive(nr:word):boolean;{ OUT: Carry is set if any errors...}
var a,b:word;
begin
asm
mov ax,150bh
mov cx,nr
int 2fh
mov a,ax;
mov b,bx;
end;
CheckDrive:=not((a=0)and(b=$ADAD));
end;
procedure CDPlay(nr:word;mode:byte;Start,len:longint);
var p:cdrh;
begin
p.len:=22;
p.cmdcode:=132;
p.daten[0]:=mode;
move(Start,p.daten[1],4);
move(len,p.daten[5],4);
CDCall(nr,p);
end;
procedure CDStop(nr:word);
var p:cdrh;
begin
p.len:=13;
p.cmdcode:=133;
CDCall(nr,p);
end;
procedure CDResume(nr:word);
var p:cdrh;
begin
p.len:=13;
p.cmdcode:=136;
CDCall(nr,p);
end;
procedure CDSeek(nr:word;mode:byte;start:longint);
var p:cdrh;
begin
p.len:=24;
p.cmdcode:=131;
p.daten[0]:=mode;
fillchar(p.daten[1],6,0);
move(start,p.daten[7],4);
CDCall(nr,p);
end;
procedure IOCTLInput(var p:cdrh;nr:word;bufsize:word);
var s,o:word;
begin
p.len:=26;
p.cmdcode:=3;
s:=seg(p.ioctldata);
o:=ofs(p.ioctldata);
move(o,p.daten[1],2);
move(s,p.daten[3],2);
move(bufsize,p.daten[5],2);
CDCall(nr,p);
end;
Function GetCDPos(nr:word;mode:byte):longint;
var l:longint;
p:cdrh;
begin
fillchar(p.ioctldata,64,0);
p.ioctldata[0]:=1;
p.ioctldata[1]:=mode;
fillchar(p.ioctldata[2],4,0);
IOCTLInput(p,nr,6);
move(p.ioctldata[2],l,4);
GetCDPos:=l;
end;
procedure GetCDInfo(Nr:word;Var min,max:byte;var l:longint);
{l:last sector , min=1st track, max=last track}
var p:cdrh;
begin
p.ioctldata[0]:=10;
IoCtlInput(p,nr,7);
min:=p.ioctldata[1];
max:=p.ioctldata[2];
move(p.ioctldata[3],l,4);
end;
function GetVolSize(nr:word):longint;
var p:cdrh; l:longint;
begin
p.ioctldata[0]:=8;
fillchar(p.ioctldata[1],4,0);
IOCTLInput(p,nr,5);
move(p.ioctldata[1],l,4);
GetVolSize:=l;
end;
procedure ResetDrive(Nr:word);
var p:cdrh;
begin
p.ioctldata[0]:=2;
IoCtlInput(p,nr,1);
end;
function DeviceState(nr:word):longint;
var p:cdrh; l:longint;
begin
p.ioctldata[0]:=6;
fillchar(p.ioctldata[1],4,0);
IOCTLInput(p,nr,5);
move(p.ioctldata[1],l,4);
DeviceState:=l;
end;
procedure GetMoreInfo(nr:word;var i:cd_info);
var p:cdrh;
begin
p.ioctldata[0]:=12;
IoctlInput(p,nr,11);
move(p.ioctldata[1],i,sizeof(cd_info));
end;
function Track2Sector(nr:word;track:byte):longint;
{ Out: Sektor (redbook) }
var p:cdrh; l:longint;
begin
p.ioctldata[0]:=11;
p.ioctldata[1]:=track;
IoctlInput(p,nr,7);
move(p.ioctldata[2],l,4);
{p.ioctldata[6] - 1 Byte - weitere TrackInfo - noch unbekannt...}
Track2Sector:=l;
Tracktype:=p.ioctldata[6];
end;
function Time2Sector(min,sec:byte):longint;
{HSG mode only - ein HSG-Sektor = 1/75 Sekunde }
begin
Time2Sector:=longint((min*60+sec)*75);
end;
procedure Sect2Time(s:longint;var min,sec:byte);
begin
min:=byte(trunc(s/75) div 60);
sec:=byte(trunc(s/76) mod 60);
end;
function Redbook2HSG(nr:word;l:longint):longint;
begin
CDSeek(nr,redbook,l);
RedBook2HSG:=GetCDPos(nr,HSGmode);
end;
function HSG2Redbook(nr:word;l:longint):longint;
begin
CDSeek(nr,HSGmode,l);
HSG2RedBook:=GetCDPos(nr,Redbook);
end;
function Sect2PCTimer(s:longint):longint;
begin
Sect2PCTimer:=memw[Seg0040:$6c]+(memw[Seg0040:$6e] shl 16)+trunc(s/75*18.2)+1;
end;
function GetTimer:longint;
begin
GetTimer:=memw[Seg0040:$6c]+(memw[Seg0040:$6e] shl 16);
end;
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment