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 >
Text File  |  1993-12-17  |  36KB  |  1,365 lines

  1. ;;=======================================================================;;
  2. ;;                  DTC.S  ->  Begun: Tue, Apr 25, 1992                  ;;
  3. ;;                    Last updated: Sat, Dec 18, 1993                    ;;
  4. ;;-----------------------------------------------------------------------;;
  5. ;; This is v2.0 of the CLI commander program for destracker.library v3.0+;;
  6. ;;-----------------------------------------------------------------------;;
  7. ;;               Designed and written by Darren E. Schebek               ;;
  8. ;;               Copyright ⌐1992,1993 by Darren E. Schebek               ;;
  9. ;;                          All rights reserved.                         ;;
  10. ;;-----------------------------------------------------------------------;;
  11. ;;                 This source code is NOT public domain                 ;;
  12. ;;=======================================================================;;
  13.  
  14.         INCLUDE    "dp:system.gs"    ;DevPac-specific global include thingy.
  15.         INCLUDE    "graphics/gfxbase.i"
  16.  
  17.         INCLUDE    "DTLib.I"    ;DES-Tracker include file.
  18.  
  19. ;---------------------------------------------------------------
  20. ; System equates...
  21.  
  22. _SYSBase    = 4        ;Pointer to exec library base.
  23.  
  24. ;---------------------------------------------------------------
  25. ; Control character equates used in text strings and in string parsing...
  26.  
  27. NULL    = $00    ;NULL
  28. TAB    = $09    ;TAB
  29. LF    = $0A    ;Linefeed
  30.  
  31. QUOTE    = $22    ;Double quote
  32.  
  33. ;---------------------------------------------------------------
  34. ; Some custom macros of my own...
  35.  
  36. LOADLIB    MACRO
  37.     MOVE.L    _\1Base,A6
  38.     ENDM
  39.  
  40. SYS    MACRO
  41.     JSR    _LVO\1(A6)
  42.     ENDM
  43.  
  44.  
  45. BYTETAB    MACRO
  46. \1    EQU    SOFFSET
  47. SOFFSET    SET    SOFFSET+\2
  48.     ENDM
  49.  
  50. ;---------------------------------------------------------------
  51. ; Variables used by the DTC program...
  52.  
  53.     STRUCTURE DTC_VARS,0
  54.     ULONG    SigBitNum
  55.     APTR    GFXBase            ;Ptr to Graphics.library base.
  56.     APTR    DosBase            ;Ptr to dos.library base.
  57.     APTR    DTBase            ;Ptr to destracker.library base.
  58.     BPTR    OutputHandle        ;Ptr to standard output handle.
  59.     STRUCT    TimeScanInfo,tsi_SIZE    ;TIMESCANINFO struct for CalcElapsedTime().
  60.     BYTETAB    FilenameString,128    ;Workspace for string handling.
  61.     BYTETAB    TimeString,16        ;WorkSpace for numeric conversion.
  62.     BYTETAB    DecString,16        ;WorkSpace for numeric conversion.
  63.     LABEL    DTC_SIZE        ;Equates to size of required var space.
  64.  
  65. ;---------------------------------------------------------------
  66. ; The beginning.  Start out by allocating space for my program variables,
  67. ; initialize the program, and then proceed to parse the command line
  68. ; arguments...
  69.  
  70. Main        Move.L    A0,A5        ;Cache argstring pointer in A3 for now.
  71.  
  72.         MoveQ    #10,D7        ;D7 holds exit code in case of error.
  73.  
  74. ; Allocate space for program variables...
  75.  
  76.         LOADLIB    SYS        ;Get SYS_Base in A6.
  77.         Move.L    #DTC_SIZE,D0    ;Size of variable space I need.
  78.         Move.L    #MEMF_CLEAR,D1    ;Initialize everything to 0 for me.
  79.         SYS    AllocMem    ;Attempt to allocate variable space.
  80.         Tst.L    D0        ;Error?
  81.         Ble    .ProgAbort    ;Yup, what a washout.
  82.         Move.L    D0,A4        ;Nobody's allowed to touch A4!
  83.  
  84. ; Open graphics.library...
  85.  
  86.         Lea    GfxName,A1    ;Name of the library.
  87.         MoveQ.L    #0,D0
  88.         SYS    OpenLibrary    ;Attempt to open (it should work).
  89.         Move.L    D0,GFXBase(A4)    ;Store ptr to gfx library base.
  90.         Bne    .1        ;If <> 0 then open succeeded.
  91.  
  92.         Move.L    #GFXErrText,D2    ;Say "couldn't open gfx.lib"
  93. .PrintGo    Bsr    PrintNicely
  94.         Bra    .Abort        ;And abort
  95.  
  96. ; Open dos.library...
  97.  
  98. .1        Lea    DosName,A1    ;Open dos.library (what the hell).
  99.         MoveQ.L    #0,D0
  100.         SYS    OpenLibrary    ;Attempt open dos.library.
  101.         Move.L    D0,DosBase(A4)    ;Store ptr to dos library base.
  102.         Bne    .2        ;What the...?
  103.  
  104.         Move.L    #DOSErrText,D2
  105.         Bra    .PrintGo
  106.  
  107. ; Get handle of standard output...
  108.  
  109. .2        Move.L    D0,A6        ;Get output handle for text output.
  110.         SYS    Output
  111.         Move.L    D0,OutputHandle(A4)    ;Save ptr to std. output handle.
  112.  
  113. ; Open DES-Tracker library.
  114.  
  115.         LOADLIB    SYS        ;Get SYS_Base.
  116.         Lea    DTLName,A1    ;"destracker.library".
  117.         MoveQ    #3,D0        ;Must be version 3+ of library.
  118.         SYS    OpenLibrary    ;Attempt to open destracker.library.
  119.         Move.L    D0,DTBase(A4)    ;Store pointer to library base.
  120.         Bne    .3        ;If <>0 then open succeeded.
  121.  
  122.         Move.L    #NoLibOpenText,D2    ;Say "couldn't open lib..."
  123.         Bra    .PrintGo        ;Abort with error.
  124.  
  125. ; Say hi...
  126.  
  127. .3        Move.L    #HelloText,D2    ;Say hello.
  128.         Bsr    PrintNicely    ;Nicely means you can pause text output.
  129.  
  130. ; Inform user which CIA timer is being used...
  131.  
  132.         Move.L    #WhichTimerText,D2
  133.         Move.L    #WhichTimerLen,D3
  134.         Bsr    PrintCLI
  135.  
  136.         Move.L    DTBase(A4),A6
  137.         Move.L    #CIAAText,D2
  138.         Move.L    #CIAALen,D3
  139.         BTst    #1,dtl_WhichTimer(A6)
  140.         Beq.S    .SayCIA
  141.  
  142.         Move.L    #CIABText,D2
  143.         Move.L    #CIABLen,D3
  144.  
  145. .SayCIA        Bsr    PrintCLI
  146.  
  147.         Move.L    #TimerAText,D2
  148.         Move.L    #TimerALen,D3
  149.         BTst    #0,dtl_WhichTimer(A6)
  150.         Beq.S    .SayTimer
  151.  
  152.         Move.L    #TimerBText,D2
  153.         Move.L    #TimerBLen,D3
  154.  
  155. .SayTimer    Bsr    PrintCLI
  156.  
  157. ;-------------------------------
  158. ; Initialization complete.  Now go off and do whatever the user typed...
  159.  
  160.         Bsr    ProcessCmdLine        ;Process whatever user typed.
  161.         Tst.L    D0            ;Did an error occur?
  162.         Bne    .Abort            ;Yup, free resources and abort.
  163.  
  164.         MoveQ    #0,D7            ;No, exit with success code.
  165.  
  166. ;-------------------------------
  167. ; Deallocate everything and leave...
  168.  
  169. .Abort        LOADLIB    SYS            ;Get SYS_Base.
  170.         Move.L    DTBase(A4),D0        ;DES-Tracker lib base ptr.
  171.         Beq    .4            ;It didn't open.
  172.         Move.L    D0,A1            ;It is open.
  173.         SYS    CloseLibrary        ;Close it.
  174.  
  175. .4        Move.L    DosBase(A4),D0        ;DOS lib base ptr.
  176.         Beq    .5            ;DOS didn't open (?!?!?)
  177.         Move.L    D0,A1            ;It opened.
  178.         SYS    CloseLibrary        ;Close it.
  179.  
  180. .5        Move.L    GFXBase(A4),D0        ;gfx lib base ptr.
  181.         Beq    .6            ;Didn't open.
  182.         Move.L    D0,A1            ;Yes it did.
  183.         SYS    CloseLibrary        ;Well look, this isn't an argument.
  184.  
  185. .6        Move.L    A4,A1            ;Release program variable space.
  186.         Move.L    #DTC_SIZE,D0        ;Size of variable space.
  187.         SYS    FreeMem            ;Free it.
  188.  
  189. .Leave        Move.L    D7,D0            ;Return exit code in D0.
  190.         Rts
  191.  
  192. .ProgAbort    MoveQ    #10,D7            ;Error exit code in D7.
  193.         Bra    .Leave            ;Abort with error.
  194.  
  195. ;---------------------------------------------------------------
  196. ; ProcessCmdLine routine.  Parse user input from the command line and acts
  197. ; upon it.  Does not return until all user input has been processed.
  198. ;
  199. ;   Input: A5 = Ptr to command-line argstring.
  200. ;
  201. ;  Output: D0 = 0  if all processing successful.
  202. ;        -1 if an error occurred at any point.
  203. ;
  204.  
  205. ProcessCmdLine    Move.B    (A5)+,D0    ;Fetch 1st char of command.
  206.         Cmp.B    #LF,D0        ;End of line?
  207.         Beq    .Bad        ;Yup, not a very good command. :)
  208.         Cmp.B    #" ",D0        ;Space char?
  209.         Beq    ProcessCmdLine    ;Yes, skip leading white space.
  210.         Cmp.B    #TAB,D0        ;TAB?
  211.         Beq    ProcessCmdLine    ;Yes, skip leading white space.
  212.         Cmp.B    #'a',D0        ;Now, if char is lower-case...
  213.         Blt    .Good1        ;It isn't
  214.         Cmp.B    #'z',D0
  215.         Bgt    .Good1        ;It isn't.
  216.         Sub.B    #$20,D0        ;It is, so make it upper-case.
  217.  
  218. .Good1        Asl.W    #8,D0        ;Shift first char up in D0.
  219.         Move.B    (A5)+,D0    ;Get second char of command.
  220.         Cmp.B    #LF,D0        ;Premature end of line?
  221.         Beq    .Bad        ;Yup, bad command.
  222.         Cmp.B    #'a',D0        ;Again, if char is lower-case
  223.         Blt    .Good2        ; then make it upper case.
  224.         Cmp.B    #'z',D0
  225.         Bgt    .Good2
  226.         Sub.B    #$20,D0        ;Make command char upper-case.
  227.  
  228. .Good2        Lea    CommVectors,A1    ;Ptr to command jump vectors.
  229.         Lea    CommChars,A2    ;Ptr to command chars table.
  230.         MoveQ    #NUMCOMMANDS-1,D1 ;Do for number of commands supported.
  231.  
  232. .CheckComm    Move.L    (A1)+,A0    ;Get vector for this command.
  233.         Cmp.W    (A2)+,D0    ;Is it this command?
  234.         Beq    .FoundCommand    ;Yup, so go call it.
  235.  
  236.         DBra    D1,.CheckComm    ;Nope, try next command.
  237.         Bra    .Bad        ;Unknown command.
  238.  
  239. .FoundCommand    Move.L    DTBase(A4),A6    ;Put DTLib base in A6 for command.
  240.         Jsr    (A0)        ;Call the appropriate command routine.
  241.         Tst.L    D0        ;Did an error occur?
  242.         Bne    .Abort        ;Yup, so abort.
  243.  
  244. ; Now check to see if any input remains in the command-line argstring...
  245.  
  246. .CheckInput    Move.B    (A5),D1        ;Get next char from argstring.
  247.         Beq    .Done        ;If another command exists
  248.         Cmp.B    #LF,D1        ; in the argstring, then
  249.         Beq    .Done        ; I must process that one as well.
  250.         Cmp.B    #" ",D1
  251.         Beq    .RNext
  252.         Cmp.B    #TAB,D1
  253.         Bne    ProcessCmdLine    ;More input, go and process it.
  254. .RNext        AddQ    #1,A5        ;Skip white space and get next char.
  255.         Bra    .CheckInput
  256.  
  257. .Done        MoveQ    #0,D0        ;All input processed successfully.
  258. .Leave        Rts            ;Leave, damn-it.
  259.  
  260. .Bad        Move.L    #ComText,D2    ;Bad input.
  261.         Bsr    PrintNicely    ;Show available commands to user.
  262.  
  263. .Abort        MoveQ    #-1,D0        ;Return with error code.
  264.         Bra    .Leave
  265.  
  266. ;---------------------------------------------------------------
  267. ; PrintCLI routine.  Prints a text string to the standard output.
  268. ;
  269. ;  Input: D2 = Pointer to the text string to print (NOT NULL-terminated).
  270. ;      D3 = Length of the text string.
  271. ;
  272. ; Output: Nothing.
  273. ;
  274. PrintCLI    Move.L    A6,-(Sp)
  275.         Move.L    OutputHandle(A4),D1
  276.         Move.L    DosBase(A4),A6
  277.         SYS    Write
  278.         Move.L    (Sp)+,A6
  279.         Rts
  280.  
  281. ;---------------------------------------------------------------
  282. ; PrintNicely routine.  Prints a NULL-Terminated text string one line at a time
  283. ; (using the PrintCLI routine above) so that the output can be paused by
  284. ; pressing a key.
  285. ;
  286. ;  Input: D2 = Pointer to the text string to print (NULL-terminated).
  287. ;
  288. ; Output: Nothing.
  289. ;
  290. PrintNicely    MoveM.L    A3/A5,-(Sp)
  291.         Move.L    D2,A5
  292.  
  293. .NextLine    Move.L    A5,A3
  294.         MoveQ    #0,D3
  295. .CountChars    AddQ    #1,D3
  296.         Move.B    (A3)+,D0
  297.         Beq    .Done
  298.         Cmp.B    #LF,D0
  299.         Bne    .CountChars
  300.  
  301.         Move.L    A5,D2
  302.         Move.L    A3,A5
  303.         Bsr    PrintCLI
  304.         Bra    .NextLine
  305.  
  306. .Done        MoveM.L    (Sp)+,A3/A5
  307.         Rts
  308.  
  309. ;---------------------------------------------------------------
  310. ; GetFilename routine.  This will extract a file specification from the
  311. ; command line argstring.  It skips white space and understands quotes, too. :)
  312. ;
  313. ;  Input: A5 = Pointer to current position in argstring.
  314. ;
  315. ; Output: FilenameString[] holds the extracted filespec.
  316. ;
  317. GetFilename    Lea    FilenameString(A4),A0
  318.  
  319. .Skip        Move.B    (A5),D0        ;Get char from argstring.
  320.         Cmp.B    #QUOTE,D0    ;Is it a double-quote?
  321.         Beq.S    .DoQuote    ;Yes, do special quote handling.
  322.         Cmp.B    #TAB,D0        ;Is it a TAB?
  323.         Beq    .Next        ;Yes, skip white space.
  324.         Cmp.B    #" ",D0        ;Is it a space?
  325.         Bne    .Copy        ;No, start copying chars.
  326. .Next        AddQ    #1,A5        ;Yes, skip white space.
  327.         Bra    .Skip        ;Loop until non-white-space found.
  328.  
  329. .DoQuote    AddQ    #1,A5        ;Skip the open quote char.
  330.         Move.B    (A5),D0        ;Get next char.
  331.         Cmp.B    #LF,D0        ;End of line (ie, no close quote)?
  332.         Beq    .Done        ;Yes, all done.
  333.         Cmp.B    #QUOTE,D0    ;Is it a close quote?
  334.         Beq    .EndQuote    ;Yes, skip past it and leave.
  335.         Move.B    D0,(A0)+    ;Otherwise, just store the character.
  336.         Bra    .DoQuote    ;Loop 'til EOL or close quote found.
  337.  
  338. .EndQuote    AddQ    #1,A5        ;Skip past close quote.
  339.         Bra    .Done        ;And leave.
  340.  
  341. .Copy        Cmp.B    #LF,(A5)    ;EOL yet?
  342.         Beq    .Done        ;Yup, all done.
  343. .Copy1        Move.B    (A5)+,(A0)+    ;Else copy the character.
  344.         Cmp.B    #" ",(A5)    ;Is next char a space?
  345.         Beq.S    .Done        ;Yup, white-space is a delimiter.
  346.         Cmp.B    #TAB,(A5)    ;Is it a TAB?
  347.         Beq.S    .Done        ;Yup, also a delimiter.
  348.         Cmp.B    #LF,(A5)    ;Is it EOL?
  349.         Bne.S    .Copy1        ;No, so go get next char.
  350.  
  351. .Done        Clr.B    (A0)        ;Time to go, NULL-terminate parsed string.
  352.  
  353.         Rts            ;And return.
  354.  
  355. ;---------------------------------------------------------------
  356. ; ReportLibErr routine.  Takes a library return code and turns it into
  357. ; an error message that is displayed to the user.
  358. ;
  359. ;  Input: D0 = Library return code.
  360. ;
  361. ; Output: Nothing.
  362.  
  363. ReportLibErr    Tst.L    D0        ;Did an error actually occur?
  364.         Bpl    .Done        ;Nope.
  365.  
  366.         Neg.W    D0        ;Make return code positive.
  367.         SubQ    #1,D0        ;Code now in 0..n range.
  368.         Add.W    D0,D0        ;Make longword index out of it.
  369.         Add.W    D0,D0
  370.         Lea    ErrorLookup,A0    ;Ptr to err msg addr lookup table.
  371.         Move.L    0(A0,D0.W),D2    ;Get ptr to the error message.
  372.         Bsr    PrintNicely    ;And print it.
  373.  
  374.         MoveQ    #-1,D0        ;Return general failure code.
  375.  
  376. .Done        Rts            ;That was easy.
  377.  
  378. ;---------------------------------------------------------------
  379. ; GetDecValue routine.  Extracts a string of digits from the command line
  380. ; argstring and converts the string into a binary value.
  381. ;
  382. ;  Input: A5 = Pointer to current position in the argstring.
  383. ;
  384. ; Output: D0 = extracted binary value or 0 if invalid decimal string.
  385. ;
  386. GetDecValue    MoveM.L    D1-D4/A0-A2,-(Sp)
  387.  
  388.         MoveQ    #0,D4        ;D4 is used to hold sign of result.
  389.         MoveQ    #0,D3        ;D3 will hold converted value.
  390.  
  391. .FindStart    Cmp.B    #LF,(A5)    ;EOL?
  392.         Beq    .Done        ;Yes, no value was supplied.
  393.         Cmp.B    #" ",(A5)    ;Space char?
  394.         Beq    .Next        ;Yup, skip it.
  395.         Cmp.B    #TAB,(A5)    ;TAB?
  396.         Bne    .Start        ;Nope, start processing digits.
  397. .Next        AddQ    #1,A5        ;Yes, skip it.
  398.         Bra    .FindStart    ;Loop until non-white-space found.
  399.  
  400. .Start        Cmp.B    #"+",(A5)    ;If char is "+" then skip it.
  401.         Beq    .Trim
  402.         Cmp.B    #"-",(A5)    ;If char is "-" then D4 = neg, skip char.
  403.         Bne    .OK
  404.         St    D4
  405. .Trim        AddQ    #1,A5
  406.  
  407. ; Locate the end of the decimal string, since I have to start with the
  408. ; least significant digit...
  409.  
  410. .OK        Move.L    A5,A1        ;Make copy of argstring ptr.
  411. .1        Cmp.B    #"9",(A5)    ;Is char an ASCII digit?
  412.         Bgt    .2        ;No, see if any digits were found.
  413.         Cmp.B    #"0",(A5)
  414.         Blt    .2
  415.         AddQ    #1,A5        ;Char is a digit, check next char.
  416.         Bra    .1
  417.  
  418. .2        Cmp.L    A5,A1        ;Were any digits found?
  419.         Beq    .Done        ;No, return value of 0 (in D3).
  420.  
  421.         MoveQ    #1,D2        ;Start at 10^0.
  422.         Move.L    A5,A2        ;A5 has to mark pos. after value.
  423. .3        MoveQ    #0,D0        ;D0 will hold char converted to value.
  424.         Move.B    -(A2),D0    ;Get char from string.
  425.         Sub.B    #"0",D0        ;Convert to binary value.
  426.         MulU    D2,D0        ;Times appropriate power of ten.
  427.         Add.L    D0,D3        ;Add to result accumulator.
  428.  
  429.         Move.W    D2,D0        ;Create next power of 10 (n) in D2.
  430.         Asl.W    #3,D2        ;n*8
  431.         Add.W    D0,D0        ;n*2
  432.         Add.W    D0,D2        ;D2 = (n*8)+(n*2) = 10^(p+1)
  433.  
  434.         Cmp.L    A1,A2        ;Reached end (start?) of decimal string?
  435.         Bne    .3        ;Not, yet, process next digit.
  436.  
  437. .Done        Move.L    D3,D0        ;Return converted value in D0.
  438.         Tst.B    D4        ;Was a "-" char prepended to string?
  439.         Beq    .Go        ;Nope.
  440.         Neg.L    D0        ;Yes, so negate result.
  441.  
  442. .Go        MoveM.L    (Sp)+,D1-D4/A0-A2
  443.         Rts            ;All done.
  444.  
  445. ;---------------------------------------------------------------
  446. ; Here are the functions that correspond to the commands supported by
  447. ; DTC.  Essentially, they just pass the user input on to the library
  448. ; and report any errors that may crop up.  This first routine, called
  449. ; "CommandDone", handles generic clean-up for all commands.  Therefore,
  450. ; all commands eventually wind up at this routine...
  451.  
  452. CommandDone    Bsr    ReportLibErr
  453.         Rts
  454.  
  455. ;---------------------------------------------------------------
  456. ; FlushLibrary command.  Invoked with "XL"...
  457.  
  458. FlushLibrary    Move.L    #FlushText,D2
  459.         Bsr    PrintNicely
  460.  
  461.         LOADLIB    SYS
  462.         Move.L    DTBase(A4),A1
  463.         SYS    RemLibrary
  464.  
  465.         MoveQ    #0,D0
  466.         Bra    CommandDone
  467.  
  468. ;---------------------------------------------------------------
  469. ; SaveModule command.  Invoked with "SM"...
  470.  
  471. SaveModule    Bsr    GetFilename        ;Get filespec from argstring.
  472.  
  473.         Lea    FilenameString(A4),A0    ;Get ptr to filespec string.
  474.         Tst.B    (A0)            ;NULL string?
  475.         Bne    .DoCall            ;Nope, proceed normally.
  476.  
  477.         Sub.L    A0,A0            ;Yes, so pass NULL-Ptr.
  478.  
  479. .DoCall        SYS    SaveModule
  480.  
  481.         Bra    CommandDone
  482.  
  483. ;---------------------------------------------------------------
  484. ; SetSaveFormat command. Invoked with "MF"...
  485.  
  486. SetSaveFormat    Bsr    GetDecValue    ;Extract decimal value from argstring.
  487.  
  488.         SYS    SetSaveFormat
  489.  
  490.         Bra    CommandDone
  491.  
  492. ;---------------------------------------------------------------
  493. ; WaitEndPlay command. Invoked with "WE".
  494. ;
  495. ; Note that this function uses a combination of the event signalling and
  496. ; examination of the status flags, since there may be many reasons why a
  497. ; module would not be playing (eg, stopped, unloaded, finished, etc), so
  498. ; rather than wait for and check all these events, I just wait for a few
  499. ; types of events to occur and then check the DF_PLAYING flag, which is 0
  500. ; if no song is playing, regardless of how it came to be suddenly not
  501. ; playing anymore. :)  Note that I can't just wait for SEF_SECOND all by
  502. ; itself, since if the module stops playing for any reason, then I will
  503. ; no longer get signalled (SEF_SECOND signals upon each second of elapsed
  504. ; *play* time).
  505. ;
  506.  
  507. SIGBITS    = SEF_SECOND|SEF_FINISH|SEF_STOP|SEF_MODUNLOADED|SEF_MODLOADED
  508.  
  509. WaitEndPlay    Move.L    A6,A5
  510.         LOADLIB    SYS
  511.  
  512.         BTst    #DF_PLAYING,dtl_Flags+1(A5)
  513.         Beq    .Leave
  514.  
  515.         Bsr    GetDecValue
  516.         Tst.L    D0
  517.         Bmi    .Leave
  518.         Bne    .Go
  519.  
  520.         Move.L    #600,D0        ;Set default of ten minutes.
  521.  
  522. ; Calc current elapsed time in seconds...
  523.  
  524. .Go        Move.L    dtl_ElapsedTime(A5),D3
  525.         DivU    #60,D3
  526.  
  527.         MoveQ    #-1,D0
  528.         SYS    AllocSignal
  529.         Move.L    D0,SigBitNum(A4)
  530.         Beq    .Leave        ;Just leave if signal didn't allocate.
  531.  
  532.         Move.L    DTBase(A4),A6
  533.         Move.W    #SIGBITS,D1    ;Specify events I want to be signalled about.
  534.         SYS    AddStatusSignal
  535.         Tst.L    D0
  536.         Bne    .Done        ;Lib call failed.
  537.  
  538. .WaitLoop    LOADLIB    SYS        ;SYS_Base back in A6
  539.         MoveQ    #0,D0
  540.         Move.L    SigBitNum(A4),D6
  541.         BSet    D6,D0        ;Wait for signal I allocated.
  542.         BSet    #SIGBREAKB_CTRL_C,D0
  543.         SYS    Wait        ;Wait for my signal.
  544.  
  545.         BTst    #SIGBREAKB_CTRL_C,D0
  546.         Beq    .NoAbort
  547.  
  548.         Move.L    #AbortedText,D2
  549.         Move.L    #AbortedLen,D3
  550.         Bsr    PrintCLI
  551.         Bra    .Done
  552.  
  553. .NoAbort    BTst    #DF_PLAYING,dtl_Flags+1(A5)    ;Still playing?
  554.         Beq    .Done                ;Nope, time to go.
  555.  
  556.         Move.L    dtl_ElapsedTime(A5),D2    ;Get elapsed time in jiffies.
  557.         DivU    #60,D2            ;Convert it to seconds.
  558.  
  559.         Cmp.L    D2,D3        ;Has specified time elapsed?
  560.         Bgt    .WaitLoop    ;Nope, wait another second.
  561.  
  562. .Done        LOADLIB    SYS
  563.         Move.L    SigBitNum(A4),D0
  564.         SYS    FreeSignal    ;Free up signal I had allocated.
  565.  
  566.         Move.L    dtl_ElapsedTime(A5),D0
  567.         Bsr    BinToTime
  568.  
  569. .Leave        Move.L    A5,A6
  570.         MoveQ    #0,D0
  571.         Bra    CommandDone
  572.  
  573. AbortedText    Dc.B    LF,"*** User abort ***",LF
  574. AbortedLen    = *-AbortedText
  575.         Even
  576.  
  577. ;---------------------------------------------------------------
  578. ; RetitleModule command. Invoked with "RM"...
  579.  
  580. RetitleModule    Bsr    GetFilename        ;Extract filespec from argstring.
  581.  
  582.         Lea    FilenameString(A4),A0    ;Ptr to filespec string.
  583.         SYS    RetitleModule
  584.  
  585.         Bra    CommandDone
  586.  
  587. ;---------------------------------------------------------------
  588. ; SetDefaultTempo command.  Invoked with "DT"...
  589.  
  590. SetDefaultTempo    Bsr    GetDecValue        ;Extract decimal val from argstring.
  591.  
  592.         SYS    SetDefaultTempo
  593.  
  594.         Bra    CommandDone
  595.  
  596. ;---------------------------------------------------------------
  597. ; ApplyGlobalTempo command.  Invoked with "AT"...
  598.  
  599. ApplyGlobalTempo
  600.         SYS    ApplyGlobalTempo    ;Ooo, really tricky code here. :)
  601.  
  602.         Bra    CommandDone
  603.  
  604. ;---------------------------------------------------------------
  605. ; SetIterations command.  Invoked with "SI"...
  606.  
  607. SetIterations    Bsr    GetDecValue        ;Extract dec val from argstring.
  608.  
  609.         SYS    SetIterations
  610.  
  611.         Bra    CommandDone
  612.  
  613. ;---------------------------------------------------------------
  614. ; SetStartPosition command.  Invoked with "SS"...
  615.  
  616. SetStartPosition
  617.         Bsr    GetDecValue        ;Extract dec val from argstring.
  618.  
  619.         MoveQ    #0,D1            ;Start note index always 0 for DTC.
  620.         SYS    SetStartPosition
  621.  
  622.         Bra    CommandDone
  623.  
  624. ;---------------------------------------------------------------
  625. ; SetEndPosition command.  Invoked with "SE"...
  626.  
  627. SetEndPosition    Bsr    GetDecValue        ;Get dec val from argstring.
  628.  
  629.         MoveQ    #0,D1            ;End note index always 0 for DTC.
  630.         SYS    SetEndPosition
  631.  
  632.         Bra    CommandDone
  633.  
  634. ;---------------------------------------------------------------
  635. ; SetCurPosition command.  Invoked with "SC"...
  636.  
  637. SetCurPosition    Bsr    GetDecValue        ;You get the idea by now. :)
  638.  
  639.         MoveQ    #0,D1            ;Current note index always 0 for DTC.
  640.         SYS    SetCurPosition
  641.  
  642.         Bra    CommandDone
  643.  
  644. ;---------------------------------------------------------------
  645. ; ChannelEnable command.  Invoked with "CE"...
  646.  
  647. ChannelEnable    Bsr    GetDecValue
  648.         MoveQ    #-128,D1
  649.         Tst.L    D0
  650.         Bpl.S    .1
  651.  
  652.         Neg.W    D0
  653.         MoveQ    #0,D1
  654.  
  655. .1        Cmp.W    #1000,D0
  656.         Blt.S    .2
  657.         Sub.W    #1000,D0
  658.         BSet    #3,D1
  659.  
  660. .2        Cmp.W    #100,D0
  661.         Blt.S    .3
  662.         Sub.W    #100,D0
  663.         BSet    #2,D1
  664.  
  665. .3        Cmp.W    #10,D0
  666.         Blt.S    .4
  667.         Sub.W    #10,D0
  668.         BSet    #1,D1
  669.  
  670. .4        Cmp.W    #1,D0
  671.         Blt.S    .5
  672.         BSet    #0,D1
  673.  
  674. .5        Move.W    D1,D0
  675.         SYS    SetChannelEnable
  676.  
  677.         Bra    CommandDone
  678.  
  679. ;---------------------------------------------------------------
  680. ; TimingMode command.  Invoked with "TM"...
  681.  
  682. TimingMode    Bsr    GetDecValue
  683.  
  684.         SYS    SetTimingMode
  685.  
  686.         Bra    CommandDone
  687.  
  688. ;---------------------------------------------------------------
  689. ; SetLoopIntent command.  Invoked with "LI"...
  690.  
  691. SetLoopIntent    Bsr    GetDecValue
  692.  
  693.         SYS    SetLoopIntent
  694.  
  695.         Bra    CommandDone
  696.  
  697. ;---------------------------------------------------------------
  698. ; SetFineTempo command.  Invoked with "FT"...
  699.  
  700. SetFineTempo    Bsr    GetDecValue
  701.  
  702.         SYS    SetFineTempo
  703.  
  704.         Bra    CommandDone
  705.  
  706. ;---------------------------------------------------------------
  707. ; AutoDetect command.  Invoked with "AD"...
  708.  
  709. AutoDetect    Bsr    GetDecValue
  710.  
  711.         SYS    SetAutoTiming
  712.  
  713.         Bra    CommandDone
  714.  
  715. ;---------------------------------------------------------------
  716. ; SetTempoInt command.  Invoked with "TI"...
  717.  
  718. SetTempoInt    Bsr    GetDecValue
  719.  
  720.         SYS    SetTempoInt
  721.  
  722.         Bra    CommandDone
  723.  
  724. ;---------------------------------------------------------------
  725. ; SetModulePath command.  Invoked with "SP"...
  726.  
  727. SetModulePath    Bsr    GetFilename        ;Extract filespec from argstring.
  728.  
  729.         Lea    FilenameString(A4),A0    ;Get ptr to extracted filespec.
  730.         Cmp.B    #"?",(A0)        ;Does it start with "?"?
  731.         Beq    .DisplayPaths        ;Yes, just display current paths.
  732.         Tst.B    (A0)            ;Is it a NULL string?
  733.         Bne    .DoCall            ;Nope, proceed normally.
  734.  
  735.         Sub.L    A0,A0            ;Yup, so pass NULL-ptr instead.
  736.  
  737. .DoCall        SYS    SetModulePath
  738.         Move.L    D0,D7            ;Save return code temporarily.
  739.  
  740. ; Display all current paths as a convenience to the user...
  741.  
  742. .DisplayPaths    Tst.L    dtl_ModPathList(A6)    ;Ptr to 1st path in list.
  743.         Bne    .SayPaths        ;List contains 1 or more paths.
  744.  
  745.         Move.L    #NoPathsText,D2        ;List is empty, say so.
  746.         Move.L    #NoPathsLen,D3
  747.         Bsr    PrintCLI
  748.         Bra    .Go            ;And leave.
  749.  
  750. .SayPaths    Move.L    #PathsText,D2        ;Say "Current paths are..."
  751.         Move.L    #PathsLen,D3
  752.         Bsr    PrintCLI
  753.  
  754.         Lea    dtl_ModPathList(A6),A3    ;Ptr to ptr to 1st path in list.
  755. .NextPath    Move.L    (A3),D1            ;Get next pathentry ptr.
  756.         Beq    .Go            ;Reached end of list, so leave.
  757.         Move.L    D1,A3            ;A3 = ptr to next pathentry.
  758.         MoveQ    #0,D3
  759.         Move.W    pe_Length(A3),D3    ;Length of pathentry string.
  760.         SubQ    #1,D3            ;Less 1 for the NULL.
  761.         Lea    pe_SIZE(A3),A0        ;A0 pts to the string.
  762.         Move.L    A0,D2            ;Stupid DOS wants ptr in D2.
  763.         Bsr    PrintCLI
  764.         Move.L    #LFText,D2        ;Print linfeed in lieu of NULL.
  765.         Move.L    #LFLen,D3
  766.         Bsr    PrintCLI
  767.         Bra    .NextPath        ;Go print next path (if one).
  768.  
  769. .Go        Move.L    #LFText,D2        ;An extra linefeed.
  770.         Move.L    #LFLen,D3        ; (looks better).
  771.         Bsr    PrintCLI
  772.  
  773.         Move.L    D7,D0            ;Return code back in D0.
  774.         Bra    CommandDone
  775.  
  776. PathsText    Dc.B    LF,"Current paths are:",LF
  777. PathsLen    = *-PathsText
  778. NoPathsText    Dc.B    LF,"Path list is empty",LF
  779. NoPathsLen    = *-NoPathsText
  780. LFText        Dc.B    LF
  781. LFLen        = 1
  782.         Even
  783.  
  784. ;---------------------------------------------------------------
  785. ; LoadModule command.  Invoked with "LM"...
  786.  
  787. LoadModule    Bsr    GetFilename
  788.  
  789.         Lea    FilenameString(A4),A0
  790.         SYS    LoadModule
  791.  
  792.         Bra    CommandDone
  793.  
  794. ;---------------------------------------------------------------
  795. ; LoadAndGo command.  Invoked with "LP"...
  796.  
  797. LoadAndGo    Bsr    GetFilename
  798.  
  799.         Lea    FilenameString(A4),A0
  800.         SYS    LoadModule
  801.  
  802.         Tst.L    D0        ;Error during load?
  803.         Bmi    CommandDone    ;Yup, don't bother trying to play it.
  804.  
  805.         Bra    BeginPlaySeq    ;Go start the song playing.
  806.  
  807. ;---------------------------------------------------------------
  808. ; UnloadModule command.  Invoked with "UM"...
  809.  
  810. UnloadModule    SYS    UnloadModule
  811.  
  812.         Bra    CommandDone
  813.  
  814. ;---------------------------------------------------------------
  815. ; BeginPlaySeq command.  Invoked with "BP"...
  816.  
  817. BeginPlaySeq    SYS    BeginPlaySeq
  818.  
  819.         Bra    CommandDone
  820.  
  821. ;---------------------------------------------------------------
  822. ; SetGlobalTempo command.  Invoked with "ST"...
  823.  
  824. SetGlobalTempo    Bsr    GetDecValue
  825.  
  826.         SYS    SetGlobalTempo
  827.  
  828.         Bra    CommandDone
  829.  
  830. ;---------------------------------------------------------------
  831. ; SetFilter command.  Invoked with "SF"...
  832.  
  833. SetFilter    Bsr    GetDecValue
  834.  
  835.         SYS    SetFilter
  836.  
  837.         Bra    CommandDone
  838.  
  839. ;---------------------------------------------------------------
  840. ; PausePlaySeq command.  Invoked with "PP"...
  841.  
  842. PausePlaySeq    SYS    PausePlaySeq
  843.  
  844.         Bra    CommandDone
  845.  
  846. ;---------------------------------------------------------------
  847. ; ContinuePlaySeq command.  Invoked with "CP"...
  848.  
  849. ContinuePlaySeq    SYS    ContinuePlaySeq
  850.  
  851.         Bra    CommandDone
  852.  
  853. ;---------------------------------------------------------------
  854. ; StopPlaySeq command.  Invoked with "KI"...
  855.  
  856. StopPlaySeq    SYS    StopPlaySeq
  857.  
  858.         Bra    CommandDone
  859.  
  860. ;---------------------------------------------------------------
  861. ; SetGlobalVolume command.  Invoked with "SV"...
  862.  
  863. SetGlobalVolume    Bsr    GetDecValue
  864.  
  865.         SYS    SetGlobalVolume
  866.  
  867.         Bra    CommandDone
  868.  
  869. ;---------------------------------------------------------------
  870. ; SetVolumeFadeRate command.  Invoked with "FR"...
  871.  
  872. SetVolumeFadeRate
  873.         Bsr    GetDecValue
  874.  
  875.         SYS    SetVolumeFadeRate
  876.  
  877.         Bra    CommandDone
  878.  
  879. ;---------------------------------------------------------------
  880. ; FadeGlobalVolume command.  Invoked with "FV"...
  881.  
  882. FadeGlobalVolume
  883.         Bsr    GetDecValue
  884.  
  885.         SYS    FadeGlobalVolume
  886.  
  887.         Bra    CommandDone
  888.  
  889. ;---------------------------------------------------------------
  890. ; ResetDefaults command.  Invoked with "RD"...
  891.  
  892. ResetDefaults    SYS    ResetDefaults
  893.  
  894.         Bra    CommandDone
  895.  
  896. ;---------------------------------------------------------------
  897. ; CalcElapsedTime command.  Invoked with "ET"...
  898.  
  899. CalcElapsedTime    Lea    TimeScanInfo(A4),A0
  900.  
  901. ; Initialize the TIMESCANINFO structure...
  902.  
  903.         Move.B    dtl_StartPosition(A6),tsi_StartPos(A0)
  904.         Move.B    dtl_StartNoteIndex(A6),tsi_StartNote(A0)
  905.         Move.B    dtl_EndPosition(A6),tsi_EndPos(A0)
  906.         Move.B    dtl_EndNoteIndex(A6),tsi_EndNote(A0)
  907.         Move.B    dtl_DefaultTempo(A6),tsi_DefaultTempo(A0)
  908.         Move.B    dtl_FineTempo(A6),tsi_FineTempo(A0)
  909.  
  910.         MoveQ    #0,D0
  911.         Tst.B    dtl_TimingMode(A6)
  912.         Beq    .1
  913.         BSet    #TSIB_TIMINGMODE,D0
  914.  
  915. .1        BTst    #DF_TEMPOINT-8,dtl_Flags2(A6)
  916.         Beq    .2
  917.         BSet    #TSIB_TEMPOINTERP,D0
  918.  
  919. .2        Tst.B    dtl_Iterations(A6)
  920.         Beq    .Multi
  921.         Cmp.B    #1,dtl_Iterations(A6)
  922.         Beq    .3
  923.  
  924. .Multi        BSet    #TSIB_MULTIPLEITERS,D0
  925.  
  926. .3        Move.B    D0,tsi_Flags(A0)
  927.  
  928.         SYS    CalcElapsedTime
  929.  
  930.         Tst.L    D0
  931.         Bmi    .Err
  932.  
  933.         Lea    TimeScanInfo(A4),A2
  934.  
  935.         Move.L    tsi_FirstIterTime(A2),D0
  936.         Move.L    tsi_ConsecIterTime(A2),D1
  937.  
  938.         MoveQ    #0,D2
  939.         Move.B    dtl_Iterations(A6),D2
  940.         Bra    .4
  941.  
  942. .AddIterLoop    Add.L    D1,D0
  943.  
  944. .4        SubQ    #1,D2
  945.         Bgt    .AddIterLoop
  946.  
  947. ; I now have the total elapsed time for the requested iterations, so
  948. ; convert the value to a string and print it...
  949.  
  950.         Bsr    BinToTime
  951.  
  952.         Move.L    #SayTimeText,D2
  953.         Move.L    #SayTimeLen,D3
  954.         Bsr    PrintCLI
  955.  
  956.         Lea    TimeString(A4),A0
  957.         Move.L    A0,D2
  958.         MoveQ    #11,D3
  959.         Bsr    PrintCLI
  960.  
  961.         Move.L    #SayLFText,D2
  962.         Move.L    #SayLFLen,D3
  963.         Bsr    PrintCLI
  964.  
  965.         MoveQ    #0,D0
  966.  
  967. .Err        Bra    CommandDone
  968.  
  969. ;---------------------------------------------------------------
  970. ; SetTemporalStart command.  Invoked with "TS"...
  971.  
  972. SetTemporalStart
  973.         Bsr    GetDecValue
  974.  
  975.         SYS    SetTemporalStart
  976.  
  977.         Bra    CommandDone
  978.  
  979. ;---------------------------------------------------------------
  980. ; SetTemporalEnd command.  Invoked with "TE"...
  981.  
  982. SetTemporalEnd
  983.         Bsr    GetDecValue
  984.  
  985.         SYS    SetTemporalEnd
  986.  
  987.         Bra    CommandDone
  988.  
  989. ;---------------------------------------------------------------
  990. ; SetTemporalPos command.  Invoked with "TC"...
  991.  
  992. SetTemporalPos
  993.         Bsr    GetDecValue
  994.  
  995.         SYS    SetTemporalPos
  996.  
  997.         Bra    CommandDone
  998.  
  999. ;---------------------------------------------------------------
  1000. ; CalcVolFadeTime command.  Invoked with "CF"...
  1001.  
  1002. CalcVolFadeTime    Bsr    GetDecValue
  1003.  
  1004.         Move.B    D0,D1
  1005.         Move.B    dtl_GlobalVolume(A6),D0
  1006.         Move.B    dtl_VolFadeRate(A6),D2
  1007.         
  1008.         SYS    CalcVolFadeTime
  1009.  
  1010.         Bsr    BinToTime
  1011.  
  1012.         Move.L    #SayFadeText,D2
  1013.         Move.L    #SayFadeLen,D3
  1014.         Bsr    PrintCLI
  1015.  
  1016.         Lea    TimeString+6(A4),A0
  1017.         Move.L    A0,D2
  1018.         MoveQ    #11-6,D3
  1019.         Bsr    PrintCLI
  1020.  
  1021.         Move.L    #SayLFText,D2
  1022.         Move.L    #SayLFLen,D3
  1023.         Bsr    PrintCLI
  1024.  
  1025.         MoveQ    #0,D0
  1026.         Bra    CommandDone
  1027.  
  1028. SayFadeText    Dc.B    LF,"Volume Fade Time (SS:JJ): "
  1029. SayFadeLen    = *-SayFadeText
  1030.         Even
  1031.  
  1032. ;---------------------------------------------------------------
  1033. ; VerifyModule command.  Invoked with "VM"...
  1034.  
  1035. VerifyModule    Bsr    GetFilename
  1036.  
  1037.         Lea    FilenameString(A4),A0
  1038.         SYS    VerifyModule
  1039.         Tst.L    D0
  1040.         Bmi    CommandDone
  1041.  
  1042.         Lea    STText(PC),A0        ;Assume ST v2.6 format.
  1043.         MoveQ.L    #STTLen,D3
  1044.         Cmp.B    #MF_SOUNDTRACKER,D0    ;Is it ST v2.6?
  1045.         Beq    .Print            ;Yup, say so.
  1046.  
  1047.         Lea    DTText(PC),A0
  1048.         MoveQ.L    #DTTLen,D3
  1049.         Cmp.B    #MF_DESTRACKER,D0
  1050.         Beq    .Print
  1051.  
  1052.         Lea    NTText(PC),A0        ;Must be Noisetracker then.
  1053.         MoveQ.L    #NTTLen,D3
  1054.  
  1055. .Print        Move.L    A0,D2            ;Print module format.
  1056.         Bsr    PrintCLI
  1057.  
  1058.         MoveQ    #0,D0            ;Success.
  1059.  
  1060. .Error        Bra    CommandDone
  1061.  
  1062. STText        Dc.B    LF,"File is Soundtracker v2.6 format.",LF,LF
  1063. STTLen        = *-STText
  1064. NTText        Dc.B    LF,"File is Noisetracker/ProTracker format.",LF,LF
  1065. NTTLen        = *-NTText
  1066. DTText        Dc.B    LF,"File is DES-Tracker v1.0 format.",LF,LF
  1067. DTTLen        = *-DTText
  1068.  
  1069.         Even
  1070.  
  1071. ;---------------------------------------------------------------
  1072. ; BinToDec routine.  Converts an unsigned long into a decimal string
  1073. ; that can be printed.  The resultant string is NULL-Terminated.
  1074. ;
  1075. ;  Input: D0 = unsigned longword to convert.
  1076. ;
  1077. ; Output: DecString[] holds the decimal string of the value.
  1078. ;
  1079. BinToDec    MoveM.L    D0-D3/A0,-(Sp)
  1080.  
  1081.         MoveQ    #10-1,D1    ;Start with index for highest power of 10.
  1082.         Lea    DecString(A4),A0
  1083.  
  1084. .Loop        Move.L    D1,D2
  1085.         Add.L    D2,D2
  1086.         Add.L    D2,D2
  1087.         Move.L    PowerTable(PC,D2.W),D2    ;D2 holds current power of 10.
  1088.  
  1089.         MoveQ    #-1,D3
  1090. .1        AddQ.W    #1,D3
  1091.         Sub.L    D2,D0
  1092.         Bpl    .1
  1093.         Add.L    D2,D0
  1094.         Add.B    #"0",D3        ;D3 holds ASCII digit.
  1095.         Move.B    D3,(A0)+    ;Store digit in string.
  1096.  
  1097.         DBra    D1,.Loop
  1098.         Clr.B    (A0)
  1099.         MoveM.L    (Sp)+,D0-D3/A0
  1100.         Rts
  1101.  
  1102. PowerTable    Dc.L    1
  1103.         Dc.L    10
  1104.         Dc.L    100
  1105.         Dc.L    1000
  1106.         Dc.L    10000
  1107.         Dc.L    100000
  1108.         Dc.L    1000000
  1109.         Dc.L    10000000
  1110.         Dc.L    100000000
  1111.         Dc.L    1000000000
  1112.  
  1113. ;---------------------------------------------------------------
  1114. ; BinToTime routine.  Converts a longword number of ticks (units of
  1115. ; 1/60 second) into a string of the form "00:00:00:00"...
  1116. ;
  1117. ;  Input: D0.L = unsigned longword value to convert.
  1118. ;
  1119. ; Output: TimeString holds the time string of the value.
  1120. ;
  1121. BinToTime    MoveM.L    D2-D3/A2,-(Sp)
  1122.  
  1123.         Move.L    D0,D2
  1124.         Lea    TimeString(A4),A2
  1125.  
  1126. ; Calculate number of hours...
  1127.  
  1128.         Move.L    #216000,D1
  1129.         MoveQ    #0,D3
  1130.  
  1131. .HoursLoop    AddQ    #1,D3
  1132.         Sub.L    D1,D2
  1133.         Bpl    .HoursLoop
  1134.  
  1135.         Add.L    D1,D2
  1136.         SubQ    #1,D3
  1137.         Move.L    D3,D0
  1138.         Bsr    BinToDec
  1139.         Lea    DecString+8(A4),A0
  1140.         Move.B    (A0)+,(A2)+
  1141.         Move.B    (A0)+,(A2)+
  1142.         Move.B    #":",(A2)+
  1143.  
  1144. ; Calculate number of minutes...
  1145.  
  1146.         Move.L    #3600,D1
  1147.         MoveQ    #0,D3
  1148.  
  1149. .MinutesLoop    AddQ    #1,D3
  1150.         Sub.L    D1,D2
  1151.         Bpl    .MinutesLoop
  1152.  
  1153.         Add.L    D1,D2
  1154.         SubQ    #1,D3
  1155.         Move.L    D3,D0
  1156.         Bsr    BinToDec
  1157.         Lea    DecString+8(A4),A0
  1158.         Move.B    (A0)+,(A2)+
  1159.         Move.B    (A0)+,(A2)+
  1160.         Move.B    #":",(A2)+
  1161.  
  1162. ; Calculate number of seconds...
  1163.  
  1164.         MoveQ    #60,D1
  1165.         MoveQ    #0,D3
  1166.  
  1167. .SecondsLoop    AddQ    #1,D3
  1168.         Sub.L    D1,D2
  1169.         Bpl    .SecondsLoop
  1170.  
  1171.         Add.L    D1,D2
  1172.         SubQ    #1,D3
  1173.         Move.L    D3,D0
  1174.         Bsr    BinToDec
  1175.         Lea    DecString+8(A4),A0
  1176.         Move.B    (A0)+,(A2)+
  1177.         Move.B    (A0)+,(A2)+
  1178.         Move.B    #":",(A2)+
  1179.  
  1180. ; Calculate number of jiffies...
  1181.  
  1182.         Move.L    D2,D0
  1183.         Bsr    BinToDec
  1184.         Lea    DecString+8(A4),A0
  1185.         Move.B    (A0)+,(A2)+
  1186.         Move.B    (A0)+,(A2)+
  1187.         Clr.B    (A2)
  1188.  
  1189.         MoveM.L    (Sp)+,D2-D3/A2
  1190.         Rts
  1191.  
  1192.  
  1193. ;==============================
  1194.  
  1195.         DATA
  1196.         Even
  1197.  
  1198. ; Here is the table that holds all support command "names"...
  1199.  
  1200. CommChars    Dc.W    "LM","BP","ST","PP","CP","SV","FR","FV","UM","SF"
  1201.         Dc.W    "SI","SS","SE","SC","CE","SP","DT","AT","RM","WE"
  1202.         Dc.W    "XL","SM","VM","TM","AD","FT","LI","MF","RD","LP"
  1203.         Dc.W    "TI","KI","CT","TS","TE","TC","CF"
  1204. NUMCOMMANDS    = (*-CommChars)/2
  1205.  
  1206. ; Here is the table that holds vectors to each supported command...
  1207.  
  1208. CommVectors    Dc.L    LoadModule
  1209.         Dc.L    BeginPlaySeq
  1210.         Dc.L    SetGlobalTempo
  1211.         Dc.L    PausePlaySeq
  1212.         Dc.L    ContinuePlaySeq
  1213.         Dc.L    SetGlobalVolume
  1214.         Dc.L    SetVolumeFadeRate
  1215.         Dc.L    FadeGlobalVolume
  1216.         Dc.L    UnloadModule
  1217.         Dc.L    SetFilter
  1218.         Dc.L    SetIterations
  1219.         Dc.L    SetStartPosition
  1220.         Dc.L    SetEndPosition
  1221.         Dc.L    SetCurPosition
  1222.         Dc.L    ChannelEnable
  1223.         Dc.L    SetModulePath
  1224.         Dc.L    SetDefaultTempo
  1225.         Dc.L    ApplyGlobalTempo
  1226.         Dc.L    RetitleModule
  1227.         Dc.L    WaitEndPlay
  1228.         Dc.L    FlushLibrary
  1229.         Dc.L    SaveModule
  1230.         Dc.L    VerifyModule
  1231.         Dc.L    TimingMode
  1232.         Dc.L    AutoDetect
  1233.         Dc.L    SetFineTempo
  1234.         Dc.L    SetLoopIntent
  1235.         Dc.L    SetSaveFormat
  1236.         Dc.L    ResetDefaults
  1237.         Dc.L    LoadAndGo
  1238.         Dc.L    SetTempoInt
  1239.         Dc.L    StopPlaySeq
  1240.         Dc.L    CalcElapsedTime
  1241.         Dc.L    SetTemporalStart
  1242.         Dc.L    SetTemporalEnd
  1243.         Dc.L    SetTemporalPos
  1244.         Dc.L    CalcVolFadeTime
  1245.  
  1246. ; Lookup table for error message string addresses...
  1247.  
  1248. ErrorLookup    Dc.L    Owned
  1249.         Dc.L    NoMod
  1250.         Dc.L    NoPlay
  1251.         Dc.L    OutRnge
  1252.         Dc.L    Trimmed
  1253.         Dc.L    LoadErr
  1254.         Dc.L    NoMem
  1255.         Dc.L    BadPath
  1256.         Dc.L    Format
  1257.         Dc.L    SaveErr
  1258.         Dc.L    NoInstErr
  1259.         Dc.L    NotFoundErr
  1260.         Dc.L    MInstsErr
  1261.         Dc.L    SeqActive
  1262.         Dc.L    TooManyPatts
  1263.  
  1264. ; Error messages...
  1265.  
  1266. Owned        Dc.B    LF,"ERROR: Library has been owned by another prog.",LF,LF,NULL
  1267. NoMod        Dc.B    LF,"ERROR: No module is loaded.",LF,LF,NULL
  1268. NoPlay        Dc.B    LF,"ERROR: No play sequence is active.",LF,LF,NULL
  1269. OutRnge        Dc.B    LF,"ERROR: Input value out of range.",LF,LF,NULL
  1270. Trimmed        Dc.B    LF,"NOTE: Input value was trimmed.",LF,LF,NULL
  1271. LoadErr        Dc.B    LF,"ERROR: Could not load file.",LF,LF,NULL
  1272. NoMem        Dc.B    LF,"ERROR: Insufficient memory.",LF,LF,NULL
  1273. BadPath        Dc.B    LF,"ERROR: Illegal pathname.",LF,LF,NULL
  1274. Format        Dc.B    LF,"ERROR: Unrecognized module format.",LF,LF,NULL
  1275. SaveErr        Dc.B    LF,"ERROR: Could not save file.",LF,LF,NULL
  1276. NoInstErr    Dc.B    LF,"ERROR: Non-existent instrument.",LF,LF,NULL
  1277. NotFoundErr    Dc.B    LF,"ERROR: File not found.",LF,LF,NULL
  1278. MInstsErr    Dc.B    LF,"ERROR: Module is missing instrument(s).",LF,LF,NULL
  1279. SeqActive    Dc.B    LF,"ERROR: Play sequence is already active.",LF,LF,NULL
  1280. TooManyPatts    Dc.B    LF,"ERROR: Too many patterns for S/T v2.6 format.",LF,LF,NULL
  1281.  
  1282. SayTimeText    Dc.B    LF,"Total Play Time: "
  1283. SayTimeLen    = *-SayTimeText
  1284.  
  1285. SayLFText    Dc.B    LF,LF
  1286. SayLFLen    = *-SayLFText
  1287.  
  1288. FlushText    Dc.B    LF,"Flushing DES-Tracker library...",LF,0
  1289.  
  1290. WhichTimerText    Dc.B    "DES-Tracker is currently using CIA "
  1291. WhichTimerLen    = *-WhichTimerText
  1292. CIAAText    Dc.B    "A, "
  1293. CIAALen        = *-CIAAText
  1294. CIABText    Dc.B    "B, "
  1295. CIABLen        = *-CIABText
  1296. TimerAText    Dc.B    "timer A.",LF
  1297. TimerALen    = *-TimerAText
  1298. TimerBText    Dc.B    "timer B.",LF
  1299. TimerBLen    = *-TimerBText
  1300.  
  1301. GFXErrText    Dc.B    LF,"ERROR: Couldn't open graphics.library.",LF,LF,NULL
  1302. DOSErrText    Dc.B    LF,"ERROR: Couldn't open dos.library.",LF,LF,NULL
  1303. NoLibOpenText    Dc.B    LF,"ERROR: You need destracker.library v3.0.",LF,LF,NULL
  1304.  
  1305. ; Title, copyright, and usage text...
  1306.  
  1307. HelloText    Dc.B    "destracker.library Commander program",LF
  1308.         Dc.B    "Copyright (c)1992,1993 by Darren Schebek",LF
  1309.         Dc.B    "Version 2.0  Dec 18, 1993",LF
  1310.         Dc.B    NULL
  1311.  
  1312. ComText        Dc.B    LF,"usage: dtc command { command command...}",LF,LF
  1313.         Dc.B    "Commands:",LF
  1314.         Dc.B    "AD {0|1}       Auto-detect PAL/NTSC off/on",LF
  1315.         Dc.B    "AT             Apply global tempo to song",LF
  1316.         Dc.B    "BP             Begin play sequence",LF
  1317.         Dc.B    "CE {+|-ssss}   Enable/disable channels",LF
  1318.         Dc.B    "CP             Continue play sequence",LF
  1319.         Dc.B    "CF {destvol}   Calculate time for a volume fade",LF
  1320.         Dc.B    "CT             Calculate play time (1 iteration)",LF
  1321.         Dc.B    "DT {1..31}     Set default module tempo",LF
  1322.         Dc.B    "FR {0..31}     Set volume fade rate",LF
  1323.         Dc.B    "FT {-128..127} Set fine tempo control",LF
  1324.         Dc.B    "FV {0..64}     Fade global volume",LF
  1325.         Dc.B    "KI             Kill (stop) current play sequence.",LF
  1326.         Dc.B    "LI {0|1}       Set whether song is intended to loop",LF
  1327.         Dc.B    "LM {filename}  Load module (pathname optional)",LF
  1328.         Dc.B    "LP {filename}  Load and play module (pathname optional)",LF
  1329.         Dc.B    "MF {0|1|2}     Set save format (0=STv2.6, 1=NTv2.0, 1=DTv1.0)",LF
  1330.         Dc.B    "PP             Pause play sequence",LF
  1331.         Dc.B    "RD             Reset library parms to default values",LF
  1332.         Dc.B    "RM {songname}  Retitle a loaded module",LF
  1333.         Dc.B    "SC {0..?}      Set current play sequence position",LF
  1334.         Dc.B    "SE {0..?}      Set play sequence end position",LF
  1335.         Dc.B    "SF {0|1}       Set filter off/on",LF
  1336.         Dc.B    "SI {0..255}    Set # of play sequence iterations",LF
  1337.         Dc.B    "SM [filespec]  Save module to disk (pathname optional)",LF
  1338.         Dc.B    "SP [pathname]  Add/remove load module search path(s)",LF
  1339.         Dc.B    "SS {0..?}      Set play sequence start position",LF
  1340.         Dc.B    "ST {-16..15}   Set global tempo",LF
  1341.         Dc.B    "SV {0..64}     Set global volume",LF
  1342.         Dc.B    "TI {0|1}       Set tempo interpretation (BPM or Non-BPM)",LF
  1343.         Dc.B    "TM {0|1}       Set timing mode (0 = NTSC,1 = PAL)",LF
  1344.         Dc.B    "TE {jiffies}   Set end position based on time.",LF
  1345.         Dc.B    "TS {jiffies}   Set start position based on time.",LF
  1346.         Dc.B    "TC {jiffies}   Set current position based on time.",LF
  1347.         Dc.B    "UM             Unload module",LF
  1348.         Dc.B    "VM {filename}  Determine if a disk file is a module.",LF
  1349.         Dc.B    "WE {seconds}   Wait end of song or n seconds (def. 600)",LF
  1350.         Dc.B    "XL             Flush library (and loaded song, if one)",LF,LF
  1351.         Dc.B    NULL
  1352.  
  1353. ; Library names used for OpenLibrary()...
  1354.  
  1355. DosName        Dc.B    "dos.library",NULL
  1356. GfxName        Dc.B    "graphics.library",NULL
  1357.  
  1358. DTLName        DTLIBNAME
  1359.  
  1360.         Even
  1361.  
  1362. ; The end.
  1363.  
  1364.         End
  1365.