home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Audio 4.94 - Over 11,000 Files
/
audio-11000.iso
/
amiga
/
players
/
modplyrs
/
dstrckr2.lha
/
DTL
/
code
/
DTC.S
next >
Wrap
Text File
|
1993-12-17
|
36KB
|
1,365 lines
;;=======================================================================;;
;; DTC.S -> Begun: Tue, Apr 25, 1992 ;;
;; Last updated: Sat, Dec 18, 1993 ;;
;;-----------------------------------------------------------------------;;
;; This is v2.0 of the CLI commander program for destracker.library v3.0+;;
;;-----------------------------------------------------------------------;;
;; Designed and written by Darren E. Schebek ;;
;; Copyright ⌐1992,1993 by Darren E. Schebek ;;
;; All rights reserved. ;;
;;-----------------------------------------------------------------------;;
;; This source code is NOT public domain ;;
;;=======================================================================;;
INCLUDE "dp:system.gs" ;DevPac-specific global include thingy.
INCLUDE "graphics/gfxbase.i"
INCLUDE "DTLib.I" ;DES-Tracker include file.
;---------------------------------------------------------------
; System equates...
_SYSBase = 4 ;Pointer to exec library base.
;---------------------------------------------------------------
; Control character equates used in text strings and in string parsing...
NULL = $00 ;NULL
TAB = $09 ;TAB
LF = $0A ;Linefeed
QUOTE = $22 ;Double quote
;---------------------------------------------------------------
; Some custom macros of my own...
LOADLIB MACRO
MOVE.L _\1Base,A6
ENDM
SYS MACRO
JSR _LVO\1(A6)
ENDM
BYTETAB MACRO
\1 EQU SOFFSET
SOFFSET SET SOFFSET+\2
ENDM
;---------------------------------------------------------------
; Variables used by the DTC program...
STRUCTURE DTC_VARS,0
ULONG SigBitNum
APTR GFXBase ;Ptr to Graphics.library base.
APTR DosBase ;Ptr to dos.library base.
APTR DTBase ;Ptr to destracker.library base.
BPTR OutputHandle ;Ptr to standard output handle.
STRUCT TimeScanInfo,tsi_SIZE ;TIMESCANINFO struct for CalcElapsedTime().
BYTETAB FilenameString,128 ;Workspace for string handling.
BYTETAB TimeString,16 ;WorkSpace for numeric conversion.
BYTETAB DecString,16 ;WorkSpace for numeric conversion.
LABEL DTC_SIZE ;Equates to size of required var space.
;---------------------------------------------------------------
; The beginning. Start out by allocating space for my program variables,
; initialize the program, and then proceed to parse the command line
; arguments...
Main Move.L A0,A5 ;Cache argstring pointer in A3 for now.
MoveQ #10,D7 ;D7 holds exit code in case of error.
; Allocate space for program variables...
LOADLIB SYS ;Get SYS_Base in A6.
Move.L #DTC_SIZE,D0 ;Size of variable space I need.
Move.L #MEMF_CLEAR,D1 ;Initialize everything to 0 for me.
SYS AllocMem ;Attempt to allocate variable space.
Tst.L D0 ;Error?
Ble .ProgAbort ;Yup, what a washout.
Move.L D0,A4 ;Nobody's allowed to touch A4!
; Open graphics.library...
Lea GfxName,A1 ;Name of the library.
MoveQ.L #0,D0
SYS OpenLibrary ;Attempt to open (it should work).
Move.L D0,GFXBase(A4) ;Store ptr to gfx library base.
Bne .1 ;If <> 0 then open succeeded.
Move.L #GFXErrText,D2 ;Say "couldn't open gfx.lib"
.PrintGo Bsr PrintNicely
Bra .Abort ;And abort
; Open dos.library...
.1 Lea DosName,A1 ;Open dos.library (what the hell).
MoveQ.L #0,D0
SYS OpenLibrary ;Attempt open dos.library.
Move.L D0,DosBase(A4) ;Store ptr to dos library base.
Bne .2 ;What the...?
Move.L #DOSErrText,D2
Bra .PrintGo
; Get handle of standard output...
.2 Move.L D0,A6 ;Get output handle for text output.
SYS Output
Move.L D0,OutputHandle(A4) ;Save ptr to std. output handle.
; Open DES-Tracker library.
LOADLIB SYS ;Get SYS_Base.
Lea DTLName,A1 ;"destracker.library".
MoveQ #3,D0 ;Must be version 3+ of library.
SYS OpenLibrary ;Attempt to open destracker.library.
Move.L D0,DTBase(A4) ;Store pointer to library base.
Bne .3 ;If <>0 then open succeeded.
Move.L #NoLibOpenText,D2 ;Say "couldn't open lib..."
Bra .PrintGo ;Abort with error.
; Say hi...
.3 Move.L #HelloText,D2 ;Say hello.
Bsr PrintNicely ;Nicely means you can pause text output.
; Inform user which CIA timer is being used...
Move.L #WhichTimerText,D2
Move.L #WhichTimerLen,D3
Bsr PrintCLI
Move.L DTBase(A4),A6
Move.L #CIAAText,D2
Move.L #CIAALen,D3
BTst #1,dtl_WhichTimer(A6)
Beq.S .SayCIA
Move.L #CIABText,D2
Move.L #CIABLen,D3
.SayCIA Bsr PrintCLI
Move.L #TimerAText,D2
Move.L #TimerALen,D3
BTst #0,dtl_WhichTimer(A6)
Beq.S .SayTimer
Move.L #TimerBText,D2
Move.L #TimerBLen,D3
.SayTimer Bsr PrintCLI
;-------------------------------
; Initialization complete. Now go off and do whatever the user typed...
Bsr ProcessCmdLine ;Process whatever user typed.
Tst.L D0 ;Did an error occur?
Bne .Abort ;Yup, free resources and abort.
MoveQ #0,D7 ;No, exit with success code.
;-------------------------------
; Deallocate everything and leave...
.Abort LOADLIB SYS ;Get SYS_Base.
Move.L DTBase(A4),D0 ;DES-Tracker lib base ptr.
Beq .4 ;It didn't open.
Move.L D0,A1 ;It is open.
SYS CloseLibrary ;Close it.
.4 Move.L DosBase(A4),D0 ;DOS lib base ptr.
Beq .5 ;DOS didn't open (?!?!?)
Move.L D0,A1 ;It opened.
SYS CloseLibrary ;Close it.
.5 Move.L GFXBase(A4),D0 ;gfx lib base ptr.
Beq .6 ;Didn't open.
Move.L D0,A1 ;Yes it did.
SYS CloseLibrary ;Well look, this isn't an argument.
.6 Move.L A4,A1 ;Release program variable space.
Move.L #DTC_SIZE,D0 ;Size of variable space.
SYS FreeMem ;Free it.
.Leave Move.L D7,D0 ;Return exit code in D0.
Rts
.ProgAbort MoveQ #10,D7 ;Error exit code in D7.
Bra .Leave ;Abort with error.
;---------------------------------------------------------------
; ProcessCmdLine routine. Parse user input from the command line and acts
; upon it. Does not return until all user input has been processed.
;
; Input: A5 = Ptr to command-line argstring.
;
; Output: D0 = 0 if all processing successful.
; -1 if an error occurred at any point.
;
ProcessCmdLine Move.B (A5)+,D0 ;Fetch 1st char of command.
Cmp.B #LF,D0 ;End of line?
Beq .Bad ;Yup, not a very good command. :)
Cmp.B #" ",D0 ;Space char?
Beq ProcessCmdLine ;Yes, skip leading white space.
Cmp.B #TAB,D0 ;TAB?
Beq ProcessCmdLine ;Yes, skip leading white space.
Cmp.B #'a',D0 ;Now, if char is lower-case...
Blt .Good1 ;It isn't
Cmp.B #'z',D0
Bgt .Good1 ;It isn't.
Sub.B #$20,D0 ;It is, so make it upper-case.
.Good1 Asl.W #8,D0 ;Shift first char up in D0.
Move.B (A5)+,D0 ;Get second char of command.
Cmp.B #LF,D0 ;Premature end of line?
Beq .Bad ;Yup, bad command.
Cmp.B #'a',D0 ;Again, if char is lower-case
Blt .Good2 ; then make it upper case.
Cmp.B #'z',D0
Bgt .Good2
Sub.B #$20,D0 ;Make command char upper-case.
.Good2 Lea CommVectors,A1 ;Ptr to command jump vectors.
Lea CommChars,A2 ;Ptr to command chars table.
MoveQ #NUMCOMMANDS-1,D1 ;Do for number of commands supported.
.CheckComm Move.L (A1)+,A0 ;Get vector for this command.
Cmp.W (A2)+,D0 ;Is it this command?
Beq .FoundCommand ;Yup, so go call it.
DBra D1,.CheckComm ;Nope, try next command.
Bra .Bad ;Unknown command.
.FoundCommand Move.L DTBase(A4),A6 ;Put DTLib base in A6 for command.
Jsr (A0) ;Call the appropriate command routine.
Tst.L D0 ;Did an error occur?
Bne .Abort ;Yup, so abort.
; Now check to see if any input remains in the command-line argstring...
.CheckInput Move.B (A5),D1 ;Get next char from argstring.
Beq .Done ;If another command exists
Cmp.B #LF,D1 ; in the argstring, then
Beq .Done ; I must process that one as well.
Cmp.B #" ",D1
Beq .RNext
Cmp.B #TAB,D1
Bne ProcessCmdLine ;More input, go and process it.
.RNext AddQ #1,A5 ;Skip white space and get next char.
Bra .CheckInput
.Done MoveQ #0,D0 ;All input processed successfully.
.Leave Rts ;Leave, damn-it.
.Bad Move.L #ComText,D2 ;Bad input.
Bsr PrintNicely ;Show available commands to user.
.Abort MoveQ #-1,D0 ;Return with error code.
Bra .Leave
;---------------------------------------------------------------
; PrintCLI routine. Prints a text string to the standard output.
;
; Input: D2 = Pointer to the text string to print (NOT NULL-terminated).
; D3 = Length of the text string.
;
; Output: Nothing.
;
PrintCLI Move.L A6,-(Sp)
Move.L OutputHandle(A4),D1
Move.L DosBase(A4),A6
SYS Write
Move.L (Sp)+,A6
Rts
;---------------------------------------------------------------
; PrintNicely routine. Prints a NULL-Terminated text string one line at a time
; (using the PrintCLI routine above) so that the output can be paused by
; pressing a key.
;
; Input: D2 = Pointer to the text string to print (NULL-terminated).
;
; Output: Nothing.
;
PrintNicely MoveM.L A3/A5,-(Sp)
Move.L D2,A5
.NextLine Move.L A5,A3
MoveQ #0,D3
.CountChars AddQ #1,D3
Move.B (A3)+,D0
Beq .Done
Cmp.B #LF,D0
Bne .CountChars
Move.L A5,D2
Move.L A3,A5
Bsr PrintCLI
Bra .NextLine
.Done MoveM.L (Sp)+,A3/A5
Rts
;---------------------------------------------------------------
; GetFilename routine. This will extract a file specification from the
; command line argstring. It skips white space and understands quotes, too. :)
;
; Input: A5 = Pointer to current position in argstring.
;
; Output: FilenameString[] holds the extracted filespec.
;
GetFilename Lea FilenameString(A4),A0
.Skip Move.B (A5),D0 ;Get char from argstring.
Cmp.B #QUOTE,D0 ;Is it a double-quote?
Beq.S .DoQuote ;Yes, do special quote handling.
Cmp.B #TAB,D0 ;Is it a TAB?
Beq .Next ;Yes, skip white space.
Cmp.B #" ",D0 ;Is it a space?
Bne .Copy ;No, start copying chars.
.Next AddQ #1,A5 ;Yes, skip white space.
Bra .Skip ;Loop until non-white-space found.
.DoQuote AddQ #1,A5 ;Skip the open quote char.
Move.B (A5),D0 ;Get next char.
Cmp.B #LF,D0 ;End of line (ie, no close quote)?
Beq .Done ;Yes, all done.
Cmp.B #QUOTE,D0 ;Is it a close quote?
Beq .EndQuote ;Yes, skip past it and leave.
Move.B D0,(A0)+ ;Otherwise, just store the character.
Bra .DoQuote ;Loop 'til EOL or close quote found.
.EndQuote AddQ #1,A5 ;Skip past close quote.
Bra .Done ;And leave.
.Copy Cmp.B #LF,(A5) ;EOL yet?
Beq .Done ;Yup, all done.
.Copy1 Move.B (A5)+,(A0)+ ;Else copy the character.
Cmp.B #" ",(A5) ;Is next char a space?
Beq.S .Done ;Yup, white-space is a delimiter.
Cmp.B #TAB,(A5) ;Is it a TAB?
Beq.S .Done ;Yup, also a delimiter.
Cmp.B #LF,(A5) ;Is it EOL?
Bne.S .Copy1 ;No, so go get next char.
.Done Clr.B (A0) ;Time to go, NULL-terminate parsed string.
Rts ;And return.
;---------------------------------------------------------------
; ReportLibErr routine. Takes a library return code and turns it into
; an error message that is displayed to the user.
;
; Input: D0 = Library return code.
;
; Output: Nothing.
ReportLibErr Tst.L D0 ;Did an error actually occur?
Bpl .Done ;Nope.
Neg.W D0 ;Make return code positive.
SubQ #1,D0 ;Code now in 0..n range.
Add.W D0,D0 ;Make longword index out of it.
Add.W D0,D0
Lea ErrorLookup,A0 ;Ptr to err msg addr lookup table.
Move.L 0(A0,D0.W),D2 ;Get ptr to the error message.
Bsr PrintNicely ;And print it.
MoveQ #-1,D0 ;Return general failure code.
.Done Rts ;That was easy.
;---------------------------------------------------------------
; GetDecValue routine. Extracts a string of digits from the command line
; argstring and converts the string into a binary value.
;
; Input: A5 = Pointer to current position in the argstring.
;
; Output: D0 = extracted binary value or 0 if invalid decimal string.
;
GetDecValue MoveM.L D1-D4/A0-A2,-(Sp)
MoveQ #0,D4 ;D4 is used to hold sign of result.
MoveQ #0,D3 ;D3 will hold converted value.
.FindStart Cmp.B #LF,(A5) ;EOL?
Beq .Done ;Yes, no value was supplied.
Cmp.B #" ",(A5) ;Space char?
Beq .Next ;Yup, skip it.
Cmp.B #TAB,(A5) ;TAB?
Bne .Start ;Nope, start processing digits.
.Next AddQ #1,A5 ;Yes, skip it.
Bra .FindStart ;Loop until non-white-space found.
.Start Cmp.B #"+",(A5) ;If char is "+" then skip it.
Beq .Trim
Cmp.B #"-",(A5) ;If char is "-" then D4 = neg, skip char.
Bne .OK
St D4
.Trim AddQ #1,A5
; Locate the end of the decimal string, since I have to start with the
; least significant digit...
.OK Move.L A5,A1 ;Make copy of argstring ptr.
.1 Cmp.B #"9",(A5) ;Is char an ASCII digit?
Bgt .2 ;No, see if any digits were found.
Cmp.B #"0",(A5)
Blt .2
AddQ #1,A5 ;Char is a digit, check next char.
Bra .1
.2 Cmp.L A5,A1 ;Were any digits found?
Beq .Done ;No, return value of 0 (in D3).
MoveQ #1,D2 ;Start at 10^0.
Move.L A5,A2 ;A5 has to mark pos. after value.
.3 MoveQ #0,D0 ;D0 will hold char converted to value.
Move.B -(A2),D0 ;Get char from string.
Sub.B #"0",D0 ;Convert to binary value.
MulU D2,D0 ;Times appropriate power of ten.
Add.L D0,D3 ;Add to result accumulator.
Move.W D2,D0 ;Create next power of 10 (n) in D2.
Asl.W #3,D2 ;n*8
Add.W D0,D0 ;n*2
Add.W D0,D2 ;D2 = (n*8)+(n*2) = 10^(p+1)
Cmp.L A1,A2 ;Reached end (start?) of decimal string?
Bne .3 ;Not, yet, process next digit.
.Done Move.L D3,D0 ;Return converted value in D0.
Tst.B D4 ;Was a "-" char prepended to string?
Beq .Go ;Nope.
Neg.L D0 ;Yes, so negate result.
.Go MoveM.L (Sp)+,D1-D4/A0-A2
Rts ;All done.
;---------------------------------------------------------------
; Here are the functions that correspond to the commands supported by
; DTC. Essentially, they just pass the user input on to the library
; and report any errors that may crop up. This first routine, called
; "CommandDone", handles generic clean-up for all commands. Therefore,
; all commands eventually wind up at this routine...
CommandDone Bsr ReportLibErr
Rts
;---------------------------------------------------------------
; FlushLibrary command. Invoked with "XL"...
FlushLibrary Move.L #FlushText,D2
Bsr PrintNicely
LOADLIB SYS
Move.L DTBase(A4),A1
SYS RemLibrary
MoveQ #0,D0
Bra CommandDone
;---------------------------------------------------------------
; SaveModule command. Invoked with "SM"...
SaveModule Bsr GetFilename ;Get filespec from argstring.
Lea FilenameString(A4),A0 ;Get ptr to filespec string.
Tst.B (A0) ;NULL string?
Bne .DoCall ;Nope, proceed normally.
Sub.L A0,A0 ;Yes, so pass NULL-Ptr.
.DoCall SYS SaveModule
Bra CommandDone
;---------------------------------------------------------------
; SetSaveFormat command. Invoked with "MF"...
SetSaveFormat Bsr GetDecValue ;Extract decimal value from argstring.
SYS SetSaveFormat
Bra CommandDone
;---------------------------------------------------------------
; WaitEndPlay command. Invoked with "WE".
;
; Note that this function uses a combination of the event signalling and
; examination of the status flags, since there may be many reasons why a
; module would not be playing (eg, stopped, unloaded, finished, etc), so
; rather than wait for and check all these events, I just wait for a few
; types of events to occur and then check the DF_PLAYING flag, which is 0
; if no song is playing, regardless of how it came to be suddenly not
; playing anymore. :) Note that I can't just wait for SEF_SECOND all by
; itself, since if the module stops playing for any reason, then I will
; no longer get signalled (SEF_SECOND signals upon each second of elapsed
; *play* time).
;
SIGBITS = SEF_SECOND|SEF_FINISH|SEF_STOP|SEF_MODUNLOADED|SEF_MODLOADED
WaitEndPlay Move.L A6,A5
LOADLIB SYS
BTst #DF_PLAYING,dtl_Flags+1(A5)
Beq .Leave
Bsr GetDecValue
Tst.L D0
Bmi .Leave
Bne .Go
Move.L #600,D0 ;Set default of ten minutes.
; Calc current elapsed time in seconds...
.Go Move.L dtl_ElapsedTime(A5),D3
DivU #60,D3
MoveQ #-1,D0
SYS AllocSignal
Move.L D0,SigBitNum(A4)
Beq .Leave ;Just leave if signal didn't allocate.
Move.L DTBase(A4),A6
Move.W #SIGBITS,D1 ;Specify events I want to be signalled about.
SYS AddStatusSignal
Tst.L D0
Bne .Done ;Lib call failed.
.WaitLoop LOADLIB SYS ;SYS_Base back in A6
MoveQ #0,D0
Move.L SigBitNum(A4),D6
BSet D6,D0 ;Wait for signal I allocated.
BSet #SIGBREAKB_CTRL_C,D0
SYS Wait ;Wait for my signal.
BTst #SIGBREAKB_CTRL_C,D0
Beq .NoAbort
Move.L #AbortedText,D2
Move.L #AbortedLen,D3
Bsr PrintCLI
Bra .Done
.NoAbort BTst #DF_PLAYING,dtl_Flags+1(A5) ;Still playing?
Beq .Done ;Nope, time to go.
Move.L dtl_ElapsedTime(A5),D2 ;Get elapsed time in jiffies.
DivU #60,D2 ;Convert it to seconds.
Cmp.L D2,D3 ;Has specified time elapsed?
Bgt .WaitLoop ;Nope, wait another second.
.Done LOADLIB SYS
Move.L SigBitNum(A4),D0
SYS FreeSignal ;Free up signal I had allocated.
Move.L dtl_ElapsedTime(A5),D0
Bsr BinToTime
.Leave Move.L A5,A6
MoveQ #0,D0
Bra CommandDone
AbortedText Dc.B LF,"*** User abort ***",LF
AbortedLen = *-AbortedText
Even
;---------------------------------------------------------------
; RetitleModule command. Invoked with "RM"...
RetitleModule Bsr GetFilename ;Extract filespec from argstring.
Lea FilenameString(A4),A0 ;Ptr to filespec string.
SYS RetitleModule
Bra CommandDone
;---------------------------------------------------------------
; SetDefaultTempo command. Invoked with "DT"...
SetDefaultTempo Bsr GetDecValue ;Extract decimal val from argstring.
SYS SetDefaultTempo
Bra CommandDone
;---------------------------------------------------------------
; ApplyGlobalTempo command. Invoked with "AT"...
ApplyGlobalTempo
SYS ApplyGlobalTempo ;Ooo, really tricky code here. :)
Bra CommandDone
;---------------------------------------------------------------
; SetIterations command. Invoked with "SI"...
SetIterations Bsr GetDecValue ;Extract dec val from argstring.
SYS SetIterations
Bra CommandDone
;---------------------------------------------------------------
; SetStartPosition command. Invoked with "SS"...
SetStartPosition
Bsr GetDecValue ;Extract dec val from argstring.
MoveQ #0,D1 ;Start note index always 0 for DTC.
SYS SetStartPosition
Bra CommandDone
;---------------------------------------------------------------
; SetEndPosition command. Invoked with "SE"...
SetEndPosition Bsr GetDecValue ;Get dec val from argstring.
MoveQ #0,D1 ;End note index always 0 for DTC.
SYS SetEndPosition
Bra CommandDone
;---------------------------------------------------------------
; SetCurPosition command. Invoked with "SC"...
SetCurPosition Bsr GetDecValue ;You get the idea by now. :)
MoveQ #0,D1 ;Current note index always 0 for DTC.
SYS SetCurPosition
Bra CommandDone
;---------------------------------------------------------------
; ChannelEnable command. Invoked with "CE"...
ChannelEnable Bsr GetDecValue
MoveQ #-128,D1
Tst.L D0
Bpl.S .1
Neg.W D0
MoveQ #0,D1
.1 Cmp.W #1000,D0
Blt.S .2
Sub.W #1000,D0
BSet #3,D1
.2 Cmp.W #100,D0
Blt.S .3
Sub.W #100,D0
BSet #2,D1
.3 Cmp.W #10,D0
Blt.S .4
Sub.W #10,D0
BSet #1,D1
.4 Cmp.W #1,D0
Blt.S .5
BSet #0,D1
.5 Move.W D1,D0
SYS SetChannelEnable
Bra CommandDone
;---------------------------------------------------------------
; TimingMode command. Invoked with "TM"...
TimingMode Bsr GetDecValue
SYS SetTimingMode
Bra CommandDone
;---------------------------------------------------------------
; SetLoopIntent command. Invoked with "LI"...
SetLoopIntent Bsr GetDecValue
SYS SetLoopIntent
Bra CommandDone
;---------------------------------------------------------------
; SetFineTempo command. Invoked with "FT"...
SetFineTempo Bsr GetDecValue
SYS SetFineTempo
Bra CommandDone
;---------------------------------------------------------------
; AutoDetect command. Invoked with "AD"...
AutoDetect Bsr GetDecValue
SYS SetAutoTiming
Bra CommandDone
;---------------------------------------------------------------
; SetTempoInt command. Invoked with "TI"...
SetTempoInt Bsr GetDecValue
SYS SetTempoInt
Bra CommandDone
;---------------------------------------------------------------
; SetModulePath command. Invoked with "SP"...
SetModulePath Bsr GetFilename ;Extract filespec from argstring.
Lea FilenameString(A4),A0 ;Get ptr to extracted filespec.
Cmp.B #"?",(A0) ;Does it start with "?"?
Beq .DisplayPaths ;Yes, just display current paths.
Tst.B (A0) ;Is it a NULL string?
Bne .DoCall ;Nope, proceed normally.
Sub.L A0,A0 ;Yup, so pass NULL-ptr instead.
.DoCall SYS SetModulePath
Move.L D0,D7 ;Save return code temporarily.
; Display all current paths as a convenience to the user...
.DisplayPaths Tst.L dtl_ModPathList(A6) ;Ptr to 1st path in list.
Bne .SayPaths ;List contains 1 or more paths.
Move.L #NoPathsText,D2 ;List is empty, say so.
Move.L #NoPathsLen,D3
Bsr PrintCLI
Bra .Go ;And leave.
.SayPaths Move.L #PathsText,D2 ;Say "Current paths are..."
Move.L #PathsLen,D3
Bsr PrintCLI
Lea dtl_ModPathList(A6),A3 ;Ptr to ptr to 1st path in list.
.NextPath Move.L (A3),D1 ;Get next pathentry ptr.
Beq .Go ;Reached end of list, so leave.
Move.L D1,A3 ;A3 = ptr to next pathentry.
MoveQ #0,D3
Move.W pe_Length(A3),D3 ;Length of pathentry string.
SubQ #1,D3 ;Less 1 for the NULL.
Lea pe_SIZE(A3),A0 ;A0 pts to the string.
Move.L A0,D2 ;Stupid DOS wants ptr in D2.
Bsr PrintCLI
Move.L #LFText,D2 ;Print linfeed in lieu of NULL.
Move.L #LFLen,D3
Bsr PrintCLI
Bra .NextPath ;Go print next path (if one).
.Go Move.L #LFText,D2 ;An extra linefeed.
Move.L #LFLen,D3 ; (looks better).
Bsr PrintCLI
Move.L D7,D0 ;Return code back in D0.
Bra CommandDone
PathsText Dc.B LF,"Current paths are:",LF
PathsLen = *-PathsText
NoPathsText Dc.B LF,"Path list is empty",LF
NoPathsLen = *-NoPathsText
LFText Dc.B LF
LFLen = 1
Even
;---------------------------------------------------------------
; LoadModule command. Invoked with "LM"...
LoadModule Bsr GetFilename
Lea FilenameString(A4),A0
SYS LoadModule
Bra CommandDone
;---------------------------------------------------------------
; LoadAndGo command. Invoked with "LP"...
LoadAndGo Bsr GetFilename
Lea FilenameString(A4),A0
SYS LoadModule
Tst.L D0 ;Error during load?
Bmi CommandDone ;Yup, don't bother trying to play it.
Bra BeginPlaySeq ;Go start the song playing.
;---------------------------------------------------------------
; UnloadModule command. Invoked with "UM"...
UnloadModule SYS UnloadModule
Bra CommandDone
;---------------------------------------------------------------
; BeginPlaySeq command. Invoked with "BP"...
BeginPlaySeq SYS BeginPlaySeq
Bra CommandDone
;---------------------------------------------------------------
; SetGlobalTempo command. Invoked with "ST"...
SetGlobalTempo Bsr GetDecValue
SYS SetGlobalTempo
Bra CommandDone
;---------------------------------------------------------------
; SetFilter command. Invoked with "SF"...
SetFilter Bsr GetDecValue
SYS SetFilter
Bra CommandDone
;---------------------------------------------------------------
; PausePlaySeq command. Invoked with "PP"...
PausePlaySeq SYS PausePlaySeq
Bra CommandDone
;---------------------------------------------------------------
; ContinuePlaySeq command. Invoked with "CP"...
ContinuePlaySeq SYS ContinuePlaySeq
Bra CommandDone
;---------------------------------------------------------------
; StopPlaySeq command. Invoked with "KI"...
StopPlaySeq SYS StopPlaySeq
Bra CommandDone
;---------------------------------------------------------------
; SetGlobalVolume command. Invoked with "SV"...
SetGlobalVolume Bsr GetDecValue
SYS SetGlobalVolume
Bra CommandDone
;---------------------------------------------------------------
; SetVolumeFadeRate command. Invoked with "FR"...
SetVolumeFadeRate
Bsr GetDecValue
SYS SetVolumeFadeRate
Bra CommandDone
;---------------------------------------------------------------
; FadeGlobalVolume command. Invoked with "FV"...
FadeGlobalVolume
Bsr GetDecValue
SYS FadeGlobalVolume
Bra CommandDone
;---------------------------------------------------------------
; ResetDefaults command. Invoked with "RD"...
ResetDefaults SYS ResetDefaults
Bra CommandDone
;---------------------------------------------------------------
; CalcElapsedTime command. Invoked with "ET"...
CalcElapsedTime Lea TimeScanInfo(A4),A0
; Initialize the TIMESCANINFO structure...
Move.B dtl_StartPosition(A6),tsi_StartPos(A0)
Move.B dtl_StartNoteIndex(A6),tsi_StartNote(A0)
Move.B dtl_EndPosition(A6),tsi_EndPos(A0)
Move.B dtl_EndNoteIndex(A6),tsi_EndNote(A0)
Move.B dtl_DefaultTempo(A6),tsi_DefaultTempo(A0)
Move.B dtl_FineTempo(A6),tsi_FineTempo(A0)
MoveQ #0,D0
Tst.B dtl_TimingMode(A6)
Beq .1
BSet #TSIB_TIMINGMODE,D0
.1 BTst #DF_TEMPOINT-8,dtl_Flags2(A6)
Beq .2
BSet #TSIB_TEMPOINTERP,D0
.2 Tst.B dtl_Iterations(A6)
Beq .Multi
Cmp.B #1,dtl_Iterations(A6)
Beq .3
.Multi BSet #TSIB_MULTIPLEITERS,D0
.3 Move.B D0,tsi_Flags(A0)
SYS CalcElapsedTime
Tst.L D0
Bmi .Err
Lea TimeScanInfo(A4),A2
Move.L tsi_FirstIterTime(A2),D0
Move.L tsi_ConsecIterTime(A2),D1
MoveQ #0,D2
Move.B dtl_Iterations(A6),D2
Bra .4
.AddIterLoop Add.L D1,D0
.4 SubQ #1,D2
Bgt .AddIterLoop
; I now have the total elapsed time for the requested iterations, so
; convert the value to a string and print it...
Bsr BinToTime
Move.L #SayTimeText,D2
Move.L #SayTimeLen,D3
Bsr PrintCLI
Lea TimeString(A4),A0
Move.L A0,D2
MoveQ #11,D3
Bsr PrintCLI
Move.L #SayLFText,D2
Move.L #SayLFLen,D3
Bsr PrintCLI
MoveQ #0,D0
.Err Bra CommandDone
;---------------------------------------------------------------
; SetTemporalStart command. Invoked with "TS"...
SetTemporalStart
Bsr GetDecValue
SYS SetTemporalStart
Bra CommandDone
;---------------------------------------------------------------
; SetTemporalEnd command. Invoked with "TE"...
SetTemporalEnd
Bsr GetDecValue
SYS SetTemporalEnd
Bra CommandDone
;---------------------------------------------------------------
; SetTemporalPos command. Invoked with "TC"...
SetTemporalPos
Bsr GetDecValue
SYS SetTemporalPos
Bra CommandDone
;---------------------------------------------------------------
; CalcVolFadeTime command. Invoked with "CF"...
CalcVolFadeTime Bsr GetDecValue
Move.B D0,D1
Move.B dtl_GlobalVolume(A6),D0
Move.B dtl_VolFadeRate(A6),D2
SYS CalcVolFadeTime
Bsr BinToTime
Move.L #SayFadeText,D2
Move.L #SayFadeLen,D3
Bsr PrintCLI
Lea TimeString+6(A4),A0
Move.L A0,D2
MoveQ #11-6,D3
Bsr PrintCLI
Move.L #SayLFText,D2
Move.L #SayLFLen,D3
Bsr PrintCLI
MoveQ #0,D0
Bra CommandDone
SayFadeText Dc.B LF,"Volume Fade Time (SS:JJ): "
SayFadeLen = *-SayFadeText
Even
;---------------------------------------------------------------
; VerifyModule command. Invoked with "VM"...
VerifyModule Bsr GetFilename
Lea FilenameString(A4),A0
SYS VerifyModule
Tst.L D0
Bmi CommandDone
Lea STText(PC),A0 ;Assume ST v2.6 format.
MoveQ.L #STTLen,D3
Cmp.B #MF_SOUNDTRACKER,D0 ;Is it ST v2.6?
Beq .Print ;Yup, say so.
Lea DTText(PC),A0
MoveQ.L #DTTLen,D3
Cmp.B #MF_DESTRACKER,D0
Beq .Print
Lea NTText(PC),A0 ;Must be Noisetracker then.
MoveQ.L #NTTLen,D3
.Print Move.L A0,D2 ;Print module format.
Bsr PrintCLI
MoveQ #0,D0 ;Success.
.Error Bra CommandDone
STText Dc.B LF,"File is Soundtracker v2.6 format.",LF,LF
STTLen = *-STText
NTText Dc.B LF,"File is Noisetracker/ProTracker format.",LF,LF
NTTLen = *-NTText
DTText Dc.B LF,"File is DES-Tracker v1.0 format.",LF,LF
DTTLen = *-DTText
Even
;---------------------------------------------------------------
; BinToDec routine. Converts an unsigned long into a decimal string
; that can be printed. The resultant string is NULL-Terminated.
;
; Input: D0 = unsigned longword to convert.
;
; Output: DecString[] holds the decimal string of the value.
;
BinToDec MoveM.L D0-D3/A0,-(Sp)
MoveQ #10-1,D1 ;Start with index for highest power of 10.
Lea DecString(A4),A0
.Loop Move.L D1,D2
Add.L D2,D2
Add.L D2,D2
Move.L PowerTable(PC,D2.W),D2 ;D2 holds current power of 10.
MoveQ #-1,D3
.1 AddQ.W #1,D3
Sub.L D2,D0
Bpl .1
Add.L D2,D0
Add.B #"0",D3 ;D3 holds ASCII digit.
Move.B D3,(A0)+ ;Store digit in string.
DBra D1,.Loop
Clr.B (A0)
MoveM.L (Sp)+,D0-D3/A0
Rts
PowerTable Dc.L 1
Dc.L 10
Dc.L 100
Dc.L 1000
Dc.L 10000
Dc.L 100000
Dc.L 1000000
Dc.L 10000000
Dc.L 100000000
Dc.L 1000000000
;---------------------------------------------------------------
; BinToTime routine. Converts a longword number of ticks (units of
; 1/60 second) into a string of the form "00:00:00:00"...
;
; Input: D0.L = unsigned longword value to convert.
;
; Output: TimeString holds the time string of the value.
;
BinToTime MoveM.L D2-D3/A2,-(Sp)
Move.L D0,D2
Lea TimeString(A4),A2
; Calculate number of hours...
Move.L #216000,D1
MoveQ #0,D3
.HoursLoop AddQ #1,D3
Sub.L D1,D2
Bpl .HoursLoop
Add.L D1,D2
SubQ #1,D3
Move.L D3,D0
Bsr BinToDec
Lea DecString+8(A4),A0
Move.B (A0)+,(A2)+
Move.B (A0)+,(A2)+
Move.B #":",(A2)+
; Calculate number of minutes...
Move.L #3600,D1
MoveQ #0,D3
.MinutesLoop AddQ #1,D3
Sub.L D1,D2
Bpl .MinutesLoop
Add.L D1,D2
SubQ #1,D3
Move.L D3,D0
Bsr BinToDec
Lea DecString+8(A4),A0
Move.B (A0)+,(A2)+
Move.B (A0)+,(A2)+
Move.B #":",(A2)+
; Calculate number of seconds...
MoveQ #60,D1
MoveQ #0,D3
.SecondsLoop AddQ #1,D3
Sub.L D1,D2
Bpl .SecondsLoop
Add.L D1,D2
SubQ #1,D3
Move.L D3,D0
Bsr BinToDec
Lea DecString+8(A4),A0
Move.B (A0)+,(A2)+
Move.B (A0)+,(A2)+
Move.B #":",(A2)+
; Calculate number of jiffies...
Move.L D2,D0
Bsr BinToDec
Lea DecString+8(A4),A0
Move.B (A0)+,(A2)+
Move.B (A0)+,(A2)+
Clr.B (A2)
MoveM.L (Sp)+,D2-D3/A2
Rts
;==============================
DATA
Even
; Here is the table that holds all support command "names"...
CommChars Dc.W "LM","BP","ST","PP","CP","SV","FR","FV","UM","SF"
Dc.W "SI","SS","SE","SC","CE","SP","DT","AT","RM","WE"
Dc.W "XL","SM","VM","TM","AD","FT","LI","MF","RD","LP"
Dc.W "TI","KI","CT","TS","TE","TC","CF"
NUMCOMMANDS = (*-CommChars)/2
; Here is the table that holds vectors to each supported command...
CommVectors Dc.L LoadModule
Dc.L BeginPlaySeq
Dc.L SetGlobalTempo
Dc.L PausePlaySeq
Dc.L ContinuePlaySeq
Dc.L SetGlobalVolume
Dc.L SetVolumeFadeRate
Dc.L FadeGlobalVolume
Dc.L UnloadModule
Dc.L SetFilter
Dc.L SetIterations
Dc.L SetStartPosition
Dc.L SetEndPosition
Dc.L SetCurPosition
Dc.L ChannelEnable
Dc.L SetModulePath
Dc.L SetDefaultTempo
Dc.L ApplyGlobalTempo
Dc.L RetitleModule
Dc.L WaitEndPlay
Dc.L FlushLibrary
Dc.L SaveModule
Dc.L VerifyModule
Dc.L TimingMode
Dc.L AutoDetect
Dc.L SetFineTempo
Dc.L SetLoopIntent
Dc.L SetSaveFormat
Dc.L ResetDefaults
Dc.L LoadAndGo
Dc.L SetTempoInt
Dc.L StopPlaySeq
Dc.L CalcElapsedTime
Dc.L SetTemporalStart
Dc.L SetTemporalEnd
Dc.L SetTemporalPos
Dc.L CalcVolFadeTime
; Lookup table for error message string addresses...
ErrorLookup Dc.L Owned
Dc.L NoMod
Dc.L NoPlay
Dc.L OutRnge
Dc.L Trimmed
Dc.L LoadErr
Dc.L NoMem
Dc.L BadPath
Dc.L Format
Dc.L SaveErr
Dc.L NoInstErr
Dc.L NotFoundErr
Dc.L MInstsErr
Dc.L SeqActive
Dc.L TooManyPatts
; Error messages...
Owned Dc.B LF,"ERROR: Library has been owned by another prog.",LF,LF,NULL
NoMod Dc.B LF,"ERROR: No module is loaded.",LF,LF,NULL
NoPlay Dc.B LF,"ERROR: No play sequence is active.",LF,LF,NULL
OutRnge Dc.B LF,"ERROR: Input value out of range.",LF,LF,NULL
Trimmed Dc.B LF,"NOTE: Input value was trimmed.",LF,LF,NULL
LoadErr Dc.B LF,"ERROR: Could not load file.",LF,LF,NULL
NoMem Dc.B LF,"ERROR: Insufficient memory.",LF,LF,NULL
BadPath Dc.B LF,"ERROR: Illegal pathname.",LF,LF,NULL
Format Dc.B LF,"ERROR: Unrecognized module format.",LF,LF,NULL
SaveErr Dc.B LF,"ERROR: Could not save file.",LF,LF,NULL
NoInstErr Dc.B LF,"ERROR: Non-existent instrument.",LF,LF,NULL
NotFoundErr Dc.B LF,"ERROR: File not found.",LF,LF,NULL
MInstsErr Dc.B LF,"ERROR: Module is missing instrument(s).",LF,LF,NULL
SeqActive Dc.B LF,"ERROR: Play sequence is already active.",LF,LF,NULL
TooManyPatts Dc.B LF,"ERROR: Too many patterns for S/T v2.6 format.",LF,LF,NULL
SayTimeText Dc.B LF,"Total Play Time: "
SayTimeLen = *-SayTimeText
SayLFText Dc.B LF,LF
SayLFLen = *-SayLFText
FlushText Dc.B LF,"Flushing DES-Tracker library...",LF,0
WhichTimerText Dc.B "DES-Tracker is currently using CIA "
WhichTimerLen = *-WhichTimerText
CIAAText Dc.B "A, "
CIAALen = *-CIAAText
CIABText Dc.B "B, "
CIABLen = *-CIABText
TimerAText Dc.B "timer A.",LF
TimerALen = *-TimerAText
TimerBText Dc.B "timer B.",LF
TimerBLen = *-TimerBText
GFXErrText Dc.B LF,"ERROR: Couldn't open graphics.library.",LF,LF,NULL
DOSErrText Dc.B LF,"ERROR: Couldn't open dos.library.",LF,LF,NULL
NoLibOpenText Dc.B LF,"ERROR: You need destracker.library v3.0.",LF,LF,NULL
; Title, copyright, and usage text...
HelloText Dc.B "destracker.library Commander program",LF
Dc.B "Copyright (c)1992,1993 by Darren Schebek",LF
Dc.B "Version 2.0 Dec 18, 1993",LF
Dc.B NULL
ComText Dc.B LF,"usage: dtc command { command command...}",LF,LF
Dc.B "Commands:",LF
Dc.B "AD {0|1} Auto-detect PAL/NTSC off/on",LF
Dc.B "AT Apply global tempo to song",LF
Dc.B "BP Begin play sequence",LF
Dc.B "CE {+|-ssss} Enable/disable channels",LF
Dc.B "CP Continue play sequence",LF
Dc.B "CF {destvol} Calculate time for a volume fade",LF
Dc.B "CT Calculate play time (1 iteration)",LF
Dc.B "DT {1..31} Set default module tempo",LF
Dc.B "FR {0..31} Set volume fade rate",LF
Dc.B "FT {-128..127} Set fine tempo control",LF
Dc.B "FV {0..64} Fade global volume",LF
Dc.B "KI Kill (stop) current play sequence.",LF
Dc.B "LI {0|1} Set whether song is intended to loop",LF
Dc.B "LM {filename} Load module (pathname optional)",LF
Dc.B "LP {filename} Load and play module (pathname optional)",LF
Dc.B "MF {0|1|2} Set save format (0=STv2.6, 1=NTv2.0, 1=DTv1.0)",LF
Dc.B "PP Pause play sequence",LF
Dc.B "RD Reset library parms to default values",LF
Dc.B "RM {songname} Retitle a loaded module",LF
Dc.B "SC {0..?} Set current play sequence position",LF
Dc.B "SE {0..?} Set play sequence end position",LF
Dc.B "SF {0|1} Set filter off/on",LF
Dc.B "SI {0..255} Set # of play sequence iterations",LF
Dc.B "SM [filespec] Save module to disk (pathname optional)",LF
Dc.B "SP [pathname] Add/remove load module search path(s)",LF
Dc.B "SS {0..?} Set play sequence start position",LF
Dc.B "ST {-16..15} Set global tempo",LF
Dc.B "SV {0..64} Set global volume",LF
Dc.B "TI {0|1} Set tempo interpretation (BPM or Non-BPM)",LF
Dc.B "TM {0|1} Set timing mode (0 = NTSC,1 = PAL)",LF
Dc.B "TE {jiffies} Set end position based on time.",LF
Dc.B "TS {jiffies} Set start position based on time.",LF
Dc.B "TC {jiffies} Set current position based on time.",LF
Dc.B "UM Unload module",LF
Dc.B "VM {filename} Determine if a disk file is a module.",LF
Dc.B "WE {seconds} Wait end of song or n seconds (def. 600)",LF
Dc.B "XL Flush library (and loaded song, if one)",LF,LF
Dc.B NULL
; Library names used for OpenLibrary()...
DosName Dc.B "dos.library",NULL
GfxName Dc.B "graphics.library",NULL
DTLName DTLIBNAME
Even
; The end.
End