DECLARE SUB LoadDirectory ()
DECLARE SUB RefreshVariables ()
DECLARE SUB PrintTemplate ()
DECLARE SUB ShuffleSongs ()
DECLARE SUB TextOutput (textOut$)
DECLARE SUB LoadPlayList (fileName AS STRING)
DECLARE SUB SonyPlayNextTrack ()
DECLARE SUB ProcessKeyPress ()
DECLARE SUB SetAlarm ()
DECLARE SUB SonyJogUp (numberOfDiscs!)
DECLARE SUB SonyJogDown (numberOfDiscs!)
DECLARE SUB SonyGodisc (nextDisc!)
DECLARE SUB SonyInitialize ()
DECLARE SUB SonyHold (button!)
DECLARE SUB SonyGotrack (track!)
DECLARE SUB SonyEntertrack (discToEnter!, trackToEnter!)
DECLARE SUB SonyPress (button!)
DECLARE SUB SonyWaitfor (delay!)

REM **** Variables for determining disc position ****
COMMON SHARED currentDisc AS INTEGER, totalDiscs AS INTEGER

REM **** Delay declarations ****
COMMON SHARED jogDelay AS INTEGER
COMMON SHARED pressDelay AS INTEGER
COMMON SHARED holdDelay AS INTEGER

REM **** Key name declarations ****
COMMON SHARED jog1 AS INTEGER, jog2 AS INTEGER, jog12 AS INTEGER
COMMON SHARED release AS INTEGER
COMMON SHARED program AS INTEGER
COMMON SHARED clearr AS INTEGER
COMMON SHARED trackUp AS INTEGER
COMMON SHARED trackDown AS INTEGER
COMMON SHARED playy AS INTEGER
COMMON SHARED stopp AS INTEGER
COMMON SHARED enter AS INTEGER
COMMON SHARED continue AS INTEGER
COMMON SHARED block1 AS INTEGER
COMMON SHARED block2 AS INTEGER

REM **** Filename, file pointer, & other related declarations ****
COMMON SHARED dataFilePath AS STRING
COMMON SHARED tempFilePath AS STRING
COMMON SHARED dbaseFileName AS STRING
COMMON SHARED songPointer AS INTEGER
COMMON SHARED selectedFile AS STRING
COMMON SHARED selectedFilePointer AS INTEGER
COMMON SHARED alarmListFile AS STRING
COMMON SHARED playListFile AS STRING
COMMON SHARED playListTempFile AS STRING
COMMON SHARED dirTempFile AS STRING
TYPE songRecord
        discNum AS INTEGER
        trackNum AS INTEGER
END TYPE
DIM SHARED song AS songRecord

REM **** Misc variable declarations ****
COMMON SHARED keyPress AS STRING
COMMON SHARED port AS INTEGER
COMMON SHARED quit AS INTEGER
COMMON SHARED playingTracks AS INTEGER
COMMON SHARED continuousMode AS INTEGER
COMMON SHARED shuffleMode AS INTEGER
COMMON SHARED getUpTime AS LONG, alarmIsRinging AS INTEGER, alarmEnabled AS INTEGER
COMMON SHARED false AS INTEGER, true AS INTEGER

REM **** Delay assignments ****
jogDelay = 15
pressDelay = 55
holdDelay = 3800

REM **** Key assignments ****
jog1 = 88
jog2 = 132
jog12 = 28
release = 192
program = 80
clearr = 130
trackUp = 134
trackDown = 129
playy = 133
stopp = 128
enter = 120
continue = 64
block1 = 72
block2 = 112

REM **** Filename variable assignments ****
dataFilePath = "c:\cd\ply\"
tempFilePath = "c:\cd\"
dbaseFileName = "cd"
alarmListFile = "upbeat"
playListFile = "mar02"
playListTempFile = "playlist"
dirTempFile = "dir"

REM **** Misc. assignments ****
port = &H378 '<-- This is the address for lpt1:
totalDiscs = 114
true = -1
false = 0

CLS
OPEN tempFilePath + playListTempFile + ".tmp" FOR RANDOM AS #2 LEN = 4
OPEN tempFilePath + dirTempFile + ".tmp" FOR RANDOM AS #3
LoadDirectory
SCREEN 11
selectedFilePointer = 1
PrintTemplate
LoadPlayList (playListFile)
songPointer = 1
alarmIsRinging = false
continuousMode = false
shuffleMode = true
quit = false
playingTracks = false
RefreshVariables
SonyInitialize
DO WHILE quit = false
       
        REM check to see if track has ended:
        IF (NOT ((INP(port + 1) AND 16) = 16)) AND (playingTracks = true) THEN
                SonyPlayNextTrack
                RefreshVariables
        END IF

        REM check to see if alarm has gone off:
        IF alarmEnabled AND (TIMER < (getUpTime + 60)) AND (TIMER > getUpTime) AND (NOT alarmIsRinging) THEN
                alarmIsRinging = true
                playingTracks = true
                TextOutput "alarm is ringing, getting alarm playlist..."
                LoadPlayList (alarmListFile)
                SonyInitialize
                RefreshVariables
        END IF

        REM check to see if key has been pressed:
        keyPress = INKEY$
        IF keyPress <> "" THEN
                ProcessKeyPress
                RefreshVariables
        END IF

LOOP
CLOSE
END

SUB LoadDirectory
        CLOSE #3
        KILL tempFilePath + dirTempFile + ".tmp"
        OPEN tempFilePath + dirTempFile + ".tmp" FOR RANDOM AS #3 LEN = 10
        SHELL "dir " + dataFilePath + "*.ply >" + tempFilePath + "dir.txt"
        OPEN tempFilePath + "dir.txt" FOR INPUT AS #4
        FOR counter = 1 TO 5
                LINE INPUT #4, fileName$
        NEXT counter
        counter = 1
        DO
                LINE INPUT #4, fileName$
                fileName$ = LEFT$(fileName$, 8)
                IF LEFT$(fileName$, 1) <> " " THEN
                        PUT #3, counter, fileName$
                        counter = counter + 1
                END IF
        LOOP WHILE (LEFT$(fileName$, 1) <> " ") AND (NOT EOF(4))
        CLOSE #4
        KILL tempFilePath + "dir.txt"
'        REM **** the next bit is for test purposes only ****
'        FOR counter = 1 TO LOF(3) / 10
'                GET #3, counter, fileName$
'                PRINT fileName$ + "<"
'        NEXT counter
'        PRINT
'        PRINT "LOF (3)="; LOF(3)
'        PRINT "# of files="; LOF(3) / 10
'        PRINT "directory printout done."
END SUB

SUB LoadPlayList (fileName AS STRING)
        TextOutput "loading playlist..."
        CLOSE #2
        KILL tempFilePath + playListTempFile + ".tmp"
        OPEN dataFilePath + fileName + ".ply" FOR INPUT AS #1
        OPEN tempFilePath + playListTempFile + ".tmp" FOR RANDOM AS #2 LEN = 4
        songPointer = 1
        DO WHILE NOT EOF(1)
                LINE INPUT #1, a$
                song.discNum = VAL(a$)
                IF song.discNum <> 0 THEN
                        song.trackNum = VAL(RIGHT$(a$, LEN(a$) - INSTR(a$, ",")))
                        PUT #2, songPointer, song
                        songPointer = songPointer + 1
                END IF
        LOOP
        CLOSE #1
        songPointer = 1
        TextOutput "done loading."
END SUB

SUB PrintTemplate
        CLS
        LOCATE 1, 1: PRINT "                                        �         � Alarm is:                   ";
        LOCATE 2, 1: PRINT "                                        �         � Alarm time is:              ";
        LOCATE 3, 1: PRINT "                                        �         � Alarm playlist:             ";
        LOCATE 4, 1: PRINT "                                        �         � Regular playlist:           ";
        LOCATE 5, 1: PRINT "                                        �         � CD player is:               ";
        LOCATE 6, 1: PRINT "                                        �         ������������������������������";
        LOCATE 7, 1: PRINT "                                        �         � Toggles:                    ";
        LOCATE 8, 1: PRINT "                                        �         �                             ";
        LOCATE 9, 1: PRINT "                                        �         �   alarm                     ";
        LOCATE 10, 1: PRINT "                                        �         �   ^                         ";
        LOCATE 11, 1: PRINT "                                        �         �   continuous mode           ";
        LOCATE 12, 1: PRINT "                                        �         �   ^                         ";
        LOCATE 13, 1: PRINT "                                        �         �   random play               ";
        LOCATE 14, 1: PRINT "                                        �         �   ^                         ";
        LOCATE 15, 1: PRINT "                                        �>        �                             ";
        LOCATE 16, 1: PRINT "                                        �         ������������������������������";
        LOCATE 17, 1: PRINT "                                        �         � Commands:                   ";
        LOCATE 18, 1: PRINT "                                        �         �                             ";
        LOCATE 19, 1: PRINT "                                        �         �   play / initialize & Play  ";
        LOCATE 20, 1: PRINT "                                        �         �   ^                   ^     ";
        LOCATE 21, 1: PRINT "                                        �         �   stop                      ";
        LOCATE 22, 1: PRINT "                                        �         �   ^                         ";
        LOCATE 23, 1: PRINT "                                        �         �   set Alarm                 ";
        LOCATE 24, 1: PRINT "                                        �         �       ^                     ";
        LOCATE 25, 1: PRINT "                                        �         �   Quit                      ";
        LOCATE 26, 1: PRINT "                                        �         �   ^                         ";
        LOCATE 27, 1: PRINT "                                        �         �                             ";
        LOCATE 28, 1: PRINT "                                        �         �                             ";
        LOCATE 29, 1: PRINT "                                        �         �                             ";
        LOCATE 30, 1: PRINT "                                        �         �                             ";
        FOR counter = 1 TO LOF(3) / 10
                vert = counter + 15 - selectedFilePointer
                IF vert >= 1 AND vert <= 30 THEN
                        GET #3, counter, fileName$
                        LOCATE vert, 43
                        PRINT fileName$;
                END IF
        NEXT counter
END SUB

SUB ProcessKeyPress
        IF keyPress = "Q" THEN quit = true
        IF keyPress = "a" THEN alarmEnabled = NOT alarmEnabled
        IF keyPress = "A" THEN SetAlarm
        IF keyPress = "p" THEN
                TextOutput "commencing play..."
                playingTracks = true
        END IF
        IF keyPress = "P" THEN
                SonyInitialize
                TextOutput "commencing play..."
                playingTracks = true
        END IF
        IF keyPress = "s" THEN
                TextOutput "stop."
                SonyPress (stopp)
                SonyPress (clearr)
                playingTracks = false
        END IF
        IF keyPress = "r" THEN shuffleMode = NOT shuffleMode
        IF keyPress = "c" THEN continuousMode = NOT continuousMode
END SUB

SUB RefreshVariables
        LOCATE 1, 72
        PRINT "        ";
        LOCATE 2, 71
        PRINT "        ";
        LOCATE 3, 72
        PRINT "        ";
        LOCATE 4, 72
        PRINT "        ";
        LOCATE 5, 72
        PRINT "        ";
        LOCATE 9, 72
        PRINT "        ";
        LOCATE 11, 72
        PRINT "        ";
        LOCATE 13, 72
        PRINT "        ";
        LOCATE 1, 72
        IF alarmIsRinging THEN PRINT "RINGING";  ELSE PRINT "SILENT";
        LOCATE 2, 71
        PRINT STR$(INT(getUpTime / 3600)) + ":" + STR$((getUpTime - INT(getUpTime / 3600) * 3600) / 60);
        LOCATE 3, 72
        PRINT alarmListFile;
        LOCATE 4, 72
        PRINT playListFile;
        LOCATE 5, 72
        IF playingTracks THEN PRINT "PLAYING";  ELSE PRINT "STOPPED";
        LOCATE 9, 72
        IF alarmEnabled THEN PRINT "ENABLED";  ELSE PRINT "DISABLED";
        LOCATE 11, 72
        IF continuousMode THEN PRINT "ENABLED";  ELSE PRINT "DISABLED";
        LOCATE 13, 72
        IF shuffleMode THEN PRINT "ENABLED";  ELSE PRINT "DISABLED";
END SUB

SUB SetAlarm
        a$ = "The current time is:" + TIME$
        TextOutput a$
        TextOutput "Number of hrs from midnight"
        INPUT ; UserIn
        getUpTime = UserIn * 3600
        TextOutput "Number of minutes"
        INPUT ; UserIn
        getUpTime = getUpTime + (UserIn * 60)
        TextOutput "Alarm time has been set."
        alarmEnabled = true
        TextOutput "Alarm has been enabled."
END SUB

SUB ShuffleSongs
        TextOutput "randomizing..."
        IF (LOF(2) / 4) < 3 THEN EXIT SUB
        FOR pass = 1 TO 3
                RANDOMIZE TIMER
                FOR counter = 1 TO ((LOF(2) / 4) - 2)
                        GET #2, counter, song
                        disc = song.discNum
                        track = song.trackNum
                        randomPick = INT(RND * ((LOF(2) / 4) - counter + 1)) + counter
                        GET #2, randomPick, song
                        PUT #2, counter, song
                        song.discNum = disc
                        song.trackNum = track
                        PUT #2, randomPick, song
                NEXT counter
        NEXT pass
        TextOutput "done."
END SUB

SUB SonyEntertrack (discToEnter, trackToEnter)
        SonyGodisc (discToEnter)
        SonyGotrack (trackToEnter)
        SonyPress (enter)
END SUB

SUB SonyGodisc (nextDisc)
        offset = nextDisc - currentDisc
      
        REM **** If it's the same disc as last time ****
        REM **** then go up one disc, and come back ****
        REM **** down to the same spot.             ****
        IF offset = 0 THEN
                SonyJogUp (1)
                SonyJogDown (1)
                EXIT SUB
      
        REM **** Otherwise, see if there's a shortcut ****
        ELSEIF ABS(offset) > (totalDiscs / 2) THEN
                IF offset > 0 THEN
                        offset = offset - totalDiscs
                ELSE
                        offset = offset + totalDiscs
                END IF
        END IF
      
        REM **** Start jogging (up or down depending on sign of offset) ****
        IF offset > 0 THEN
                SonyJogUp (offset)
        ELSE
                SonyJogDown (offset)
        END IF
        currentDisc = nextDisc

END SUB

SUB SonyGotrack (track)
        IF track = 0 THEN
                EXIT SUB
        ELSE
                FOR counter = 1 TO track
                        SonyPress (trackUp)
                NEXT counter
        END IF
END SUB

SUB SonyHold (button)
        OUT port, button
        SonyWaitfor (holdDelay)
        OUT port, release
        SonyWaitfor (pressDelay)
END SUB

SUB SonyInitialize
        TextOutput "initializing CD player..."
        SonyPress (release)
        SonyPress (stopp)
        SonyPress (program)
        SonyHold (clearr)
        SonyPress (block2)
        SonyPress (block1)
        SonyPress (program)
        currentDisc = 1
        TextOutput "done."
END SUB

SUB SonyJogDown (numberOfDiscs)
        IF numberOfDiscs = 0 THEN EXIT SUB
        FOR counter = 1 TO ABS(numberOfDiscs)
                OUT port, jog2
                SonyWaitfor (jogDelay)
                OUT port, jog12
                SonyWaitfor (jogDelay)
                OUT port, jog1
                SonyWaitfor (jogDelay)
                OUT port, release
                SonyWaitfor (jogDelay)
        NEXT counter
END SUB

SUB SonyJogUp (numberOfDiscs)
        IF numberOfDiscs = 0 THEN EXIT SUB
        FOR counter = 1 TO ABS(numberOfDiscs)
                OUT port, jog1
                SonyWaitfor (jogDelay)
                OUT port, jog12
                SonyWaitfor (jogDelay)
                OUT port, jog2
                SonyWaitfor (jogDelay)
                OUT port, release
                SonyWaitfor (jogDelay)
        NEXT counter
END SUB

SUB SonyPlayNextTrack
        SonyPress (stopp)
        SonyPress (clearr)
        IF songPointer = 1 AND shuffleMode = true THEN ShuffleSongs
        IF songPointer <= (LOF(2) / 4) THEN
                GET #2, songPointer, song
                disc = song.discNum
                track = song.trackNum
                a$ = STR$(disc) + "    " + STR$(track)
                TextOutput a$
                SonyEntertrack disc, track
                SonyPress (playy)
                songPointer = songPointer + 1
        END IF
        IF songPointer > (LOF(2) / 4) THEN
                songPointer = 1
                IF continuousMode = false THEN playingTracks = false
                IF alarmIsRinging THEN
                        alarmIsRinging = false
                        LoadPlayList (playListFile)
                END IF
        END IF
END SUB

SUB SonyPress (button)
        OUT port, button
        SonyWaitfor (pressDelay)
        OUT port, release
        SonyWaitfor (pressDelay)
END SUB

SUB SonyWaitfor (delay)
        FOR counter = 1 TO delay
        NEXT counter
END SUB

SUB TextOutput (textOut$)
        DIM screenImage(4640)
        GET (0, 17)-(319, 480), screenImage
        PUT (0, 1), screenImage, PSET
        LINE (0, 465)-(319, 480), 0, BF
        LOCATE 30, 1
        PRINT " " + LEFT$(textOut$, 39);
END SUB