/* CD.DEVICE TEST (DATA) */

/**************************************************************************
 *                                                                        *
 * This script has been written to test the cd.device on the Amiga CD-32  *
 *                                                                        *
 * Its purpose is to test the cd.device as it relates to reading data.    *
 *  Please use Audio.cd to test audio related commands.                   *
 *                                                                        *
 * Author:  Michael McLaughlin (mikemc@hydrogen)  [Drexel Co-op student]  *
 *                                                                        *
 **************************************************************************/

/* Constants */
framesPerSec = 75   /* Frames per second */

Address CD.1           /* Reference to cd.device test program */
OPTIONS RESULTS        /* Allow results */

say
INFO initial                    /* Makes sure this doesn't run w/o a disk */
if initial.Spin = 0 then do;
  say 'Please insert disk before beginning the CD.DEVICE test.'
  say
  exit
end;

/* NOTE:  Use the FILEPOS on floppy disk, NOT the CD.

The one that returns File CD0:PATTERN/OFFSET at block 3526 ($00000DC6)
 is the wrong one.  It has been updated to return only the numeric value  */

Address command 'rxset' 'value' '`SYS:TEST/CD.DEVICE/FILEPOS CDTest3b:Tests/PATTERN/OFFSET`'
/* Address command 'rxset' 'value' '`DF0:FILEPOS CDTest3b:Tests/PATTERN/OFFSET`' */
offSet = strip(GetClip('value'))
offSet = offSet * 512                          /* Convert blocks to bytes */

Address CD.1

say

/**************************************************************************/

say 'Enter the Read test? (y n a q ?)'
pull goOn
if goOn = ? then do;
  say
  say ' y = Yes'
  say ' n = No'
  say ' a = All tests'
  say ' q = Quit this script'
  say
  pull goOn
end;
if ~((goOn ~= Y) | (goOn = Q)) | (goOn = A) then do;

/* Read */
say
say '-- Read test --'
say

say 'Reading and verifying 2048 bytes of data.'
READ offSet (2 * 1024) OV START 0                 /* Read and verify data */

say 'Reading and verifying 32 KB of data.'
READ offSet (32 * 1024) OV START 0

say 'Reading and verifying 512 KB of data.'
READ offSet (512 * 1024) OV START 0

say 'Reading and verifying 2 bytes of data.'
READ offSet 2 OV START 0

say 'Reading and verifying 2046 bytes of data.'
READ offSet 2046 OV START 0

say 'Reading and verifying 2050 bytes of data.'
READ offSet 2050 OV START 0

say 'Reading and verifying the entire 16 MB file in 512 KB chunks.'
tOffSet = offSet
do i = 1 to ((16 * 1024 * 1024) % (512 * 1024))
  READ tOffSet (512 * 1024) OV START 0         /* Read 512K block of data */
  tOffSet = tOffSet + (512 * 1024)        /* Advance starting pos by 512K */
end
say

end;

/**************************************************************************/

if (goOn ~= Q) & (goOn ~= A) then do
  say 'Enter the Read Speed test? (y n q)'
  pull goOn
end
if ~((goOn ~= Y) | (goOn = Q)) | (goOn = A) then do;

/* Read Speed */
say
say '-- Read Speed test --'
say

INFO thisDisk
currFPS = thisDisk.ReadSpeed                  /* Stores current readspeed */
call rSpeed                              /* Outputs the current readspeed */

say 'Changing data read speed to 150 Frames/Sec.'
CONFIG READSPEED 150               /* Changes ReadSpeed to 150 Frames/Sec */
call rSpeed

say 'Reading and verifying 512 KB of data.'
READ offSet (512 * 1024) OV START 0

say
say 'Changing data read speed back to the original' currFPS 'Frames/Sec.'
CONFIG READSPEED currFPS
call rSpeed

say 'Reading and verifying 512 KB of data.'
READ offSet (512 * 1024) OV START 0
say

end;

/**************************************************************************/

if (goOn ~= Q) & (goOn ~= A) then do
  say 'Enter the Drive Geometry test? (y n q)'
  pull goOn
end
if ~((goOn ~= Y) | (goOn = Q)) | (goOn = A) then do;

/* Drive Geometry */
say
say '-- Drive Geometry test --'
say

GETGEOMETRY thisDisk

say 'Sector size         ' thisDisk.SectorSize 'bytes'
say 'Total sectors       ' thisDisk.TotalSectors
say 'Cylinder count      ' thisDisk.Cylinders
say 'Sectors per Cylinder' thisDisk.CylSectors
say 'Head count          ' thisDisk.Heads
say 'Sectors per track   ' thisDisk.TrackSectors
say 'Buffer memory type  ' thisDisk.BufMemType
say 'Device type code    ' thisDisk.DeviceType
say

if thisDisk.Removable = 0 then say 'This disk is non-removable.'
  else say 'This disk is removable.'
say

end;

/**************************************************************************/

if (goOn ~= Q) & (goOn ~= A) then do
  say 'Enter the CD-ROM Recognition test? (y n q)'
  pull goOn
end
if ~((goOn ~= Y) | (goOn = Q)) | (goOn = A) then do;

/* CD-ROM Recognition */
say
say '-- CD-ROM Recognition test --'
say

INFO thisDisk                    /* Verify that a CD-ROM disc is inserted */
if thisDisk.CDROM = 0 then do
  say 'Please insert a CD-ROM disc for this test. (CR to cont.)'
  call diskSwap                  /* Calls procedure to provoke a diskswap */
end

call dInfo                              /* Reports disc/drive information */

say 'Please insert a mixed-mode disc (CD-DA and CD-ROM). (CR to cont.)'
call diskSwap

call dInfo

say 'Please insert a digital audio disc (CD-DA). (CR to cont.)'
call diskSwap

call dInfo

say 'Please re-insert the CD-ROM disc for future tests. (CR to cont.)'
call diskSwap
say

end;

/**************************************************************************/

if (goOn ~= Q) & (goOn ~= A) then do
  say 'Enter the Protection Status test? (y n q)'
  pull goOn
end
if ~((goOn ~= Y) | (goOn = Q)) | (goOn = A) then do;

/* Protection Status */
say
say '-- Protection Status test --'
say

if PROSTATUS = 0 then say 'Disc is indeed writable.'
  else say 'Disc is write-protected.'
say

if (goOn = A) then call delay(3)  /* Allows disc to be recognized for the */
say                               /* next test in the "All-Tests" status  */

end;

/**************************************************************************/

if (goOn ~= Q) & (goOn ~= A) then do
  say 'Enter the Audio Commands during I/O test? (y n q)'
  pull goOn
end
if ~((goOn ~= Y) | (goOn = Q)) | (goOn = A) then do;

/* Audio commands during I/O */
say
say '-- Audio commands during I/O test --'
say

/*
say 'Please insert the mixed-mode disc (CD-DA and CD-ROM). (CR to cont.)'
call diskSwap
*/

TOCLSN lTOC 100 0            /* Pulls the Table of Contents in LSN format */

Address command 'run rx DataPlay.rexx' offSet
Address CD.1

call delay(5)                                  /* Delay until read begins */
say

say 'Attempting to attenuate.'
ATTENUATE 375 0                            /* Effectively mutes the audio */
ATTENUATE 0 32767                          /* Bring back to "full volume" */

segTime = 20 * framesPerSec

say 'Attempting to play' (segTime % framesPerSec) 'second segment of disc.'
PLAYLSN lTOC.7.Position segTime

say 'Attempting to enter fast-forward mode.'
SEARCH FFWD                        /* Attempts to engage in Fast-FWD mode */

say 'Attempting to enter fast-reverse mode.'
SEARCH FREV                        /* Attempts to engage in Fast-REV mode */

say 'Attempting to return to normal speed mode.'
SEARCH NORMAL                 /* Attempts to re-engage in the normal mode */

say 'Attempting to pause disc play for 5 seconds.'
PAUSE ON                              /* Attempts to engage pause feature */
call delay(5)
PAUSE OFF                         /* Attempts to dis-engage pause feature */

say 'Attempting to kill motor for 5 seconds.'
MOTOR OFF                             /* Attempts to dis-engage the motor */
call delay(5)
MOTOR ON                               /* Attempts to re-engage the motor */
call delay(2)

segTime = 30 * framesPerSec

pTrack = random(3, lTOC.Summary.LastTrack, right(time('S'),2))
say 'Attempting to play 30 sec. segment of randomly selected track' pTrack
PLAYLSN lTOC.pTrack.Position segTime
PLAYTRACK pTrack 1
say

end;

/**************************************************************************/

if (goOn ~= Q) & (goOn ~= A) then do
  say 'Enter the TOC test? (y n q)'
  pull goOn
end
if ~((goOn ~= Y) | (goOn = Q)) | (goOn = A) then do;

say
INFO thisDisk
if thisDisk.CDROM = 0 then say 'This is not a CD-ROM disc.'
  else say 'This is a CD-ROM disc.'

/* LSN TOC */
say
say '-- LSN TOC test --'
say

TOCLSN lTOC 100 0                                /* Read TOC with summary */

say                                                        /* Display TOC */
say 'Summary:  FirstTrack= ' lTOC.Summary.FirstTrack
say '          LastTrack=  ' lTOC.Summary.LastTrack
say '          LeadOut=    ' lTOC.Summary.LeadOut
say

say 'Track No.  Track Pos.  Control Byte'
say '---------  ----------  ------------'

do trck = 1 to lTOC.Summary.LastTrack
  say center(lTOC.trck.Track,9) right(lTOC.trck.Position,9) right(lTOC.trck.CtlAdr,9)
  master.trck.Track = lTOC.trck.Track
  master.trck.Position = lTOC.trck.Position
  mAster.trck.CtlAdr = lTOC.trck.CtlAdr
end

/* MSF TOC */
say
say
say '-- MSF TOC test --'
say

TOCMSF mTOC 100 0                                /* Read TOC with summary */

msfEOD = toMSFform(mTOC.Summary.LeadOut.Minute, mTOC.Summary.LeadOut.Second, mTOC.Summary.LeadOut.Frame)

say                                                        /* Display TOC */
say 'Summary:  FirstTrack= ' mTOC.Summary.FirstTrack
say '          LastTrack=  ' mTOC.Summary.LastTrack
say '          LeadOut=    ' msfEOD
say

say 'Track No.  Track Pos.  Control Byte'
say '---------  ----------  ------------'

do trck = 1 to mTOC.Summary.LastTrack
  potion = toMSFform(mTOC.trck.Position.Minute, mTOC.trck.Position.Second, mTOC.trck.Position.Frame)
  mCopy.trck.Track = mTOC.trck.Track
  mCopy.trck.Position = potion
  mCopy.trck.CtlAdr = mTOC.trck.CtlAdr
  say center(mTOC.trck.Track,9) center(potion,12) center(mTOC.trck.CtlAdr,12)
end

/**************************************************************************/

/* LSN and MSF Comparisons */

say
say
say 'Differences between the LSN and the MSF specifications (LSN format):'
say

say 'Track No.  LSN Track Pos.  MSF Track Pos.  LSN Ctrl Byte  MSF Ctrl Byte'
say '---------  --------------  --------------  -------------  -------------'
do trck = 1 to mTOC.Summary.LastTrack
  mPos = msf2sec(mCopy.trck.Position) * 75
  mPos = trunc(mPos - (msf2sec(mCopy.1.Position) * 75))
  lPos = master.trck.Position
  say center(trck,9) right(lPos,11) right(mPos,15) right(master.trck.CtlAdr,12) right(mCopy.trck.CtlAdr,14)
end


/* Comparison between Master TOC and individual TOC */

say
say
say '-- Summary Verification --'
say
do trck = 1 to 99 while substr(master.trck.Track,1,1) ~= 'M'
end
tracks = trck - 1
if tracks ~= 1 then say 'There are' tracks 'tracks on this disk.'
  else say 'There is 1 track on this disk.'
if tracks = lTOC.Summary.LastTrack then say 'This agrees with the summary data.'
  else say 'The summary and the actual track information are in conflict!'
say

end;

QUIT        /* Quits from CDTEST */
exit        /* Exit from script */

/***** FUNCTIONS **********************************************************/

diskSwap: procedure                   /* Provoke a diskswap from the user */
  MOTOR OFF
  pull answ
/* if answ = 'ON' then MOTOR ON */
  INFO thisDisk
  if thisDisk.Spin = 0 then do;
    call delay(4.5)
    INFO thisDisk
  end
  do while thisDisk.Spin = 0
    say 'Disk must be spinning to continue.'
    say 'Please engage the disc player. (CR to cont.)'
    pull answ
 /* if answ = 'ON' then MOTOR ON */
    INFO thisDisk
    if thisDisk.Spin = 0 then do;
      call delay(4.5)
      INFO thisDisk
    end
    say
  end;
return

rSpeed: procedure                           /* Outputs current read speed */
  INFO thisDisk
  kps = thisDisk.ReadSpeed * 2048
  say 'Read speed is' thisDisk.ReadSpeed 'frames per second ('kps' KB/sec.)'
  say
return

dInfo: procedure                        /* Outputs disc/drive information */
  call delay(2)
  INFO thisDisk
  say 'Play speed      ' thisDisk.PlaySpeed
  say 'Read speed      ' thisDisk.ReadSpeed
  say 'CD-XL read speed' thisDisk.ReadXLSpeed
  say 'Sector size     ' thisDisk.SectorSize 'bytes'
  say 'Max drive speed ' thisDisk.MaxSpeed
  if thisDisk.Spin = 0 then say 'Disk is not spinning.'
    else say 'Disk is spinning.'
  if thisDisk.CDROM = 0 then say 'This is not a CD-ROM disc.'
    else say 'This is a CD-ROM disc.'
  say
  call delay(1)
return

delay: procedure                 /* Pauses for a specified no. of seconds */
arg timeindex
/* say 'Beginning' timeindex 'second delay. <data.cd>' */
  call time 'R'
  do until time('E') >= timeindex
  end
return

formt:                                         /* Formats 2-digit numbers */
arg oldnum
if oldnum <= 9 then newnum = '0'||oldnum
  else newnum = oldnum
return newnum

msf2sec:                                /* Converts MSF format to seconds */
arg msfForm
  min = substr(msfForm,1,2)
  sec = substr(msfForm,4,2)
  frm = substr(msfForm,7,2)
  totsec = (min * 60) + sec + frm / 75
return totsec

toMSFform:                       /* Converts mm, ss, and ff into mm:ss:ff */
arg min, sec, frm
  combo = formt(min) || ':' || formt(sec) || ':' || formt(frm)
return combo

trunc:            /* Deletes decimal point and numbers to the right of it */
arg oldnum
  key = index(oldnum||'.', '.')
  newnum = delstr(oldnum, key)
return newnum
