home *** CD-ROM | disk | FTP | other *** search
/ Sound, Music & MIDI Collection 2 / SMMVOL2.bin / DOS / SS_PLAY / APLAY121.ZIP / DEVELOPE.LHA / Examples / apSoundMon20Library.S < prev    next >
Encoding:
Text File  |  1994-09-24  |  24.6 KB  |  1,132 lines

  1. ; $VER: SoundMon20.library 2.11
  2. ;
  3.  
  4.     INCDIR    "Includes3.0:Include3.0/"
  5.     INCLUDE    "Exec/Types.i"
  6.     INCLUDE    "Own/SystemBases.i"
  7.     INCLUDE    "Own/SystemStructures.i"
  8.     INCLUDE    "Own/SystemOffsets.i"
  9.     INCLUDE    "Own/AccessiblePlayer.i"
  10.  
  11.  
  12. VERSION        =    2
  13. REVISION    =    11
  14.  
  15. TRUE        =    -1
  16. FALSE        =    0
  17.  
  18. ; Library Data
  19.  
  20. LN_Name        =    10
  21. LN_Type        =    8
  22. NT_Library    =    9
  23.  
  24. LIBB_Summing    =    0
  25. LIBB_Changed    =    1
  26. LIBB_SumUsed    =    2
  27. LIBB_DelExp    =    3
  28.  
  29. LIBF_Summing    =    1<<LIBB_Summing
  30. LIBF_Changed    =    1<<LIBB_Changed
  31. LIBF_SumUsed    =    1<<LIBB_SumUsed
  32. LIBF_DelExp    =    1<<LIBB_DelExp
  33.  
  34. ; Macros
  35.  
  36. INBYTE    MACRO
  37.     dc.b    %11100000,0
  38.     dc.w    \1
  39.     dc.b    \2,0
  40.     ENDM
  41.  
  42. INWORD    MACRO
  43.     dc.b    %11010000,0
  44.     dc.w    \1,\2
  45.     ENDM
  46.  
  47. INLONG    MACRO
  48.     dc.b    %11000000,0
  49.     dc.w    \1
  50.     dc.l    \2
  51.     ENDM
  52.  
  53. ; Library Base Structure
  54.  
  55.     STRUCTURE LibraryStruct,0
  56.     STRUCT    LIB_Node,14
  57.     UBYTE    LIB_Flags
  58.     UBYTE    LIB_Pad
  59.     UWORD    LIB_NegSize
  60.     UWORD    LIB_PosSize
  61.     UWORD    LIB_Version
  62.     UWORD    LIB_Revision
  63.     APTR    LIB_IDString
  64.     ULONG    LIB_Sum
  65.     UWORD    LIB_OpenCnt
  66.  
  67.     LONG    LIB_SegList
  68.     LABEL    LibraryStruct_SIZEOF
  69.  
  70.  
  71.     SECTION    SoundMon20.library,CODE
  72.  
  73. START    moveq    #0,d0
  74.     rts
  75. ;------------------------------------------------------------------------------
  76. LIBNAME    dc.b    "apSoundMon20.library",0
  77.  
  78. LIBID    dc.b    "SoundMon20.library 2.11 (23-September-1994)",0
  79.     even
  80. ;------------------------------------------------------------------------------
  81. ; ROMTAG Structure
  82. ;
  83.  
  84. ROMTAG    dc.w    $4afc            ;ROMTAG Indentifier
  85.     dc.l    romtag
  86.     dc.l    slut
  87.     dc.b    $80            ;Flags
  88.     dc.b    version
  89.     dc.b    $09            ;Type Of Module
  90.     dc.b    $00            ;Initialization Priority
  91.     dc.l    libname
  92.     dc.l    libid
  93.     dc.l    autinit            ;Pointer To AUTOINIT Table
  94. ;------------------------------------------------------------------------------
  95. ; AUTOINIT Table
  96. ;
  97.  
  98. AUTINIT    dc.l    LibraryStruct_SIZEOF    ;Size Of Structure AFTER Base Address
  99.     dc.l    vector            ;Pointer To Vector Table
  100.     dc.l    inittab            ;Pointer To Init Structure
  101.     dc.l    init            ;Pointer To Init Routine
  102. ;------------------------------------------------------------------------------
  103. ; Init Table
  104. ;
  105.  
  106. INITTAB    INBYTE    LN_Type,NT_Library
  107.     INBYTE    LIB_Flags,LIBF_SumUsed!LIBF_Changed
  108.     INWORD    LIB_Version,version
  109.     INWORD    LIB_Revision,revision
  110.     INLONG    LN_Name,libname
  111.     INLONG    LIB_IDString,libid
  112.     dc.l    0
  113. ;------------------------------------------------------------------------------
  114. ; Vector Table
  115. ;
  116.  
  117. VECTOR    dc.w    -1
  118.     dc.w    opnlib-vector,clslib-vector,expunge-vector,extfunc-vector
  119.     dc.w    SM_GetTags-vector
  120.     dc.w    -1
  121. ;------------------------------------------------------------------------------
  122. ; Init Routine
  123. ;
  124.  
  125. INIT    movem.l    d1-d7/a0-a6,-(sp)
  126.     move.l    d0,a4            ;Base Address
  127.     move.l    a0,LIB_SegList(a4)
  128.  
  129.     move.l    a4,d0
  130.     movem.l    (sp)+,d1-d7/a0-a6
  131.     rts
  132. ;------------------------------------------------------------------------------
  133. ; Offset  -6: Open Library
  134. ;
  135.  
  136. OPNLIB    addq.w    #1,LIB_OpenCnt(a6)
  137.     bclr    #LIBB_DelExp,LIB_Flags(a6)
  138.     move.l    a6,d0
  139.     rts
  140. ;------------------------------------------------------------------------------
  141. ; Offset -12: Close Library
  142. ;
  143.  
  144. CLSLIB    moveq    #0,d0
  145.     subq.w    #1,LIB_OpenCnt(a6)
  146.     bne.b    clslibo
  147.     btst    #LIBB_DelExp,LIB_Flags(a6)
  148.     bne.b    expunge
  149. CLSLIBO    rts
  150. ;------------------------------------------------------------------------------
  151. ; Offset -18: Expunge
  152. ;
  153.  
  154. EXPUNGE    movem.l    d1-d7/a0-a6,-(sp)
  155.     move.l    a6,a4
  156.     tst.w    LIB_OpenCnt(a4)
  157.     beq.b    exp1
  158.     bset    #LIBB_DelExp,LIB_Flags(a4)
  159.     moveq    #0,d0
  160.     bra.b    expungo
  161.  
  162. EXP1    move.l    4.w,a6
  163.     move.l    LIB_SegList(a4),d2
  164.     move.l    a4,a1
  165.     jsr    Remove(a6)
  166.  
  167.     move.l    a4,a1
  168.     moveq    #0,d0
  169.     move.w    LIB_NegSize(a4),d0
  170.     sub.l    d0,a1
  171.     add.w    LIB_PosSize(a4),d0
  172.     jsr    FreeMem(a6)
  173.     move.l    d2,d0
  174.  
  175. EXPUNGO    movem.l    (sp)+,d1-d7/a0-a6
  176.     rts
  177. ;------------------------------------------------------------------------------
  178. ; Offset -24: ExtFunc
  179. ;
  180.  
  181. EXTFUNC    moveq    #0,d0
  182.     rts
  183. ;------------------------------------------------------------------------------
  184. ;******************************************************************************
  185. ;* Sound Monitor 2.0 Player
  186. ;******************************************************************************
  187. ;------------------------------------------------------------------------------
  188. ; Structure
  189. ;
  190.  
  191.     STRUCTURE SoundMonStruct,0
  192.     APTR    SMON_Global
  193.     APTR    SMON_Module
  194.     APTR    SMON_Tables
  195.     UWORD    SMON_DMA
  196.     UWORD    SMON_BPStep
  197.     UBYTE    SMON_NumTables
  198.     UBYTE    SMON_ArpCount
  199.     UBYTE    SMON_BPCount
  200.     UBYTE    SMON_BPDelay
  201.     UBYTE    SMON_ST
  202.     UBYTE    SMON_TR
  203.     UBYTE    SMON_BPPatCount
  204.     UBYTE    SMON_BPRepCount
  205.     STRUCT    SMON_Samples,15*4
  206.     STRUCT    SMON_BPCurrent,14+18+32*3
  207.     STRUCT    SMON_BPBuffer,144
  208.     LABEL    SoundMonStruct_SIZEOF
  209. ;------------------------------------------------------------------------------
  210. ; Offset -30: GetTags
  211. ;
  212. ; IN :    Nothing
  213. ;
  214. ; OUT:    A0 = Pointer To A TagList
  215. ;
  216.  
  217. SM_GetTags
  218.     lea    SM_Tags(pc),a0
  219.     rts
  220.  
  221. SM_Tags    dc.l    APT_RequestVersion,2
  222.     dc.l    APT_EarlyCheck,SM_TestModule
  223.  
  224.     dc.l    APT_InitPlayer,SM_InitPlayer
  225.     dc.l    APT_EndPlayer,SM_EndPlayer
  226.     dc.l    APT_InitSound,SM_InitSound
  227.     dc.l    APT_EndSound,SM_EndSound
  228.     dc.l    APT_Interrupt,SM_PlayModule
  229.  
  230.     dc.l    APT_PlayerName,smname
  231.     dc.l    APT_Description,smdes
  232.     dc.l    APT_ModuleName,SM_ModuleName
  233.  
  234.     dc.l    APT_Volume,TRUE
  235.     dc.l    APT_Pause,TRUE
  236.  
  237.     dc.l    APT_GetMaxPattern,SM_GetMaxPattern
  238.     dc.l    APT_GetMaxSample,SM_GetMaxSample
  239.     dc.l    APT_GetSongLength,SM_GetSongLength
  240.  
  241.     dc.l    APT_GetSongPos,SM_GetSongPos
  242.     dc.l    APT_Rewind,SM_Rewind
  243.     dc.l    APT_Forward,SM_Forward
  244.     dc.l    TAG_END
  245.  
  246. SMNAME    dc.b    "Sound Monitor 2.0",0
  247. SMDES    dc.b    "Original player by Brian Postma.",10
  248.     dc.b    "Adapted by Tax.",0
  249.     even
  250. ;------------------------------------------------------------------------------
  251. ; TestModule
  252. ;
  253. ; IN :    Nothing
  254. ;
  255. ; OUT:    D0 = Success (0=Unknown, 1=Ok, 2=Error)
  256. ;
  257.  
  258. SM_TestModule
  259.     movem.l    d1-d2/a0/a4-a5,-(sp)
  260.  
  261.     subq.l    #4,sp
  262.     moveq    #$1a,d1
  263.     moveq    #4,d2
  264.     move.l    sp,a0
  265.     move.l    APG_CheckLoad(a5),a4
  266.     jsr    (a4)            ;Read Mark
  267.     move.l    (sp)+,d1
  268.     tst.l    d0
  269.     beq.b    .tsmod1
  270.  
  271.     moveq    #0,d0            ;Unknown
  272.     lsr.l    #8,d1
  273.     cmp.l    #"V.2",d1
  274.     bne.b    .tsmodo
  275.     moveq    #1,d0            ;Ok
  276.     bra.b    .tsmodo
  277.  
  278. .TSMOD1    moveq    #2,d0            ;Error
  279. .TSMODO    movem.l    (sp)+,d1-d2/a0/a4-a5
  280.     rts
  281. ;------------------------------------------------------------------------------
  282. ; InitPlayer
  283. ;
  284. ; IN :    A1 = Address
  285. ;
  286. ; OUT:    D1 = Success (0=Error)
  287. ;
  288.  
  289. SM_InitPlayer
  290.     movem.l    d0/a0,-(sp)
  291.     move.l    APG_AllocChannels(a5),a0
  292.     jsr    (a0)
  293.     move.l    d0,d1
  294.     movem.l    (sp)+,d0/a0
  295.     rts
  296. ;------------------------------------------------------------------------------
  297. ; EndPlayer
  298. ;
  299. ; IN :    A1 = Address
  300. ;
  301. ; OUT:    Nothing
  302. ;
  303.  
  304. SM_EndPlayer
  305.     move.l    a0,-(sp)
  306.     move.l    APG_FreeChannels(a5),a0
  307.     jsr    (a0)
  308.     move.l    (sp)+,a0
  309.     rts
  310. ;------------------------------------------------------------------------------
  311. ; InitSound
  312. ;
  313. ; IN :    A1 = Address
  314. ;
  315. ; OUT:    Nothing
  316. ;
  317.  
  318. SM_InitSound    movem.l    d0-d2/a0-a1/a4,-(sp)
  319.         lea    SM_DataArea,a4
  320.         move.l    a1,SMON_Module(a4)
  321.         move.l    a5,SMON_Global(a4)
  322.  
  323.         move.b    #1,SMON_ArpCount(a4)
  324.         move.b    #1,SMON_BPCount(a4)
  325.         move.b    #6,SMON_BPDelay(a4)
  326.         move.b    #1,SMON_BPRepCount(a4)
  327.  
  328.         clr.w    SMON_DMA(a4)
  329.         clr.w    SMON_BPStep(a4)
  330.         clr.b    SMON_BPPatCount(a4)
  331.         clr.b    SMON_ST(a4)
  332.         clr.b    SMON_TR(a4)
  333.  
  334.         lea    SMON_BPCurrent(a4),a0
  335.         lea    null,a1
  336.         clr.l    (a0)+
  337.         move.l    a1,(a0)+
  338.         move.w    #1,(a0)+
  339.         clr.l    (a0)+
  340.  
  341.         clr.l    (a0)+
  342.         clr.l    (a0)+
  343.         clr.l    (a0)+
  344.         clr.w    (a0)+
  345.         clr.w    (a0)+
  346.         clr.w    (a0)+
  347.  
  348.         moveq    #3-1,d0
  349. .initloop    clr.l    (a0)+
  350.         move.l    a1,(a0)+
  351.         move.w    #1,(a0)+
  352.         clr.l    (a0)+
  353.         clr.l    (a0)+
  354.         clr.l    (a0)+
  355.         clr.l    (a0)+
  356.         clr.l    (a0)+
  357.         clr.w    (a0)+
  358.         dbra    d0,.initloop
  359.  
  360.         lea    SMON_BPBuffer(a4),a0
  361.         moveq    #(144/2)-1,d0
  362. .initloop1    clr.w    (a0)+
  363.         dbra    d0,.initloop1
  364.  
  365.         lea    SMON_Samples(a4),a0
  366.         move.l    SMON_Module(a4),a1
  367.  
  368.         clr.b    SMON_NumTables(a4)
  369.         cmp.w    #'V.',26(a1)
  370.         bne.b    bpnotv2
  371.         cmp.b    #'2',28(a1)
  372.         bne.b    bpnotv2
  373.         move.b    29(a1),SMON_NumTables(a4)
  374.  
  375. bpnotv2        move.l    #512,d0
  376.         move.w    30(a1),d1    ;d1 now contains length in steps
  377.         moveq    #1,d2        ;1 is highest pattern number
  378.         mulu    #4,d1        ;4 voices per step
  379.         subq.w    #1,d1        ;correction for DBRA
  380. findhighest    cmp.w    (a1,d0),d2    ;Is it higher
  381.         bge.b    nothigher    ;No
  382.         move.w    (a1,d0),d2    ;Yes, so let D2 be highest
  383. nothigher    addq.l    #4,d0        ;Next Voice
  384.         dbra    d1,findhighest    ;And search
  385.  
  386.         move.w    30(a1),d1
  387.         lsl.w    #4,d1        ;16 bytes per step
  388.         move.l    #512,d0        ;header is 512 bytes
  389.         mulu    #48,d2        ;48 bytes per pattern
  390.         add.l    d2,d0
  391.         add.l    d1,d0        ;offset for samples
  392.         add.l    SMON_Module(a4),d0
  393.         move.l    d0,SMON_Tables(a4)
  394.         moveq    #0,d1
  395.         move.b    SMON_NumTables(a4),d1    ;Number of tables
  396.         lsl.l    #6,d1            ;x 64
  397.         add.l    d1,d0
  398.  
  399.         moveq    #15-1,d1    ;15 samples
  400.         lea    32(a1),a1
  401. initloop    move.l    d0,(a0)+
  402.         cmp.b    #$ff,(a1)
  403.         beq.b    bpissynth
  404.         move.w    24(a1),d2
  405.         add.w    d2,d2
  406.         add.l    d2,d0        ;offset next sample
  407. bpissynth    lea    32(a1),a1    ;Length of Sample Part in header
  408.         dbra    d1,initloop
  409.  
  410.         movem.l    (sp)+,d0-d2/a0-a1/a4
  411.         rts
  412. ;------------------------------------------------------------------------------
  413. ; EndSound
  414. ;
  415. ; IN :    A1 = Address
  416. ;
  417. ; OUT:    Nothing
  418. ;
  419.  
  420. SM_EndSound
  421.     move.l    d0,-(sp)
  422.     moveq    #0,d0
  423.     move.w    d0,$dff0a8
  424.     move.w    d0,$dff0b8
  425.     move.w    d0,$dff0c8
  426.     move.w    d0,$dff0d8
  427.     move.w    #$000f,$dff096
  428.     move.l    (sp)+,d0
  429.     rts
  430. ;------------------------------------------------------------------------------
  431. ; PlayModule
  432. ;
  433. ; IN :    A1 = Address
  434. ;    D1 = VBlank/Cia (0=CIA)
  435. ;
  436. ; OUT:    Nothing
  437. ;
  438.  
  439. SM_PlayModule    movem.l    d0-d7/a0-a6,-(sp)
  440.         lea    SM_DataArea,a5
  441.         bsr.b    bpmusic
  442.         movem.l    (sp)+,d0-d7/a0-a6
  443.         rts
  444.  
  445. bpmusic        bsr.w    bpsynth
  446.         subq.b    #1,SMON_ArpCount(a5)
  447.         moveq    #3,d0
  448.         lea    SMON_BPCurrent(a5),a0
  449.         lea    $dff0a0,a1
  450. bploop1        move.b    12(a0),d4
  451.         ext.w    d4
  452.         add.w    d4,(a0)
  453.         tst.b    $1e(a0)
  454.         bne.b    bplfo
  455.         move.w    (a0),6(a1)
  456. bplfo        move.l    4(a0),(a1)
  457.         move.w    8(a0),4(a1)
  458.         tst.b    11(a0)
  459.         bne.b    bpdoarp
  460.         tst.b    13(a0)
  461.         beq.b    not2
  462. bpdoarp        tst.b    SMON_ArpCount(a5)
  463.         bne.b    not0
  464.         move.b    11(a0),d3
  465.         move.b    13(a0),d4
  466.         and.w    #240,d4
  467.         and.w    #240,d3
  468.         lsr.w    #4,d3
  469.         lsr.w    #4,d4
  470.         add.w    d3,d4
  471.         add.b    10(a0),d4
  472.         bsr.w    bpplayarp
  473.         bra.b    not2
  474.  
  475. not0        cmpi.b    #1,SMON_ArpCount(a5)
  476.         bne.b    not1
  477.         move.b    11(a0),d3
  478.         move.b    13(a0),d4
  479.         and.w    #15,d3
  480.         and.w    #15,d4
  481.         add.w    d3,d4
  482.         add.b    10(a0),d4
  483.         bsr.w    bpplayarp
  484.         bra.b    not2
  485.  
  486. not1        move.b    10(a0),d4
  487.         bsr.w    bpplayarp
  488. not2        lea    $10(a1),a1
  489.         lea    $20(a0),a0
  490.         dbra    d0,bploop1
  491.  
  492.         tst.b    SMON_ArpCount(a5)
  493.         bne.b    arpnotzero
  494.         move.b    #3,SMON_ArpCount(a5)
  495. arpnotzero    subq.b    #1,SMON_BPCount(a5)
  496.         beq.b    bpskip1
  497.         rts
  498.  
  499. bpskip1        move.b    SMON_BPDelay(a5),SMON_BPCount(a5)
  500. bpplay        bsr.b    bpnext
  501.         move.w    SMON_DMA(a5),$dff096
  502.  
  503.         move.l    SMON_Global(a5),a1
  504.         move.l    APG_WaitDma(a1),a1
  505.         jsr    (a1)            ;Wait For DMA
  506.  
  507.         moveq    #3,d0
  508.         lea    $dff0a0,a1
  509.         moveq    #1,d1
  510.         move.l    a5,-(sp)
  511.         lea    SMON_BPCurrent(a5),a2
  512.         lea    SMON_BPBuffer(a5),a5
  513. bploop2        btst    #15,(a2)
  514.         beq.b    bpskip7
  515.         bsr.w    bpplayit
  516. bpskip7        asl.w    #1,d1
  517.         lea    $10(a1),a1
  518.         lea    $20(a2),a2
  519.         lea    $24(a5),a5
  520.         dbra    d0,bploop2
  521.         move.l    (sp)+,a5
  522.         rts
  523.  
  524. bpnext        clr.w    SMON_DMA(a5)
  525.         move.l    SMON_Module(a5),a0
  526.         lea    $dff0a0,a3
  527.         moveq    #3,d0
  528.         moveq    #1,d7
  529.         lea    SMON_BPCurrent(a5),a1
  530. bploop3        moveq    #0,d1
  531.         move.w    SMON_BPStep(a5),d1
  532.         lsl.w    #4,d1
  533.         move.l    d0,d2
  534.         lsl.l    #2,d2
  535.         add.l    d2,d1
  536.         add.l    #512,d1
  537.         move.w    (a0,d1),d2
  538.         move.b    2(a0,d1),SMON_ST(a5)
  539.         move.b    3(a0,d1),SMON_TR(a5)
  540.         subq.w    #1,d2
  541.         mulu    #48,d2
  542.         moveq    #0,d3
  543.         move.w    30(a0),d3
  544.         lsl.w    #4,d3
  545.         add.l    d2,d3
  546.         move.l    #$00000200,d4
  547.         move.b    SMON_BPPatCount(a5),d4
  548.         add.l    d3,d4
  549.         move.l    d4,a2
  550.         add.l    a0,a2
  551.         moveq    #0,d3 
  552.         move.b    (a2),d3
  553.         tst.b    d3
  554.         bne.b    bpskip4
  555.         bra.w    bpoptionals
  556.  
  557. bpskip4        clr.w    12(a1)            ;Clear autoslide/autoarpeggio
  558.         move.b    1(a2),d4
  559.         and.b    #15,d4
  560.         cmpi.b    #10,d4            ;Option 10->transposes off
  561.         bne.b    bp_do1
  562.         move.b    2(a2),d4
  563.         and.b    #240,d4              ;Higher nibble=transpose
  564.         bne.b    bp_not1
  565. bp_do1        add.b    SMON_TR(a5),d3
  566.         ext.w    d3
  567. bp_not1        move.b    d3,10(a1)         ;Voor Arpeggio's
  568.         lea    bpper(pc),a4
  569.         lsl.w    #1,d3
  570.         move.w    -2(a4,d3.w),(a1)
  571.         bset    #15,(a1)
  572.         move.b    #$ff,2(a1)
  573.         moveq    #0,d3
  574.         move.b    1(a2),d3
  575.         lsr.b    #4,d3
  576.         and.b    #15,d3
  577.         tst.b    d3
  578.         bne.b    bpskip5
  579.         move.b    3(a1),d3 
  580. bpskip5     move.b    1(a2),d4
  581.         and.b    #15,d4
  582.         cmpi.b    #10,d4             ;option 10
  583.         bne.b    bp_do2
  584.         move.b    2(a2),d4
  585.         and.b    #15,d4
  586.         bne.b    bp_not2
  587. bp_do2        add.b    SMON_ST(a5),d3
  588. bp_not2        cmpi.w    #1,8(a1)
  589.         beq.b    bpsamplechange
  590.         cmp.b    3(a1),d3
  591.         beq.b    bpoptionals
  592. bpsamplechange    move.b    d3,3(a1)
  593.         or.w    d7,SMON_DMA(a5)
  594. bpoptionals     moveq    #0,d3
  595.         moveq    #0,d4
  596.         move.b    1(a2),d3
  597.         and.b    #15,d3
  598.         move.b    2(a2),d4
  599.  
  600.         cmpi.b    #0,d3            ; Optionals Here
  601.         bne.b    notopt0
  602.         move.b    d4,11(a1)
  603.  
  604. notopt0        cmpi.b    #1,d3
  605.         bne.b    bpskip3
  606.         move.l    d0,-(sp)
  607.         move.b    d4,2(a1)         ; Volume ook in BPCurrent
  608.         move.b    d4,d0
  609.         bsr.w    calvol
  610.         move.w    d0,8(a3)
  611.         move.l    (sp)+,d0
  612.  
  613. bpskip3        cmpi.b    #2,d3              ; Set Speed
  614.         bne.b    bpskip9
  615.         move.b    d4,SMON_BPCount(a5)
  616.         move.b    d4,SMON_BPDelay(a5)
  617.  
  618. bpskip9        cmpi.b    #3,d3             ; Filter = LED control
  619.         bne.b    bpskipa
  620.         tst.b    d4
  621.         bne.b    bpskipb
  622.         bset    #1,$bfe001
  623.         bra.b    bpskip2
  624. bpskipb        bclr    #1,$bfe001
  625.  
  626. bpskipa        cmpi.b    #4,d3             ; PortUp
  627.         bne.b    noportup
  628.         sub.w    d4,(a1)            ; Slide data in BPCurrent
  629.         clr.b    11(a1)             ; Arpeggio's uit
  630.  
  631. noportup    cmpi.b    #5,d3             ; PortDown
  632.         bne.b    noportdn
  633.         add.w    d4,(a1)            ; Slide down
  634.         clr.b    11(a1)
  635.  
  636. noportdn    cmpi.b    #6,d3            ; SetRepCount
  637.         bne.b    notopt6
  638.         move.b    d4,SMON_BPRepCount(a5)
  639.  
  640. notopt6        cmpi.b    #7,d3            ; DBRA repcount
  641.         bne.b    notopt7
  642.         subq.b    #1,SMON_BPRepCount(a5)
  643.         beq.b    notopt7
  644.         cmp.w    SMON_BPStep(a5),d4
  645.         bge.b    jump
  646.         move.l    SMON_Global(a5),a2
  647.         move.l    APG_SendMsg(a2),a2
  648.         move.w    #MSG_NextMod,d2
  649.         jsr    (a2)
  650. jump        move.w    d4,SMON_BPStep(a5)
  651.  
  652. notopt7        cmpi.b    #8,d3            ;Set AutoSlide
  653.         bne.b    notopt8
  654.         move.b    d4,12(a1)
  655.  
  656. notopt8        cmpi.b    #9,d3            ;Set AutoArpeggio
  657.         bne.b    notopt9
  658.         move.b    d4,13(a1)
  659.  
  660. notopt9
  661. bpskip2        lea    $10(a3),a3
  662.         lea    $20(a1),a1
  663.         asl.w    #1,d7
  664.         dbra    d0,bploop3
  665.  
  666.         addq.b    #3,SMON_BPPatCount(a5)
  667.         cmpi.b    #48,SMON_BPPatCount(a5)
  668.         bne.b    bpskip8
  669.         move.b    #0,SMON_BPPatCount(a5)
  670.         addq.w    #1,SMON_BPStep(a5)
  671.  
  672.         move.l    SMON_Global(a5),a2
  673.         move.l    APG_SendMsg(a2),a2
  674.         move.w    #MSG_NextPos,d2
  675.         jsr    (a2)
  676.  
  677.         move.l    SMON_Module(a5),a0
  678.         move.w    30(a0),d1
  679.         cmp.w    SMON_BPStep(a5),d1
  680.         bne.b    bpskip8
  681.         move.w    #0,SMON_BPStep(a5)
  682.  
  683.         move.l    SMON_Global(a5),a2
  684.         move.l    APG_SendMsg(a2),a2
  685.         move.w    #MSG_NextMod,d2
  686.         jsr    (a2)
  687. bpskip8        rts
  688.  
  689. bpplayit    bclr    #15,(a2)
  690.         tst.l    (a5)             ;Was EG used
  691.         beq.b    noeg1             ;No ??
  692.         moveq    #0,d3             ;Well then copy
  693.         move.l    (a5),a4            ;Old waveform back
  694.         moveq    #7,d7             ;to waveform tables
  695. eg1loop        move.l    4(a5,d3.w),(a4)+    ;Copy...
  696.         addq.w    #4,d3             ;Copy...
  697.         dbra    d7,eg1loop        ;Copy...
  698.  
  699. noeg1        move.w    (a2),6(a1)        ;Period from bpcurrent
  700.         moveq    #0,d7
  701.         move.b    3(a2),d7        ;Instrument number
  702.         move.l    d7,d6             ;Also in d6
  703.         lsl.l    #5,d7             ;Header offset
  704.         move.l    4(sp),a3
  705.         move.l    SMON_Module(a3),a3
  706.         cmpi.b    #$ff,(a3,d7.w)        ;Is synthetic
  707.         beq.w    bpplaysynthetic        ;Yes ??
  708.         clr.l    (a5)             ;EG Off
  709.         clr.b    $1a(a2)            ;Synthetic mode off
  710.         clr.w    $1e(a2)            ;Lfo Off
  711.         add.l    #24,d7             ;24 is name->ignore
  712.         lsl.l    #2,d6             ;x4 for sample offset
  713.         move.l    4(sp),a4
  714.         lea    SMON_Samples(a4),a4
  715.         move.l    -4(a4,d6),d4        ;Fetch sample pointer
  716.         beq.b    bp_nosamp        ;is zero->no sample
  717.         move.l    d4,(a1)         ;Sample pointer in hardware
  718.         move.w    (a3,d7),4(a1)        ;length in hardware
  719.  
  720.         movem.l    d0/a5,-(sp)
  721.         move.l    12(sp),a5
  722.         move.b    2(a2),d0
  723.         bsr.w    calvol
  724.         movem.l    (sp)+,d0/a5
  725.  
  726.         cmpi.b    #$ff,2(a2)        ;Use default volume
  727.         bne.b    skipxx             ;No ??
  728.  
  729.         movem.l    d0/a5,-(sp)
  730.         move.l    12(sp),a5
  731.         move.w    6(a3,d7),d0
  732.         bsr.w    calvol
  733.         move.w    d0,8(a1)
  734.         movem.l    (sp)+,d0/a5
  735.  
  736. skipxx         move.w    4(a3,d7),8(a2)        ;Length in bpcurrent
  737.         moveq    #0,d6
  738.         move.w    2(a3,d7),d6        ;Calculate repeat
  739.         add.l    d6,d4
  740.         move.l    d4,4(a2)        ;sample start in bpcurrent
  741.         cmpi.w    #1,8(a2)        ;has sample repeat part
  742.         bne.b    bpskip6            ;Yes ??
  743. bp_nosamp    move.l    #null,4(a2)        ;Play no sample
  744.         bra.b    bpskip10
  745.  
  746. bpskip6        move.w    8(a2),4(a1)        ;Length to hardware
  747.         move.l    4(a2),(a1)        ;pointer to hardware
  748. bpskip10    or.w    #$8000,d1        ;Turn on DMA for this voice
  749.         move.w    d1,$dff096        ;Yeah, do it
  750.         rts
  751.  
  752. bpplaysynthetic    move.b    #$1,$1a(a2)        ;Synthetic mode on
  753.         clr.w    $e(a2)             ;EG Pointer restart
  754.         clr.w    $10(a2)         ;LFO Pointer restart
  755.         clr.w    $12(a2)         ;ADSR Pointer restart
  756.         move.w    22(a3,d7.w),$14(a2)    ;EG Delay
  757.         addq.w    #1,$14(a2)        ;0 is nodelay
  758.         move.w    14(a3,d7.w),$16(a2)    ;LFO Delay
  759.         addq.w    #1,$16(a2)        ;So I need correction
  760.         move.w    #1,$18(a2)        ;ADSR Delay->Start immediate
  761.         move.b    17(a3,d7.w),$1d(a2)    ;EG OOC
  762.         move.b    9(a3,d7.w),$1e(a2)    ;LFO OOC
  763.         move.b    4(a3,d7.w),$1f(a2)    ;ADSR OOC
  764.         move.b    19(a3,d7.w),$1c(a2)    ;Current EG Value
  765.         move.l    4(sp),a4
  766.         move.l    SMON_Tables(a4),a4    ; so far so good,now what ??
  767.         moveq    #0,d3            ;Pointer to waveform tables
  768.         move.b    1(a3,d7.w),d3        ;Which waveform
  769.         lsl.l    #6,d3             ;x64 is length waveform table
  770.         add.l    d3,a4
  771.         move.l    a4,(a1)         ;Sample Pointer
  772.         move.l    a4,4(a2)        ;In bpcurrent
  773.         move.w    2(a3,d7.w),4(a1)    ;Length in words
  774.         move.w    2(a3,d7.w),8(a2)    ;Length in bpcurrent
  775.         tst.b    4(a3,d7.w)        ;Is ADSR on
  776.         beq.b    bpadsroff        ;No ??
  777.         move.l    4(sp),a4
  778.         move.l    SMON_Tables(a4),a4    ;Tables
  779.         moveq    #0,d3
  780.         move.b    5(a3,d7.w),d3        ;ADSR table number
  781.         lsl.l    #6,d3             ;x64 for length
  782.         add.l    d3,a4             ;Add it
  783.         moveq    #0,d3
  784.         move.b    (a4),d3         ;Get table value
  785.         add.b    #128,d3         ;I want it from 0..255
  786.         lsr.w    #2,d3             ;Divide by 4->0..63
  787.         cmpi.b    #$ff,2(a2)
  788.         bne.b    bpskip99
  789.         move.b    25(a3,d7.w),2(a2)
  790. bpskip99    moveq    #0,d4
  791.         move.b    2(a2),d4        ;Default volume
  792.         mulu    d4,d3             ;default maal init volume
  793.         lsr.w    #6,d3             ;divide by 64
  794.  
  795.         movem.l    d0/a5,-(sp)
  796.         move.l    12(sp),a5
  797.         move.w    d3,d0
  798.         bsr.w    calvol
  799.         move.w    d0,8(a1)        ;is new volume
  800.         movem.l    (sp)+,d0/a5
  801.         bra.b    bpflipper
  802.  
  803. bpadsroff    movem.l    d0/a5,-(sp)
  804.         move.l    12(sp),a5
  805.         move.b    2(a2),d0
  806.         bsr.w    calvol
  807.         move.w    d0,8(a1)        ;is new volume
  808.         movem.l    (sp)+,d0/a5
  809.  
  810.         cmpi.b    #$ff,2(a2)
  811.         bne.b    bpflipper        ;No ADSR
  812.         movem.l    d0/a5,-(sp)
  813.         move.l    12(sp),a5
  814.         move.b    25(a3,d7.w),d0
  815.         bsr.w    calvol
  816.         move.w    d0,8(a1)        ;So use default volume
  817.         movem.l    (sp)+,d0/a5
  818.  
  819. bpflipper    move.l    4(a2),a4        ;Pointer on waveform
  820.         move.l    a4,(a5)            ;Save it
  821.         moveq    #0,d3             ;Save Old waveform
  822.         moveq    #7,d4             ;data in bpbuffer
  823. eg2loop        move.l    (a4,d3.w),4(a5,d3.w)
  824.         addq.w    #4,d3             ;Copy         
  825.         dbra    d4,eg2loop
  826.  
  827.         tst.b    17(a3,d7.w)        ;EG off
  828.         beq.w    bpskip10        ;Yes ??
  829.         tst.b    19(a3,d7.w)        ;Is there an init value for EG
  830.         beq.w    bpskip10        ;No ??
  831.         moveq    #0,d3
  832.         move.b    19(a3,d7.w),d3
  833.         lsr.l    #3,d3             ;Divide by 8 ->0..31
  834.         move.b    d3,$1c(a2)        ;Current EG Value
  835.         subq.l    #1,d3             ;-1,DBRA correction
  836. eg3loop        neg.b    (a4)+
  837.         dbra    d3,eg3loop
  838.         bra.w    bpskip10
  839.  
  840. bpplayarp    lea    bpper(pc),a4
  841.         ext.w    d4
  842.         asl.w    #1,d4
  843.         move.w    -2(a4,d4.w),6(a1)
  844.         rts
  845.  
  846. bpsynth        move.l    a5,-(sp)
  847.         moveq    #3,d0
  848.         lea    SMON_BPCurrent(a5),a2
  849.         lea    $dff0a0,a1
  850.         move.l    SMON_Module(a5),a3
  851.         lea    SMON_BPBuffer(a5),a5
  852. bpsynthloop    tst.b    $1a(a2)            ;Is synthetic sound
  853.         beq.b    bpnosynth        ;No ??
  854.         bsr.b    bpyessynth        ;Yes         
  855. bpnosynth    lea    $24(a5),a5
  856.         lea    $20(a2),a2
  857.         lea    $10(a1),a1
  858.         dbra    d0,bpsynthloop
  859.         move.l    (sp)+,a5
  860.         rts
  861.  
  862. bpyessynth    moveq    #0,d7
  863.         move.b    3(a2),d7        ;Which instr. was I playing
  864.         lsl.w    #5,d7             ;x32, is length of instr.
  865.         tst.b    $1f(a2)         ;ADSR off
  866.         beq.b    bpendadsr        ;Yes ??
  867.         subq.w    #1,$18(a2)        ;Delay,May I
  868.         bne.b    bpendadsr        ;No ??
  869.         moveq    #0,d3
  870.         move.b    8(a3,d7.w),d3
  871.         move.w    d3,$18(a2)        ;Reset Delay Counter
  872.         move.l    4(sp),a4
  873.         move.l    SMON_Tables(a4),a4
  874.         move.b    5(a3,d7.w),d3        ;Which ADSR table
  875.         lsl.l    #6,d3             ;x64
  876.         add.l    d3,a4             ;This is my table
  877.         move.w    $12(a2),d3        ;Get ADSR table pointer
  878.         moveq    #0,d4
  879.         move.b    (a4,d3.w),d4        ;Value from table
  880.         add.b    #128,d4         ;Want it from 0..255
  881.         lsr.w    #2,d4             ;And now from 0..63
  882.         moveq    #0,d3
  883.         move.b    2(a2),d3        ;Current Volume
  884.         mulu    d3,d4             ;MultiPly with table volume
  885.         lsr.w    #6,d4             ;Divide by 64=New volume
  886.  
  887.         movem.l    d0/a5,-(sp)
  888.         move.l    12(sp),a5
  889.         move.w    d4,d0
  890.         bsr.w    calvol
  891.         move.w    d0,8(a1)        ;Volume in hardware
  892.         movem.l    (sp)+,d0/a5
  893.  
  894.         addq.w    #1,$12(a2)        ;Increment of ADSR pointer
  895.         move.w    6(a3,d7.w),d4        ;Length of adsr table
  896.         cmp.w    $12(a2),d4        ;End of table reached
  897.         bne.b    bpendadsr        ;No ??
  898.         clr.w    $12(a2)         ;Clear ADSR Pointer
  899.         cmpi.b    #1,$1f(a2)        ;Once
  900.         bne.b    bpendadsr        ;No ??
  901.         clr.b    $1f(a2)            ;ADSR off
  902. bpendadsr    tst.b    $1e(a2)            ;LFO On
  903.         beq.b    bpendlfo        ;No ??
  904.         subq.w    #1,$16(a2)        ;LFO delay,May I
  905.         bne.b    bpendlfo        ;No
  906.         moveq    #0,d3
  907.         move.b    16(a3,d7.w),d3
  908.         move.w    d3,$16(a2)        ;Set LFO Count
  909.         move.l    4(sp),a4
  910.         move.l    SMON_Tables(a4),a4
  911.         move.b    10(a3,d7.w),d3        ;Which LFO table
  912.         lsl.l    #6,d3             ;x64
  913.         add.l    d3,a4
  914.         move.w    $10(a2),d3        ;LFO pointer
  915.         moveq    #0,d4
  916.         move.b    (a4,d3.w),d4        ;That's my value
  917.         ext.w    d4             ;Make it a word
  918.         ext.l    d4             ;And a longword
  919.         moveq    #0,d5
  920.         move.b    11(a3,d7.w),d5        ;LFO depth
  921.         tst.b    d5
  922.         beq.b    bpnotx
  923.         divs    d5,d4             ;Calculate it
  924. bpnotx        move.w    (a2),d5         ;Period
  925.         add.w    d4,d5             ;New Period
  926.         move.w    d5,6(a1)        ;In hardware
  927.         addq.w    #1,$10(a2)        ;Next position
  928.         move.w    12(a3,d7.w),d3        ;LFO table Length
  929.         cmp.w    $10(a2),d3        ;End Reached
  930.         bne.b    bpendlfo        ;NO ??
  931.         clr.w    $10(a2)             ;Reset LFO Pointer
  932.         cmpi.b    #1,$1e(a2)        ;Once LFO
  933.         bne.b    bpendlfo        ;NO ??
  934.         clr.b    $1e(a2)         ;LFO Off
  935. bpendlfo    tst.b    $1d(a2)         ;EG On
  936.         beq.w    bpendeg            ;No ??
  937.         subq.w    #1,$14(a2)        ;EG delay,May I
  938.         bne.w    bpendeg         ;No
  939.         tst.l    (a5)
  940.         beq.b    bpendeg
  941.         moveq    #0,d3
  942.         move.b    24(a3,d7.w),d3
  943.         move.w    d3,$14(a2)        ;Set EG Count
  944.         move.l    4(sp),a4
  945.         move.l    SMON_Tables(a4),a4
  946.         move.b    18(a3,d7.w),d3        ;Which EG table
  947.         lsl.l    #6,d3             ;x64
  948.         add.l    d3,a4
  949.         move.w    $e(a2),d3        ;EG pointer
  950.         moveq    #0,d4
  951.         move.b    (a4,d3.w),d4        ;That's my value
  952.         move.l    (a5),a4         ;Pointer to waveform
  953.         add.b    #128,d4         ;0..255
  954.         lsr.l    #3,d4             ;0..31
  955.         moveq    #0,d3
  956.         move.b    $1c(a2),d3        ;Old EG Value
  957.         move.b    d4,$1c(a2)
  958.         add.l    d3,a4             ;WaveForm Position
  959.         move.l    a5,a6             ;Buffer
  960.         add.l    d3,a6             ;Position
  961.         addq.l    #4,a6             ;For adress in buffer
  962.         cmp.b    d3,d4             ;Compare old with new value
  963.         beq.b    bpnexteg        ;no change ??
  964.         bgt.b    bpishigh        ;new value is higher
  965. bpislow        sub.l    d4,d3             ;oldvalue-newvalue
  966.         subq.l    #1,d3             ;Correction for DBRA
  967. bpegloop1a    move.b    -(a6),d4
  968.         move.b    d4,-(a4)
  969.         dbra    d3,bpegloop1a
  970.         bra.b    bpnexteg
  971.  
  972. bpishigh    sub.l    d3,d4             ;Newvalue-oldvalue
  973.         subq.l    #1,d4             ;Correction for DBRA
  974. bpegloop1b    move.b    (a6)+,d3
  975.         neg.b    d3
  976.         move.b    d3,(a4)+        ;DoIt
  977.         dbra    d4,bpegloop1b
  978.  
  979. bpnexteg    addq.w    #1,$e(a2)        ;Next position
  980.         move.w    20(a3,d7.w),d3        ;EG table Length
  981.         cmp.w    $e(a2),d3        ;End Reached
  982.         bne.b    bpendeg            ;NO ??
  983.         clr.w    $e(a2)             ;Reset EG Pointer
  984.         cmpi.b    #1,$1d(a2)        ;Once EG
  985.         bne.b    bpendeg         ;NO ??
  986.         clr.b    $1d(a2)         ;EG Off
  987. bpendeg        rts
  988. ;------------------------------------------------------------------------------
  989. ; Calculate New Volume
  990. ;
  991. ; IN :    D0 = Volume
  992. ;    A5 = SMON Structure
  993. ;
  994. ; OUT:    D0 = New Volume
  995. ;
  996.  
  997. CALVOL    move.l    a5,-(sp)
  998.     move.l    SMON_Global(a5),a5
  999.     move.l    APG_CalcVolume(a5),a5
  1000.     jsr    (a5)
  1001.     move.l    (sp)+,a5
  1002.     rts
  1003. ;------------------------------------------------------------------------------
  1004.     dc.w 6848,6464,6080,5760,5440,5120,4832,4576,4320,4064,3840,3616
  1005.     dc.w 3424,3232,3040,2880,2720,2560,2416,2288,2160,2032,1920,1808
  1006.     dc.w 1712,1616,1520,1440,1360,1280,1208,1144,1080,1016,0960,0904
  1007. bpper    dc.w 0856,0808,0760,0720,0680,0640,0604,0572,0540,0508,0480,0452
  1008.     dc.w 0428,0404,0380,0360,0340,0320,0302,0286,0270,0254,0240,0226
  1009.     dc.w 0214,0202,0190,0180,0170,0160,0151,0143,0135,0127,0120,0113
  1010.     dc.w 0107,0101,0095,0090,0085,0080,0076,0072,0068,0064,0060,0057
  1011. ;------------------------------------------------------------------------------
  1012. ; ModuleName
  1013. ;
  1014. ; IN :    A1 = Address
  1015. ;
  1016. ; OUT:    A0 = Pointer To The Name
  1017. ;
  1018.  
  1019. SM_ModuleName
  1020.     move.l    a1,a0
  1021.     rts
  1022. ;------------------------------------------------------------------------------
  1023. ; GetMaxPattern
  1024. ;
  1025. ; IN :    A1 = Address
  1026. ;
  1027. ; OUT:    D1 = Number Of Patterns
  1028. ;
  1029.  
  1030. SM_GetMaxPattern
  1031.     movem.l    d0/d2/a1,-(sp)
  1032.  
  1033.     move.w    30(a1),d0        ;d1 now contains length in steps
  1034.     move.l    #512,d2
  1035.     moveq    #1,d1            ;1 is highest pattern number
  1036.     mulu    #4,d0             ;4 voices per step
  1037.     subq.w    #1,d0             ;correction for DBRA
  1038. .GTMAX1    cmp.w    (a1,d2.l),d1        ;Is it higher
  1039.     bge.b    .gtmax2            ;No
  1040.     move.w    (a1,d2.l),d1        ;Yes, so let D2 be highest
  1041. .GTMAX2    addq.l    #4,d2             ;Next Voice
  1042.     dbra    d0,.gtmax1        ;And search
  1043.  
  1044.     movem.l    (sp)+,d0/d2/a1
  1045.     rts
  1046. ;------------------------------------------------------------------------------
  1047. ; GetMaxSample
  1048. ;
  1049. ; IN :    A1 = Address
  1050. ;
  1051. ; OUT:    D1 = Number Of Samples
  1052. ;
  1053.  
  1054. SM_GetMaxSample
  1055.     moveq    #15,d1
  1056.     rts
  1057. ;------------------------------------------------------------------------------
  1058. ; GetSongLength
  1059. ;
  1060. ; IN :    A1 = Address
  1061. ;
  1062. ; OUT:    D1 = Length
  1063. ;
  1064.  
  1065. SM_GetSongLength
  1066.     move.w    30(a1),d1
  1067.     rts
  1068. ;------------------------------------------------------------------------------
  1069. ; GetSongPos
  1070. ;
  1071. ; IN :    A1 = Address
  1072. ;
  1073. ; OUT:    D1 = Position (0-x)
  1074. ;
  1075.  
  1076. SM_GetSongPos
  1077.     move.l    a0,-(sp)
  1078.     lea    SM_DataArea,a0
  1079.     move.w    SMON_BPStep(a0),d1
  1080.     move.l    (sp)+,a0
  1081.     rts
  1082. ;------------------------------------------------------------------------------
  1083. ; Rewind
  1084. ;
  1085. ; IN :    A1 = Address
  1086. ;
  1087. ; OUT:    D1 = New Position
  1088. ;
  1089.  
  1090. SM_Rewind
  1091.     movem.l    a0-a1,-(sp)
  1092.     lea    SM_DataArea,a0
  1093.  
  1094.     move.w    SMON_BPStep(a0),d1
  1095.     beq.b    sforwa1
  1096.     subq.w    #1,d1
  1097.     bra.b    sforwa1
  1098. ;------------------------------------------------------------------------------
  1099. ; Forward
  1100. ;
  1101. ; IN :    A1 = Address
  1102. ;
  1103. ; OUT:    D1 = New Position
  1104. ;
  1105.  
  1106. SM_Forward
  1107.     movem.l    a0-a1,-(sp)
  1108.     lea    SM_DataArea,a0
  1109.  
  1110.     move.w    SMON_BPStep(a0),d1
  1111.     addq.w    #1,d1
  1112.     cmp.w    30(a1),d1
  1113.     blt.b    sforwa1
  1114.     moveq    #0,d1
  1115.  
  1116. SFORWA1    move.w    d1,SMON_BPStep(a0)
  1117.     clr.b    SMON_BPPatCount(a0)
  1118.  
  1119.     movem.l    (sp)+,a0-a1
  1120.     rts
  1121. ;------------------------------------------------------------------------------
  1122.     SECTION    NullSample,DATA_C
  1123.  
  1124. NULL    dc.l    0
  1125. ;------------------------------------------------------------------------------
  1126.     SECTION    SM_DataArea,BSS
  1127.  
  1128. SM_DataArea
  1129.     ds.b    SoundMonStruct_SIZEOF
  1130. ;------------------------------------------------------------------------------
  1131. SLUT
  1132.