home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 4: The Falcon Archive / nf_archive_four_v1.0.iso / ARCHIVE / WORK / MSX / GTK08777.ZIP / GTK.DEV / PLAYDSP3.S < prev    next >
Text File  |  1996-12-12  |  161KB  |  5,365 lines

  1. ******************************************************************************
  2. *                            *
  3. *        G R A O U M F   T R A C K E R            *
  4. *                            *
  5. *    Soundtracker Falcon 030 32 voies au DSP            *
  6. *    Par Laurent de Soras (c) 1994-95                *
  7. *____________________________________________________________________________*
  8. *                            *
  9. *    Langage          :    Assembleur 68030 (sous Devpac 2.23)    *
  10. *    Nom du source    :    PLAYDSP3.S                *
  11. *    Code généré      :    GTPLAY.PGT                *
  12. *    Include          :    -                *
  13. *    IncBin           :    PERTABLE.BIN            *
  14. *            VEXP2LIN.BIN            *
  15. *            VLIN2EXP.BIN            *
  16. *            V_E2L_M.BIN            *
  17. *            V_E2L_T.BIN            *
  18. *            V_L2E_T.BIN            *
  19. *            PLAYDSP.P56            *
  20. *    Version          :    0.877                *
  21. *    Date             :    2/12/1996                *
  22. *                            *
  23. *    Routine de replay pour le Graoumf Tracker, joue les modules    *
  24. *    et les sons, gère le MIDI.                *
  25. *                            *
  26. *    Tab = 11                        *
  27. *                            *
  28. ******************************************************************************
  29.  
  30.  
  31.  
  32.     Opt    p=68030,x-,d-,e-,s-
  33.     Output    f:\dev.gtk\sys\gtplay.pgt
  34.  
  35.  
  36.  
  37. *≈≈≈ Constantes ≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈*
  38.  
  39. REPLAY_FREQ:    Equ    49170    ; Fréquence de base de replay
  40.  
  41. NBRVOIES_MAXI:    Equ    32    ; Nombre maximum de voies, on peut en mettre
  42.                 ; autant qu'on veut en fait, du moment que le
  43.                 ; processeur est assez rapide pour toutes les jouer !
  44. SAMPLE_AMPLIFICATION:    Equ    1    ; 0 = ne peut pas amplifier les samples au-dessus
  45.                 ; de leur volume naturel.
  46.                 ; 1 = amplification à puissance élevée possible.
  47.                 ; Ce flag n'est intéressant que pour des samples dont
  48.                 ; le volume_s * master est > $100000
  49.                 ; (vol_t * master > $800000)
  50.  
  51. NBRSAMPLES_MAXI:    Equ    1+255    ; Nombre maximum de samples (+1 vide)
  52. NBRINSTR_MAXI:    Equ    1+255    ; Nombre maximum d'instruments (+1 vide)
  53. NBRPATTERNS_VIDES:    Equ    2    ; Nombre de patterns vides
  54. NBRPATTERNS_MAXI:    Equ    256+NBRPATTERNS_VIDES    ; Nombre maximum de patterns (+n vides)
  55. NBRVOLENV_MAXI:    Equ    1+63    ; Nombre maximum d'enveloppes de volume (+1 vide)
  56. NBRTONENV_MAXI:    Equ    1+63    ; Nombre maximum d'enveloppes de tonalité (+1 vide)
  57. NBRPANENV_MAXI:    Equ    1+63    ; Nombre maximum d'enveloppes de panning (+1 vide)
  58.  
  59.  
  60. DSP_EXCEPTION:    Equ    255    ; Numéro du vecteur d'interruption HOST du DSP
  61.  
  62. INTERRUPTION_TYPE:    Equ    3    ; 0 = interruption DSP
  63.                 ; 1 = Timer A
  64.                 ; 2 = Timer C
  65.                 ; 3 = Timer D
  66.  
  67. CHECK:        Equ    2    ; 0 = aucune vérification (+ rapide - fiable)
  68.                 ; 1 = vérifie lors de chaque opération que les
  69.                 ;     résultats sont bien dans les bons intervalles
  70.                 ; 2 = Idem que 1 mais vérifie aussi l'intégrité
  71.                 ;     des paramètres donnés.
  72.  
  73.         IfNE    CHECK
  74. PERIOD_MAXI:    Equ    32575
  75. PERIOD_MINI:    Equ    71
  76.         EndC
  77.  
  78. ENV_COMMANDMAX:    Equ    16    ; Nombre de commande maximum par tick
  79.                 ; dans une enveloppe
  80.  
  81. MIDI_NBR_CHANNELS:    Equ    16    ; Nombre de canaux MIDI
  82.  
  83. MIDI_IN:        Equ    1    ; 0 = pas de Midi In
  84.                 ; 1 = gestion du Midi In
  85.         IfNE    MIDI_IN
  86. MIDI_IN_MAX_TCLK:    Equ    16    ; En mode Synchro In, nombre max d'impulsions
  87.                 ; qu'on peut rattraper. Remise à 0 après.
  88. MIDI_IN_DATA_BUF_LEN:    Equ    256    ; Buffer de réception de données MIDI (pour une commande)
  89.         EndC
  90.  
  91. MIDI_OUT:        Equ    1    ; 0 = pas de Midi Out
  92.                 ; 1 = gestion du Midi Out
  93.         IfNE    MIDI_OUT
  94. MIDI_OUT_DATA_BUF_LEN:    Equ    4096    ; Buffer d'émission des données MIDI
  95.         EndC
  96.  
  97. ;--- Numéros des commandes des enveloppes ------------------------------------
  98.  
  99. ENV_COM_END:    Equ    $00
  100. ENV_COM_JUMP:    Equ    $01
  101. ENV_COM_WAIT:    Equ    $02
  102. ENV_COM_SET_COUNTER:    Equ    $03
  103. ENV_COM_LOOP:    Equ    $04
  104. ENV_COM_KEY_OFF:    Equ    $05
  105.  
  106. ENV_COM_SET_VOLUME:    Equ    $80
  107. ENV_COM_SET_VOL_STEP    Equ    $81
  108. ENV_COM_SET_VOL_SPD    Equ    $82
  109. ENV_COM_TREMOLO_ON    Equ    $83
  110. ENV_COM_TREMOLO_OFF    Equ    $84
  111. ENV_COM_SET_TRM_WID:    Equ    $85
  112. ENV_COM_SET_TRM_SPD:    Equ    $86
  113. ENV_COM_TREMOR_ON:    Equ    $87
  114. ENV_COM_TREMOR_OFF:    Equ    $88
  115. ENV_COM_SET_TREMOR_1:    Equ    $89
  116. ENV_COM_SET_TREMOR_2:    Equ    $8A
  117.  
  118. ENV_COM_SET_TONE:    Equ    $A0
  119. ENV_COM_SET_TON_STEP:    Equ    $A1
  120. ENV_COM_SET_TON_SPD:    Equ    $A2
  121. ENV_COM_VIBRATO_ON:    Equ    $A3
  122. ENV_COM_VIBRATO_OFF:    Equ    $A4
  123. ENV_COM_SET_VIB_WID:    Equ    $A5
  124. ENV_COM_SET_VIB_SPD:    Equ    $A6
  125.  
  126. ENV_COM_SET_PANNING:    Equ    $C0
  127. ENV_COM_SET_PAN_STEP:    Equ    $C1
  128. ENV_COM_SET_PAN_SPD:    Equ    $C2
  129.  
  130. ;--- Adresses ----------------------------------------------------------------
  131.  
  132. DSPHCR:        Equ    $ffffa200    ; Host Control Register
  133. DSPHSR:        Equ    $ffffa202    ; Host Status Register
  134. DSPIVR:        Equ    $ffffa203    ; Interrupt Vector register
  135. DSPHRDR_L:        Equ    $ffffa204    ; Host Receive Data Register (Long)
  136. DSPHTDR_L:        Equ    $ffffa204    ; Host Transmit Data Register (Long)
  137. DSPHRDR_3:        Equ    $ffffa205    ; Host Receive Data Register (24 bits)
  138. DSPHTDR_3:        Equ    $ffffa205    ; Host Transmit Data Register (24 bits)
  139. DSPHRDR_W:        Equ    $ffffa206    ; Host Receive Data Register (Word)
  140. DSPHTDR_W:        Equ    $ffffa206    ; Host Transmit Data Register (Word)
  141. DSPHRDR_B:        Equ    $ffffa207    ; Host Receive Data Register (Byte)
  142. DSPHTDR_B:        Equ    $ffffa207    ; Host Transmit Data Register (Byte)
  143.  
  144. PLAYINT:        Equ    $ffff8900
  145. PLAYMOD:        Equ    $ffff8901
  146. CBASEHI:        Equ    $ffff8909    ; Octet haut de la position DMA de lecture/enregistrement (bits 16-23)
  147. CBASEMID:        Equ    $ffff890b    ; Octet moyen (bits 8-15)
  148. CBASELO:        Equ    $ffff890d    ; Octet bas (bits 0-7)
  149. TRAKCTRL:        Equ    $ffff8920
  150. SAMPMOD:        Equ    $ffff8921
  151. SDMATRIX:        Equ    $ffff8930    ; Source Device Matrix
  152. DDMATRIX:        Equ    $ffff8932    ; Destination Device Matrix
  153. FDECLOCK:        Equ    $ffff8934    ; Frequency Diviser External Clock
  154. FDISYNC:        Equ    $ffff8935    ; Frequency Diviser Internal Sync
  155.  
  156. FCOLOR00:        Equ    $ffff9800    ; Falcon Color $0
  157. FC_BLACK:        Equ    $00000000    ; Noir
  158. FC_RED:        Equ    $ff000000    ; Rouge
  159. FC_GREEN:        Equ    $00ff0000    ; Vert
  160. FC_BLUE:        Equ    $000000ff    ; Bleu
  161. FC_YELLOW:        Equ    FC_RED+FC_GREEN
  162. FC_MAGENTA:    Equ    FC_RED+FC_BLUE
  163. FC_CYAN:        Equ    FC_GREEN+FC_BLUE
  164. FC_WHITE:        Equ    FC_RED+FC_GREEN+FC_BLUE
  165.  
  166. MFPST_INT_TIMERA:    Equ    $134
  167. MFPST_INT_TIMERC:    Equ    $114
  168. MFPST_INT_TIMERD:    Equ    $110
  169. MFPIERA:        Equ    $fffffa07
  170. MFPIERB:        Equ    $fffffa09
  171. MFPISRA:        Equ    $fffffa0f
  172. MFPISRB:        Equ    $fffffa11
  173. MFPIMRA:        Equ    $fffffa13
  174. MFPIMRB:        Equ    $fffffa15
  175. MFPTACR:        Equ    $fffffa19
  176. MFPTBCR:        Equ    $fffffa1b
  177. MFPTCDCR:        Equ    $fffffa1d
  178. MFPTADR:        Equ    $fffffa1f
  179. MFPTBDR:        Equ    $fffffa21
  180. MFPTCDR:        Equ    $fffffa23
  181. MFPTDDR:        Equ    $fffffa25
  182.  
  183.  
  184.  
  185. *≈≈≈ Macros ≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈*
  186.  
  187. ;--- Port Host du DSP --------------------------------------------------------
  188.  
  189. writhost:    Macro            ; Attend que le port Host soit
  190. .wrhst\@:    btst    #1,DSPHSR.w    ; libre en écriture
  191.     beq.s    .wrhst\@
  192.     EndM
  193.  
  194. readhost:    Macro            ; Attend qu'une donnée soit
  195. .rdhst\@:    btst    #0,DSPHSR.w    ; présente sur le port Host afin
  196.     beq.s    .rdhst\@        ; d'être lue
  197.     EndM
  198.  
  199. ;--- Initialisation des enveloppes -------------------------------------------
  200.  
  201. env_initialisation:    Macro
  202.     ; Paramètres :
  203.     ; 1) Registre d'adresse pointant sur le descripteur de la voie
  204.     ; 2) 0 si aucune enveloppe à mettre, sinon paramètre 3 pris en compte
  205.     ; 3) Registre d'adresse pointant sur le nouvel instrument
  206.  
  207.     IfEq    \2
  208.  
  209.     clr.w    nevol_t(\1)    ; Efface les numéros d'enveloppe
  210.     clr.w    neton_t(\1)
  211.     clr.w    nepan_t(\1)
  212.  
  213.     Else            ; Réinitialise tous les paramètres
  214.  
  215.     move.w    volenv_i(\3),nevol_t(\1)    ; Enveloppe de volume
  216.     beq.s    .suite1\@
  217.     env_volume_init    \1
  218. .suite1\@:
  219.     move.w    tonenv_i(\3),neton_t(\1)    ; Enveloppe de tonalité
  220.     beq.s    .suite2\@
  221.     env_tone_init    \1
  222. .suite2\@:
  223.     move.w    panenv_i(\3),nepan_t(\1)    ; Enveloppe de panning
  224.     beq.s    .suite3\@
  225.     env_panning_init    \1
  226. .suite3\@:
  227.     EndC
  228.  
  229.     EndM
  230.  
  231. env_volume_init:    Macro
  232.     ; Paramètres:
  233.     ; 1) Registre d'adresse pointant sur le descripteur de la voie
  234.     clr.w    ev_waitcpt_t(\1)
  235.     clr.w    ev_loopcpt_t(\1)
  236.     move.w    #$4000,ev_volume_t(\1)
  237.     clr.w    ev_volstep_t(\1)
  238.     move.w    #1,ev_volspeed_t(\1)
  239.     clr.w    ev_volcpt_t(\1)
  240.     clr.b    ev_tremoloflag_t(\1)
  241.     clr.b    ev_tremorflag_t(\1)
  242.     clr.b    ev_tremolospeed_t(\1)
  243.     clr.b    ev_tremolowidth_t(\1)
  244.     clr.b    ev_tremolocpt_t(\1)
  245.     clr.b    ev_tremolotype_t(\1)
  246.     move.b    #3,ev_tremortime1_t(\1)
  247.     move.b    #3,ev_tremortime2_t(\1)
  248.     clr.b    ev_tremorsection_t(\1)
  249.     clr.b    ev_tremorcpt_t(\1)
  250.     clr.w    pevol_t(\1)    ; Position dans l'enveloppe à 0
  251.     move.w    #data_e,devol_t(\1)    ; Pointeur sur les section courante (Normale ici)
  252.     EndM
  253.  
  254. env_tone_init:    Macro
  255.     ; Paramètres:
  256.     ; 1) Registre d'adresse pointant sur le descripteur de la voie
  257.     clr.w    et_waitcpt_t(\1)
  258.     clr.w    et_loopcpt_t(\1)
  259.     move.w    #$1000,et_tone_t(\1)
  260.     clr.w    et_tonestep_t(\1)
  261.     move.w    #1,et_tonespeed_t(\1)
  262.     clr.w    et_tonecpt_t(\1)
  263.     clr.b    et_vibratoflag_t(\1)
  264.     clr.b    et_vibratospeed_t(\1)
  265.     clr.b    et_vibratowidth_t(\1)
  266.     clr.b    et_vibratocpt_t(\1)
  267.     clr.b    et_vibratotype_t(\1)
  268.     clr.w    peton_t(\1)    ; Position dans l'enveloppe à 0
  269.     move.w    #data_e,deton_t(\1)    ; Pointeur sur les section courante (Normale ici)
  270.     EndM
  271.  
  272. env_panning_init:    Macro
  273.     ; Paramètres:
  274.     ; 1) Registre d'adresse pointant sur le descripteur de la voie
  275.     clr.w    ep_waitcpt_t(\1)
  276.     clr.w    ep_loopcpt_t(\1)
  277.     move.w    #$800,ep_pan_t(\1)
  278.     clr.w    ep_panstep_t(\1)
  279.     move.w    #1,ep_panspeed_t(\1)
  280.     clr.w    ep_pancpt_t(\1)
  281.     clr.w    peton_t(\1)    ; Position dans l'enveloppe à 0
  282.     move.w    #data_e,deton_t(\1)    ; Pointeur sur les section courante (Normale ici)
  283.     EndM
  284.  
  285.  
  286.  
  287. *≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈*
  288.  
  289.     Text
  290.  
  291.  
  292.  
  293. ;--- Programmes principaux, appelés par le GfA Basic -------------------------
  294.  
  295.     bra    relocation        ; Relocation du prg, et fournit quelques
  296.                 ; adresses au GfA
  297.     bra    player_on        ; Déclenche toute l'installation du
  298.                 ; player avec le DSP
  299.     bra    boucle_instrument    ; Boucle un instrument
  300.     bra    gfa_play_one_sample    ; Joue un sample dont on a fourni les
  301.                 ; paramètre
  302.     bra    gfa_play_one_note    ; Joue un instrument dans une voie donnée
  303.     bra    songrecord_routine_no_realtime1    ; Enregistre un module
  304.  
  305.  
  306.  
  307. player_on:    movem.l    d0-a6,-(sp)
  308.     pea    init_mod_player
  309.     move.w    #$26,-(sp)
  310.     trap    #14        ; Exécute en Superviseur
  311.     addq.l    #6,sp
  312.     movem.l    (sp)+,d0-a6
  313.     rts
  314.  
  315. gfa_play_one_sample:
  316.     move.l    a0,-(sp)
  317.     move.l    4+4(sp),a0
  318.     move.w    4+8(sp),d0
  319.     bsr    play_one_sample
  320.     move.l    (sp)+,a0
  321.     rts
  322.  
  323. gfa_play_one_note:            ; Param:
  324.     movem.l    d0/a0,-(sp)    ; - Adresse.l des 5 octets de la note
  325.     move.l    8+4(sp),a0        ; - Numéro.w de la voie
  326.     move.w    8+8(sp),d0
  327.     bsr    play_one_note
  328.     movem.l    (sp)+,d0/a0
  329.     rts
  330.  
  331. songrecord_routine_no_realtime1:
  332.     movem.l    d0/a0,-(sp)
  333.     pea    songrecord_routine_no_realtime
  334.     move.w    #$26,-(sp)
  335.     trap    #14        ; Exécute en Superviseur
  336.     addq.l    #6,sp
  337.     movem.l    (sp)+,d0/a0
  338.     rts
  339.  
  340.  
  341. ;-----------------------------------------------------------------------------
  342. ;    Routine de relocation.
  343. ;    Fournir l'adresse du PRG chargé en 4(sp), renvoie l'adresse de
  344. ;    de adr_labels dans d0
  345. ;-----------------------------------------------------------------------------
  346. relocation:   
  347.     movem.l    d1/a0-a2,-(sp)
  348.     move.l    16+4(sp),a0    ; 4(sp) : adresse du PRG
  349.     move.l    2(a0),d0
  350.     add.l    6(a0),d0
  351.     add.l    14(a0),d0
  352.     adda.l    #$1c,a0
  353.     move.l    a0,d1
  354.     movea.l    a0,a1
  355.     movea.l    a1,a2
  356.     adda.l    d0,a1
  357.     move.l    (a1)+,d0
  358.     adda.l    d0,a2
  359.     add.l    d1,(a2)
  360.     clr.l    d0
  361. relocloop:    move.b    (a1)+,d0
  362.     beq.s    reloc_end
  363.     cmp.b    #1,d0
  364.     beq.s    reloc_nxt
  365.     adda.l    d0,a2
  366.     add.l    d1,(a2)
  367.     bra.s    relocloop
  368. reloc_nxt:    adda.l    #$fe,a2
  369.     bra.s    relocloop
  370. reloc_end:    lea    adr_labels(pc),a0
  371.     move.l    a0,d0
  372.     movem.l    (sp)+,d1/a0-a2
  373.     rts
  374.  
  375.  
  376.  
  377. ;-----------------------------------------------------------------------------
  378. ;    Petite initialisation
  379. ;-----------------------------------------------------------------------------
  380. init_mod_player:
  381.  
  382.     movem.l    d0-a6,-(sp)
  383.  
  384. ;--- Prépare le module -------------------------------------------------------
  385.  
  386.     bsr    prepare_module
  387.     IfNE    MIDI_IN
  388.     bsr    gestmidi_init_in
  389.     EndC
  390.  
  391. ;--- Charge la routine DSP en mémoire DSP ------------------------------------
  392.  
  393.     move.w    #$71,-(sp)        ; DSP request ability
  394.     trap    #14
  395.     move.w    d0,(sp)
  396.     move.l    #(routine_dsp_lon-routine_dsp)/3,-(sp)    ; La longueur
  397.     pea    routine_dsp
  398.     move.w    #$6d,-(sp)        ; Charge le prog en mémoire DSP
  399.     trap    #14
  400.     lea    12(sp),sp
  401.  
  402.     move.l    #$902000,SDMATRIX.w    ; Connecte le DSP à la matrice
  403.     move.w    #$101,FDECLOCK.w    ; 50 KHz
  404.     move.b    #$0,PLAYMOD.w
  405.     move.w    #$3,TRAKCTRL.w
  406.  
  407. ;--- Initialise l'interruption -----------------------------------------------
  408.  
  409.     IfNE    INTERRUPTION_TYPE=0    ; Interruption DSP
  410.     move.b    #DSP_EXCEPTION,DSPIVR.w    ; Numéro de l'exception déclenchée lors de la
  411.     move.l    #soundtracking_kernel,DSP_EXCEPTION*4.w    ; réception d'une donnée par le port Host
  412.     move.b    #1,DSPHCR.w    ; Autorise l'interruption
  413.     move.l    #DSP_EXCEPTION*4,adr_adr_inter
  414.     Else
  415.     move.l    #soundtracking_kernel,adresse_interruption
  416.     move.l    #adresse_interruption,adr_adr_inter
  417.     EndC
  418.  
  419.     IfNE    INTERRUPTION_TYPE=1    ; Interruption Timer A
  420.     move.l    MFPST_INT_TIMERA.w,sauvegarde_timer
  421.     bclr    #5,MFPIMRA.w    ; Timer A masqué
  422.     bset    #5,MFPIERA.w    ; Timer A autorisé
  423.     move.b    #6,MFPTACR.w    ; 1/100 : 24576 Hz
  424.     move.b    #3,MFPTADR.w    ; /3 : 8192 Hz
  425.     move.l    #gtkr_interruption_timer,MFPST_INT_TIMERA.w
  426.     bset    #5,MFPIMRA.w    ; Timer A démasqué
  427.     EndC
  428.  
  429.     IfNE    INTERRUPTION_TYPE=2    ; Interruption Timer C
  430.     move.l    MFPST_INT_TIMERC.w,sauvegarde_timer
  431.     bclr    #5,MFPIMRB.w    ; Timer C masqué
  432.     bset    #5,MFPIERB.w    ; Timer C autorisé
  433.     and.b    #%10001111,MFPTCDCR.w
  434.     or.b    #6<<4,MFPTCDCR.w    ; 1/100 : 24576 Hz
  435.     move.b    #3,MFPTCDR.w    ; /3 : 8192 Hz
  436.     move.l    #gtkr_interruption_timer,MFPST_INT_TIMERC.w
  437.     bset    #5,MFPIMRB.w    ; Timer C démasqué
  438.     EndC
  439.  
  440.     IfNE    INTERRUPTION_TYPE=3    ; Interruption Timer D
  441.     move.l    MFPST_INT_TIMERD.w,sauvegarde_timer
  442.     bclr    #4,MFPIMRB.w    ; Timer D masqué
  443.     bset    #4,MFPIERB.w    ; Timer D autorisé
  444.     and.b    #%11111000,MFPTCDCR.w
  445.     or.b    #6,MFPTCDCR.w    ; 1/100 : 24576 Hz
  446.     move.b    #3,MFPTDDR.w    ; /3 : 8192 Hz
  447.     move.l    #gtkr_interruption_timer,MFPST_INT_TIMERD.w
  448.     bset    #4,MFPIMRB.w    ; Timer D démasqué
  449.     EndC
  450.  
  451.     clr.w    flag_the_end
  452.  
  453.     writhost
  454.     move.l    #$0,DSPHTDR_L.w    ; C'est parti mon kiki!
  455.  
  456.     movem.l    (sp)+,d0-a6
  457.     rts
  458.  
  459.  
  460.  
  461.     IfNE    INTERRUPTION_TYPE
  462.  
  463. ;≡≡≡ Routine sous Timer si celui-ci est choisi ≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡
  464.  
  465. gtkr_interruption_timer:
  466.     and.w    #%1111100011111111,sr    ; Autorise toutes les interruptions
  467.     btst    #0,DSPHSR.w    ; Une donnée a été envoyée par le DSP ?
  468.     beq.s    .rien
  469.     jmp    ([adresse_interruption])    ; Oui, faut y aller
  470. .rien:
  471.     IfNE    INTERRUPTION_TYPE=1
  472.     bclr    #5,MFPISRA.w    ; Sinon on attend le prochain coup
  473.     EndC
  474.     IfNE    INTERRUPTION_TYPE=2
  475.     bclr    #5,MFPISRB.w
  476.     EndC
  477.     IfNE    INTERRUPTION_TYPE=3
  478.     bclr    #4,MFPISRB.w
  479.     EndC
  480.     rte
  481.  
  482.     EndC
  483.  
  484.  
  485.  
  486. ;-----------------------------------------------------------------------------
  487. ;    Préparation du module. L'adresse du module doit être fournie
  488. ;    ainsi que les adresses du descripteur d'instruments, de la song,
  489. ;    des patterns et de tous les instruments
  490. ;-----------------------------------------------------------------------------
  491. prepare_module:
  492.     movem.l    d0-a6,-(sp)
  493.  
  494.     lea    module_inf1,a1
  495.     lea    module_inf2,a5
  496.     move.l    adr_module(a1),a0
  497.  
  498.     move.w    $c8(a0),d0        ; d0 = nbr de voies
  499.     move.w    d0,nbrvoies
  500.     move.w    d0,mod_nbrtrack(a5)
  501.     move.w    $ca(a0),mod_songlen(a5)
  502.     move.w    $cc(a0),mod_songrep(a5)
  503.  
  504.     lea    repeatbuffer,a6
  505.     move.w    #255,d0
  506. .eff    clr.l    (a6)+        ; Pour le sample 0, on met du vide
  507.     dbra    d0,.eff
  508.     move.w    $c4(a0),d1        ; d1 = nbr d'instr
  509.     tst.w    d1
  510.     beq.s    prepa_pas_instr
  511. prepa_mod_loop4:
  512.     move.w    d1,-(sp)
  513.     bsr    boucle_instrument    ; Bouclage
  514.     addq.l    #2,sp
  515.     subq.w    #1,d1
  516.     bne.s    prepa_mod_loop4
  517. prepa_pas_instr:
  518.  
  519.     lea    module_inf1,a1
  520.     lea    info_track,a4
  521.     lea    new_note_buffer(pc),a6
  522.     moveq    #0,d1        ; La balance courante
  523.     move.w    #$fff,d2        ; Le flag de changement de balance
  524.     moveq    #NBRVOIES_MAXI-1,d0
  525. prepa_mod_loop3:
  526.     move.w    #1,onoff_t(a4)
  527.     move.w    #1,nbits_t(a4)
  528.     move.w    #8363,fech_t(a4)
  529.     clr.w    vol_t(a4)
  530.     move.w    d1,bal_t(a4)
  531.     move.w    d1,curbal_t(a4)
  532.     eor.w    d2,d1        ; Change la balance quand d2=$fff : L R R L L R R L ...
  533.     eor.w    #$fff,d2        ; Le flag est à $fff une fois sur deux
  534.     move.w    #$6b00,per_t(a4)
  535.     move.l    #sample_vide,adrsam_t(a4)
  536.     clr.l    pos_t(a4)
  537.     clr.w    finepos_t(a4)
  538.     clr.l    reppos_t(a4)
  539.     move.l    #2,replen_t(a4)
  540.     move.l    #repeatbuffer,rbuffer_t(a4)
  541.     clr.w    interpol_t(a4)
  542.     clr.w    c_n_t(a4)
  543.     clr.w    c_i_t(a4)
  544.     clr.w    c_e_t(a4)
  545.     clr.w    c_v_t(a4)
  546.     move.w    #0,ninstr_t(a4)
  547.     clr.w    norm_f_t(a4)
  548.     clr.w    norm_v_t(a4)
  549.     move.w    #24,curnote_t(a4)
  550.     move.w    #$6b00,pernote_t(a4)
  551.     clr.w    vollnot_t(a4)
  552.     clr.w    volenot_t(a4)
  553.     clr.w    portspd_t(a4)
  554.     clr.w    tportspd_t(a4)
  555.     move.w    #48,note2sl_t(a4)
  556.     move.w    #$1ac0,per2sl_t(a4)
  557.     clr.b    vibspd_t(a4)
  558.     clr.b    vibcpt_t(a4)
  559.     clr.b    vibamp_t(a4)
  560.     clr.b    vibwav_t(a4)
  561.     clr.b    tremspd_t(a4)
  562.     clr.b    tremcpt_t(a4)
  563.     clr.b    tremamp_t(a4)
  564.     clr.b    tremwav_t(a4)
  565.     move.b    #3,rollspd_t(a4)
  566.     clr.b    rollcpt_t(a4)
  567.     clr.w    rollnbr_t(a4)
  568.     clr.w    delay_t(a4)
  569.     clr.w    cut_del_t(a4)
  570.     clr.w    tremorc_t(a4)
  571.     move.b    #3,tremor1_t(a4)
  572.     move.b    #6,tremor2_t(a4)
  573.     clr.w    ploopp_t(a4)
  574.     clr.w    ploops_t(a4)
  575.     clr.w    ploopn_t(a4)
  576.     clr.w    instr_t(a4)
  577.     clr.w    transp_t(a4)
  578.     move.w    #$100,volsam_t(a4)
  579.     env_initialisation    a4,0
  580.     clr.w    flag_autotempo_t(a4)
  581.     clr.w    flag_autoperiod_t(a4)
  582.     move.w    #$1000,mix_volume_t(a4)
  583.     move.w    #$C00,mix_volume_e_t(a4)
  584.     clr.w    ltvolslspd_t(a4)
  585.     clr.w    etvolslspd_t(a4)
  586.     clr.w    fetvolslspd_t(a4)
  587.     clr.b    (a6)        ; Le buffer de nouvelle note
  588.     add.w    #next_t,a4
  589.     addq.w    #6,a6
  590.     dbra    d0,prepa_mod_loop3
  591.  
  592.     clr.w    current_track
  593.     clr.w    dsp_plein
  594.     clr.w    mod_songpos(a5)
  595.     clr.w    mod_numpat(a5)
  596.     clr.w    mod_linepos(a5)
  597.     clr.w    mod_patrep(a5)
  598.     move.w    #125,mod_tempo(a5)
  599.     move.w    #6,mod_speed(a5)
  600.     move.w    #-1,mod_nbrvbl(a5)
  601.     move.l    #$3000,d0
  602.     move.w    mod_nbrtrack(a5),d1
  603.     addq.w    #4,d1
  604.     divu.w    d1,d0
  605.     move.w    d0,master_vol
  606.     moveq    #0,d0
  607.     move.w    replay_frequency,d0
  608.     divu.w    #125*4*6/60,d0
  609.     move.w    d0,vblsize
  610.     move.w    d0,vblcurrentsize
  611.     clr.w    d0
  612.     divu.w    #125*4*6/60,d0
  613.     move.w    d0,vblsize_frac
  614.     clr.w    vblcurrentsize_frac
  615.     move.w    #1,vblnumber
  616.     clr.w    vblcpt
  617.     clr.w    flag_stop_voices
  618.     clr.w    flag_mt_display
  619.     clr.w    flag_new_notes
  620.     clr.w    flag_overflow
  621.     clr.w    cpu_time_pourcent
  622.     clr.w    current_play_mode
  623.     clr.w    current_edit_mode
  624.     clr.w    midi_in_on
  625.     clr.w    midi_in_gfa_playline
  626.     move.w    #-1,midi_current_status
  627.     move.w    #-1,midi_old_status
  628.     clr.w    midi_in_sync_flag
  629.     clr.w    midi_in_sync_cpt
  630.     clr.w    songrecord_flag
  631.  
  632.     lea    midi_in_noteoff_flag(pc),a2
  633.     moveq    #MIDI_NBR_CHANNELS-1,d0
  634. .loop1:    move.w    #-1,(a2)+
  635.     dbra    d0,.loop1
  636.  
  637.     lea    midi_in_velo_flag(pc),a2
  638.     moveq    #MIDI_NBR_CHANNELS-1,d0
  639. .loop2:    move.w    #-1,(a2)+
  640.     dbra    d0,.loop2
  641.  
  642.     lea    midi_instr_map(pc),a2
  643.     moveq    #MIDI_NBR_CHANNELS-1,d0
  644. .loop3:    move.w    #1,(a2)+
  645.     dbra    d0,.loop3
  646.  
  647.     bsr    gestion_partition
  648.  
  649.     movem.l    (sp)+,d0-a6
  650.     rts
  651.  
  652.  
  653.  
  654. ;-----------------------------------------------------------------------------
  655. ;    Bouclage d'un instrument
  656. ;    Fournir en 4(sp).w le numéro de l'instrument à boucler
  657. ;    Modifie d0
  658. ;-----------------------------------------------------------------------------
  659. boucle_instrument:
  660.     moveq    #0,d0
  661.     move.w    4(sp),d0
  662.     movem.l    d1-a6,-(sp)
  663.     lea    module_inf1,a1
  664.     move.l    (a1,d0.w*4),a1
  665.     lea    repeat_s(a1),a3
  666.     lea    data_s(a1),a1    ; a1 pointe sur le sample
  667.     lea    repeatbuffer,a6
  668.     swap    d0
  669.     lsr.l    #6,d0
  670.     add.l    d0,a6
  671.     move.w    #512,d1
  672. .loop1:    move.l    a1,a2
  673.     add.l    (a3),a2        ; a2 pointe sur le début de la boucle
  674.     move.l    replen_s-repeat_s(a3),d2    ; d2 = replen
  675.     lsr.l    #1,d2
  676.     subq.l    #1,d2
  677.     tst.l    d2
  678.     bne.s    .loop2
  679.     tst.l    (a3)
  680.     bne.s    .loop2
  681.  
  682.     cmp.w    #16,nbits_s-repeat_s(a3)
  683.     beq.s    .bouc16b
  684. .bouc8b:    move.w    #1023,d1        ; Pas bouclage 8 bits
  685.     add.l    length_s-repeat_s(a3),a2
  686.     subq.l    #1,a2
  687. .loop3:    move.b    (a2),(a6)+
  688.     dbra    d1,.loop3
  689.     bra.s    .fini
  690. .bouc16b:    subq.w    #1,d1        ; Pas de bouclage 16 bits
  691.     add.l    length_s-repeat_s(a3),a2
  692.     subq.l    #2,a2
  693. .loop4:    move.w    (a2),(a6)+
  694.     dbra    d1,.loop4
  695.     bra.s    .fini
  696.  
  697. .loop2:    move.w    (a2)+,(a6)+    ; Bouclage normal
  698.     subq.w    #1,d1
  699.     beq.s    .fini
  700.     subq.l    #1,d2
  701.     bpl.s    .loop2
  702.     bra.s    .loop1
  703.  
  704. .fini:    movem.l    (sp)+,d1-a6
  705.     rts
  706.  
  707.  
  708.  
  709. ;-----------------------------------------------------------------------------
  710. ;    Joue un sample
  711. ;    d0 = numéro de voie (0-31)
  712. ;    a0 = adresse.l du bloc de description de la voie.
  713. ;    Numéro de la note à la place de la période
  714. ;-----------------------------------------------------------------------------
  715. play_one_sample:
  716.     movem.l    a1-a2,-(sp)
  717.     lea    info_track,a1
  718.     mulu.w    #next_t,d0
  719.     add.l    d0,a1        ; a1 pointe sur les infos de la voie
  720.     lea    per_table(pc),a2
  721.     move.w    per_t(a0),d0    ; Prend la note
  722.     sub.w    #24,d0
  723.     lsl.w    #4,d0
  724.     move.w    (a2,d0.w),per_t(a1)    ; Envoie la période
  725.     move.w    (a2,d0.w),pernote_t(a1)    ; Pour la partition
  726.     move.w    #1,onoff_t(a1)
  727.     move.w    nbits_t(a0),nbits_t(a1)
  728.     move.w    fech_t(a0),fech_t(a1)
  729.     move.w    vol_t(a0),vol_t(a1)
  730.     move.w    vol_t(a0),vollnot_t(a1)
  731.     move.l    adrsam_t(a0),adrsam_t(a1)
  732.     move.l    reppos_t(a0),reppos_t(a1)
  733.     move.l    replen_t(a0),replen_t(a1)
  734.     move.l    rbuffer_t(a0),rbuffer_t(a1)
  735.     clr.l    pos_t(a1)
  736.     clr.w    finepos_t(a1)
  737.     move.l    a1,d0        ; Renvoie dans d0 l'adresse du descripteur de piste
  738.     movem.l    (sp)+,a1-a2
  739.     rts
  740.  
  741.  
  742.  
  743. ;-----------------------------------------------------------------------------
  744. ;    Joue une note d'un instrument.
  745. ;    Stoque en fait la note dans un buffer qui sera scanné lors du
  746. ;    décodage de la prochaine ligne.
  747. ;    a0 = adresse de la note
  748. ;    d0 = numéro.w de la voie
  749. ;-----------------------------------------------------------------------------
  750. play_one_note:
  751.     movem.l    d0-d1/a1,-(sp)
  752.     move.w    d0,d1        ; d0 = d0 * 6
  753.     add.w    d0,d0        ;
  754.     add.w    d1,d0        ;
  755.     add.w    d0,d0        ;
  756.     lea    new_note_buffer(pc),a1
  757.     move.l    (a0),1(a1,d0.w)    ; Copie la note
  758.     move.b    4(a0),5(a1,d0.w)
  759.     move.b    #1,(a1,d0.w)    ; Mise en place du flag
  760.     movem.l    (sp)+,d0-d1/a1
  761.     rts
  762.  
  763.  
  764.  
  765. ;-----------------------------------------------------------------------------
  766. ;    Routine d'enregistrement d'un module sous forme des sample,
  767. ;    sans utiliser l'interruption.
  768. ;-----------------------------------------------------------------------------
  769. songrecord_routine_no_realtime:
  770.     movem.l    d0-d1/a0,-(sp)
  771.  
  772.     move.w    songrecord_state(pc),d0
  773.     cmp.w    #4,d0        ; Teste si on est bien en enregistrement
  774.     beq.s    .rec_end
  775.  
  776. .waitloop:    tst.w    songrecord_flag2    ; Attend qu'on ait fini le mixage
  777.     beq.s    .waitloop
  778.  
  779.     move.l    songrecord_startadr,a0
  780.     readhost
  781.  
  782.     move.l    DSPHRDR_L.w,d0    ; d0 = nombre de paquets à recevoir (2 x 24 bits)
  783.     swap    d0
  784.     clr.w    d0
  785.     swap    d0
  786.     move.l    d0,d1
  787.     add.l    d1,d1        ; => en samples
  788.     add.l    d1,d1        ; => en octets
  789.     move.l    d1,songrecord_bufpos    ; Ca donne la position finale
  790.     beq.s    .rec_loop_end
  791.     subq.w    #1,d0
  792.  
  793. .rec_loop:
  794.     readhost            ; Sample de gauche
  795.     move.l    DSPHRDR_L.w,d1
  796.     lsr.l    #8,d1        ; 24 -> 16 bits
  797.     move.w    d1,(a0)+
  798.  
  799.     readhost            ; Sample de droite
  800.     move.l    DSPHRDR_L.w,d1
  801.     lsr.l    #8,d1        ; 24 -> 16 bits
  802.     move.w    d1,(a0)+
  803.  
  804.     dbra    d0,.rec_loop
  805. .rec_loop_end
  806.  
  807.     move.w    sr,-(sp)
  808.     or    #$2700,sr
  809.  
  810.     IfNE    INTERRUPTION_TYPE=0
  811.     move.b    #1,DSPHCR.w    ; Réautorise l'interruption
  812.     EndC
  813.     IfNE    INTERRUPTION_TYPE=1
  814.     bset    #5,MFPIMRA.w    ; Timer A démasqué
  815.     EndC
  816.     IfNE    INTERRUPTION_TYPE=2
  817.     bset    #5,MFPIMRB.w    ; Timer C démasqué
  818.     EndC
  819.     IfNE    INTERRUPTION_TYPE=3
  820.     bset    #4,MFPIMRB.w    ; Timer D démasqué
  821.     EndC
  822.  
  823.     writhost            ; Donne le signal de reprise
  824.     move.l    #0,DSPHTDR_L.w
  825.  
  826.     move    (sp)+,sr
  827.  
  828. .rec_end:
  829.     movem.l    (sp)+,d0-d1/a0
  830.     rts
  831.  
  832.  
  833.  
  834. ;-----------------------------------------------------------------------------
  835. ;    Routine exécutée sur l'interruption DSP juste avant le noyau.
  836. ;    Met en route le DMA pour l'enregistrement d'un module sous
  837. ;    forme de sample.
  838. ;    Arrête ensuite le DMA et remet le vecteur à sa place
  839. ;-----------------------------------------------------------------------------
  840. songrecord_routine:
  841.     movem.l    d0-a6,-(sp)
  842.     and.w    #%1111100011111111,sr    ; Autorise toutes les interruptions
  843.     tst.w    current_track(pc)    ; Première voie ?
  844.     bne    sngrec_end        ; Non, c'est pas la peine de rester
  845.  
  846.     tst.w    songrecord_state(pc)    ; 0 - On a pas encore commencé à enregistrer ?
  847.     beq.s    sngrec_state0
  848.     cmp.w    #1,songrecord_state    ; 1 - On doit commencer maintenant ?
  849.     beq    sngrec_state1
  850.     cmp.w    #2,songrecord_state    ; 2 - Attente de la fin de l'enregistrement ?
  851.     beq    sngrec_state2
  852.     bra    sngrec_state3    ; 3 - Coupe l'enregistrement.
  853.  
  854. ;--- Attend l'endroit où on doit commencer -----------------------------------
  855. sngrec_state0:
  856.     move.w    songrecord_startpos(pc),d0
  857.     cmp.w    module_inf2+mod_cursongpos,d0
  858.     bne    sngrec_end        ; Pas encore la bonne position
  859.     move.w    songrecord_startline(pc),d0
  860.     cmp.w    module_inf2+mod_curlinepos,d0
  861.     bne    sngrec_end        ; Pas encore la bonne ligne
  862.     cmp.w    #NBRPATTERNS_MAXI-NBRPATTERNS_VIDES-1,module_inf2+mod_numpat
  863.     bgt    sngrec_end        ; Si on est encore dans les patterns vides
  864.     move.w    module_inf2+mod_nbrvbl,d0
  865.     cmp.w    module_inf2+mod_speed,d0
  866.     bge    sngrec_end        ; Si c'était la fin du mode Stop
  867.  
  868.     move.w    replay_frequency(pc),songrecord_srecfreq    ; Sauve l'ancienne fréquence
  869.     move.w    songrecord_recfreq(pc),replay_frequency    ; Fixe la fréquence d'échantillonnage
  870.  
  871. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  872. ; Recalcule les valeurs de samples/frame
  873.     move.w    module_inf2+mod_tempo,d0
  874.     mulu.w    #4*6,d0
  875.     move.w    replay_frequency(pc),d1
  876.     mulu.w    #60,d1
  877.     divu.w    d0,d1        ; d1 = freq.repl * 60 s / (tempo * 4 lig * 6 ticks)
  878.     move.l    d1,d3        ;    = nombre de spl par tick
  879.     clr.w    d3
  880.     divu.w    d0,d3        ; d3 = nbr de spl par tick, frac
  881.     swap    d3
  882.     move.w    d1,d3
  883.     swap    d3        ; d3 = nbr de spl par tick * $10000
  884.     move.l    #1200-1,d0
  885.     add.w    d1,d0
  886.     divu.w    #1200,d0        ; d0 = splpartick/1200 arrondi par excès
  887.     ext.l    d0
  888.     divu.l    d0,d3        ; d3 = Nbr de spl par VBL * $10000
  889.     move.l    d3,vblsize        ; Stoque d'un coup les parties entière et fractionnaire
  890.     move.w    d0,vblnumber
  891.     clr.w    d3
  892.     move.l    d3,vblcurrentsize
  893.  
  894. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  895.     tst.w    songrecord_realtime(pc)
  896.     bne.s    .realtime
  897.  
  898.     readhost
  899.     move.w    DSPHRDR_W.w,d0    ; Récupère la commande émise par le dsp (même pas en fait)
  900.     writhost
  901.     move.l    #1<<6,DSPHTDR_L.w    ; Passage en mode pas à pas
  902.     readhost            ; Attend un nouvel appel du DSP
  903.     move.w    #1,songrecord_flag
  904.     clr.w    songrecord_flag2
  905.     move.w    #2,songrecord_state    ; On est maintenant en enregistrement
  906.     bra    sngrec_end
  907.  
  908. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  909. .realtime:
  910.     move.w    #1,songrecord_state    ; Attend encore une frame à cause
  911.     bra    sngrec_end        ; du double buffer du DSP
  912.  
  913. ;--- Commence l'enregistrement -----------------------------------------------
  914. sngrec_state1:
  915.     tst.w    songrecord_realtime(pc)
  916.     beq.s    .stat1end
  917. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  918. ; Fixe l'adresse du buffer
  919.     move.l    songrecord_endadr,-(sp)
  920.     move.l    songrecord_startadr,-(sp)
  921.     move.w    #1,-(sp)        ; Précise que c'est pour l'écriture
  922.     move.w    #$83,-(sp)        ; Setbuffer
  923.     trap    #14
  924.     lea    12(sp),sp
  925.  
  926. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  927. ; Connecte la sortie DSP à l'enregistrement DMA
  928.     move.w    $ffff8934.w,songrecord_sprediv    ; Sauve l'ancienne prédivision
  929.     move.w    #1,-(sp)        ; Sortie DSP
  930.     move.w    #%0001,-(sp)    ; Enregistrement DMA
  931.     clr.w    -(sp)        ; Horloge interne 25.175 MHz
  932.     move.w    #1,-(sp)        ; Prédivision
  933.     move.w    #1,-(sp)        ; Handshake
  934.     move.w    #$8b,-(sp)        ; Devconnect
  935.     trap    #14
  936.     lea    12(sp),sp
  937.     move.b    songrecord_prediv+1(pc),$ffff8934+1.w
  938.  
  939. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  940. ; Commence l'enregistrement
  941.     move.w    #%1100,-(sp)    ; Enregistrement avec bouclage
  942.     move.w    #$88,-(sp)        ; Buffoper
  943.     trap    #14
  944.     addq.l    #4,sp
  945.  
  946. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  947. .stat1end:    move.w    #2,songrecord_state    ; On passe en phase d'attente de la fin
  948.     bra    sngrec_state2    ; Teste maintenant si c'est la fin
  949.  
  950. ;--- Attend la fin de l'enregistrement ---------------------------------------
  951. sngrec_state2:
  952.     move.w    songrecord_endpos(pc),d0
  953.     cmp.w    module_inf2+mod_cursongpos,d0
  954.     bne    sngrec_end        ; Pas encore la bonne position
  955.     move.w    songrecord_endline(pc),d0
  956.     cmp.w    module_inf2+mod_curlinepos,d0
  957.     bne    sngrec_end        ; Pas encore la bonne ligne
  958.     tst.w    songrecord_realtime(pc)
  959.     beq.s    sngrec_restore
  960.  
  961.     move.w    #3,songrecord_state    ; Attend encore une frame à cause
  962.     bra    sngrec_end        ; du double buffer du DSP
  963.  
  964. ;--- Arrête maintenant l'enregistrement --------------------------------------
  965. sngrec_state3:
  966.     tst.w    songrecord_realtime(pc)
  967.     beq.s    sngrec_restore
  968.  
  969. ; Récupère l'adresse de la dernière position d'enregistrement
  970.     move.b    $ffff8901.w,d0    ; Sélectionne le registre d'enregistrement
  971.     bset    #7,d0
  972.     move.b    d0,$ffff8901.w
  973.     moveq    #0,d0
  974.     move.b    $ffff8909.w,d0    ; On le lit
  975.     swap    d0
  976.     move.b    $ffff890b.w,d0
  977.     lsl.w    #8,d0
  978.     move.b    $ffff890d.w,d0
  979.     move.l    d0,songrecord_lastadr
  980.  
  981. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  982. ; Arrête le DMA
  983.     move.w    #%0000,-(sp)    ; Stop
  984.     move.w    #$88,-(sp)        ; Buffoper
  985.     trap    #14
  986.     addq.l    #4,sp
  987.  
  988.     move.w    songrecord_sprediv(pc),$ffff8934.w    ; Restaure l'ancienne prédivision
  989.  
  990. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  991. ; Recalcule les valeurs de samples/frame
  992. sngrec_restore:
  993.     move.w    songrecord_srecfreq(pc),replay_frequency    ; Restaure l'ancienne fréquence
  994.     move.w    module_inf2+mod_tempo,d0
  995.     mulu.w    #4*6,d0
  996.     move.w    replay_frequency(pc),d1
  997.     mulu.w    #60,d1
  998.     divu.w    d0,d1        ; d1 = freq.repl * 60 s / (tempo * 4 lig * 6 ticks)
  999.     move.l    d1,d3        ;    = nombre de spl par tick
  1000.     clr.w    d3
  1001.     divu.w    d0,d3        ; d3 = nbr de spl par tick, frac
  1002.     swap    d3
  1003.     move.w    d1,d3
  1004.     swap    d3        ; d3 = nbr de spl par tick * $10000
  1005.     move.l    #1200-1,d0
  1006.     add.w    d1,d0
  1007.     divu.w    #1200,d0        ; d0 = splpartick/1200 arrondi par excès
  1008.     ext.l    d0
  1009.     divu.l    d0,d3        ; d1 = Nbr de spl par VBL * $10000
  1010.     move.l    d3,vblsize        ; Stoque d'un coup les parties entière et fractionnaire
  1011.     move.w    d0,vblnumber
  1012.     clr.w    d3
  1013.     move.l    d3,vblcurrentsize
  1014.  
  1015. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  1016. ; Signale que c'est terminé
  1017.     clr.w    songrecord_flag
  1018.     move.w    #4,songrecord_state
  1019.     IfNE    INTERRUPTION_TYPE=0
  1020.     move.l    #soundtracking_kernel,DSP_EXCEPTION*4.w
  1021.     Else
  1022.     move.l    #soundtracking_kernel,adresse_interruption
  1023.     EndC
  1024.  
  1025.     tst.w    songrecord_realtime(pc)
  1026.     bne.s    .sngresend
  1027.     readhost
  1028.     move.l    DSPHRDR_L.w,d0    ; Mot de commande du DSP gobé
  1029.     writhost
  1030.     move.l    #1<<7,DSPHTDR_L.w    ; Signale au DSP qu'il peut reprendre normalement
  1031. .sngresend:
  1032.  
  1033. sngrec_end:
  1034.     movem.l    (sp)+,d0-a6
  1035.     bra    soundtracking_kernel
  1036.  
  1037.  
  1038.  
  1039.  
  1040.  
  1041. *≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈*
  1042. *    Noyau de la routine de soundtrack, envoie les samples au DSP.    *
  1043. *≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈*
  1044. *    Cette routine doit être placée sur l'interruption DSP        *
  1045. *    Les samples sont signés. Toutes les informations (rep, pos...)    *
  1046. *    sont données en octets. Un sample non bouclé doit avoir un    *
  1047. *    replen à 2 et reppos = longueur - 2. Tout sample doit avoir    *
  1048. *    un buffer de bouclage.                *
  1049. *≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈*
  1050. soundtracking_kernel:
  1051.  
  1052.     movem.l    d0-a6,-(sp)
  1053.  
  1054.     tst.w    flag_mt_display(pc)
  1055.     beq.s    .finsi
  1056.     move.l    #FC_RED,FCOLOR00.w    ; Le rouge montre le temps machine utilisé par la routine
  1057. .finsi:
  1058.  
  1059.     readhost
  1060.     move.w    DSPHRDR_W.w,d0    ; Récupère le temps machine donné par le DSP
  1061.     cmp.w    #255,d0
  1062.     bne.s    .nooverld
  1063.     move.w    #1,flag_overflow
  1064. .nooverld:    move.w    d0,cpu_time_pourcent
  1065.  
  1066.     tst.w    flag_the_end    ; On doit tout arrêter ?
  1067.     beq.s    sendsam_nostop
  1068.     move.b    #0,DSPHCR.w    ; Plus d'interruption DSP Host
  1069.     writhost
  1070.     move.l    #1<<3,DSPHTDR_L.w    ; Arrêt de la routine DSP
  1071.     tst.w    flag_mt_display(pc)
  1072.     beq.s    .stop_timer
  1073.     clr.l    FCOLOR00.w        ; Nuit !
  1074. .stop_timer:
  1075.     IfNE    INTERRUPTION_TYPE=1    ; Arret du Timer A s'il était là
  1076.     bclr    #5,MFPIMRA.w    ; Timer A masqué
  1077.     bclr    #5,MFPIERA.w    ; Timer A annulé
  1078.     move.l    sauvegarde_timer,MFPST_INT_TIMERA.w
  1079.     EndC
  1080.     IfNE    INTERRUPTION_TYPE=2    ; Arret du Timer C
  1081.     bclr    #5,MFPIMRB.w    ; Timer C masqué
  1082.     bclr    #5,MFPIERB.w    ; Timer C annulé
  1083.     move.l    sauvegarde_timer,MFPST_INT_TIMERC.w
  1084.     EndC
  1085.     IfNE    INTERRUPTION_TYPE=3    ; Arret du Timer D s'il était là
  1086.     bclr    #4,MFPIMRB.w    ; Timer D masqué
  1087.     bclr    #4,MFPIERB.w    ; Timer D annulé
  1088.     move.l    sauvegarde_timer,MFPST_INT_TIMERD.w
  1089.     EndC
  1090.     bra    sendsam_the_end
  1091.  
  1092. sendsam_nostop:
  1093.     lea    info_track,a0    ; a0 pointe sur le tableau d'infos des voies
  1094.     move.w    current_track(pc),d0    ; d0 = voie courante
  1095.     bne.s    .ok
  1096.     writhost            ; Si c'est la première voie : on indique
  1097.     move.l    #1<<5,DSPHTDR_L.w    ; le nombre de samples par tick (dépend
  1098.     moveq    #0,d1        ; du tempo)
  1099.     move.w    vblcurrentsize(pc),d1
  1100.     writhost
  1101.     move.l    d1,DSPHTDR_L.w
  1102. .ok:    move.w    nbrvoies(pc),d1    ; d1 = nbr de voies
  1103.     move.w    d0,d2
  1104.     mulu.w    #next_t,d2
  1105.     add.w    d2,a0        ; Mise à jour du pointeur sur la voie courante
  1106. sendsam_tsttrkloop:
  1107.     cmp.w    d0,d1        ; C'était la dernière voie ?
  1108.     beq    sendsam_apuvoi
  1109.     tst.w    onoff_t(a0)    ; Voie active ?
  1110.     beq    sendsam_tsttrknxt
  1111.     cmp.l    #2,replen_t(a0)    ; Sample non bouclé ? *** Gagne du temps machine, mais
  1112.     bgt.s    .suite        ;                     *** provoque un petit bruit à la
  1113.     tst.l    reppos_t(a0)    ; Sample vide ?
  1114.     beq    sendsam_tsttrknxt
  1115.     move.l    pos_t(a0),d3    ; Si non, la fin ?    *** fin des samples dont la
  1116.     cmp.l    reppos_t(a0),d3    ;                     *** courbe ne revient pas à 0
  1117.     bge.s    sendsam_cst    ;                     *** (mettre ces lignes en commentaires)
  1118. .suite:    tst.w    vol_t(a0)        ; Volume à 0 ?
  1119.     bne    sendsam_voieon    ; Non, on envoie le sample
  1120.     moveq    #0,d5        ; Oui, on fait avancer la position
  1121.     move.w    per_t(a0),d5
  1122.     mulu.w    replay_frequency,d5    ; d5 = Per(note) * Freplay
  1123.     move.l    #$1ac00000,d2    ; d2 = Per(C2) * $10000
  1124.     moveq    #0,d4
  1125.     move.w    fech_t(a0),d4
  1126.     mulu.l    d4,d3:d2
  1127.     divu.l    d5,d3:d2        ; d2 = $10000 * Fech(C2) * Per(C2) / Per(note) / Freplay
  1128.     moveq    #0,d5
  1129.     move.w    vblcurrentsize(pc),d5
  1130.     mulu.l    d2,d5        ; d5 = nbr d'échantillons à envoyer en 1 VBL * 65536
  1131.     add.w    d5,finepos_t(a0)
  1132.     bcc.s    .nocarry
  1133.     add.l    #$10000,d5
  1134. .nocarry:    clr.w    d5
  1135.     swap    d5
  1136.     cmp.w    #2,nbits_t(a0)
  1137.     bne.s    .8bits
  1138.     add.l    d5,d5
  1139. .8bits:    add.l    pos_t(a0),d5    ; Position suivante
  1140.     cmp.l    reppos_t(a0),d5
  1141.     ble.s    .fin
  1142.     sub.l    reppos_t(a0),d5
  1143.     divul.l    replen_t(a0),d4:d5
  1144.     add.l    reppos_t(a0),d4
  1145.     move.l    d4,d5        ; d5 = nvlpos = ((pos + N - rep) MOD replen) + rep
  1146. .fin:    move.l    d5,pos_t(a0)
  1147. sendsam_tsttrknxt:
  1148.     addq.w    #1,d0
  1149.     add.w    #next_t,a0
  1150.     bra    sendsam_tsttrkloop
  1151.  
  1152. sendsam_cst:            ; Envoi d'un sample constant (quand un
  1153.     moveq    #0,d4        ; instrument est fini et non bouclé)
  1154.     writhost
  1155.     move.l    #1<<4,DSPHTDR_L.w    ; Bit 4 : spl cst
  1156.     move.w    vol_t(a0),d4
  1157.     mulu.w    master_vol,d4    ; On multiplie par le master
  1158.     writhost
  1159.     move.l    d4,DSPHTDR_L.w    ; Volume
  1160.     move.w    bal_t(a0),d4    ; Envoie la balance
  1161.     lsl.w    #3,d4
  1162.     lsl.l    #8,d4
  1163.     writhost
  1164.     move.l    d4,DSPHTDR_L.w
  1165.     moveq    #0,d4
  1166.     move.l    rbuffer_t(a0),a1    ; Cherche le sample constant
  1167.     move.w    (a1),d4        ; a1 sur le premier octet du buffer de répétition
  1168. ;    neg.w    d4        ; Inverse le signe (à cause des autres samples
  1169.     lsl.l    #8,d4        ; qui avaient leur signe inversé à la réception
  1170.     cmp.w    #2,nbits_t(a0)    ; sur le DSP)
  1171.     beq.s    .16
  1172.     clr.w    d4
  1173. .16:    writhost
  1174.     move.l    d4,DSPHTDR_L.w
  1175.     clr.l    reppos_t(a0)    ; A pu sample
  1176.     bra.s    sendsam_tsttrknxt
  1177.  
  1178.  
  1179.  
  1180. sendsam_voieon:
  1181.     move.l    reppos_t(a0),d1    ; Vérifie que pos < reppos+replen
  1182.     add.l    replen_t(a0),d1
  1183.     cmp.l    pos_t(a0),d1
  1184.     bgt.s    .finsi1
  1185.     subq.l    #2,d1        ; Sinon, pos = reppos+replen-2
  1186.     move.l    d1,pos_t(a0)
  1187. .finsi1:    lea    DSPHTDR_L.w,a2    ; *** Penser à optimiser avec ces registres
  1188.     lea    DSPHTDR_W.w,a3    ; *** en enlevant les macros
  1189.     lea    DSPHSR.w,a4    ; *** ISR
  1190.     writhost
  1191.     move.l    #1,DSPHTDR_L.w    ; Bit 1 : voie on
  1192.  
  1193.     move.w    vol_t(a0),d1    ; d1 = volume
  1194.     mulu.w    master_vol,d1    ; On multiplie par le master
  1195.     moveq    #0,d2        ; Le nombre de décalages à faire en cas d'amplif.
  1196.  
  1197.     IfNE    SAMPLE_AMPLIFICATION
  1198.     cmp.l    #$800000,d1
  1199.     blt.s    .samampok
  1200. .samamplp:    addq.w    #1,d2
  1201.     lsr.l    #1,d1
  1202.     cmp.l    #$800000,d1
  1203.     bge.s    .samamplp
  1204. .samampok:
  1205.     EndC
  1206.  
  1207.     writhost
  1208.     move.l    d1,DSPHTDR_L.w    ; Le volume
  1209.     writhost
  1210.     move.l    d2,DSPHTDR_L.w    ; Les décalages
  1211.  
  1212.     move.w    bal_t(a0),d1    ; Envoie la balance
  1213.     lsl.w    #3,d1
  1214.     lsl.l    #8,d1
  1215.     writhost
  1216.     move.l    d1,DSPHTDR_L.w
  1217.  
  1218.     moveq    #0,d1
  1219.     move.w    per_t(a0),d1
  1220.     mulu.w    replay_frequency,d1    ; d1 = Per(note) * Freplay
  1221.     move.l    #$1ac00000,d2    ; d2 = Per(C2) * $10000
  1222.     moveq    #0,d4
  1223.     move.w    fech_t(a0),d4
  1224.     mulu.l    d4,d3:d2
  1225.     divu.l    d1,d3:d2        ; d2.l = $10000 * Fech(C2) * Per(C2) / Per(note) / Freplay
  1226.     swap    d2
  1227.     moveq    #0,d1
  1228.     move.w    d2,d1        ; d1.w = incrément de position (entier)
  1229.     swap    d2        ; d2.w = incrément de position (1/65536)
  1230.     cmp.w    #2,d1
  1231.     bge    sendsam_030    ; Si y en a trop à envoyer, rééchantillonnage au 030
  1232.     move.w    d2,d3
  1233.     lsl.l    #8,d3
  1234.     writhost
  1235.     move.l    d1,DSPHTDR_L.w    ; Période mot fort
  1236.     writhost            ; Envoie la période du sample mot faible
  1237.     move.l    d3,DSPHTDR_L.w
  1238.  
  1239.     move.w    finepos_t(a0),d3
  1240.     lsl.l    #8,d3
  1241.     writhost
  1242.     move.l    d3,DSPHTDR_L.w    ; Envoie une précision de la position
  1243.  
  1244.     moveq    #0,d1
  1245.     move.w    interpol_t(a0),d1    ; Interpolation ?
  1246.     writhost
  1247.     move.l    d1,DSPHTDR_L.w
  1248.  
  1249.     move.w    vblcurrentsize(pc),d1
  1250.     mulu.l    d2,d1        ; d1 = nbr d'échantillons à envoyer en 1 VBL * 65536
  1251.     add.w    d1,finepos_t(a0)
  1252.     bcc.s    .nocarry
  1253.     add.l    #$10000,d1
  1254. .nocarry:    clr.w    d1
  1255.     swap    d1
  1256.     cmp.w    #2,nbits_t(a0)
  1257.     beq    sendsam_16bits    ; Si c'est du 16 bits
  1258.  
  1259.  
  1260.  
  1261. ;--- Envoi de samples 8 bits -------------------------------------------------
  1262. sendsam_8bits:
  1263.     writhost
  1264.     move.l    #1,DSPHTDR_L.w
  1265.     addq.l    #1+1,d1        ; *** Dernier sample à mixer : en envoyer 1 de plus
  1266.                 ; *** car le nbr est décimal (arrondit par défaut)
  1267.                 ; *** Plus 1 pour l'interpolation
  1268.     btst    #0,pos_t+3(a0)
  1269.     beq.s    sendsam_8even    ; Adresse de début de bloc paire
  1270.  
  1271.     move.l    reppos_t(a0),d3
  1272.     addq.l    #1,d3
  1273.     cmp.l    pos_t(a0),d3
  1274.     bne.s    .else
  1275.     move.l    rbuffer_t(a0),a1    ; Si on tombe sur le 2ème octet de la boucle, on prend
  1276.     addq.l    #1,a1        ; celui du bouclage (évite grésillements pour le sample 0)
  1277.     bra.s    .finsi
  1278. .else    move.l    adrsam_t(a0),a1    ; a1 = adresse du sample
  1279.     add.l    pos_t(a0),a1
  1280. .finsi    move.l    d1,d2        ; là c'est impair
  1281.     subq.l    #2,d2
  1282.     lsr.l    #1,d2        ; d2 = N/2-1 arrondi par défaut
  1283.     subq.l    #1,d1
  1284.     addq.l    #1,pos_t(a0)
  1285.     writhost
  1286.     move.l    d2,DSPHTDR_L.w    ; Envoie le nbr de mots (2 échantillons)
  1287.     writhost
  1288.     move.w    #1,DSPHTDR_W.w    ; Adresse impaire
  1289.     writhost
  1290.     move.b    (a1)+,DSPHTDR_B.w    ; Envoi 1 échantillon -> adresse paire
  1291.     bra.s    sendsam_8transfert
  1292.  
  1293. sendsam_8even:            ; Là c'est pair
  1294.     move.l    d1,d2
  1295.     subq.l    #1,d2
  1296.     lsr.l    #1,d2        ; Arrondit par excès
  1297.     writhost
  1298.     move.l    d2,DSPHTDR_L.w
  1299.     writhost
  1300.     move.l    #0,DSPHTDR_L.w
  1301.  
  1302. sendsam_8transfert:
  1303.     move.l    d1,d2
  1304.     subq.l    #1+1,d1        ; *** correction position réelle/nbr de spl envoyés
  1305.     add.l    pos_t(a0),d1    ; Calcul de la position suivante
  1306.     cmp.l    reppos_t(a0),d1
  1307.     ble.s    .else
  1308.     sub.l    reppos_t(a0),d1
  1309.     divul.l    replen_t(a0),d6:d1
  1310.     add.l    reppos_t(a0),d6    ; d6 = nvlpos = ((pos + N - rep) MOD replen) + rep
  1311.     bra.s    .finsi
  1312. .else:    move.l    d1,d6
  1313. .finsi:
  1314.  
  1315. sendsam_8avantfin:
  1316.     move.l    pos_t(a0),d3
  1317.     move.l    reppos_t(a0),d4
  1318.     cmp.l    d4,d3        ; Teste si on est juste sur le début de la boucle
  1319.     beq.s    sendsam_8boucle    ; (par ex. dans le cas de samples non bouclés)
  1320.     move.l    adrsam_t(a0),a1    ; a1 = adresse du sample
  1321.     add.l    d3,a1
  1322.     add.l    d2,d3
  1323.     add.l    replen_t(a0),d4
  1324.     cmp.l    d4,d3        ; On dépasse la fin ?
  1325.     blt    sendsam_8noloop
  1326.     sub.l    pos_t(a0),d4    ; d4 = nbr d'octets avant la boucle
  1327.     beq.s    sendsam_8boucle
  1328.     sub.l    d4,d2
  1329.     subq.l    #1,d4        ; Arrondit par excès
  1330.     lsr.l    #1,d4
  1331.  
  1332.     move.w    d4,d3        ; Transfert ce qu'il y a avant la boucle
  1333.     not.w    d3
  1334.     and.w    #15,d3
  1335.     lsr.w    #4,d4
  1336.     writhost            ; Après ça plus de tests, DSP et 030 synchro!
  1337.     jmp    (sendsam_8loopt2,d3.w*2)
  1338. sendsam_8loopt2:
  1339.     REPT    16        ; Pour cartes accélératrices : intercaller des
  1340.     move.w    (a1)+,(a3)        ; NOPs ou des tests du TXDE, ne pas oublier de
  1341.     ENDR            ; modifier le d3.w*2 du jmp d'avant. Idem plus loin
  1342.     dbra    d4,sendsam_8loopt2
  1343.     tst.l    d2
  1344.     bne.s    sendsam_8boucle
  1345.     move.l    d6,pos_t(a0)    ; Si on s'arrète pile-poil à la fin
  1346.     bra    sendsam_next
  1347.  
  1348. sendsam_8boucle:            ; Envoie la boucle
  1349.     move.l    rbuffer_t(a0),a1
  1350.     move.l    #1024,d3
  1351.     cmp.l    d3,d2
  1352.     bgt.s    .finsi
  1353.     move.l    d2,d3        ; Si le transfert se termine dans le buffer de boucle
  1354. .finsi:    sub.l    d3,d2
  1355.     move.l    d3,d5        ; d5 = nbr d'octets transférés
  1356.     subq.l    #1,d3
  1357.     lsr.l    #1,d3        ; Arrondit par excès
  1358.     move.w    d3,d4        ; Transfert ce qu'il y a dans la boucle
  1359.     not.w    d4
  1360.     and.w    #15,d4
  1361.     lsr.w    #4,d3
  1362.     writhost
  1363.     jmp    (sendsam_8loopt3,d4.w*2)
  1364. sendsam_8loopt3:
  1365.     REPT    16
  1366.     move.w    (a1)+,(a3)
  1367.     ENDR
  1368.     dbra    d3,sendsam_8loopt3
  1369.  
  1370.     tst.l    d2        ; Qu'est-ce qui reste ?
  1371.     beq.s    sendsam_8fin    ; Rien, on se tire
  1372.     divul.l    replen_t(a0),d4:d5
  1373.     add.l    reppos_t(a0),d4
  1374.     move.l    d4,pos_t(a0)    ; pos = ((pos + N - rep) MOD replen) + rep
  1375.     bra    sendsam_8avantfin    ; On revient pour finir le transfert
  1376.  
  1377. sendsam_8fin:
  1378.     move.l    d6,pos_t(a0)    ; Nouvelle position
  1379.     bra    sendsam_next
  1380.  
  1381. sendsam_8noloop:
  1382.     subq.l    #1,d2
  1383.     lsr.l    #1,d2        ; Arrondit par excès
  1384.     move.w    d2,d4        ; Transfert !
  1385.     not.w    d4
  1386.     and.w    #15,d4
  1387.     lsr.w    #4,d2
  1388.     writhost
  1389.     jmp    (sendsam_8loopt1,d4.w*2)
  1390. sendsam_8loopt1:
  1391.     REPT    16
  1392.     move.w    (a1)+,(a3)
  1393.     ENDR
  1394.     dbra    d2,sendsam_8loopt1
  1395.     move.l    d6,pos_t(a0)    ; Nouvelle position
  1396.     bra    sendsam_next
  1397.  
  1398.  
  1399.  
  1400. ;--- Envoi de samples 16 bits ------------------------------------------------
  1401. sendsam_16bits:
  1402.     writhost
  1403.     move.l    #2,DSPHTDR_L.w    ; Signale que c'est du 16 bits
  1404.     move.l    d1,d2
  1405.     add.l    d2,d2        ; d2 = nombre d'octets
  1406.     addq.l    #2+2,d2        ; *** 1 sample de sécurité
  1407.                 ; *** plus 1 sample pour l'interpolation
  1408.     addq.l    #-1+1+1,d1        ; d1 = nombre de samples -1 à envoyer en une VBL
  1409.                 ; *** + 1 sample à cause de l'arrondi par excès
  1410.                 ; *** + 1 pour l'interpolation
  1411.     writhost
  1412.     move.l    d1,DSPHTDR_L.w
  1413.  
  1414. sendsam_16avantfin:
  1415.     move.l    pos_t(a0),d3
  1416.     move.l    adrsam_t(a0),a1    ; a1 = adresse du sample
  1417.     add.l    d3,a1
  1418.     add.l    d2,d3
  1419.     move.l    reppos_t(a0),d4
  1420.     add.l    replen_t(a0),d4
  1421.     cmp.l    d4,d3        ; On dépasse la fin ?
  1422.     blt    sendsam_16noloop
  1423.     sub.l    pos_t(a0),d4    ; d4 = nbr d'octets avant la boucle
  1424.     beq.s    sendsam_16boucle
  1425.     sub.l    d4,d2
  1426.     lsr.l    #1,d4
  1427.     subq.l    #1,d4
  1428.  
  1429.     move.w    d4,d3        ; Transfert ce qu'il y a avant la boucle
  1430.     not.w    d3
  1431.     and.w    #15,d3
  1432.     lsr.w    #4,d4
  1433.     writhost
  1434.     jmp    (sendsam_16loopt2,d3.w*2)
  1435. sendsam_16loopt2:
  1436.     REPT    16
  1437.     move.w    (a1)+,(a3)
  1438.     ENDR
  1439.     dbra    d4,sendsam_16loopt2
  1440.     tst.l    d2
  1441.     bne.s    sendsam_16boucle
  1442.     move.l    reppos_t(a0),d1    ; Si on s'arrète pile-poil à la fin
  1443.     add.l    replen_t(a0),d1
  1444.     subq.l    #2+2,d1        ; *** Enlève le sample de sécurité + interp.
  1445.     move.l    d1,pos_t(a0)
  1446.     bra    sendsam_next
  1447.  
  1448. sendsam_16boucle:            ; Envoie la boucle
  1449.     move.l    rbuffer_t(a0),a1
  1450.     move.l    #1024,d3
  1451.     cmp.l    d3,d2
  1452.     bgt.s    .finsi
  1453.     move.l    d2,d3        ; Si le transfert se termine dans le buffer de boucle
  1454. .finsi:    sub.l    d3,d2
  1455.     move.l    d3,d5        ; d5 = nbr d'octets transférés
  1456.     lsr.l    #1,d3
  1457.     subq.l    #1,d3
  1458.     move.w    d3,d4        ; Transfert ce qu'il y a dans la boucle
  1459.     not.w    d4
  1460.     and.w    #15,d4
  1461.     lsr.w    #4,d3
  1462.     writhost
  1463.     jmp    (sendsam_16loopt3,d4.w*2)
  1464. sendsam_16loopt3:
  1465.     REPT    16
  1466.     move.w    (a1)+,(a3)
  1467.     ENDR
  1468.     dbra    d3,sendsam_16loopt3
  1469.  
  1470.     tst.l    d2        ; Qu'est-ce qui reste ?
  1471.     beq.s    sendsam_16fin    ; Rien, on se tire
  1472.     divul.l    replen_t(a0),d4:d5
  1473.     add.l    reppos_t(a0),d4
  1474.     move.l    d4,pos_t(a0)    ; pos = ((pos + N - rep) MOD replen) + rep
  1475.     bra    sendsam_16avantfin    ; On revient pour finir le transfert
  1476.  
  1477. sendsam_16fin:
  1478.     subq.l    #2+2,d5        ; *** Enlève le sample de sécurité + interp.
  1479.     divul.l    replen_t(a0),d4:d5
  1480.     add.l    reppos_t(a0),d4
  1481.     move.l    d4,pos_t(a0)    ; pos = ((pos + N - rep) MOD replen) + rep
  1482.     bra    sendsam_next
  1483.  
  1484. sendsam_16noloop:
  1485.     lsr.w    #1,d2
  1486.     subq.w    #1,d2
  1487.     move.w    d2,d4        ; Transfert !
  1488.     not.w    d4
  1489.     and.w    #15,d4
  1490.     lsr.w    #4,d2
  1491.     writhost
  1492.     jmp    (sendsam_16loopt1,d4.w*2)
  1493. sendsam_16loopt1:
  1494.     REPT    16
  1495.     move.w    (a1)+,(a3)
  1496.     ENDR
  1497.     dbra    d2,sendsam_16loopt1
  1498.     subq.l    #2+2,d3        ; *** Enlève le sample supplémentaire + interp.
  1499.     move.l    d3,pos_t(a0)    ; Nouvelle position
  1500.     bra    sendsam_next
  1501.  
  1502.  
  1503.  
  1504. ;--- Rééchantillonnage au 030 (mais mixage DSP) ------------------------------
  1505. sendsam_030:            ; d2 contient l'incrément entier.frac
  1506.     writhost            ; d1 contient l'incrément 0.entier
  1507.     move.l    #$800000,DSPHTDR_L.w
  1508.     move.l    pos_t(a0),d3    ; d3 = position.l, partie entière
  1509.     move.w    finepos_t(a0),d4    ; d4 = position.w, partie fractionnaire
  1510.     moveq    #0,d5
  1511.     move.w    vblcurrentsize(pc),d5    ; d5 = nombre.w d'échantillons à envoyer
  1512.     move.l    adrsam_t(a0),a1    ; a1 = adresse du sample
  1513.     move.l    rbuffer_t(a0),a2    ; a2 = adresse du buffer
  1514.     cmp.w    #2,nbits_t(a0)
  1515.     beq    sendsam_03016
  1516.  
  1517.  
  1518.  
  1519. sendsam_0308:
  1520.     lea    DSPHTDR_B.w,a3
  1521.     writhost
  1522.     move.l    #$8000,DSPHTDR_L.w
  1523.     writhost            ; 030 et DSP synchros
  1524. .sendloop:
  1525.     move.l    reppos_t(a0),d6
  1526.     add.l    replen_t(a0),d6
  1527.     sub.l    d3,d6        ; d6 = longueur avant la fin
  1528.     subq.l    #1,d6        ; On soustrait 1 AVANT le div pour arrondir par excès
  1529.     moveq    #0,d7        ; Mets d6 * $10000 dans d7:d6
  1530.     swap    d6        ; |
  1531.     move.w    d6,d7        ; |
  1532.     clr.w    d6        ; |
  1533.     divu.l    d2,d7:d6        ; d6 = nbr de samples -1 possibles à envoyer avant la fin
  1534.     subq.l    #1,d5
  1535.     cmp.l    d5,d6
  1536.     ble.s    .s1
  1537.     move.l    d5,d6
  1538. .s1:    sub.l    d6,d5        ; Ajuste le compteur de samples
  1539.  
  1540. .loop1:
  1541.     move.b    (a1,d3.l),(a3)
  1542.     add.w    d2,d4
  1543.     addx.l    d1,d3
  1544.     dbra    d6,.loop1
  1545.  
  1546.     move.l    reppos_t(a0),d6
  1547.     add.l    replen_t(a0),d6
  1548.     cmp.l    d6,d3
  1549.     blt.s    .s2a
  1550.     sub.l    replen_t(a0),d3
  1551.     tst.l    d5
  1552.     ble    .fini
  1553.     bra.s    .s2b
  1554. .s2a:    tst.l    d5
  1555.     ble    .fini
  1556.     move.l    reppos_t(a0),d3    ; Si erreur d'arrondi, on remet au début de la boucle
  1557. .s2b:
  1558.  
  1559. ; Dans la boucle maintenant
  1560.     move.l    #1024-1,d6
  1561.     sub.l    reppos_t(a0),d3
  1562.     sub.l    d3,d6
  1563.     swap    d6
  1564.     moveq    #0,d7
  1565.     divul.l    d2,d7:d6        ; d6 = nbr de samples -1 à envoyer avant la fin de la boucle
  1566.     subq.l    #1,d5
  1567.     cmp.l    d5,d6
  1568.     ble.s    .s3
  1569.     move.l    d5,d6
  1570. .s3:    sub.l    d6,d5        ; Ajuste le compteur de samples
  1571.  
  1572. .loop2:
  1573.     move.b    (a2,d3.l),(a3)
  1574.     add.w    d2,d4
  1575.     addx.l    d1,d3
  1576.     dbra    d6,.loop2
  1577.  
  1578.     moveq    #0,d6
  1579.     divul.l    replen_t(a0),d6:d3
  1580.     move.l    d6,d3
  1581.     add.l    reppos_t(a0),d3    ; Réajuste la position en fin de boucle
  1582.     tst.l    d5
  1583.     bgt    .sendloop
  1584.  
  1585. .fini:
  1586.     move.l    d3,pos_t(a0)
  1587.     move.w    d4,finepos_t(a0)
  1588.     bra    sendsam_next
  1589.  
  1590.  
  1591.  
  1592. sendsam_03016:
  1593.     lea    DSPHTDR_W.w,a3
  1594.     lsr.l    #1,d3        ; d3 : Octets -> Samples
  1595.     writhost
  1596.     move.l    #$80,DSPHTDR_L.w
  1597.     writhost            ; 030 et DSP synchros
  1598. .sendloop:
  1599.     move.l    reppos_t(a0),d6
  1600.     add.l    replen_t(a0),d6
  1601.     lsr.l    #1,d6        ; En samples !
  1602.     sub.l    d3,d6        ; Longueur avant la fin
  1603.     subq.l    #1,d6
  1604.     moveq    #0,d7
  1605.     swap    d6
  1606.     move.w    d6,d7
  1607.     clr.w    d6
  1608.     divu.l    d2,d7:d6        ; d6 = nbr de samples -1 possibles à envoyer avant la fin
  1609.     subq.l    #1,d5
  1610.     cmp.l    d5,d6
  1611.     ble.s    .s1
  1612.     move.l    d5,d6
  1613. .s1:    sub.l    d6,d5        ; Ajuste le compteur de samples
  1614.  
  1615. .loop1:
  1616.     move.w    (a1,d3.l*2),(a3)
  1617.     add.w    d2,d4
  1618.     addx.l    d1,d3
  1619.     dbra    d6,.loop1
  1620.  
  1621.     add.l    d3,d3
  1622.     move.l    reppos_t(a0),d6
  1623.     add.l    replen_t(a0),d6
  1624.     cmp.l    d6,d3
  1625.     blt.s    .s2a
  1626.     sub.l    replen_t(a0),d3
  1627.     tst.l    d5
  1628.     ble    .fini2
  1629.     bra.s    .s2b
  1630. .s2a:    tst.l    d5
  1631.     ble    .fini2
  1632.     move.l    reppos_t(a0),d3    ; Si erreur d'arrondi, on remet au début de la boucle
  1633. .s2b:
  1634.  
  1635.  
  1636. ; Dans la boucle maintenant
  1637.     move.l    #1024/2-1,d6
  1638.     sub.l    reppos_t(a0),d3
  1639.     lsr.l    #1,d3
  1640.     sub.l    d3,d6
  1641.     swap    d6
  1642.     moveq    #0,d7
  1643.     divul.l    d2,d7:d6        ; d6 = nbr de samples -1 à envoyer avant la fin de la boucle
  1644.     subq.l    #1,d5
  1645.     cmp.l    d5,d6
  1646.     ble.s    .s3
  1647.     move.l    d5,d6
  1648. .s3:    sub.l    d6,d5        ; Ajuste le compteur de samples
  1649.  
  1650. .loop2:
  1651.     move.w    (a2,d3.l*2),(a3)
  1652.     add.w    d2,d4
  1653.     addx.l    d1,d3
  1654.     dbra    d6,.loop2
  1655.  
  1656.     moveq    #0,d6
  1657.     add.l    d3,d3
  1658.     divul.l    replen_t(a0),d6:d3
  1659.     move.l    d6,d3
  1660.     add.l    reppos_t(a0),d3    ; Réajuste la position en fin de boucle
  1661.     tst.l    d5
  1662.     ble.s    .fini2
  1663.     lsr.l    #1,d3
  1664.     bra    .sendloop
  1665.  
  1666. .fini:    add.l    d3,d3
  1667. .fini2:    move.l    d3,pos_t(a0)
  1668.     move.w    d4,finepos_t(a0)
  1669.  
  1670.  
  1671.  
  1672. sendsam_next:
  1673.     st    dsp_plein        ; C'est bon, on a rempli le buffer du DSP
  1674.     tst.w    flag_mt_display(pc)
  1675.     beq.s    .finsi
  1676.     move.l    #FC_BLUE,FCOLOR00.w    ; Bleu, le dsp est occupé
  1677. .finsi    addq.w    #1,d0        ; Voie suivante
  1678.     bra.s    sendsam_encore
  1679.  
  1680. sendsam_apuvoi:
  1681.     tst.w    songrecord_flag(pc)    ; Regarde si on est en enregistrement
  1682.     beq.s    .finsi4        ; sans temps réel et qu'on doit
  1683.     cmp.w    #2,songrecord_state    ; éliminer les interruptions pour
  1684.     bne.s    .finsi4        ; faire un dump du buffer DSP
  1685.  
  1686.     IfNE    INTERRUPTION_TYPE=0
  1687.     move.b    #0,DSPHCR.w    ; Interdit l'interruption
  1688.     EndC
  1689.     IfNE    INTERRUPTION_TYPE=1    ; Arret du Timer A s'il était là
  1690.     bclr    #5,MFPIMRA.w    ; Timer A masqué
  1691.     EndC
  1692.     IfNE    INTERRUPTION_TYPE=2    ; Arret du Timer C
  1693.     bclr    #5,MFPIMRB.w    ; Timer C masqué
  1694.     EndC
  1695.     IfNE    INTERRUPTION_TYPE=3    ; Arret du Timer D s'il était là
  1696.     bclr    #4,MFPIMRB.w    ; Timer D masqué
  1697.     EndC
  1698.     move.w    #1,songrecord_flag2
  1699.  
  1700. .finsi4:
  1701.     moveq    #0,d0        ; On recommencera la prochaine fois à la voie 0
  1702.     moveq    #1<<1,d1        ; Si les deux canaux sont utilisés, fin normale
  1703.     tst.w    dsp_plein
  1704.     bne.s    .finsi
  1705.     moveq    #1<<2,d1        ; Si rien n'a été envoyé, on vide les buffers du DSP
  1706. .finsi:    writhost
  1707.     move.l    d1,DSPHTDR_L.w    ; Plus de voie à mixer
  1708.     clr.w    dsp_plein        ; On remet à 0 l'indicateurs
  1709.     tst.w    flag_mt_display(pc)
  1710.     beq.s    .finsi2
  1711.     move.l    #FC_GREEN,FCOLOR00.w    ; Vert : gestion de partition
  1712. .finsi2:
  1713.  
  1714. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  1715. ; Peuvent être placées ici des routines de contrôle des samples
  1716.     IfNE    MIDI_IN
  1717.     tst.w    midi_in_on(pc)
  1718.     beq.s    .no_midi_in
  1719.     bsr    gestion_midi    ; Teste le port Midi In
  1720. .no_midi_in:
  1721.     EndC
  1722.  
  1723.     bsr    gestion_partition    ; Prépare les samples pour la prochaine fois
  1724.  
  1725. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  1726.     tst.w    flag_mt_display(pc)
  1727.     beq.s    .finsi3
  1728.     clr.l    FCOLOR00.w        ; Noir, c'est fini pour la vbl
  1729. .finsi3:
  1730.  
  1731. sendsam_encore:
  1732.     move.w    d0,current_track
  1733.  
  1734. sendsam_the_end:
  1735.     movem.l    (sp)+,d0-a6
  1736.     IfNE    INTERRUPTION_TYPE=1
  1737.     bclr    #5,MFPISRA.w    ; Et signale la fin de l'interruption
  1738.     EndC
  1739.     IfNE    INTERRUPTION_TYPE=2
  1740.     bclr    #5,MFPISRB.w
  1741.     EndC
  1742.     IfNE    INTERRUPTION_TYPE=3
  1743.     bclr    #4,MFPISRB.w
  1744.     EndC
  1745.     rte
  1746.  
  1747.  
  1748.  
  1749.  
  1750.  
  1751. *≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈*
  1752. *    Gestion de la partition pour modules .GTK            *
  1753. *≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈*
  1754. *    Cette routine est appelée sous interruption, par l'intermédiaire    *
  1755. *    du noyau.                        *
  1756. *≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈*
  1757. gestion_partition:
  1758.  
  1759.     movem.l    d0-a6,-(sp)
  1760.  
  1761.     addq.w    #1,vblcpt        ; Compteur de VBL pour faire un tick
  1762.     move.w    vblnumber(pc),d0
  1763.     cmp.w    vblcpt(pc),d0
  1764.     bgt    fin_gestion_partition    ; Tick pas fini : rien à faire
  1765.     clr.w    vblcpt
  1766.  
  1767.     lea    module_inf2,a0    ; a0 pointe sur le bloc 2 d'informations (mod)
  1768.     lea    module_inf1,a1    ; a1 pointe sur le bloc 1 d'informations (adr)
  1769.     lea    per_table(pc),a5    ; a5 pointe sur la table des périodes
  1770.  
  1771.     move.w    mod_nbrtrack(a0),nbrvoies    ; *** Pour que nbr de voies DSP = nbr de voies soundtrack
  1772.  
  1773. ;--- Demande d'arrêt de toutes les voies ? -----------------------------------
  1774.  
  1775.     tst.w    flag_stop_voices(pc)
  1776.     beq    gp_new_vbl
  1777.     moveq    #NBRVOIES_MAXI-1,d0
  1778.     lea    info_track(pc),a4
  1779.     lea    sample_vide,a2
  1780. .loop:
  1781.     clr.w    vol_t(a4)
  1782.     move.l    a2,adrsam_t(a4)
  1783.     clr.l    pos_t(a4)
  1784.     clr.w    finepos_t(a4)
  1785.     clr.l    reppos_t(a4)
  1786.     move.l    #2,replen_t(a4)
  1787.     move.l    #repeatbuffer,rbuffer_t(a4)
  1788.     clr.w    c_n_t(a4)
  1789.     clr.w    c_i_t(a4)
  1790.     clr.w    c_e_t(a4)
  1791.     clr.w    c_v_t(a4)
  1792.     move.w    #0,ninstr_t(a4)
  1793.     clr.w    norm_f_t(a4)
  1794.     clr.w    norm_v_t(a4)
  1795.     move.w    #$100,volsam_t(a4)
  1796.     move.w    #24,curnote_t(a4)
  1797.     move.w    #$6b00,pernote_t(a4)
  1798.     clr.w    vollnot_t(a4)
  1799.     clr.w    volenot_t(a4)
  1800.     clr.w    portspd_t(a4)
  1801.     clr.w    tportspd_t(a4)
  1802.     move.w    #48,note2sl_t(a4)
  1803.     move.w    #$1ac0,per2sl_t(a4)
  1804.     clr.b    vibspd_t(a4)
  1805.     clr.b    vibcpt_t(a4)
  1806.     clr.b    vibamp_t(a4)
  1807.     clr.b    vibwav_t(a4)
  1808.     clr.b    tremspd_t(a4)
  1809.     clr.b    tremcpt_t(a4)
  1810.     clr.b    tremamp_t(a4)
  1811.     clr.b    tremwav_t(a4)
  1812.     clr.w    tremorc_t(a4)
  1813.     move.b    #3,tremor1_t(a4)
  1814.     move.b    #6,tremor2_t(a4)
  1815.     clr.w    ploopp_t(a4)
  1816.     clr.w    ploops_t(a4)
  1817.     clr.w    ploopn_t(a4)
  1818.     clr.w    instr_t(a4)
  1819.     clr.w    transp_t(a4)
  1820.     env_initialisation    a4,0
  1821.     clr.w    flag_autotempo_t(a4)
  1822.     clr.w    flag_autoperiod_t(a4)
  1823.     add.w    #next_t,a4
  1824.     dbra    d0,.loop
  1825.     clr.w    flag_stop_voices
  1826.  
  1827. ;--- Nouvelle VBL, teste si on a une nouvelle ligne, position etc... ---------
  1828.  
  1829. gp_new_vbl:
  1830.  
  1831. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  1832. ; Si on est en mode Syncro Externe, on regarde si on peut lancer une VBL (ou
  1833. ; plusieurs si on est en retard).
  1834.     IfNE    MIDI_IN
  1835.  
  1836.     tst.w    midi_in_on(pc)
  1837.     beq.s    gp_new_vbl_ok
  1838.     tst.w    midi_in_sync_flag(pc)
  1839.     beq.s    gp_new_vbl_ok
  1840.     tst.w    current_play_mode(pc)
  1841.     beq.s    gp_new_vbl_ok
  1842. gp_new_vbl_loop:
  1843.     tst.w    midi_in_sync_cpt(pc)
  1844.     ble    fin_gestion_partition
  1845.     subq.w    #1,midi_in_sync_cpt
  1846. gp_new_vbl_ok:
  1847.  
  1848.     EndC
  1849. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  1850.  
  1851.     move.w    mod_nbrvbl(a0),d0    ; Nouvelle vbl
  1852.     addq.w    #1,d0
  1853.     cmp.w    mod_speed(a0),d0    ; Fin de la ligne courante ?
  1854.     blt    .suite_ligne
  1855.     moveq    #0,d0
  1856.     tst.w    mod_patrep(a0)    ; Répétition de la ligne ?
  1857.     beq.s    .newline        ; Non, on s'en fout
  1858.  
  1859.     subq.w    #1,mod_patrep(a0)    ; Répétition -1
  1860.     move.w    d0,mod_nbrvbl(a0)
  1861.     lea    info_track,a3    ; On initialise quelques trucs...
  1862.     move.w    mod_nbrtrack(a0),d7
  1863.     subq.w    #1,d7        ; d7 = compteur de voie
  1864.     bra    pas_seulement_1ere_vbl    ; ... puis on passe à la suite
  1865.  
  1866. .newline:    move.w    mod_songpos(a0),mod_cursongpos(a0)    ; Actualise la position
  1867.     move.w    mod_linepos(a0),mod_curlinepos(a0)
  1868.     clr.w    mod_flagnewpos(a0)    ; Indique que les positions et lignes restent les mêmes
  1869.     clr.w    mod_flagnewline(a0)    ; pour le moment (sert aux effets 0Bxx et 0Dxx)
  1870.     move.w    mod_numpat(a0),d3    ; Met dans chaque descripteur de voie une partie de la ligne
  1871.     move.l    (adr_pattern,a1,d3.w*4),a4    ; a4 pointe sur le chunk du pattern
  1872.     move.w    mod_linepos(a0),d1
  1873.     move.w    mod_nbrtrack(a0),d3
  1874.     mulu.w    #5,d3
  1875.     mulu.w    d1,d3
  1876.     lea    data_p(a4,d3.l),a2    ; a2 contient l'adresse de la nouvelle ligne
  1877.     lea    info_track,a3    ; a3 pointe sur le descripteur de voies
  1878.     move.w    mod_nbrtrack(a0),d3
  1879.     subq.w    #1,d3        ; d3 contient le nombre de voies -1
  1880. .loop:    move.b    (a2)+,c_n_t+1(a3)    ; Recopie la note
  1881.     move.b    (a2)+,c_i_t+1(a3)    ; Recopie l'instrument
  1882.     move.w    (a2)+,c_e_t(a3)    ; Recopie l'effet
  1883.     move.b    (a2)+,c_v_t+1(a3)    ; Recopie la commande de volume
  1884.     move.w    #1,flag_new_note_t(a3)    ; La note est nouvelle
  1885.     add.w    #next_t,a3        ; Voie suivante
  1886.     dbra    d3,.loop
  1887.  
  1888.     addq.w    #1,d1        ; Calcule la prochaine ligne
  1889.     cmp.w    nlines_p(a4),d1    ; Fin du pattern ?
  1890.     blt.s    .suite_pos
  1891.     moveq    #0,d1
  1892.     move.w    mod_songpos(a0),d2    ; Nouvelle position
  1893.     addq.w    #1,d2
  1894.     cmp.w    mod_songlen(a0),d2    ; Fin de la song ?
  1895.     blt.s    .suite_song
  1896.     move.w    mod_songrep(a0),d2    ; Oui, bouclage
  1897. .suite_song:
  1898.     move.w    d2,mod_songpos(a0)
  1899.     move.w    ([adr_song,a1],d2.w*2),mod_numpat(a0)    ; Trouve le nouveau pattern
  1900. .suite_pos:
  1901.     move.w    d1,mod_linepos(a0)    ; Pointe sur la ligne suivante
  1902. .suite_ligne:
  1903.     move.w    d0,mod_nbrvbl(a0)
  1904.  
  1905. ;--- Passe aux crible toutes les voies ---------------------------------------
  1906.  
  1907.     bsr    additional_notes    ; * Modifie d3, a2, a3, éventuellement d2, a4 et le pattern
  1908.     lea    info_track,a3    ; a3 pointe sur les informations des voies
  1909.     move.w    mod_nbrtrack(a0),d7
  1910.     subq.w    #1,d7        ; d7 = compteur de voie
  1911.     tst.w    flag_new_notes(pc)
  1912.     bne.s    premiere_vbl    ; Si on a des notes qui arrivent en cours de route
  1913.     tst.w    d0        ; C'est la première VBL ?
  1914.     bne    pas_seulement_1ere_vbl
  1915.     tst.w    mod_patrep(a0)    ; Sinon, c'est en cours de répétition ?
  1916.     bne    pas_seulement_1ere_vbl
  1917.  
  1918. ;--- Décode les différentes parties d'une ligne -----------------------------
  1919.  
  1920. premiere_vbl:
  1921.     clr.w    flag_new_notes    ; Au cas où on aurait eu des notes suplémentaire
  1922. premvbl_loop:            ; Boucle de test si c'est la première vbl
  1923.     tst.w    flag_new_note_t(a3)    ; Nouvelle note?
  1924.     beq    prmvbl_next_track    ; Non, on teste la suivante
  1925.     clr.w    flag_new_note_t(a3)
  1926.     move.w    c_n_t(a3),d0    ; d0 = note
  1927.     move.w    c_i_t(a3),d1    ; d1 = instrument
  1928.     move.w    c_e_t(a3),d2    ; d2 = effet
  1929.  
  1930.     tst.w    d1
  1931.     bne.s    instrum        ; S'il y a instrument
  1932.     tst.w    d0
  1933.     bne    pas_instrument    ; S'il y a note sans instr
  1934.     tst.w    d2
  1935.     bne    effets1        ; Seulement l'effet
  1936.     tst.w    c_v_t(a3)
  1937.     beq    fx_fin1        ; Pas de volume on se tire
  1938.     bra    effets1
  1939.     
  1940. instrum:    move.w    d2,d3
  1941.     and.w    #$FF00,d3        ; d3 = numéro de l'effet 2 chiffres
  1942.     cmp.w    #$900,d3        ; Note delay, on s'en va directos
  1943.     beq    effets1_no_vol
  1944.  
  1945.     tst.w    d1        ; Y a-t-il un instrument ?
  1946.     beq.s    pas_instrument
  1947.     move.w    d1,instr_t(a3)    ; Oui, il devient l'instrument courant
  1948.     mulu.w    #next_i,d1
  1949.     lea    ([adr_instrset,a1],d1.l),a2    ; a2 pointe sur l'instrument
  1950.     move.w    vol_i(a2),d3    ; Prend le volume dans d3
  1951.     move.w    curnote_t(a3),d4    ; Recherche le sample qui va avec la note courante
  1952.     move.b    transp_i(a2,d4.w*2),d1
  1953.     ext.w    d1
  1954.     move.w    d1,transp_t(a3)    ; Transposition
  1955.     moveq    #0,d1
  1956.     move.b    splnum_i(a2,d4.w*2),d1
  1957. .fin_s:    move.w    d1,ninstr_t(a3)    ; Il devient le sample courant
  1958.     lea    ([adr_samples,a1,d1.w*4],vol_s),a2
  1959.     move.w    (a2),volsam_t(a3)    ; Le volume propre du sample
  1960.     move.w    d3,norm_v_t(a3)    ; Recopie le volume de l'instrument dans la voie
  1961.     move.w    2(a2),norm_f_t(a3)
  1962.     move.w    autobal_s-vol_s(a2),d3
  1963.     bmi.s    .pasbalnc
  1964.     move.w    d3,curbal_t(a3)    ; Avec la balance
  1965. .pasbalnc:    move.w    norm_v_t(a3),d3
  1966.     lea    vlin_2_exp(pc),a4
  1967.     move.w    (a4,d3.w*2),volenot_t(a3)    ; Sans oublier le volume exponentiel
  1968.     lsl.w    #3,d3
  1969.     move.w    d3,vollnot_t(a3)    ; Volume courant aussi
  1970.  
  1971. pas_instrument:
  1972.     tst.w    d0
  1973.     beq    effets1        ; S'il n'y a pas de note on s'en va
  1974.     move.w    d2,d3
  1975.     and.w    #$FF00,d3        ; d3 = numéro de l'effet 2 chiffres
  1976.     cmp.w    #$300,d3
  1977.     beq.s    tone_p
  1978.     cmp.w    #$500,d3
  1979.     beq.s    tone_p
  1980.     cmp.w    #$600,d3
  1981.     beq.s    tone_p
  1982.     cmp.w    #$AB00,d3
  1983.     beq.s    tone_p
  1984.     cmp.w    #$1800,d3
  1985.     blt.s    pas_tone_p
  1986.     cmp.w    #$1B00,d3
  1987.     bgt.s    pas_tone_p
  1988. tone_p:                ; S'il y a un tone portamento (3,5,6,ab,18,19,1a ou 1b)
  1989.     move.w    d0,note2sl_t(a3)
  1990.     move.w    d0,d3
  1991.     add.w    transp_t(a3),d3    ; Transposition du sample courant
  1992.     sub.w    #24,d3
  1993.     IfNE    CHECK
  1994.     bpl.s    .check1ok
  1995.     moveq    #24,d3
  1996. .check1ok:    cmp.w    #127,d3
  1997.     ble.s    .check2ok
  1998.     moveq    #127,d3
  1999. .check2ok:
  2000.     EndC
  2001.     lsl.w    #3,d3
  2002.     add.w    norm_f_t(a3),d3
  2003.     move.w    (a5,d3.w*2),per2sl_t(a3)    ; on met la période de côté
  2004.     move.w    c_v_t(a3),d3        ; Commande de volume ?
  2005.     beq    fx_fin1
  2006.     lea    vlin_2_exp(pc),a4
  2007.     move.w    (a4,d3.w*2),volenot_t(a3)    ; Volume exponentiel
  2008.     lsl.w    #3,d3
  2009.     move.w    d3,vollnot_t(a3)        ; Volume courant ajusté
  2010.     bra    fx_fin1
  2011.  
  2012. pas_tone_p:
  2013.     move.w    d0,curnote_t(a3)
  2014.     move.w    d0,note2sl_t(a3)
  2015.     move.w    d0,d3
  2016.     move.w    instr_t(a3),d1
  2017.     mulu.w    #next_i,d1
  2018.     lea    ([adr_instrset,a1],d1.l),a2    ; a2 pointe sur l'instrument
  2019.     env_initialisation    a3,1,a2        ; Initialise les enveloppes
  2020.     move.w    curnote_t(a3),d4        ; Recherche le sample qui va avec la note courante
  2021.     move.b    transp_i(a2,d4.w*2),d1
  2022.     ext.w    d1
  2023.     move.w    d1,transp_t(a3)        ; Transposition
  2024.     add.w    d1,d3            ; Sur la note
  2025.     moveq    #0,d1
  2026.     move.b    splnum_i(a2,d4.w*2),d1
  2027.     move.w    d1,ninstr_t(a3)        ; Il devient le sample courant
  2028.     move.l    (adr_samples,a1,d1.w*4),a4
  2029.     move.w    vol_s(a4),volsam_t(a3)    ; Recopie le volume du sample
  2030.     move.w    ftune_s(a4),norm_f_t(a3)    ; Recopie le finetune du sample
  2031.     move.w    autobal_s(a4),d4
  2032.     bmi.s    .pas_autb
  2033.     move.w    d4,curbal_t(a3)        ; Recopie la balance du sample
  2034. .pas_autb:    sub.w    #24,d3
  2035.     IfNE    CHECK
  2036.     bpl.s    .check1ok
  2037.     moveq    #24,d3
  2038. .check1ok:    cmp.w    #127,d3
  2039.     ble.s    .check2ok
  2040.     moveq    #127,d3
  2041. .check2ok:
  2042.     EndC
  2043.     lsl.w    #3,d3
  2044.     add.w    norm_f_t(a3),d3
  2045.     add.w    d3,d3
  2046.     move.w    (a5,d3.w),pernote_t(a3)    ; Sinon c'est une note normale
  2047.     move.w    (a5,d3.w),per2sl_t(a3)
  2048.  
  2049. fin_tone_p:
  2050.     moveq    #0,d3        ; d3 position dans le sample (au début)
  2051.     move.w    d2,d4
  2052.     and.w    #$F000,d4        ; d4 numéro de l'effet 1 chiffre
  2053.     cmp.w    #$9000,d4        ; On doit jouer à partir d'un certain point ?
  2054.     bne.s    fin_ppart
  2055.     move.w    d2,d3        ; Sample Offset
  2056.     sub.w    #$9000,d3
  2057.     lsl.l    #8,d3
  2058. fin_ppart:    move.l    d3,pos_t(a3)
  2059.     clr.w    finepos_t(a3)
  2060.     clr.w    tremorc_t(a3)
  2061.     move.w    ninstr_t(a3),d1
  2062.     move.l    (adr_samples,a1,d1.w*4),a4
  2063.     move.l    a4,adrsam_t(a3)    ; Recopie l'adresse du sample
  2064.     add.l    #data_s,adrsam_t(a3)
  2065.     moveq    #0,d3
  2066.     move.w    d1,d3
  2067.     swap    d3
  2068.     lsr.l    #6,d3        ; d3 = d1*1024
  2069.     add.l    #repeatbuffer,d3
  2070.     move.l    d3,rbuffer_t(a3)    ; l'adresse du buffer de répétition,
  2071.     move.w    nbits_s(a4),d3    ; Nombre de bits
  2072.     lsr.w    #3,d3
  2073.     move.w    d3,nbits_t(a3)
  2074.     move.w    fech_s(a4),fech_t(a3)        ; Fréquence d'échantillonnage
  2075.     lea    repeat_s(a4),a4
  2076.     move.l    (a4)+,d3        ; le point de répétition,
  2077.     move.l    (a4),d4        ; et la taille de la boucle
  2078.     move.l    d4,d5
  2079.     add.l    d3,d5
  2080.     cmp.l    #2,d5
  2081.     bgt.s    .finsi
  2082.     move.l    -replen_s+length_s(a4),d3    ; Si pas de bouclage
  2083.     moveq    #2,d4
  2084.     subq.l    #2,d3
  2085.     tst.l    d3
  2086.     bpl.s    .finsi
  2087.     moveq    #0,d3
  2088. .finsi:
  2089.     move.l    d3,reppos_t(a3)
  2090.     move.l    d4,replen_t(a3)
  2091.  
  2092. ;--- Là on gère les effets qui n'agissent qu'en début de note ---------------
  2093.  
  2094. effets1:
  2095.     move.w    c_v_t(a3),d3    ; Commande de volume ?
  2096.     beq.s    effets1_no_vol
  2097.     lea    vlin_2_exp(pc),a4
  2098.     move.w    (a4,d3.w*2),volenot_t(a3)    ; Volume exponentiel
  2099.     lsl.w    #3,d3
  2100.     move.w    d3,vollnot_t(a3)    ; Volume courant ajusté
  2101. effets1_no_vol:
  2102.     move.w    d2,d3
  2103.     lsr.w    #8,d3        ; d3 = numéro d'effet
  2104.     move.w    d2,d4
  2105.     cmp.w    #$20,d3        ; section 00xx - 1fxx
  2106.     blt.s    .saute
  2107.     cmp.w    #$a0,d3
  2108.     blt.s    .ef1ch
  2109.     cmp.w    #$cf,d3        ; section a0xx - cfxx
  2110.     bgt.s    .ef1ch
  2111.     sub.w    #$80,d3        ; transforme en 20xx - 4fxx
  2112. .saute:    and.w    #$FF,d4        ; d4 = paramètre 8 bits
  2113.     jmp    ([fx_table_de_sauts1,d3.w*4])    ; On saute dans la bonne routine
  2114.  
  2115. .ef1ch:    lsr.b    #4,d3        ; Pour les effets à 1 chiffre
  2116.     and.w    #$FFF,d4        ; d4 = paramètre 12 bits
  2117.     jmp    ([fx_table_de_sauts1b,d3.w*4])    ; Hop on y va
  2118.  
  2119. fx_fin1:
  2120.  
  2121. prmvbl_next_track:
  2122.     add.w    #next_t,a3
  2123.     dbra    d7,premvbl_loop
  2124.     lea    info_track,a3    ; a3 pointe sur les informations des voies
  2125.     move.w    mod_nbrtrack(a0),d7
  2126.     subq.w    #1,d7        ; d7 = compteur de voie
  2127.  
  2128. ;--- Ici on exécute les effets qui agissent pendant toute la durée de la note
  2129.  
  2130. pas_seulement_1ere_vbl:
  2131.     move.w    c_n_t(a3),d0
  2132.     move.w    c_i_t(a3),d1
  2133.     move.w    c_e_t(a3),d2
  2134.     beq    fx_fin_normale    ; Si pas d'effet
  2135.     move.w    d2,d3
  2136.     lsr.w    #8,d3
  2137.     move.w    d2,d4        ; d4 paramètre de l'effet
  2138.     cmp.w    #$20,d3        ; section 00xx - 1fxx
  2139.     blt.s    .saute
  2140.     cmp.w    #$a0,d3
  2141.     blt.s    .ef1ch2
  2142.     cmp.w    #$cf,d3        ; section a0xx - cfxx
  2143.     bgt.s    .ef1ch2
  2144.     sub.w    #$80,d3        ; transforme en 20xx - 4fxx
  2145. .saute    and.w    #$FF,d4
  2146.     jmp    ([fx_table_de_sauts2,d3.w*4])    ; On saute dans la bonne routine
  2147.  
  2148. .ef1ch2:    lsr.b    #4,d3        ; Encore une fois, les effets à 1 chiffre
  2149.     and.w    #$FFF,d4
  2150.  
  2151.     cmp.b    #7,d3
  2152.     beq    fx_roll_7        ; Roll (simple)
  2153.     cmp.b    #8,d3
  2154.     beq    fx_roll_and_vsl    ; Roll + vol slide + set bal
  2155.  
  2156. fx_fin_normale:            ; C'est l'adresse normale de retour.
  2157.     move.w    vollnot_t(a3),vol_t(a3)    ; Les routines qui modifient normalement
  2158.     move.w    pernote_t(a3),per_t(a3)    ; les paramètres passent par là.
  2159.     move.w    curbal_t(a3),bal_t(a3)
  2160. fx_fin_speciale:
  2161.     move.w    vol_t(a3),d5    ; Tout à la fin, il faut aussi
  2162.     mulu.w    volsam_t(a3),d5    ; tenir compte du volume propre
  2163.     lsr.l    #8,d5        ; du sample. -> /$800
  2164.     mulu.w    mix_volume_t(a3),d5    ; Et du volume de mix: /$800 * /$1000 -> /$800000
  2165.     lsl.l    #4,d5        ; -> /$8000000
  2166.     swap    d5        ; -> /$800
  2167.     move.w    d5,vol_t(a3)    ; Volume final
  2168.  
  2169. ;--- Gestion de l'enveloppe de volume ----------------------------------------
  2170.  
  2171. gestion_env_volume:
  2172.     move.w    nevol_t(a3),d0    ; d0 = Numéro d'enveloppe
  2173.     beq    gestion_env_tone    ; Pas d'enveloppe de volume
  2174.     tst.w    ev_waitcpt_t(a3)    ; On est sur un Wait ?
  2175.     bgt    .enveloppe_wait    ; Oui, alors on le continue
  2176.     move.w    ev_volume_t(a3),d1
  2177.     tst.w    pevol_t(a3)    ; Position négative ?
  2178.     bmi    .env_set_volume    ; Oui, l'enveloppe est finie
  2179.     lea    ([module_inf1+adr_evol,d0.w*4]),a4
  2180.     add.w    devol_t(a3),a4    ; a4 pointe sur la section courante
  2181.     moveq    #0,d6        ; d6 = Nombre de commandes exécutées à la file.
  2182.                 ; Limite car si l'utilisateur oublie les Waits
  2183.                 ; on peut avoir des problèmes de boucles infinies
  2184.     move.w    pevol_t(a3),d0    ; d0 = position dans la section courante
  2185.  
  2186. .comloop:    move.b    (a4,d0.w),d2    ; d2 = numéro de commande
  2187.     beq    .c_end
  2188.     addq.w    #1,d0        ; Pointe maintenant sur le paramètre
  2189.     cmp.b    #ENV_COM_JUMP,d2
  2190.     beq    .c_jump
  2191.     cmp.b    #ENV_COM_WAIT,d2
  2192.     beq    .c_wait
  2193.     cmp.b    #ENV_COM_SET_COUNTER,d2
  2194.     beq    .c_set_counter
  2195.     cmp.b    #ENV_COM_LOOP,d2
  2196.     beq    .c_loop
  2197.     cmp.b    #ENV_COM_KEY_OFF,d2
  2198.     beq    .c_key_off
  2199.     cmp.b    #ENV_COM_SET_VOLUME,d2
  2200.     beq    .c_volume
  2201.     cmp.b    #ENV_COM_SET_VOL_STEP,d2
  2202.     beq    .c_vol_step
  2203.     cmp.b    #ENV_COM_SET_VOL_SPD,d2
  2204.     beq    .c_vol_speed
  2205.     cmp.b    #ENV_COM_TREMOLO_ON,d2
  2206.     beq    .c_tremolo_on
  2207.     cmp.b    #ENV_COM_TREMOLO_OFF,d2
  2208.     beq    .c_tremolo_off
  2209.     cmp.b    #ENV_COM_SET_TRM_WID,d2
  2210.     beq    .c_tremolo_width
  2211.     cmp.b    #ENV_COM_SET_TRM_SPD,d2
  2212.     beq    .c_tremolo_speed
  2213.     cmp.b    #ENV_COM_TREMOR_ON,d2
  2214.     beq    .c_tremor_on
  2215.     cmp.b    #ENV_COM_TREMOR_OFF,d2
  2216.     beq    .c_tremor_off
  2217.     cmp.b    #ENV_COM_SET_TREMOR_1,d2
  2218.     beq    .c_tremor_time1
  2219.     cmp.b    #ENV_COM_SET_TREMOR_2,d2
  2220.     beq    .c_tremor_time2
  2221.                 ; ??? Commande inconnue, on passe à la suite
  2222. .comsuite:    addq.w    #1,d6        ; Une commande de plus
  2223.     cmp.w    #ENV_COMMANDMAX,d6
  2224.     ble    .comloop        ; Tout baigne, prochaine commande
  2225.     move.w    ev_volume_t(a3),d1    ; Sinon on arrête pour ce tick
  2226.     move.w    d0,pevol_t(a3)
  2227.     bra    .env_set_volume
  2228.  
  2229. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2230. .c_end:
  2231.     move.w    #-1,pevol_t(a3)    ; Signale qu'on s'arrête
  2232.     move.w    ev_volume_t(a3),d1
  2233.     bra    .env_set_volume
  2234. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2235. .c_wait:
  2236.     move.w    (a4,d0.w),ev_waitcpt_t(a3)
  2237.     addq.w    #2,d0
  2238.     move.w    d0,pevol_t(a3)
  2239.     bra    .enveloppe_wait
  2240. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2241. .c_jump:
  2242.     move.w    (a4,d0.w),d0
  2243.     bra.s    .comsuite
  2244. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2245. .c_set_counter:
  2246.     moveq    #0,d2
  2247.     move.b    (a4,d0.w),d2
  2248.     move.w    d2,ev_loopcpt_t(a3)
  2249.     addq.w    #1,d0
  2250.     bra.s    .comsuite
  2251. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2252. .c_loop:
  2253.     addq.w    #2,d0
  2254.     subq.w    #1,ev_loopcpt_t(a3)
  2255.     ble.s    .comsuite
  2256.     move.w    -2(a4,d0.w),d0
  2257.     bra.s    .comsuite
  2258. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2259. .c_key_off:
  2260.     move.w    neton_t(a3),d0
  2261.     lea    ([module_inf1+adr_eton,d0.w*4]),a4
  2262.     move.w    keyoffoffset_e(a4),d2
  2263.     add.w    #data_e,d2
  2264.     move.w    d2,deton_t(a3)
  2265.     clr.w    peton_t(a3)
  2266.     clr.w    et_waitcpt_t(a3)
  2267.     move.w    nepan_t(a3),d0
  2268.     lea    ([module_inf1+adr_epan,d0.w*4]),a4
  2269.     move.w    keyoffoffset_e(a4),d2
  2270.     add.w    #data_e,d2
  2271.     move.w    d2,depan_t(a3)
  2272.     clr.w    pepan_t(a3)
  2273.     clr.w    ep_waitcpt_t(a3)
  2274.     move.w    nevol_t(a3),d0
  2275.     lea    ([module_inf1+adr_evol,d0.w*4]),a4
  2276.     move.w    keyoffoffset_e(a4),d2
  2277.     add.w    #data_e,d2
  2278.     move.w    d2,devol_t(a3)
  2279.     add.w    d2,a4
  2280.     moveq    #0,d0
  2281.     moveq    #0,d6
  2282.     bra    .comsuite
  2283. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2284. .c_volume:
  2285.     move.w    (a4,d0.w),ev_volume_t(a3)
  2286.     addq.w    #2,d0
  2287.     bra    .comsuite
  2288. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2289. .c_vol_step:
  2290.     move.w    (a4,d0.w),ev_volstep_t(a3)
  2291.     addq.w    #2,d0
  2292.     bra    .comsuite
  2293. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2294. .c_vol_speed:
  2295.     moveq    #0,d2
  2296.     move.b    (a4,d0.w),d2
  2297.     move.w    d2,ev_volspeed_t(a3)
  2298.     clr.w    ev_volcpt_t(a3)
  2299.     addq.w    #1,d0
  2300.     bra    .comsuite
  2301. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2302. .c_tremolo_on:
  2303.     move.b    #1,ev_tremoloflag_t(a3)
  2304.     clr.b    ev_tremolocpt_t(a3)
  2305.     bra    .comsuite
  2306. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2307. .c_tremolo_off:
  2308.     clr.b    ev_tremoloflag_t(a3)
  2309.     bra    .comsuite
  2310. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2311. .c_tremolo_width:
  2312.     move.b    (a4,d0.w),ev_tremolowidth_t(a3)
  2313.     addq.w    #1,d0
  2314.     bra    .comsuite
  2315. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2316. .c_tremolo_speed:
  2317.     move.b    (a4,d0.w),ev_tremolospeed_t(a3)
  2318.     addq.w    #1,d0
  2319.     bra    .comsuite
  2320. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2321. .c_tremor_on:
  2322.     move.b    #1,ev_tremorflag_t(a3)
  2323.     clr.b    ev_tremorcpt_t(a3)
  2324.     clr.b    ev_tremorsection_t(a3)
  2325.     bra    .comsuite
  2326. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2327. .c_tremor_off:
  2328.     clr.b    ev_tremorflag_t(a3)
  2329.     bra    .comsuite
  2330. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2331. .c_tremor_time1:
  2332.     move.b    (a4,d0.w),ev_tremortime1_t(a3)
  2333.     addq.w    #1,d0
  2334.     bra    .comsuite
  2335. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2336. .c_tremor_time2:
  2337.     move.b    (a4,d0.w),ev_tremortime2_t(a3)
  2338.     addq.w    #1,d0
  2339.     bra    .comsuite
  2340.  
  2341. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2342. .enveloppe_wait:
  2343.     subq.w    #1,ev_waitcpt_t(a3)    ; On décrémente le Wait
  2344.     move.w    ev_volcpt_t(a3),d0    ; Montée de volume ?
  2345.     bne.s    .noincvol
  2346.     IfNE    CHECK
  2347.     moveq    #0,d1
  2348.     move.w    ev_volume_t(a3),d1
  2349.     move.w    ev_volstep_t(a3),d2
  2350.     ext.l    d2
  2351.     add.l    d2,d1
  2352.     bpl.s    .incvols1
  2353.     moveq    #0,d1
  2354. .incvols1:    cmp.l    #32767,d1
  2355.     ble.s    .incvols2
  2356.     move.w    #32767,d1
  2357. .incvols2:    move.w    d1,ev_volume_t(a3)
  2358.     Else
  2359.     move.w    ev_volstep_t(a3),d1
  2360.     add.w    d1,ev_volume_t(a3)
  2361.     EndC
  2362. .noincvol:    addq.w    #1,d0        ; On incrémente le compteur de volume
  2363.     cmp.w    ev_volspeed_t(a3),d0
  2364.     blt.s    .volcptok
  2365.     moveq    #0,d0
  2366. .volcptok:    move.w    d0,ev_volcpt_t(a3)
  2367.  
  2368. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2369.     moveq    #0,d1
  2370.     move.w    ev_volume_t(a3),d1
  2371.     tst.b    ev_tremoloflag_t(a3)
  2372.     beq.s    .tremor
  2373.     moveq    #0,d3
  2374.     move.b    ev_tremolocpt_t(a3),d3
  2375.     lea    sin_table(pc),a4
  2376.     lsr.w    #2,d3
  2377.     and.w    #$3f,d3        ; d3 = offset dans la table de sinus
  2378.     move.w    (a4,d3.w*2),d3    ; d3 = sinus
  2379.     move.b    ev_tremolowidth_t(a3),d4
  2380.     and.w    #$ff,d4
  2381.     muls.w    d4,d3        ; Multiplie par l'amplitude
  2382.     asr.w    #2,d3
  2383.     add.l    d3,d1        ; Additionne au volume
  2384.     IfNE    CHECK
  2385.     bpl.s    .tremolo1
  2386.     moveq    #0,d1
  2387. .tremolo1:    cmp.l    #32767,d1
  2388.     ble.s    .tremolo2
  2389.     move.w    #32767,d1
  2390. .tremolo2:
  2391.     EndC
  2392.     move.b    ev_tremolospeed_t(a3),d2
  2393.     add.b    d2,ev_tremolocpt_t(a3)
  2394.  
  2395. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2396. .tremor:    tst.b    ev_tremorflag_t(a3)
  2397.     beq.s    .env_set_volume
  2398.     move.b    ev_tremorcpt_t(a3),d2
  2399.     addq.b    #1,d2
  2400.     tst.b    ev_tremorsection_t(a3)    ; Volume On ou Off ?
  2401.     beq.s    .tremors1
  2402.     moveq    #0,d1            ; Volume à 0
  2403.     cmp.b    ev_tremortime2_t(a3),d2
  2404.     blt.s    .tremors2
  2405.     moveq    #0,d2
  2406.     clr.b    ev_tremorsection_t(a3)
  2407.     bra.s    .tremors2
  2408. .tremors1:    cmp.b    ev_tremortime1_t(a3),d2    ; Plein volume
  2409.     blt.s    .tremors2
  2410.     moveq    #0,d2
  2411.     move.b    #1,ev_tremorsection_t(a3)
  2412. .tremors2:    move.b    d2,ev_tremorcpt_t(a3)
  2413.  
  2414. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2415. .env_set_volume:
  2416.     mulu.w    vol_t(a3),d1
  2417.     add.l    d1,d1
  2418.     add.l    d1,d1
  2419.     swap    d1
  2420.     move.w    d1,vol_t(a3)
  2421.  
  2422. ;--- Gestion de l'enveloppe de tonalité --------------------------------------
  2423.  
  2424. gestion_env_tone:
  2425.     move.w    neton_t(a3),d0    ; d0 = Numéro d'enveloppe
  2426.     beq    gestion_env_panning
  2427.     tst.w    et_waitcpt_t(a3)    ; On est sur un Wait ?
  2428.     bgt    .enveloppe_wait    ; Oui, alors on le continue
  2429.     move.w    et_tone_t(a3),d1
  2430.     tst.w    peton_t(a3)    ; Position négative ?
  2431.     bmi    .env_set_tone    ; Oui, l'enveloppe est finie
  2432.     lea    ([module_inf1+adr_eton,d0.w*4]),a4
  2433.     add.w    deton_t(a3),a4    ; a4 pointe sur la section courante
  2434.     moveq    #0,d6        ; d6 = Nombre de commandes exécutées à la file.
  2435.                 ; Limite car si l'utilisateur oublie les Waits
  2436.                 ; on peut avoir des problèmes de boucles infinies
  2437.     move.w    peton_t(a3),d0    ; d0 = position dans la section courante
  2438.  
  2439. .comloop:    move.b    (a4,d0.w),d2    ; d2 = numéro de commande
  2440.     beq.s    .c_end
  2441.     addq.w    #1,d0        ; Pointe maintenant sur le paramètre
  2442.     cmp.b    #ENV_COM_JUMP,d2
  2443.     beq    .c_jump
  2444.     cmp.b    #ENV_COM_WAIT,d2
  2445.     beq.s    .c_wait
  2446.     cmp.b    #ENV_COM_SET_COUNTER,d2
  2447.     beq    .c_set_counter
  2448.     cmp.b    #ENV_COM_LOOP,d2
  2449.     beq    .c_loop
  2450.     cmp.b    #ENV_COM_KEY_OFF,d2
  2451.     beq    .c_key_off
  2452.     cmp.b    #ENV_COM_SET_TONE,d2
  2453.     beq    .c_tone
  2454.     cmp.b    #ENV_COM_SET_TON_STEP,d2
  2455.     beq    .c_tone_step
  2456.     cmp.b    #ENV_COM_SET_TON_SPD,d2
  2457.     beq    .c_tone_speed
  2458.     cmp.b    #ENV_COM_VIBRATO_ON,d2
  2459.     beq    .c_vibrato_on
  2460.     cmp.b    #ENV_COM_VIBRATO_OFF,d2
  2461.     beq    .c_vibrato_off
  2462.     cmp.b    #ENV_COM_SET_VIB_WID,d2
  2463.     beq    .c_vibrato_width
  2464.     cmp.b    #ENV_COM_SET_VIB_SPD,d2
  2465.     beq    .c_vibrato_speed
  2466.                 ; ??? Commande inconnue, on passe à la suite
  2467. .comsuite:    addq.w    #1,d6        ; Une commande de plus
  2468.     cmp.w    #ENV_COMMANDMAX,d6
  2469.     ble.s    .comloop        ; Tout baigne, prochaine commande
  2470.     move.w    et_tone_t(a3),d1    ; Sinon on arrête pour ce tick
  2471.     move.w    d0,peton_t(a3)
  2472.     bra    .env_set_tone
  2473.  
  2474. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2475. .c_end:
  2476.     move.w    #-1,peton_t(a3)    ; Signale qu'on s'arrête
  2477.     move.w    et_tone_t(a3),d1
  2478.     bra    .env_set_tone
  2479. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2480. .c_wait:
  2481.     move.w    (a4,d0.w),et_waitcpt_t(a3)
  2482.     addq.w    #2,d0
  2483.     move.w    d0,peton_t(a3)
  2484.     bra    .enveloppe_wait
  2485. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2486. .c_jump:
  2487.     move.w    (a4,d0.w),d0
  2488.     bra.s    .comsuite
  2489. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2490. .c_set_counter:
  2491.     moveq    #0,d2
  2492.     move.b    (a4,d0.w),d2
  2493.     move.w    d2,et_loopcpt_t(a3)
  2494.     addq.w    #1,d0
  2495.     bra.s    .comsuite
  2496. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2497. .c_loop:
  2498.     addq.w    #2,d0
  2499.     subq.w    #1,et_loopcpt_t(a3)
  2500.     ble.s    .comsuite
  2501.     move.w    -2(a4,d0.w),d0
  2502.     bra.s    .comsuite
  2503. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2504. .c_key_off:
  2505.     move.w    nevol_t(a3),d0
  2506.     lea    ([module_inf1+adr_evol,d0.w*4]),a4
  2507.     move.w    keyoffoffset_e(a4),d2
  2508.     add.w    #data_e,d2
  2509.     move.w    d2,devol_t(a3)
  2510.     clr.w    pevol_t(a3)
  2511.     clr.w    ev_waitcpt_t(a3)
  2512.     move.w    nepan_t(a3),d0
  2513.     lea    ([module_inf1+adr_epan,d0.w*4]),a4
  2514.     move.w    keyoffoffset_e(a4),d2
  2515.     add.w    #data_e,d2
  2516.     move.w    d2,depan_t(a3)
  2517.     clr.w    pepan_t(a3)
  2518.     clr.w    ep_waitcpt_t(a3)
  2519.     move.w    neton_t(a3),d0
  2520.     lea    ([module_inf1+adr_eton,d0.w*4]),a4
  2521.     move.w    keyoffoffset_e(a4),d2
  2522.     add.w    #data_e,d2
  2523.     move.w    d2,deton_t(a3)
  2524.     add.w    d2,a4
  2525.     moveq    #0,d0
  2526.     moveq    #0,d6
  2527.     bra    .comsuite
  2528. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2529. .c_tone:
  2530.     move.w    (a4,d0.w),et_tone_t(a3)
  2531.     addq.w    #2,d0
  2532.     bra    .comsuite
  2533. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2534. .c_tone_step:
  2535.     move.w    (a4,d0.w),et_tonestep_t(a3)
  2536.     addq.w    #2,d0
  2537.     bra    .comsuite
  2538. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2539. .c_tone_speed:
  2540.     moveq    #0,d2
  2541.     move.b    (a4,d0.w),d2
  2542.     move.w    d2,et_tonespeed_t(a3)
  2543.     clr.w    et_tonecpt_t(a3)
  2544.     addq.w    #1,d0
  2545.     bra    .comsuite
  2546. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2547. .c_vibrato_on:
  2548.     move.b    #1,et_vibratoflag_t(a3)
  2549.     clr.b    et_vibratocpt_t(a3)
  2550.     bra    .comsuite
  2551. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2552. .c_vibrato_off:
  2553.     clr.b    et_vibratoflag_t(a3)
  2554.     bra    .comsuite
  2555. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2556. .c_vibrato_width:
  2557.     move.b    (a4,d0.w),et_vibratowidth_t(a3)
  2558.     addq.w    #1,d0
  2559.     bra    .comsuite
  2560. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2561. .c_vibrato_speed:
  2562.     move.b    (a4,d0.w),et_vibratospeed_t(a3)
  2563.     addq.w    #1,d0
  2564.     bra    .comsuite
  2565.  
  2566. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2567. .enveloppe_wait:
  2568.     subq.w    #1,et_waitcpt_t(a3)    ; On décrémente le Wait
  2569.     move.w    et_tonecpt_t(a3),d0    ; Montée de période ?
  2570.     bne.s    .noincton
  2571.     IfNE    CHECK
  2572.     moveq    #0,d1
  2573.     move.w    et_tone_t(a3),d1
  2574.     move.w    et_tonestep_t(a3),d2
  2575.     ext.l    d2
  2576.     add.l    d2,d1
  2577.     bpl.s    .inctons1
  2578.     moveq    #0,d1
  2579. .inctons1:    cmp.l    #32767,d1
  2580.     ble.s    .inctons2
  2581.     move.w    #32767,d1
  2582. .inctons2:    move.w    d1,et_tone_t(a3)
  2583.     Else
  2584.     move.w    et_tonestep_t(a3),d1
  2585.     add.w    d1,et_tone_t(a3)
  2586.     EndC
  2587. .noincton:    addq.w    #1,d0        ; On incrémente le compteur de tonalité
  2588.     cmp.w    et_tonespeed_t(a3),d0
  2589.     blt.s    .toncptok
  2590.     moveq    #0,d0
  2591. .toncptok:    move.w    d0,et_tonecpt_t(a3)
  2592.  
  2593. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2594.     moveq    #0,d1
  2595.     move.w    et_tone_t(a3),d1
  2596.     tst.b    et_vibratoflag_t(a3)
  2597.     beq.s    .env_set_tone
  2598.     moveq    #0,d3
  2599.     move.b    et_vibratocpt_t(a3),d3
  2600.     lea    sin_table(pc),a4
  2601.     lsr.w    #2,d3
  2602.     and.w    #$3f,d3        ; d3 = offset dans la table de sinus
  2603.     move.w    (a4,d3.w*2),d3    ; d3 = sinus
  2604.     move.b    et_vibratowidth_t(a3),d4
  2605.     and.w    #$ff,d4
  2606.     muls.w    d4,d3        ; Multiplie par l'amplitude
  2607.     asr.w    #5,d3
  2608.     add.l    d3,d1        ; Additionne à la période
  2609.     IfNE    CHECK
  2610.     bpl.s    .vibrato1
  2611.     moveq    #0,d1
  2612. .vibrato1:    cmp.l    #32767,d1
  2613.     ble.s    .vibrato2
  2614.     move.w    #32767,d1
  2615. .vibrato2:
  2616.     EndC
  2617.     move.b    et_vibratospeed_t(a3),d2
  2618.     add.b    d2,et_vibratocpt_t(a3)
  2619.  
  2620. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2621. .env_set_tone:
  2622.     mulu.w    per_t(a3),d1
  2623.     lsl.l    #4,d1
  2624.     IfNE    CHECK
  2625.     clr.w    d1
  2626.     swap    d1
  2627.     cmp.l    #PERIOD_MINI,d1
  2628.     bge.s    .setton1
  2629.     move.w    #PERIOD_MINI,d1
  2630. .setton1:    cmp.l    #PERIOD_MAXI,d1
  2631.     ble.s    .setton2
  2632.     move.w    #PERIOD_MAXI,d1
  2633.     Else
  2634.     swap    d1
  2635.     EndC
  2636. .setton2:    move.w    d1,per_t(a3)
  2637.  
  2638. ;--- Gestion de l'enveloppe de panning ---------------------------------------
  2639.  
  2640. gestion_env_panning:
  2641.     move.w    nepan_t(a3),d0    ; d0 = Numéro d'enveloppe
  2642.     beq    fin_gestion_enveloppes
  2643.     tst.w    ep_waitcpt_t(a3)    ; On est sur un Wait ?
  2644.     bgt    .enveloppe_wait    ; Oui, alors on le continue
  2645.     move.w    ep_pan_t(a3),d1
  2646.     tst.w    pepan_t(a3)    ; Position négative ?
  2647.     bmi    .env_set_pan    ; Oui, l'enveloppe est finie
  2648.     lea    ([module_inf1+adr_epan,d0.w*4]),a4
  2649.     add.w    depan_t(a3),a4    ; a4 pointe sur la section courante
  2650.     moveq    #0,d6        ; d6 = Nombre de commandes exécutées à la file.
  2651.                 ; Limite car si l'utilisateur oublie les Waits
  2652.                 ; on peut avoir des problèmes de boucles infinies
  2653.     move.w    pepan_t(a3),d0    ; d0 = position dans la section courante
  2654.  
  2655. .comloop:    move.b    (a4,d0.w),d2    ; d2 = numéro de commande
  2656.     beq.s    .c_end
  2657.     addq.w    #1,d0        ; Pointe maintenant sur le paramètre
  2658.     cmp.b    #ENV_COM_JUMP,d2
  2659.     beq.s    .c_jump
  2660.     cmp.b    #ENV_COM_WAIT,d2
  2661.     beq.s    .c_wait
  2662.     cmp.b    #ENV_COM_SET_COUNTER,d2
  2663.     beq.s    .c_set_counter
  2664.     cmp.b    #ENV_COM_LOOP,d2
  2665.     beq.s    .c_loop
  2666.     cmp.b    #ENV_COM_KEY_OFF,d2
  2667.     beq.s    .c_key_off
  2668.     cmp.b    #ENV_COM_SET_PANNING,d2
  2669.     beq    .c_pan
  2670.     cmp.b    #ENV_COM_SET_PAN_STEP,d2
  2671.     beq    .c_pan_step
  2672.     cmp.b    #ENV_COM_SET_PAN_SPD,d2
  2673.     beq    .c_pan_speed
  2674.                 ; ??? Commande inconnue, on passe à la suite
  2675. .comsuite:    addq.w    #1,d6        ; Une commande de plus
  2676.     cmp.w    #ENV_COMMANDMAX,d6
  2677.     ble.s    .comloop        ; Tout baigne, prochaine commande
  2678.     move.w    ep_pan_t(a3),d1    ; Sinon on arrête pour ce tick
  2679.     move.w    d0,pepan_t(a3)
  2680.     bra    .env_set_pan
  2681.  
  2682. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2683. .c_end:
  2684.     move.w    #-1,pepan_t(a3)    ; Signale qu'on s'arrête
  2685.     move.w    ep_pan_t(a3),d1
  2686.     bra    .env_set_pan
  2687. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2688. .c_wait:
  2689.     move.w    (a4,d0.w),ep_waitcpt_t(a3)
  2690.     addq.w    #2,d0
  2691.     move.w    d0,pepan_t(a3)
  2692.     bra    .enveloppe_wait
  2693. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2694. .c_jump:
  2695.     move.w    (a4,d0.w),d0
  2696.     bra.s    .comsuite
  2697. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2698. .c_set_counter:
  2699.     moveq    #0,d2
  2700.     move.b    (a4,d0.w),d2
  2701.     move.w    d2,ep_loopcpt_t(a3)
  2702.     addq.w    #1,d0
  2703.     bra.s    .comsuite
  2704. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2705. .c_loop:
  2706.     addq.w    #2,d0
  2707.     subq.w    #1,ep_loopcpt_t(a3)
  2708.     ble.s    .comsuite
  2709.     move.w    -2(a4,d0.w),d0
  2710.     bra.s    .comsuite
  2711. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2712. .c_key_off:
  2713.     move.w    nevol_t(a3),d0
  2714.     lea    ([module_inf1+adr_evol,d0.w*4]),a4
  2715.     move.w    keyoffoffset_e(a4),d2
  2716.     add.w    #data_e,d2
  2717.     move.w    d2,devol_t(a3)
  2718.     clr.w    pevol_t(a3)
  2719.     clr.w    ev_waitcpt_t(a3)
  2720.     move.w    neton_t(a3),d0
  2721.     lea    ([module_inf1+adr_eton,d0.w*4]),a4
  2722.     move.w    keyoffoffset_e(a4),d2
  2723.     add.w    #data_e,d2
  2724.     move.w    d2,deton_t(a3)
  2725.     clr.w    peton_t(a3)
  2726.     clr.w    et_waitcpt_t(a3)
  2727.     move.w    nepan_t(a3),d0
  2728.     lea    ([module_inf1+adr_epan,d0.w*4]),a4
  2729.     move.w    keyoffoffset_e(a4),d2
  2730.     add.w    #data_e,d2
  2731.     move.w    d2,depan_t(a3)
  2732.     add.w    d2,a4
  2733.     moveq    #0,d0
  2734.     moveq    #0,d6
  2735.     bra    .comsuite
  2736. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2737. .c_pan:
  2738.     move.w    (a4,d0.w),ep_pan_t(a3)
  2739.     addq.w    #2,d0
  2740.     bra    .comsuite
  2741. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2742. .c_pan_step:
  2743.     move.w    (a4,d0.w),ep_panstep_t(a3)
  2744.     addq.w    #2,d0
  2745.     bra    .comsuite
  2746. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2747. .c_pan_speed:
  2748.     moveq    #0,d2
  2749.     move.b    (a4,d0.w),d2
  2750.     move.w    d2,ep_panspeed_t(a3)
  2751.     clr.w    ep_pancpt_t(a3)
  2752.     addq.w    #1,d0
  2753.     bra    .comsuite
  2754.  
  2755. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2756. .enveloppe_wait:
  2757.     subq.w    #1,ep_waitcpt_t(a3)    ; On décrémente le Wait
  2758.     move.w    ep_pancpt_t(a3),d0    ; Montée de période ?
  2759.     bne.s    .noincpan
  2760.     IfNE    CHECK
  2761.     moveq    #0,d1
  2762.     move.w    ep_pan_t(a3),d1
  2763.     move.w    ep_panstep_t(a3),d2
  2764.     ext.l    d2
  2765.     add.l    d2,d1
  2766.     bpl.s    .incpans1
  2767.     moveq    #0,d1
  2768. .incpans1:    cmp.l    #$FFF,d1
  2769.     ble.s    .incpans2
  2770.     move.w    #$FFF,d1
  2771. .incpans2:    move.w    d1,ep_pan_t(a3)
  2772.     Else
  2773.     move.w    ep_panstep_t(a3),d1
  2774.     add.w    d1,ep_pan_t(a3)
  2775.     EndC
  2776. .noincpan:    addq.w    #1,d0        ; On incrémente le compteur de tonalité
  2777.     cmp.w    ep_panspeed_t(a3),d0
  2778.     blt.s    .pancptok
  2779.     moveq    #0,d0
  2780. .pancptok:    move.w    d0,ep_pancpt_t(a3)
  2781.     move.w    ep_pan_t(a3),d1
  2782.  
  2783. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2784. .env_set_pan:
  2785.     move.w    bal_t(a3),d2
  2786.     sub.w    #$800,d2
  2787.     bmi.s    .envsetp1
  2788.     neg.w    d2        ; d2 = -abs(PanPos-2048)
  2789. .envsetp1:    add.w    #$800,d2
  2790.     sub.w    #$800,d1        ; d1 = PanEnv-2048
  2791.     muls.w    d2,d1        ; Multiplication signée
  2792.     asl.l    #5,d1        ; Divise par 2048 (*32/65536)
  2793.     swap    d1
  2794.     add.w    d1,bal_t(a3)    ; PanPos + (PanEnv-2048)*(2048-abs(PanPos-2048))/2048
  2795.  
  2796. ;--- Voie suivante... --------------------------------------------------------
  2797.  
  2798. fin_gestion_enveloppes:
  2799.     add.w    #next_t,a3
  2800.     dbra    d7,pas_seulement_1ere_vbl
  2801.  
  2802. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2803.     IfNE    MIDI_IN
  2804.  
  2805.     tst.w    midi_in_on(pc)
  2806.     beq.s    .no_midi_in
  2807.     tst.w    midi_in_sync_flag(pc)
  2808.     beq.s    .no_sync
  2809.     tst.w    current_play_mode(pc)
  2810.     bne    gp_new_vbl_loop
  2811. .no_sync:
  2812. .no_midi_in:
  2813.  
  2814.     EndC
  2815. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  2816.  
  2817. fin_gestion_partition:
  2818.  
  2819. ;--- Mise à jour du nombre de spl par vbl ------------------------------------
  2820.  
  2821.     move.l    vblsize(pc),d0    ; Prend d'un coup les parties entières et frac
  2822.     moveq    #0,d1
  2823.     move.w    vblcurrentsize_frac(pc),d1    ; Le compteur frac courant
  2824.     add.l    d1,d0        ; Ajoute 1 à vblsize en cas de retenue
  2825.     move.l    d0,vblcurrentsize    ; Mise à jour des 2 parties
  2826.  
  2827.     movem.l    (sp)+,d0-a6
  2828.     rts
  2829.  
  2830.  
  2831.  
  2832. ;-----------------------------------------------
  2833. ;    Quand une note est rentrée
  2834. ;    au clavier en plus de la song
  2835. ;    Modifie d3, a2, a3 et eventuellement
  2836. ;    d2, a4 et le pattern
  2837. ;-----------------------------------------------
  2838. additional_notes:
  2839.     lea    info_track,a3
  2840.     lea    new_note_buffer(pc),a2
  2841.     tst.w    current_edit_mode(pc)    ; Si on est en Edit + Play, on
  2842.     beq    .addnotes_normal    ; enregistre les nouvelles notes
  2843.     tst.w    current_play_mode(pc)    ; sur le pattern
  2844.     bne.s    .play_mode
  2845.  
  2846. ;--- En mode Edit sans Play, signale au GfA l'arrivée de nouvelles notes -----
  2847.     move.w    mod_nbrtrack(a0),d3
  2848.     subq.w    #1,d3
  2849. .nn_loop3:    tst.b    (a2)        ; Note rentrée?
  2850.     beq.s    .nonewn3
  2851.     move.w    #1,midi_in_gfa_playline
  2852. .nonewn3:    addq.l    #6,a2
  2853.     dbra    d3,.nn_loop3
  2854.     rts
  2855.  
  2856. ;--- En mode Edit + Play, on change le pattern -------------------------------
  2857. .play_mode:
  2858.     move.w    mod_numpat(a0),d3
  2859.     move.w    mod_curlinepos(a0),d1
  2860.     move.l    (adr_pattern,a1,d3.w*4),a4    ; a4 pointe sur le chunk du pattern
  2861.     move.w    mod_nbrtrack(a0),d3
  2862.     mulu.w    #5,d3
  2863.     mulu.w    d1,d3
  2864.     lea    data_p(a4,d3.l),a4    ; a4 contient l'adresse de la ligne à modifier
  2865.     move.w    mod_nbrtrack(a0),d3
  2866.     subq.w    #1,d3
  2867. .nn_loop:    tst.b    (a2)        ; Note rentrée?
  2868.     beq.s    .nonewnot
  2869.     move.b    1(a2),d2        ; Recopie la note
  2870.     beq.s    .copynote        ; Insère-la dans le pattern
  2871.     move.b    d2,(a4)        ; si elle existe (<> 0)
  2872. .copynote:    move.b    d2,c_n_t+1(a3)
  2873.     move.b    2(a2),d2        ; Recopie l'instrument
  2874.     beq.s    .copyinst
  2875.     move.b    d2,1(a4)
  2876. .copyinst:    move.b    d2,c_i_t+1(a3)
  2877.     move.w    3(a2),d2        ; Recopie l'effet
  2878.     beq.s    .copyfx
  2879.     move.w    d2,2(a4)
  2880. .copyfx:    move.w    d2,c_e_t(a3)
  2881.     move.b    5(a2),d2        ; Recopie la commande de volume
  2882.     beq.s    .copyvol
  2883.     move.b    d2,4(a4)
  2884. .copyvol:    move.b    d2,c_v_t+1(a3)
  2885.     clr.b    (a2)        ; Signale qu'on a vidé la nouvelle note
  2886.     move.w    #1,flag_new_notes    ; Idem, mais pour dire au player qu'il y a du neuf
  2887.     move.w    #1,flag_new_note_t(a3)    ; Précise la piste
  2888. .nonewnot:    add.w    #next_t,a3
  2889.     addq.l    #6,a2
  2890.     addq.l    #5,a4
  2891.     dbra    d3,.nn_loop
  2892.     rts
  2893.  
  2894. ;--- En mode Normal (sans Edit) ----------------------------------------------
  2895. .addnotes_normal:
  2896.     move.w    mod_nbrtrack(a0),d3
  2897.     subq.w    #1,d3
  2898. .nn_loop2:    tst.b    (a2)        ; Note rentrée?
  2899.     beq.s    .nonewn2
  2900.     move.b    1(a2),c_n_t+1(a3)    ; Recopie la note
  2901.     move.b    2(a2),c_i_t+1(a3)    ; Recopie l'instrument
  2902.     move.w    3(a2),c_e_t(a3)    ; Recopie l'effet
  2903.     move.b    5(a2),c_v_t+1(a3)    ; Recopie la commande de volume
  2904.     clr.b    (a2)        ; Signale qu'on a vidé la nouvelle note
  2905.     move.w    #1,flag_new_notes    ; Idem, mais pour dire au player qu'il y a du neuf
  2906.     move.w    #1,flag_new_note_t(a3)    ; Précise la piste
  2907. .nonewn2:    add.w    #next_t,a3
  2908.     addq.l    #6,a2
  2909.     dbra    d3,.nn_loop2
  2910.     rts
  2911.  
  2912.  
  2913.  
  2914. ;***********************************************
  2915. ; Effets agissant seulement au début d'une note
  2916. ;***********************************************
  2917.  
  2918. ;-----------------------------------------------
  2919. ;    Set Linear Volume
  2920. ;-----------------------------------------------
  2921. fx_set_lin_volume:
  2922.     IfNE    CHECK=2
  2923.     cmp.w    #$100,d4
  2924.     ble.s    .ok2
  2925.     move.w    #$100,d4
  2926.     EndC
  2927.  
  2928. .ok2:    lea    vlin_2_exp(pc),a4
  2929.     move    (a4,d4.w*2),volenot_t(a3)
  2930.     lsl.w    #3,d4
  2931.     move.w    d4,vollnot_t(a3)
  2932.     bra    fx_fin1
  2933.  
  2934. ;-----------------------------------------------
  2935. ;    Set Exponential Volume
  2936. ;-----------------------------------------------
  2937. fx_set_exp_volume:
  2938.     IfNE    CHECK=2
  2939.     cmp.w    #$800,d4
  2940.     ble.s    .ok3
  2941.     move.w    #$800,d4
  2942.     EndC
  2943.  
  2944. .ok3:    move.w    d4,volenot_t(a3)
  2945.     lea    vexp_2_lin(pc),a4
  2946.     move.w    (a4,d4.w*2),vollnot_t(a3)
  2947.     bra    fx_fin1
  2948.  
  2949. ;-----------------------------------------------
  2950. ;    Set Balance
  2951. ;-----------------------------------------------
  2952. fx_set_balance:
  2953.     move.w    d4,curbal_t(a3)
  2954.     bra    fx_fin1
  2955.  
  2956. ;-----------------------------------------------
  2957. ;    Set Linear Master Volume
  2958. ;-----------------------------------------------
  2959. fx_set_lin_master_vol:
  2960.     IfNE    CHECK=2
  2961.     cmp.w    #$FFF,d4
  2962.     ble.s    .ok5
  2963.     move.w    #$FFF,d4
  2964.     EndC
  2965.  
  2966. .ok5:    move.w    d4,master_vol
  2967.     bra    fx_fin1
  2968.  
  2969. ;-----------------------------------------------
  2970. ;    Set Exponential Master Volume
  2971. ;-----------------------------------------------
  2972. fx_set_exp_master_vol:
  2973.     lea    vexp_2_lin_master(pc),a4
  2974.     move.w    (a4,d4.w*2),master_vol
  2975.     bra    fx_fin1
  2976.  
  2977. ;-----------------------------------------------
  2978. ;    Roll (initialisation)
  2979. ;-----------------------------------------------
  2980. fx_roll_7_init:
  2981.     move.w    d4,d5
  2982.     and.w    #$FF,d5        ; d5 = nbr de coups maxi
  2983.     bne.s    .pl7
  2984.     moveq    #-1,d5        ; Si d5 = 0, répétitions infinies
  2985. .pl7:    move.w    d5,rollnbr_t(a3)
  2986.     lsr.w    #8,d4        ; d4 = vitesse
  2987.     tst.b    d4
  2988.     beq    fx_fin1        ; Si vitesse = 0, répétitions continues
  2989.     move.b    d4,rollspd_t(a3)
  2990.     clr.b    rollcpt_t(a3)
  2991.     bra    fx_fin1
  2992.  
  2993. ;-----------------------------------------------
  2994. ;    Roll + volume slide + set balance
  2995. ;    (initialisation)
  2996. ;-----------------------------------------------
  2997. fx_roll_and_vsl_and_sbl_init:
  2998.     move.w    d4,d5
  2999.     and.w    #$F00,d5
  3000.     move.w    d5,curbal_t(a3)    ; Fixe la balance
  3001.     and.w    #15,d4        ; d4 = vitesse
  3002.     beq    fx_fin1        ; Si vitesse = 0, répétitions continues
  3003.     move.b    d4,rollspd_t(a3)
  3004.     clr.b    rollcpt_t(a3)
  3005.     bra    fx_fin1
  3006.  
  3007. ;-----------------------------------------------
  3008. ;    Arpeggio, initialisation
  3009. ;-----------------------------------------------
  3010. fx_arpeggio_init:
  3011.     clr.w    arpegcpt_t(a3)    ; Compteur à 0
  3012.     bra    fx_fin1
  3013.  
  3014. ;-----------------------------------------------
  3015. ;     Detune
  3016. ;-----------------------------------------------
  3017. fx_set_ftune:
  3018.     move.w    d4,d5
  3019.     and.w    #$F,d4
  3020.     lsr.w    #4,d5
  3021.     sub.w    d4,d5
  3022.     move.w    d5,norm_f_t(a3)    ; nouveau finetune
  3023.     tst.w    d0
  3024.     beq    fx_fin1        ; On s'en va si il n'y a pas de note à côté
  3025.     move.w    d0,d3
  3026.     add.w    transp_t(a3),d3
  3027.     sub.w    #24,d3
  3028.     lsl.w    #3,d3
  3029.     add.w    d5,d3
  3030.     move.w    (a5,d3.w*2),pernote_t(a3)    ; Sinon on corrige la note
  3031.     bra    fx_fin1
  3032.  
  3033. ;-----------------------------------------------
  3034. ;    Note cut, initialisation
  3035. ;-----------------------------------------------
  3036. fx_note_precut:
  3037.     move.w    d4,cut_del_t(a3)
  3038.     bra    fx_fin1
  3039.  
  3040. ;-----------------------------------------------
  3041. ;    Position Jump
  3042. ;-----------------------------------------------
  3043. fx_pos_jump:
  3044.     tst.w    mod_flagnewline(a0)    ; La ligne n'a pas encore été changée par un 0Dxx ?
  3045.     bne.s    .ok
  3046.     clr.w    mod_linepos(a0)
  3047. .ok:
  3048.     IfNE    CHECK
  3049.     cmp.w    mod_songlen(a0),d4
  3050.     bge    fx_fin1
  3051.     EndC
  3052.     move.w    d4,mod_songpos(a0)    ; Nouvelle position
  3053.     move.w    ([adr_song,a1],d4.w*2),mod_numpat(a0)    ; Trouve le nouveau pattern
  3054.     move.w    #-1,mod_flagnewpos(a0)    ; On signale que la position a été modifiée
  3055.     bra    fx_fin1
  3056.  
  3057. ;-----------------------------------------------
  3058. ;    Set vibrato wave
  3059. ;-----------------------------------------------
  3060. fx_set_vib_wave:
  3061.     IfNE    CHECK=2
  3062.     and.b    #3,d4
  3063.     EndC
  3064.     move.b    d4,vibwav_t(a3)
  3065.     bra    fx_fin1
  3066.  
  3067. ;-----------------------------------------------
  3068. ;    Set tremolo wave
  3069. ;-----------------------------------------------
  3070. fx_set_trem_wave:
  3071.     IfNE    CHECK=2
  3072.     and.b    #3,d4
  3073.     EndC
  3074.     move.b    d4,tremwav_t(a3)
  3075.     bra    fx_fin1
  3076.  
  3077. ;-----------------------------------------------
  3078. ;    Break pattern & jump to line
  3079. ;-----------------------------------------------
  3080. fx_break_pat:
  3081.     tst.w    mod_flagnewpos(a0)    ; La position a déjà été changée ?
  3082.     bne.s    .np_end        ; Oui, on ne le refait pas.
  3083.     move.w    mod_cursongpos(a0),d3
  3084.     addq.w    #1,d3        ; Nouvelle position
  3085.     cmp.w    mod_songlen(a0),d3    ; Fin de la song ?
  3086.     blt.s    .s_song
  3087.     move.w    mod_songrep(a0),d3    ; Oui, bouclage
  3088. .s_song:    move.w    d3,mod_songpos(a0)
  3089.     move.w    ([adr_song,a1],d3.w*2),mod_numpat(a0)    ; Trouve le nouveau pattern
  3090. .np_end:
  3091.     IfNE    CHECK=2
  3092.     move.w    mod_numpat(a0),d5
  3093.     move.l    (adr_pattern,a1,d5.w*4),a4
  3094.     cmp.w    nlines_p(a4),d4
  3095.     blt.s    .ok
  3096.     moveq    #0,d4        ; Si la nouvelle ligne est en dehors du pattern
  3097.     EndC
  3098. .ok:    move.w    d4,mod_linepos(a0)    ; Pointe sur la nouvelle ligne du pattern
  3099.     move.w    #-1,mod_flagnewline(a0)
  3100.     bra    fx_fin1
  3101.  
  3102. ;-----------------------------------------------
  3103. ;    Pattern loop
  3104. ;-----------------------------------------------
  3105. fx_pattern_loop:
  3106.     tst.b    d4        ; Début de boucle ?
  3107.     bne.s    .doloop        ; Non, c'est la fin de la boucle alors
  3108.     tst.w    ploopn_t(a3)
  3109.     bne    fx_fin1        ; C'est pas la 1ère fois, on fait rien
  3110.     move.w    mod_curlinepos(a0),ploopp_t(a3)    ; Sinon, on mémorise la position de bouclage
  3111.     move.w    mod_cursongpos(a0),ploops_t(a3)
  3112.     bra    fx_fin1
  3113. .doloop:    tst.w    ploopn_t(a3)    ; Déjà dans une boucle ?
  3114.     beq.s    .suite        ; Non, nouveau compteur
  3115.     move.w    ploopn_t(a3),d4    ; d4 = nbr de répétition à faire
  3116.     subq.w    #1,d4        ; Boucle -1
  3117. .suite:    move.w    d4,ploopn_t(a3)
  3118.     beq    fx_fin1        ; Si on en est à 0, fin de la boucle
  3119.     move.w    ploopp_t(a3),mod_linepos(a0)    ; Point de bouclage
  3120.     move.w    ploops_t(a3),mod_songpos(a0)    ; On se remet sur la bonne position
  3121.     move.w    mod_songpos(a0),d3        ; Pattern correspondant
  3122.     move.w    ([adr_song,a1],d3.w*2),mod_numpat(a0)
  3123.     bra    fx_fin1        ; si par hasard on était allé ailleurs
  3124.  
  3125. ;-----------------------------------------------
  3126. ;    Set global speed
  3127. ;-----------------------------------------------
  3128. fx_set_global_speed:
  3129.     tst.w    d4
  3130.     beq    fx_fin1
  3131.     cmp.w    #31,d4
  3132.     bgt.s    .tempo
  3133.     move.w    d4,mod_speed(a0)
  3134.     moveq    #125,d4        ; Tempo 125
  3135. .tempo:
  3136.     tst.w    midi_in_on(pc)    ; Si on est en sychro MIDI externe,
  3137.     beq.s    .chgtempo        ; on change la valeur du tempo mais
  3138.     tst.w    midi_in_sync_flag(pc) ; pas la durée d'un tick.
  3139.     bne    fx_fin1
  3140.  
  3141. .chgtempo:    move.w    d4,-(sp)
  3142.     bsr    fx_change_tempo
  3143.     addq.l    #2,sp
  3144.     bra    fx_fin1
  3145.  
  3146. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  3147. ; Change le tempo. Nouveau tempo: mot en paramètre dans la pile.
  3148. fx_change_tempo:
  3149.     movem.l    d3-d5,-(sp)
  3150.     move.w    4*3+4(sp),d4
  3151.     move.w    d4,mod_tempo(a0)
  3152.     mulu.w    #4*6,d4
  3153.     move.w    replay_frequency(pc),d5
  3154.     mulu.w    #60,d5
  3155.     divu.w    d4,d5        ; d5 = freq.repl * 60 s / (tempo * 4 lig * 6 ticks)
  3156.     move.l    d5,d3        ;    = nombre de spl par tick
  3157.     clr.w    d3
  3158.     divu.w    d4,d3        ; d3 = nbr de spl par tick, frac
  3159.     swap    d3
  3160.     move.w    d5,d3
  3161.     swap    d3        ; d3 = nbr de spl par tick * $10000
  3162.     move.l    #1200-1,d4
  3163.     add.w    d5,d4
  3164.     divu.w    #1200,d4        ; d4 = splpartick/1200 arrondi par excès
  3165.     ext.l    d4
  3166.     divu.l    d4,d3        ; d3 = Nbr de spl par VBL * $10000
  3167.     move.l    d3,vblsize        ; Stoque d'un coup les parties entière et fractionnaire
  3168.     move.w    d4,vblnumber
  3169.     movem.l    (sp)+,d3-d5
  3170.     rts
  3171.  
  3172. ;-----------------------------------------------
  3173. ;    Set number of frames
  3174. ;-----------------------------------------------
  3175. fx_set_nbr_of_frames:
  3176.     IfNE    CHECK=2
  3177.     tst.w    d4
  3178.     beq    fx_fin1
  3179.     EndC
  3180.     move.w    d4,mod_speed(a0)
  3181.     bra    fx_fin1
  3182.  
  3183. ;-----------------------------------------------
  3184. ;    Set fine speed
  3185. ;-----------------------------------------------
  3186. fx_set_fine_speed:
  3187.     add.w    d4,d4
  3188.     IfNE    CHECK=2
  3189.     beq    fx_fin1
  3190.     EndC
  3191.     moveq    #0,d5
  3192.     move.w    replay_frequency,d5
  3193.     divu.w    #125*4*6/60,d5
  3194.     sub.w    #256,d5
  3195.     add.w    d5,d4
  3196.     move.w    d4,vblsize        ; Attention, Tempo non modifié.
  3197.     bra    fx_fin1
  3198.  
  3199. ;-----------------------------------------------
  3200. ;    Fine portamento up
  3201. ;-----------------------------------------------
  3202. fx_fine_porta_up:
  3203.     move.w    pernote_t(a3),d5
  3204.     lsl.w    #4,d4
  3205.     bne.s    .ok2
  3206.     move.w    fportspd_t(a3),d4
  3207. .ok2:    move.w    d4,fportspd_t(a3)
  3208.     sub.w    d4,d5
  3209.     IfNE    CHECK
  3210.     cmp.w    #PERIOD_MINI,d5
  3211.     bge.s    .ok
  3212.     move.w    #PERIOD_MINI,d5
  3213.     EndC
  3214. .ok:    move.w    d5,pernote_t(a3)
  3215.     bra    fx_fin1
  3216.  
  3217. ;-----------------------------------------------
  3218. ;    Fine portamento down
  3219. ;-----------------------------------------------
  3220. fx_fine_porta_down:
  3221.     IfNE    CHECK
  3222.     ext.l    d4
  3223.     EndC
  3224.     lsl.w    #4,d4
  3225.     bne.s    .ok2
  3226.     move.w    fportspd_t(a3),d4
  3227. .ok2:    move.w    d4,fportspd_t(a3)
  3228.     add.w    pernote_t(a3),d4
  3229.     IfNE    CHECK
  3230.     cmp.l    #PERIOD_MAXI,d4
  3231.     ble.s    .ok
  3232.     move.w    #PERIOD_MAXI,d4
  3233.     EndC
  3234. .ok:    move.w    d4,pernote_t(a3)
  3235.     bra    fx_fin1
  3236.  
  3237. ;-----------------------------------------------
  3238. ;    Note delay - initialisation
  3239. ;-----------------------------------------------
  3240. fx_predelay:
  3241.     move.w    d4,delay_t(a3)
  3242.     bra    fx_fin1
  3243.  
  3244. ;-----------------------------------------------
  3245. ;    Fine volume slide
  3246. ;-----------------------------------------------
  3247. fx_fine_v_sldown_l:
  3248.     neg.w    d4
  3249. fx_fine_v_slup_l:
  3250.     tst.w    d4
  3251.     bne.s    .ok
  3252.     move.w    fvolslspd_t(a3),d4
  3253. .ok:    move.w    d4,fvolslspd_t(a3)
  3254.     bsr    fx_do_v_slide_l
  3255.     bra    fx_fin1
  3256.  
  3257. ;-----------------------------------------------
  3258. ;    Fine exponential volume slide
  3259. ;-----------------------------------------------
  3260. ; *** Ces 2 effets sont inutilisés pour l'instant
  3261. ;fx_fine_v_sldown_e:            ; Fine volume slide down (exp) \
  3262. ;    neg.w    d4        ;                               > *** Ne pas séparer
  3263. ;fx_fine_v_slup_e:            ; Fine volume slide up (exp)   /
  3264. ;    bsr    fx_do_v_slide_e
  3265. ;    bra    fx_fin1
  3266.  
  3267. ;-----------------------------------------------
  3268. ;    Fine master volume slide
  3269. ;-----------------------------------------------
  3270. fx_fine_mv_sldown_l:            ; Fine master volume slide up (lin)   \
  3271.     neg.w    d4        ;                                      > *** Ne pas séparer
  3272. fx_fine_mv_slup_l:            ; Fine master volume slide down (lin) /
  3273.     bsr    fx_do_mv_slide_l
  3274.     bra    fx_fin1
  3275.  
  3276. ;-----------------------------------------------
  3277. ;    Pattern delay
  3278. ;-----------------------------------------------
  3279. fx_pattern_delay:
  3280.     move.w    d4,mod_patrep(a0)
  3281.     bra    fx_fin1
  3282.  
  3283. ;-----------------------------------------------
  3284. ;    Roll + volume slide (initialisation)
  3285. ;-----------------------------------------------
  3286. fx_roll_and_vsl_init:
  3287.     and.w    #15,d4        ; d4 = vitesse
  3288.     beq    fx_fin1        ; Si vitesse = 0, répétitions continues
  3289.     move.b    d4,rollspd_t(a3)
  3290.     clr.b    rollcpt_t(a3)
  3291.     bra    fx_fin1
  3292.  
  3293. ;-----------------------------------------------
  3294. ;    Tremor (initialisation)
  3295. ;-----------------------------------------------
  3296. fx_tremor_init:
  3297.     tst.b    d4
  3298.     beq    fx_fin1
  3299.     move.b    d4,d5
  3300.     lsr.b    #4,d5
  3301.     bne.s    .ok1
  3302.     moveq    #16,d5
  3303. .ok1:    move.b    d5,tremor1_t(a3)
  3304.     and.b    #15,d4
  3305.     bne.s    .ok2
  3306.     moveq    #16,d4
  3307. .ok2:    add.b    d5,d4
  3308.     move.b    d4,tremor2_t(a3)
  3309.     bra    fx_fin1
  3310.  
  3311. ;-----------------------------------------------
  3312. ;    Set flags
  3313. ;-----------------------------------------------
  3314. fx_set_flags:
  3315. .bit0:
  3316.     btst    #0,d4        ; Bit 0 : interpolation
  3317.     beq.s    .bit0off
  3318.     move.w    #1,interpol_t(a3)
  3319.     bra.s    .fin
  3320. .bit0off:    clr.w    interpol_t(a3)
  3321. .fin:
  3322.     bra    fx_fin1
  3323.  
  3324. ;-----------------------------------------------
  3325. ;    Set volume envelope
  3326. ;-----------------------------------------------
  3327. fx_set_vol_env:
  3328.     IfNE    CHECK=2
  3329.     cmp.w    #NBRVOLENV_MAXI-1,d4
  3330.     ble.s    .ok
  3331.     moveq    #0,d4
  3332. .ok:
  3333.     EndC
  3334.     move.w    d4,nevol_t(a3)
  3335.     beq    fx_fin1
  3336.  
  3337.     env_volume_init    a3
  3338.     bra    fx_fin1
  3339.  
  3340. ;-----------------------------------------------
  3341. ;    Set tone envelope
  3342. ;-----------------------------------------------
  3343. fx_set_ton_env:
  3344.     IfNE    CHECK=2
  3345.     cmp.w    #NBRTONENV_MAXI-1,d4
  3346.     ble.s    .ok
  3347.     moveq    #0,d4
  3348. .ok:
  3349.     EndC
  3350.     move.w    d4,neton_t(a3)
  3351.     beq    fx_fin1
  3352.  
  3353.     env_tone_init    a3
  3354.     bra    fx_fin1
  3355.  
  3356. ;-----------------------------------------------
  3357. ;    Set panning envelope
  3358. ;-----------------------------------------------
  3359. fx_set_pan_env:
  3360.     IfNE    CHECK=2
  3361.     cmp.w    #NBRPANENV_MAXI-1,d4
  3362.     ble.s    .ok
  3363.     moveq    #0,d4
  3364. .ok:
  3365.     EndC
  3366.     move.w    d4,nepan_t(a3)
  3367.     beq    fx_fin1
  3368.  
  3369.     env_panning_init    a3
  3370.     bra    fx_fin1
  3371.  
  3372. ;-----------------------------------------------
  3373. ;    Set volume envelope (Key Off)
  3374. ;-----------------------------------------------
  3375. fx_set_vol_env_ko:
  3376.     IfNE    CHECK=2
  3377.     cmp.w    #NBRVOLENV_MAXI-1,d4
  3378.     ble.s    .ok
  3379.     moveq    #0,d4
  3380. .ok:
  3381.     EndC
  3382.     move.w    d4,nevol_t(a3)
  3383.     beq    fx_fin1
  3384.  
  3385.     env_volume_init    a3
  3386.     move.w    ([module_inf1+adr_evol,d4.w*4],keyoffoffset_e.w),d6
  3387.     add.w    d6,devol_t(a3)
  3388.     bra    fx_fin1
  3389.  
  3390. ;-----------------------------------------------
  3391. ;    Set tone envelope (Key Off)
  3392. ;-----------------------------------------------
  3393. fx_set_ton_env_ko:
  3394.     IfNE    CHECK=2
  3395.     cmp.w    #NBRTONENV_MAXI-1,d4
  3396.     ble.s    .ok
  3397.     moveq    #0,d4
  3398. .ok:
  3399.     EndC
  3400.     move.w    d4,neton_t(a3)
  3401.     beq    fx_fin1
  3402.  
  3403.     env_tone_init    a3
  3404.     move.w    ([module_inf1+adr_eton,d4.w*4],keyoffoffset_e.w),d6
  3405.     add.w    d6,deton_t(a3)
  3406.     bra    fx_fin1
  3407.  
  3408. ;-----------------------------------------------
  3409. ;    Set panning envelope (Key Off)
  3410. ;-----------------------------------------------
  3411. fx_set_pan_env_ko:
  3412.     IfNE    CHECK=2
  3413.     cmp.w    #NBRPANENV_MAXI-1,d4
  3414.     ble.s    .ok
  3415.     moveq    #0,d4
  3416. .ok:
  3417.     EndC
  3418.     move.w    d4,nepan_t(a3)
  3419.     beq    fx_fin1
  3420.  
  3421.     env_panning_init    a3
  3422.     move.w    ([module_inf1+adr_epan,d4.w*4],keyoffoffset_e.w),d6
  3423.     add.w    d6,depan_t(a3)
  3424.     bra    fx_fin1
  3425.  
  3426. ;-----------------------------------------------
  3427. ;    Fine Sample Offset
  3428. ;-----------------------------------------------
  3429. fx_fine_sample_offset:
  3430.     lsl.w    #4,d4
  3431.     ext.l    d4
  3432.  
  3433.     IfNE    CHECK
  3434.     move.l    reppos_t(a3),d6
  3435.     add.l    replen_t(a3),d6
  3436.     cmp.l    d6,d4
  3437.     blt.s    .ok
  3438.     move.l    d6,d4
  3439.     subq.l    #1,d4
  3440.     bpl.s    .ok
  3441.     moveq    #0,d4
  3442.     EndC
  3443.  
  3444. .ok:    move.l    d4,pos_t(a3)
  3445.     bra    fx_fin1
  3446.  
  3447. ;-----------------------------------------------
  3448. ;    Very Fine Sample Offset
  3449. ;-----------------------------------------------
  3450. fx_very_fine_sample_offset:
  3451.     ext.l    d4
  3452.  
  3453.     IfNE    CHECK
  3454.     move.l    reppos_t(a3),d6
  3455.     add.l    replen_t(a3),d6
  3456.     cmp.l    d6,d4
  3457.     blt.s    .ok
  3458.     move.l    d6,d4
  3459.     subq.l    #1,d4
  3460.     bpl.s    .ok
  3461.     moveq    #0,d4
  3462.     EndC
  3463.  
  3464. .ok:    move.l    d4,pos_t(a3)
  3465.     bra    fx_fin1
  3466.  
  3467. ;-----------------------------------------------
  3468. ;    Increment Sample Position
  3469. ;-----------------------------------------------
  3470. fx_inc_sample_pos:
  3471.     ext.l    d4
  3472.     add.l    pos_t(a3),d4
  3473.  
  3474.     IfNE    CHECK
  3475.  
  3476.     move.l    reppos_t(a3),d6
  3477.     add.l    replen_t(a3),d6
  3478.     cmp.l    d6,d4
  3479.     blt.s    .ok
  3480.  
  3481.     sub.l    reppos_t(a3),d4    ; Si on déborde de la boucle
  3482.     divul.l    replen_t(a3),d6:d4
  3483.     add.l    reppos_t(a3),d6
  3484.     move.l    d6,d4        ; pos = ((pos + N - rep) MOD replen) + rep
  3485.  
  3486.     EndC
  3487.  
  3488. .ok:    move.l    d4,pos_t(a3)
  3489.     bra    fx_fin1
  3490.  
  3491. ;-----------------------------------------------
  3492. ;    Decrement Sample Position
  3493. ;-----------------------------------------------
  3494. fx_dec_sample_pos:
  3495.     ext.l    d4
  3496.     sub.l    d4,pos_t(a3)
  3497.  
  3498.     IfNE    CHECK
  3499.     bpl    fx_fin1
  3500.     clr.l    pos_t(a3)
  3501.     EndC
  3502.  
  3503.     bra    fx_fin1
  3504.  
  3505. ;-----------------------------------------------
  3506. ;    AutoTempo (initialisation)
  3507. ;-----------------------------------------------
  3508. fx_init_autotempo:
  3509.     move.w    #1,flag_autotempo_t(a3)    ; On le fait en 'tous les ticks' à cause
  3510.     bra    fx_fin1            ; d'une éventuelle commande de vitesse
  3511.  
  3512. ;-----------------------------------------------
  3513. ;    AutoPeriod (initialisation)
  3514. ;-----------------------------------------------
  3515. fx_init_autoperiod:
  3516.     move.w    #1,flag_autoperiod_t(a3)    ; On le fait en 'tous les ticks' à cause
  3517.     bra    fx_fin1            ; d'une éventuelle commande de vitesse
  3518.  
  3519. ;-----------------------------------------------
  3520. ;    Demo Synchro
  3521. ;-----------------------------------------------
  3522. fx_demo_synchro:
  3523.     bra    fx_fin1
  3524.  
  3525. ;-----------------------------------------------
  3526. ;    Set track linear volume
  3527. ;-----------------------------------------------
  3528. fx_set_trk_lin_vol:
  3529.     lsl.w    #8,d4
  3530.     bsr    fx_do_set_trk_lin_vol
  3531.     bra    fx_fin1
  3532.  
  3533. fx_do_set_trk_lin_vol:
  3534.     tst.w    d4
  3535.     beq.s    .vol_0
  3536.     move.w    d4,mix_volume_t(a3)
  3537.  
  3538.     move.w    #$F00,d5
  3539. .loop:    add.w    d4,d4
  3540.     bcs.s    .ok
  3541.     sub.w    #$100,d5
  3542.     bra.s    .loop
  3543.  
  3544. .ok:    lsr.w    #8,d4        ; De 0 à $FF
  3545.     add.w    d4,d4        ; * 2 à cause du tableau en mots
  3546.     lea    vlin_2_exp_track(pc),a4
  3547.     add.w    (a4,d4.w),d5
  3548.  
  3549.     move.w    d5,mix_volume_e_t(a3)
  3550.     rts
  3551.  
  3552. .vol_0:    clr.w    mix_volume_t(a3)
  3553.     clr.w    mix_volume_e_t(a3)
  3554.     rts
  3555.  
  3556. ;-----------------------------------------------
  3557. ;    Set track exponential volume
  3558. ;-----------------------------------------------
  3559. fx_set_trk_exp_vol:
  3560.     lsl.w    #4,d4
  3561.     bsr    fx_do_set_trk_exp_vol
  3562.     bra    fx_fin1
  3563.  
  3564. fx_do_set_trk_exp_vol:
  3565.     tst.w    d4
  3566.     beq.s    .vol_0
  3567.     move.w    d4,mix_volume_e_t(a3)
  3568.     lsr.w    #4,d4
  3569.     move.w    d4,d5
  3570.  
  3571.     and.w    #$F,d4        ; On isole la partie inférieure, pour calculer 2^(0.xxx)
  3572.     lsl.w    #4+1,d4        ; De 0 à $F0, * 2 car .w
  3573.     lea    vexp_2_lin_track(pc),a4
  3574.     move.w    (a4,d4.w),d4    ; Résultat: [2^(0/256), 2^(255/256)] => [$8000, $FFFF]
  3575.  
  3576.     lsr.w    #4,d5        ; La partie restante, c'est du 2^n
  3577.     sub.w    #$F,d5        ; Pour le sens du décalage
  3578.     neg.w    d5
  3579.     lsr.w    d5,d4        ; Finalement on a v_lin = 2 ^ (valeur/16)
  3580.  
  3581.     move.w    d4,mix_volume_t(a3)
  3582.     rts
  3583.  
  3584. .vol_0:    clr.w    mix_volume_t(a3)
  3585.     clr.w    mix_volume_e_t(a3)
  3586.     rts
  3587.  
  3588. ;-----------------------------------------------
  3589. ;    Fine exponential track volume slide
  3590. ;-----------------------------------------------
  3591. fx_fine_t_v_sldown_e:
  3592.     neg.w    d4
  3593. fx_fine_t_v_slup_e:
  3594.     tst.w    d4
  3595.     bne.s    .ok
  3596.     move.w    fetvolslspd_t(a3),d4
  3597. .ok:    move.w    d4,fetvolslspd_t(a3)
  3598.     bsr    fx_do_t_v_slide_e
  3599.     bra    fx_fin1
  3600.  
  3601.  
  3602.  
  3603. ;***********************************************
  3604. ;    Effets agissant pendant la note
  3605. ;***********************************************
  3606.  
  3607. ;-----------------------------------------------
  3608. ;    Arpeggio
  3609. ;-----------------------------------------------
  3610. fx_arpeggio:
  3611.     moveq    #0,d5
  3612.     move.w    arpegcpt_t(a3),d5
  3613.     addq.w    #1,arpegcpt_t(a3)
  3614.     divu.w    #3,d5
  3615.     swap    d5
  3616.     tst.w    d5
  3617.     beq    fx_fin_normale
  3618.     cmp.b    #1,d5
  3619.     bne.s    .suite
  3620.     lsr.b    #4,d4
  3621. .suite:    and.b    #$F,d4        ; d4 = nbr de 1/2 tons à décaler
  3622.     beq    fx_fin_normale
  3623.     add.w    curnote_t(a3),d4
  3624.     add.w    transp_t(a3),d4
  3625.     sub.w    #24,d4
  3626.     lsl.w    #3,d4
  3627.     add.w    norm_f_t(a3),d4
  3628.     move.w    (a5,d4.w*2),d4
  3629.     IfNE    CHECK
  3630.     cmp.w    #PERIOD_MINI,d4
  3631.     bge.s    .suite2
  3632.     move.w    #PERIOD_MINI,d4
  3633.     EndC
  3634. .suite2:    move.w    d4,per_t(a3)
  3635.     move.w    vollnot_t(a3),vol_t(a3)    ; On met le bon volume car on ne
  3636.     move.w    curbal_t(a3),bal_t(a3)    ; repasse pas par la fin normale
  3637.     bra    fx_fin_speciale
  3638.  
  3639. ;-----------------------------------------------
  3640. ;    Portamento up
  3641. ;-----------------------------------------------
  3642. fx_porta_up:
  3643.     lsl.w    #4,d4
  3644.     bne.s    .ok
  3645.     move.w    portspd_t(a3),d4
  3646. .ok:    move.w    d4,portspd_t(a3)
  3647.     sub.w    d4,pernote_t(a3)
  3648.     IfNE    CHECK
  3649.     cmp.w    #PERIOD_MINI,pernote_t(a3)
  3650.     bge    fx_fin_normale
  3651.     move.w    #PERIOD_MINI,pernote_t(a3)
  3652.     EndC
  3653.     bra    fx_fin_normale
  3654.  
  3655. ;-----------------------------------------------
  3656. ;    Extra fine portamento up
  3657. ;-----------------------------------------------
  3658. fx_extra_fine_porta_up:
  3659.     tst.w    d4
  3660.     bne.s    .ok
  3661.     move.w    portspd_t(a3),d4
  3662. .ok:    move.w    d4,portspd_t(a3)
  3663.     sub.w    d4,pernote_t(a3)
  3664.     IfNE    CHECK
  3665.     cmp.w    #PERIOD_MINI,pernote_t(a3)
  3666.     bge    fx_fin_normale
  3667.     move.w    #PERIOD_MINI,pernote_t(a3)
  3668.     EndC
  3669.     bra    fx_fin_normale
  3670.  
  3671. ;-----------------------------------------------
  3672. ;    Portamento down
  3673. ;-----------------------------------------------
  3674. fx_porta_down:
  3675.     lsl.w    #4,d4
  3676.     bne.s    .ok
  3677.     move.w    portspd_t(a3),d4
  3678. .ok:    move.w    d4,portspd_t(a3)
  3679.     ext.l    d4
  3680.     add.w    pernote_t(a3),d4
  3681.     IfNE    CHECK
  3682.     cmp.l    #PERIOD_MAXI,d4
  3683.     ble.s    .suite
  3684.     move.w    #PERIOD_MAXI,d4
  3685.     EndC
  3686. .suite:    move.w    d4,pernote_t(a3)
  3687.     bra    fx_fin_normale
  3688.  
  3689. ;-----------------------------------------------
  3690. ;    Extra fine portamento down
  3691. ;-----------------------------------------------
  3692. fx_extra_fine_porta_down:
  3693.     ext.l    d4
  3694.     bne.s    .ok
  3695.     move.w    portspd_t(a3),d4
  3696. .ok:    move.w    d4,portspd_t(a3)
  3697.     add.w    pernote_t(a3),d4
  3698.     IfNE    CHECK
  3699.     cmp.l    #PERIOD_MAXI,d4
  3700.     ble.s    .suite
  3701.     move.w    #PERIOD_MAXI,d4
  3702.     EndC
  3703. .suite:    move.w    d4,pernote_t(a3)
  3704.     bra    fx_fin_normale
  3705.  
  3706. ;-----------------------------------------------
  3707. ;    Tone portamento
  3708. ;-----------------------------------------------
  3709. fx_tone_porta:
  3710.     bsr.s    fx_do_tone_porta
  3711.     bra    fx_fin_normale
  3712.  
  3713. ;-----------------------------------------------
  3714. ;    Extra fine tone portamento
  3715. ;-----------------------------------------------
  3716. fx_extra_fine_tone_porta:
  3717.     bsr.s    fx_do_very_fine_tone_porta
  3718.     bra    fx_fin_normale
  3719.  
  3720. fx_do_tone_porta:            ; Exécute le Tone Portamento
  3721.     lsl.w    #4,d4
  3722. fx_do_very_fine_tone_porta:
  3723.     tst.w    d4
  3724.     bne.s    .suite1
  3725.     move.w    tportspd_t(a3),d4
  3726. .suite1:    move.w    d4,tportspd_t(a3)
  3727.     move.w    pernote_t(a3),d5    ; d5 = période actuelle
  3728.     move.w    per2sl_t(a3),d6    ; d6 = période à atteindre
  3729.     cmp.w    d6,d5
  3730.     beq.s    .fin2
  3731.     blt.s    .monte
  3732.     sub.w    d4,d5
  3733.     cmp.w    d6,d5
  3734.     bge.s    .fin
  3735.     move.w    d6,d5        ; On a atteint la nouvelle note
  3736.     move.w    note2sl_t(a3),curnote_t(a3)
  3737.     bra.s    .fin
  3738. .monte:    add.w    d4,d5
  3739.     cmp.w    d6,d5
  3740.     ble.s    .fin
  3741.     move.w    d6,d5        ; On a atteint la nouvelle note
  3742.     move.w    note2sl_t(a3),curnote_t(a3)
  3743. .fin:    move.w    d5,pernote_t(a3)
  3744. .fin2:    rts
  3745.  
  3746. ;-----------------------------------------------
  3747. ;    Vibrato
  3748. ;-----------------------------------------------
  3749. fx_vibrato:
  3750.     bsr.s    fx_do_vibrato
  3751.     bra    fx_fin_speciale
  3752.  
  3753. fx_do_vibrato:            ; Exécute le Vibrato
  3754.     move.w    d4,d5        ; Retour par fx_fin_speciale !
  3755.     and.w    #$f,d4
  3756.     beq.s    .suite1
  3757.     move.b    d4,vibamp_t(a3)
  3758. .suite1:    lsr.w    #2,d5
  3759.     and.w    #$3c,d5
  3760.     beq.s    .suite2
  3761.     move.b    d5,vibspd_t(a3)
  3762. .suite2:    moveq    #0,d3
  3763.     move.b    vibcpt_t(a3),d3
  3764.     move.b    vibwav_t(a3),d4
  3765.     lea    sin_table(pc),a4
  3766.     and.b    #3,d4
  3767.     beq.s    .sinus        ; Forme sinus : 0
  3768.     lea    square_table(pc),a4
  3769.     subq.b    #1,d4
  3770.     bne.s    .sinus        ; Forme carrée : 2 (ou 3)
  3771.     lea    rampdown_table(pc),a4
  3772. .sinus:    lsr.w    #2,d3
  3773.     and.w    #$3f,d3        ; d3 = offset dans la table de sinus
  3774.     move.w    (a4,d3.w*2),d3    ; d3 = sinus
  3775.     move.b    vibamp_t(a3),d4
  3776.     and.w    #$f,d4
  3777.     muls.w    d4,d3        ; Multiplie par l'amplitude
  3778.     asr.w    #3,d3
  3779.     move.w    pernote_t(a3),d4
  3780.     add.w    d3,d4        ; Nouvelle période de la note
  3781.     move.b    vibspd_t(a3),d3
  3782.     add.b    d3,vibcpt_t(a3)    ; Ajoute la fréquence
  3783.     move.w    d4,per_t(a3)    ; Valide la nouvelle période
  3784.     move.w    vollnot_t(a3),vol_t(a3)    ; Met le volume
  3785.     move.w    curbal_t(a3),bal_t(a3)
  3786.     rts
  3787.  
  3788. ;-----------------------------------------------
  3789. ;    Tone portamento + vibrato
  3790. ;-----------------------------------------------
  3791. fx_tone_porta_vib:
  3792.     bsr    fx_do_tone_porta
  3793.     moveq    #0,d4
  3794.     bsr    fx_do_vibrato
  3795.     bra    fx_fin_speciale
  3796.  
  3797. ;-----------------------------------------------
  3798. ;    Vibrato + tone portamento
  3799. ;-----------------------------------------------
  3800. fx_vib_tone_porta:
  3801.     move.w    d4,-(sp)
  3802.     moveq    #0,d4
  3803.     bsr    fx_do_tone_porta
  3804.     move.w    d4,(sp)+
  3805.     bsr    fx_do_vibrato
  3806.     bra    fx_fin_speciale
  3807.  
  3808. ;-----------------------------------------------
  3809. ;    Tremolo
  3810. ;-----------------------------------------------
  3811. fx_tremolo:
  3812.     move.w    d4,d5
  3813.     and.w    #$f,d4
  3814.     beq.s    .suite1
  3815.     move.b    d4,tremamp_t(a3)
  3816. .suite1:    lsr.w    #2,d5
  3817.     and.w    #$3c,d5
  3818.     beq.s    .suite2
  3819.     move.b    d5,tremspd_t(a3)
  3820. .suite2:    moveq    #0,d3
  3821.     move.b    tremcpt_t(a3),d3
  3822.     move.b    tremwav_t(a3),d4
  3823.     lea    sin_table(pc),a4
  3824.     and.b    #3,d4
  3825.     beq.s    .sinus        ; Forme sinus : 0
  3826.     lea    square_table(pc),a4
  3827.     subq.b    #1,d4
  3828.     bne.s    .sinus        ; Forme carrée : 2 (ou 3)
  3829.     lea    rampdown_table(pc),a4
  3830. .sinus:    lsr.w    #2,d3
  3831.     and.w    #$3f,d3        ; d3 = offset dans la table de sinus
  3832.     move.w    (a4,d3.w*2),d3    ; d3 = sinus
  3833.     move.b    tremamp_t(a3),d4
  3834.     and.w    #$f,d4
  3835.     muls.w    d4,d3        ; Multiplie par l'amplitude
  3836.     asr.w    #1,d3
  3837.     move.w    vollnot_t(a3),d4
  3838.     IfNE    CHECK
  3839.     tst.b    tremcpt_t(a3)    ; Négatif ?
  3840.     bmi.s    .negatif
  3841.     EndC
  3842.     add.w    d3,d4        ; Nouveau volume de la note
  3843.     IfNE    CHECK
  3844.     cmp.w    #$800,d4
  3845.     ble.s    .ok
  3846.     move.w    #$800,d4
  3847.     bra.s    .ok
  3848. .negatif:    add.w    d3,d4        ; Nouveau volume de la note
  3849.     bpl.s    .ok
  3850.     moveq    #0,d4
  3851.     EndC
  3852. .ok:    move.b    tremspd_t(a3),d3
  3853.     add.b    d3,tremcpt_t(a3)    ; Ajoute la fréquence
  3854.     move.w    d4,vol_t(a3)    ; Valide le nouveau volume
  3855.     move.w    pernote_t(a3),per_t(a3)    ; Met la période
  3856.     move.w    curbal_t(a3),bal_t(a3)
  3857.     bra    fx_fin_speciale
  3858.  
  3859. ;-----------------------------------------------
  3860. ;    Note delay
  3861. ;-----------------------------------------------
  3862. fx_delay:
  3863.     tst.w    delay_t(a3)
  3864.     bmi    fx_fin_normale    ; -1, l'effet n'a plus de raison d'être
  3865.     bne    .nxt_vbl        ; Compteur<>0, on attend encore
  3866.                 ; On initialise une note normale
  3867.     tst.w    d1        ; Y a-t-il un instrument ?
  3868.     beq    .pas_inst
  3869.     move.w    d1,instr_t(a3)    ; Oui, il devient l'instrument courant
  3870.     mulu.w    #next_i,d1
  3871.     lea    ([adr_instrset,a1],d1.l),a2    ; a2 pointe sur l'instrument
  3872.     move.w    vol_i(a2),d3    ; Prend le volume dans d3
  3873.     move.w    curnote_t(a3),d4
  3874.     tst.w    d0        ; Nouvelle note ?
  3875.     beq.s    .note_s
  3876.     move.w    d0,d4
  3877. .note_s:    move.b    transp_i(a2,d4.w*2),d1
  3878.     ext.w    d1
  3879.     move.w    d1,transp_t(a3)    ; Transposition
  3880.     add.w    d1,d3        ; Sur la note
  3881.     moveq    #0,d1
  3882.     move.b    splnum_i(a2,d4.w*2),d1
  3883.     move.w    d1,ninstr_t(a3)    ; Il devient le sample courant
  3884.     move.l    (adr_samples,a1,d1.w*4),a4    ; Recopie le finetune
  3885.     move.w    vol_s(a4),volsam_t(a3)    ; et le volume du sample.
  3886.     move.w    d3,norm_v_t(a3)        ; Le volume de l'instrument dans la voie
  3887.     move.w    ftune_s(a4),norm_f_t(a3)
  3888.     move.w    nbits_s(a4),d3        ; Nombre de bits
  3889.     lsr.w    #3,d3
  3890.     move.w    d3,nbits_t(a3)
  3891.     move.w    fech_s(a4),fech_t(a3)        ; Fréquence d'échantillonnage
  3892.     move.w    autobal_s(a4),d3
  3893.     bmi.s    .pasbalnc
  3894.     move.w    d3,curbal_t(a3)        ; La balance
  3895. .pasbalnc:    move.w    norm_v_t(a3),d3
  3896.     lea    vlin_2_exp(pc),a4
  3897.     move.w    (a4,d3.w*2),volenot_t(a3)    ; Sans oublier le volume exponentiel
  3898.     lsl.w    #3,d3
  3899.     move.w    d3,vollnot_t(a3)    ; Volume courant aussi
  3900.  
  3901. .pas_inst:    tst.w    d0
  3902.     beq    fx_fin_normale    ; S'il n'y a pas de note on s'en va
  3903.     move.w    d0,curnote_t(a3)
  3904.     move.w    d0,note2sl_t(a3)
  3905.     move.w    d0,d3
  3906.     move.w    instr_t(a3),d1
  3907.     mulu.w    #next_i,d1
  3908.     lea    ([adr_instrset,a1],d1.l),a2    ; a2 pointe sur l'instrument
  3909.     env_initialisation    a3,1,a2    ; Initialise les enveloppes
  3910.     move.b    transp_i(a2,d0.w*2),d1
  3911.     ext.w    d1
  3912.     move.w    d1,transp_t(a3)    ; Transposition
  3913.     add.w    d1,d3        ; Sur la note
  3914.     moveq    #0,d1
  3915.     move.b    splnum_i(a2,d0.w*2),d1
  3916.     move.w    d1,ninstr_t(a3)    ; Il devient le sample courant
  3917.     move.w    ([adr_samples,a1,d1.w*4],vol_s),volsam_t(a3)    ; Recopie le volume du sample
  3918.     move.w    ([adr_samples,a1,d1.w*4],autobal_s),d4
  3919.     bmi.s    .pas_autb
  3920.     move.w    d4,curbal_t(a3)    ; Recopie la balance du sample
  3921. .pas_autb:    sub.w    #24,d3
  3922.     IfNE    CHECK
  3923.     bpl.s    .check1ok
  3924.     moveq    #24,d3
  3925. .check1ok:    cmp.w    #127,d3
  3926.     ble.s    .check2ok
  3927.     moveq    #127,d3
  3928. .check2ok:
  3929.     EndC
  3930.     lsl.w    #3,d3
  3931.     add.w    norm_f_t(a3),d3
  3932.     add.w    d3,d3
  3933.     move.w    (a5,d3.w),pernote_t(a3)    ; Sinon c'est une note normale
  3934.     move.w    (a5,d3.w),per2sl_t(a3)
  3935.     clr.l    pos_t(a3)
  3936.     clr.w    finepos_t(a3)
  3937.     clr.w    tremorc_t(a3)
  3938.     move.w    ninstr_t(a3),d1
  3939.     move.l    (adr_samples,a1,d1.w*4),a4
  3940.     move.l    a4,adrsam_t(a3)    ; Recopie l'adresse du sample,
  3941.     add.l    #data_s,adrsam_t(a3)
  3942.     moveq    #0,d3
  3943.     move.w    d1,d3
  3944.     swap    d3
  3945.     lsr.l    #6,d3        ; d3 = d1*1024
  3946.     add.l    #repeatbuffer,d3
  3947.     move.l    d3,rbuffer_t(a3)    ; l'adresse du buffer de répétition,
  3948.     lea    repeat_s(a4),a4
  3949.     move.l    (a4)+,d3        ; le point de répétition,
  3950.     move.l    (a4),d4        ; et la taille de la boucle
  3951.     move.l    d4,d5
  3952.     add.l    d3,d5
  3953.     cmp.l    #2,d5
  3954.     bne.s    .finsi
  3955.     move.l    -replen_s+length_s(a4),d3    ; Si pas de bouclage
  3956.     subq.l    #2,d3
  3957.     moveq    #2,d4
  3958. .finsi:    move.l    d3,reppos_t(a3)
  3959.     move.l    d4,replen_t(a3)
  3960.     move.w    c_v_t(a3),d3    ; Commande de volume ?
  3961.     beq.s    .nxt_vbl
  3962.     lea    vlin_2_exp(pc),a4
  3963.     move.w    (a4,d3.w*2),volenot_t(a3)    ; Volume exponentiel
  3964.     lsl.w    #3,d3
  3965.     move.w    d3,vollnot_t(a3)    ; Volume courant ajusté
  3966. .nxt_vbl:    subq.w    #1,delay_t(a3)
  3967.     bra    fx_fin_normale
  3968.  
  3969. ;-----------------------------------------------
  3970. ;    Note cut
  3971. ;-----------------------------------------------
  3972. fx_note_cut:
  3973.     tst.w    cut_del_t(a3)    ; Compteur à 0 ?
  3974.     bmi    fx_fin_normale    ; -1, plus besoin de l'effet
  3975.     bne.s    .nxt_vbl        ; <>0 , on attend encore
  3976.     move.w    nepan_t(a3),d5    ; Sinon on met les enveloppes sur Key Off
  3977.     lea    ([module_inf1+adr_epan,d5.w*4]),a4
  3978.     move.w    keyoffoffset_e(a4),d6
  3979.     add.w    #data_e,d6
  3980.     move.w    d6,depan_t(a3)
  3981.     clr.w    pepan_t(a3)
  3982.     clr.w    ep_waitcpt_t(a3)
  3983.     move.w    neton_t(a3),d5
  3984.     lea    ([module_inf1+adr_eton,d5.w*4]),a4
  3985.     move.w    keyoffoffset_e(a4),d6
  3986.     add.w    #data_e,d6
  3987.     move.w    d6,deton_t(a3)
  3988.     clr.w    peton_t(a3)
  3989.     clr.w    et_waitcpt_t(a3)
  3990.     move.w    nevol_t(a3),d5
  3991.     beq.s    .pas_env        ; Si pas d'enveloppe de volume, on le coupe simplement
  3992.     lea    ([module_inf1+adr_evol,d5.w*4]),a4
  3993.     move.w    keyoffoffset_e(a4),d6
  3994.     add.w    #data_e,d6
  3995.     move.w    d6,devol_t(a3)
  3996.     clr.w    pevol_t(a3)
  3997.     clr.w    ev_waitcpt_t(a3)
  3998.     bra.s    .nxt_vbl
  3999. .pas_env:    clr.w    vollnot_t(a3)
  4000.     clr.w    volenot_t(a3)
  4001. .nxt_vbl:    subq.w    #1,cut_del_t(a3)
  4002.     bra    fx_fin_normale
  4003.  
  4004. ;-----------------------------------------------
  4005. ;    Volume slide (linear)
  4006. ;-----------------------------------------------
  4007. fx_v_sldown_l:
  4008.     neg.w    d4
  4009. fx_v_slup_l:
  4010.     tst.w    d4
  4011.     bne.s    .ok
  4012.     move.w    volslspd_t(a3),d4
  4013. .ok:    move.w    d4,volslspd_t(a3)
  4014.     bsr.s    fx_do_v_slide_l
  4015.     bra    fx_fin_normale
  4016.  
  4017. fx_do_v_slide_l:            ; Sous-routine de volume slide (lin.)
  4018.     move.w    vollnot_t(a3),d5
  4019.     lsr.w    #3,d5
  4020.     add.w    d5,d4
  4021.     IfNE    CHECK
  4022.     tst.w    d4
  4023.     bgt.s    .ok1
  4024.     moveq    #0,d4
  4025. .ok1:    cmp.w    #$100,d4
  4026.     ble.s    .ok2
  4027.     move.w    #$100,d4
  4028.     EndC
  4029. .ok2:    lea    vlin_2_exp(pc),a4
  4030.     move    (a4,d4.w*2),volenot_t(a3)
  4031.     lsl.w    #3,d4
  4032.     move.w    d4,vollnot_t(a3)
  4033.     rts
  4034.  
  4035. ;-----------------------------------------------
  4036. ;    Volume slide (exponential)
  4037. ;-----------------------------------------------
  4038. fx_v_sldown_e:            ; Volume slide down (exp) \
  4039.     neg.w    d4        ;                          > *** Ne pas séparer
  4040. fx_v_slup_e:            ; Volume slide up (exp)   /
  4041.     bsr.s    fx_do_v_slide_e
  4042.     bra    fx_fin_normale
  4043.  
  4044. fx_do_v_slide_e:            ; Sous-routine de volume slide (exp.)
  4045.     add.w    volenot_t(a3),d4
  4046.     IfNE    CHECK
  4047.     tst.w    d4
  4048.     bgt.s    .ok1
  4049.     moveq    #0,d4
  4050. .ok1:    cmp.w    #$800,d4
  4051.     ble.s    .ok2
  4052.     move.w    #$800,d4
  4053.     EndC
  4054. .ok2:    move.w    d4,volenot_t(a3)
  4055.     lea    vexp_2_lin(pc),a4
  4056.     move.w    (a4,d4.w*2),vollnot_t(a3)
  4057.     rts
  4058.  
  4059. ;-----------------------------------------------
  4060. ;    Linear volume slide + tone porta
  4061. ;-----------------------------------------------
  4062. fx_v_sldown_l_tp:
  4063.     neg.w    d4
  4064. fx_v_slup_l_tp:
  4065.     tst.w    d4
  4066.     bne.s    .ok
  4067.     move.w    volslspd_t(a3),d4
  4068. .ok:    move.w    d4,volslspd_t(a3)
  4069.     bsr.s    fx_do_v_slide_l
  4070.     moveq    #0,d4
  4071.     bsr    fx_do_tone_porta
  4072.     bra    fx_fin_normale
  4073.  
  4074. ;-----------------------------------------------
  4075. ;    Exponential volume slide + tone porta
  4076. ;-----------------------------------------------
  4077. fx_v_sldown_e_tp:            ; Volume slide down (exp) + tone porta \
  4078.     neg.w    d4        ;                                       > *** Ne pas séparer
  4079. fx_v_slup_e_tp:            ; Volume slide up (exp) + tone porta   /
  4080.     bsr.s    fx_do_v_slide_e
  4081.     moveq    #0,d4
  4082.     bsr    fx_do_tone_porta
  4083.     bra    fx_fin_normale
  4084.  
  4085. ;-----------------------------------------------
  4086. ;    Linear volume slide + vibrato
  4087. ;-----------------------------------------------
  4088. fx_v_sldown_l_vib:
  4089.     neg.w    d4
  4090. fx_v_slup_l_vib:
  4091.     tst.w    d4
  4092.     bne.s    .ok
  4093.     move.w    volslspd_t(a3),d4
  4094. .ok:    move.w    d4,volslspd_t(a3)
  4095.     bsr    fx_do_v_slide_l
  4096.     moveq    #0,d4
  4097.     bsr    fx_do_vibrato
  4098.     bra    fx_fin_speciale
  4099.  
  4100. ;-----------------------------------------------
  4101. ;    Exponential volume slide + vibrato
  4102. ;-----------------------------------------------
  4103. fx_v_sldown_e_vib:            ; Volume slide down (exp) + vibrato \
  4104.     neg.w    d4        ;                                    > *** Ne pas séparer
  4105. fx_v_slup_e_vib:            ; Volume slide up (exp) + vibrato   /
  4106.     bsr    fx_do_v_slide_e
  4107.     moveq    #0,d4
  4108.     bsr    fx_do_vibrato
  4109.     bra    fx_fin_speciale
  4110.  
  4111. ;-----------------------------------------------
  4112. ;    Linear master volume slide
  4113. ;-----------------------------------------------
  4114. fx_mv_sldown_l:            ; Master volume slide down (lin) \
  4115.     neg.w    d4        ;                                 > *** Ne pas séparer
  4116. fx_mv_slup_l:            ; Master volume slide up (lin)   /
  4117.     bsr.s    fx_do_mv_slide_l
  4118.     bra    fx_fin_normale
  4119.  
  4120. fx_do_mv_slide_l:            ; Sous-routine de master volume slide (lin)
  4121.     move.w    master_vol(pc),d5
  4122.     add.w    d5,d4
  4123.     IfNE    CHECK
  4124.     tst.w    d4
  4125.     bpl.s    .ok1
  4126.     moveq    #0,d4
  4127. .ok1:    cmp.w    #$fff,d4
  4128.     ble.s    .ok2
  4129.     move.w    #$fff,d4
  4130.     EndC
  4131. .ok2:    move.w    d4,master_vol
  4132.     rts
  4133.  
  4134. ;-----------------------------------------------
  4135. ;    Left & Right balance move
  4136. ;-----------------------------------------------
  4137. fx_left_bal_move:
  4138.     neg.w    d4
  4139. fx_right_bal_move:
  4140.     lsl.w    #4,d4
  4141.     bne.s    .ok
  4142.     move.w    panslspd_t(a3),d4
  4143. .ok:    move.w    d4,panslspd_t(a3)
  4144.     add.w    curbal_t(a3),d4
  4145.     IfNE    CHECK
  4146.     bge.s    .ok3
  4147.     moveq    #0,d4
  4148. .ok3:    cmp.w    #$fff,d4
  4149.     ble.s    .ok2
  4150.     move.w    #$fff,d4
  4151.     EndC
  4152. .ok2:    move.w    d4,curbal_t(a3)
  4153.     bra    fx_fin_normale
  4154.  
  4155. ;-----------------------------------------------
  4156. ;    Roll
  4157. ;-----------------------------------------------
  4158. fx_roll_7:
  4159.     tst.w    rollnbr_t(a3)
  4160.     beq    fx_fin_normale
  4161.     tst.b    rollcpt_t(a3)
  4162.     bne    .nxt_roll
  4163.     clr.l    pos_t(a3)
  4164.     clr.w    finepos_t(a3)
  4165.     clr.w    tremorc_t(a3)
  4166.     subq.w    #1,rollnbr_t(a3)
  4167. .nxt_roll:    move.b    rollcpt_t(a3),d4
  4168.     addq.b    #1,d4
  4169.     cmp.b    rollspd_t(a3),d4
  4170.     bne.s    .fin_roll
  4171.     moveq    #0,d4
  4172. .fin_roll:    move.b    d4,rollcpt_t(a3)
  4173.     bra    fx_fin_normale
  4174.  
  4175. ;-----------------------------------------------
  4176. ;    Roll + volume slide
  4177. ;-----------------------------------------------
  4178. fx_roll_and_vsl:
  4179.     tst.b    rollcpt_t(a3)
  4180.     bne    .nxt_roll
  4181.     clr.l    pos_t(a3)
  4182.     clr.w    finepos_t(a3)
  4183.     clr.w    tremorc_t(a3)
  4184. .nxt_roll:    move.b    rollcpt_t(a3),d5
  4185.     addq.b    #1,d5
  4186.     cmp.b    rollspd_t(a3),d5
  4187.     bne.s    .fin_roll
  4188.     move.w    vollnot_t(a3),d3    ; Récupère le volume courant
  4189.     and.w    #$FF,d4
  4190.     lsr.w    #4,d4
  4191.     cmp.b    #5,d4
  4192.     bgt.s    .x2_3
  4193.     moveq    #1,d5        ; 0, -1, -2, -4, -8, -16
  4194.     addq.w    #2,d4
  4195.     lsl.w    d4,d5
  4196.     and.w    #-8,d5
  4197.     sub.w    d5,d3
  4198.     bra.s    .vol_ok
  4199. .x2_3:    cmp.b    #6,d4        ; x 2/3
  4200.     bne.s    .x1_2
  4201.     add.w    d3,d3
  4202.     divu.w    #3,d3
  4203.     bra.s    .vol_ok
  4204. .x1_2:    cmp.b    #7,d4        ; x 1/2
  4205.     bne.s    .plus_n
  4206.     lsr.w    #1,d3
  4207.     bra.s    .vol_ok
  4208. .plus_n:    cmp.b    #13,d4        ; 0, +1, +2, +4, +8, +16
  4209.     bgt.s    .x3_2
  4210.     moveq    #1,d5
  4211.     subq.w    #6,d4
  4212.     lsl.w    d4,d5
  4213.     and.w    #-8,d5
  4214.     add.w    d5,d3
  4215.     bra.s    .vol_ok
  4216. .x3_2:    cmp.b    #14,d4
  4217.     bne.s    .x2
  4218.     move.w    d3,d5
  4219.     add.w    d3,d3
  4220.     add.w    d5,d3
  4221.     lsr.w    #1,d3
  4222.     bra.s    .vol_ok
  4223. .x2:    add.w    d3,d3
  4224. .vol_ok:    lea    vlin_2_exp(pc),a4
  4225.     tst.w    d3
  4226.     bpl.s    .finsi1
  4227.     moveq    #0,d3
  4228. .finsi1:    cmp.w    #$800,d3
  4229.     ble.s    .finsi2
  4230.     move.w    #$800,d3
  4231. .finsi2:    move.w    d3,vollnot_t(a3)    ; Volume courant
  4232.     lsr.w    #3,d3
  4233.     move.w    (a4,d3.w*2),volenot_t(a3)    ; Sans oublier le volume exponentiel
  4234.     moveq    #0,d5
  4235. .fin_roll:    move.b    d5,rollcpt_t(a3)
  4236.     bra    fx_fin_normale
  4237.  
  4238. ;-----------------------------------------------
  4239. ;    Tremor
  4240. ;-----------------------------------------------
  4241. fx_tremor:
  4242.     move.w    tremorc_t(a3),d4
  4243.     addq.w    #1,d4
  4244.     cmp.b    tremor2_t(a3),d4
  4245.     blt.s    .ok
  4246.     moveq    #0,d4
  4247. .ok:    move.w    tremorc_t(a3),d5
  4248.     move.w    d4,tremorc_t(a3)
  4249.     cmp.b    tremor1_t(a3),d5
  4250.     blt    fx_fin_normale    ; Volume on
  4251.     clr.w    vol_t(a3)        ; Volume off
  4252.     move.w    pernote_t(a3),per_t(a3)
  4253.     move.w    curbal_t(a3),bal_t(a3)
  4254.     bra    fx_fin_speciale
  4255.  
  4256. ;-----------------------------------------------
  4257. ;    AutoTempo
  4258. ;-----------------------------------------------
  4259. fx_autotempo:
  4260.     tst.w    flag_autotempo_t(a3)    ; Déjà venu ?
  4261.     beq    fx_fin_normale    ; Oui, on repart
  4262.  
  4263. ; Tempo = 60 s * lignes * freqech * speed / (4 lignespartemps * longueurenspl * 6 ticks)
  4264.     move.w    d4,d5        ; {
  4265.     add.w    d4,d4        ;   d4 * 5
  4266.     add.w    d4,d4        ;   car 5 = 60/4/(6/2)
  4267.     add.w    d5,d4        ; }
  4268.     mulu.w    mod_speed(a0),d4
  4269.     mulu.w    fech_t(a3),d4
  4270.     move.l    reppos_t(a3),d5
  4271.     add.l    replen_t(a3),d5    ; d5 = longueur du sample
  4272.     cmp.w    #2,nbits_t(a3)    ; en unités et non en octets
  4273.     bne.s    .ok1
  4274.     add.l    d4,d4        ; Optimisation de la division par 2 de d5
  4275. .ok1:    cmp.l    #1024,d5        ; Ne marche qu'avec des samples > 1 Ko.
  4276.     blt    fx_fin_normale
  4277.     add.l    d5,d5        ; * 2 -> /(6/2) de d4
  4278.     move.l    d5,d3        ; {
  4279.     lsr.l    #1,d3        ;   Division avec résultat arrondi au plus proche
  4280.     add.l    d3,d4        ;
  4281.     divu.l    d5,d4        ; } d4 = tempo
  4282.     beq    fx_fin_normale    ; On s'en va si un des paramètres était nul
  4283. .test2:    cmp.l    #999,d4        ; Tempo trop rapide ?
  4284.     ble.s    .ok2
  4285.     lsr.l    #1,d4        ; On divise par 2 alors
  4286.     bra.s    .test2
  4287. .ok2:
  4288.     move.w    d4,-(sp)
  4289.     bsr    fx_change_tempo    ; Hop le nouveau tempo
  4290.     addq.l    #2,sp
  4291.  
  4292.     clr.w    flag_autotempo_t(a3)    ; C'est fini pour aujourd'hui
  4293.     bra    fx_fin_normale
  4294.  
  4295. ;-----------------------------------------------
  4296. ;    AutoPeriod
  4297. ;-----------------------------------------------
  4298. fx_autoperiod:
  4299.     tst.w    flag_autoperiod_t(a3)    ; Déjà venu ?
  4300.     beq    fx_fin_normale    ; Oui, on repart
  4301.  
  4302. ; Periode = $1ac0 * 60 s * nbrlignes * speed * freqech / (tempo * 4 ligpartps * longueurspl * 6 ticks)
  4303.     mulu.w    #$1ac0*60/4/6,d4
  4304.     move.w    mod_speed(a0),d5
  4305.     mulu.w    fech_t(a3),d5
  4306.     mulu.l    d5,d5:d4        ; d5:d4 = $1ac0*60*nbrlig*speed*fech/4/6
  4307.  
  4308.     move.l    reppos_t(a3),d3
  4309.     add.l    replen_t(a3),d3    ; d3 = longueur du sample
  4310.     cmp.w    #2,nbits_t(a3)    ; en unités et non en octets
  4311.     bne.s    .ok1
  4312.     add.l    d4,d4        ; Optimisation de la division par 2 de d5:d4
  4313.     addx.l    d5,d5
  4314. .ok1:    cmp.l    #1024,d3        ; Ne marche qu'avec des samples > 1 Ko.
  4315.     blt    fx_fin_normale
  4316.  
  4317.     divu.l    d3,d5:d4        ; *** résultat sur plus de 32 bits ???
  4318.     moveq    #0,d5
  4319.     move.w    mod_tempo(a0),d5
  4320.     divu.l    d5,d4
  4321.  
  4322.     IfNE    CHECK
  4323.  
  4324.     ble    fx_fin_normale
  4325.  
  4326. .test1:    cmp.l    #PERIOD_MINI,d4
  4327.     bge.s    .oktest1
  4328.     add.l    d4,d4
  4329.     bra.s    .test1
  4330. .oktest1:
  4331.  
  4332. .test2:    cmp.l    #PERIOD_MAXI,d4
  4333.     ble.s    .oktest2
  4334.     lsr.l    d4,d4
  4335.     bra.s    .test2
  4336. .oktest2:
  4337.  
  4338.     EndC
  4339.  
  4340.     move.w    d4,pernote_t(a3)    ; Fixe la nouvelle période
  4341.  
  4342.     clr.w    flag_autoperiod_t(a3)    ; C'est fini pour aujourd'hui
  4343.     bra    fx_fin_normale
  4344.  
  4345. ;-----------------------------------------------
  4346. ;    Linear track volume slide
  4347. ;-----------------------------------------------
  4348. fx_t_v_sldown_l:
  4349.     neg.w    d4
  4350. fx_t_v_slup_l:
  4351.     asl.w    #4,d4
  4352.     bne.s    .ok
  4353.     move.w    ltvolslspd_t(a3),d4
  4354. .ok:    move.w    d4,ltvolslspd_t(a3)
  4355.     bsr    fx_do_t_v_slide_l
  4356.     bra    fx_fin_normale
  4357.  
  4358. fx_do_t_v_slide_l:
  4359.     moveq    #0,d5
  4360.     move.w    d4,d5
  4361.     moveq    #0,d4
  4362.     move.w    mix_volume_t(a3),d4
  4363.     add.l    d5,d4
  4364.     IfNE    CHECK
  4365.     bpl.s    .ok
  4366.     moveq    #0,d4
  4367. .ok:    cmp.l    #$FFFF,d4
  4368.     ble.s    .ok2
  4369.     move.l    #$FFFF,d4
  4370. .ok2:
  4371.     EndC
  4372.     bsr    fx_do_set_trk_lin_vol
  4373.     rts
  4374.  
  4375. ;-----------------------------------------------
  4376. ;    Exponential track volume slide
  4377. ;-----------------------------------------------
  4378. fx_t_v_sldown_e:
  4379.     neg.w    d4
  4380. fx_t_v_slup_e:
  4381.     tst.w    d4
  4382.     bne.s    .ok
  4383.     move.w    etvolslspd_t(a3),d4
  4384. .ok:    move.w    d4,etvolslspd_t(a3)
  4385.     bsr    fx_do_t_v_slide_e
  4386.     bra    fx_fin_normale
  4387.  
  4388. fx_do_t_v_slide_e:
  4389.     move.w    mix_volume_e_t(a3),d5
  4390.     add.w    d5,d4
  4391.     IfNE    CHECK
  4392.     bpl.s    .ok
  4393.     moveq    #0,d4
  4394. .ok:    cmp.w    #$FFF,d4
  4395.     ble.s    .ok2
  4396.     move.w    #$FFF,d4
  4397. .ok2:
  4398.     EndC
  4399.     bsr    fx_do_set_trk_exp_vol
  4400.     rts
  4401.  
  4402.  
  4403.  
  4404.     IfNE    MIDI_IN
  4405.  
  4406. *≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈*
  4407. *    Gestion du port Midi                    *
  4408. *≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈*
  4409. *    Cette routine est appelée sous interruption, par l'intermédiaire    *
  4410. *    du noyau.                        *
  4411. *≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈*
  4412. gestion_midi:
  4413.  
  4414.     movem.l    d0-a6,-(sp)
  4415.     lea    midi_data_buffer(pc),a2    ; a2 = adresse du buffer de données
  4416.     lea    midi_track_state(pc),a3    ; a3 = adresse de l'activité des pistes
  4417.  
  4418. ;--- Cherche les données arrivées sur le port Midi ---------------------------
  4419. gestmidi_new_data:
  4420.     move.w    sr,-(sp)
  4421.     or.w    #$700,sr        ; Pour ne pas être dérangé
  4422.     move.l    midi_iorec_adr(pc),a0
  4423.     move.w    iorec_ibufhd(a0),d1    ; Position de lecture
  4424.     cmp.w    iorec_ibuftl(a0),d1
  4425.     beq    gestmidi_no_more_data    ; Pas de nouvelles données Midi
  4426.  
  4427.     addq.w    #1,d1        ; Ajourne d'abord la position de lecture
  4428.     cmp.w    iorec_ibufsz(a0),d1
  4429.     blt.s    .nxtposok
  4430.     moveq    #0,d1
  4431. .nxtposok:    moveq    #0,d0
  4432.     move.b    ([a0,iorec_ibuf.w],d1.w),d0    ; d0 = donnée
  4433.     move.w    d1,iorec_ibufhd(a0)
  4434.     move.w    (sp)+,sr
  4435.  
  4436.     cmp.b    #$FE,d0        ; Active Sensing, inintéressant
  4437.     beq    gestmidi_data_loop_end
  4438.     tst.b    d0        ; C'est un octet de status?
  4439.     bmi.s    gestmidi_new_status
  4440.  
  4441. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  4442. ; Reprend l'ancien status
  4443.     move.w    midi_current_channel(pc),d1
  4444.     move.w    midi_current_status(pc),d2
  4445.     move.w    midi_nbr_bytes_recvd(pc),d3
  4446.     addq.w    #1,d3        ; Nouvel octet de donnée reçu
  4447.     move.w    d3,midi_nbr_bytes_recvd
  4448.     bra.s    gestmidi_data_sort
  4449.  
  4450. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  4451. ; Change le status et le canal
  4452. gestmidi_new_status:
  4453.     cmp.w    #$F0,d0        ; System Message ?
  4454.     blt.s    gestmidi_new_status_normal
  4455.     move.w    midi_current_status(pc),midi_old_status
  4456.     move.w    d0,d2
  4457.     move.w    d2,midi_current_status
  4458.     move.w    midi_nbr_bytes_recvd(pc),midi_old_nbrbytesrec
  4459.     moveq    #0,d3
  4460.     move.w    d3,midi_nbr_bytes_recvd
  4461.     bra.s    gestmidi_new_status_end
  4462.  
  4463. gestmidi_new_status_normal:
  4464.     move.b    d0,d1
  4465.     move.b    d0,d2
  4466.     and.w    #15,d1
  4467.     addq.w    #1,d1        ; d1 = numéro du canal Midi (1-16)
  4468.     lsr.b    #4,d2
  4469.     and.w    #7,d2        ; d2 = numéro de commande
  4470.     moveq    #0,d3        ; d3 = Nombre - 1 d'octets déjà reçus
  4471.     move.w    d1,midi_current_channel
  4472.     move.w    d2,midi_current_status
  4473.     move.w    d3,midi_nbr_bytes_recvd
  4474. gestmidi_new_status_end:
  4475.  
  4476. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  4477. ; Tri des données.
  4478. ; A cet endroit:
  4479. ; d0.l = nouvelle donnée
  4480. ; d1.w = numéro du canal
  4481. ; d2.w = numéro de la commande
  4482. ; d3.w = position dans le buffer de réception
  4483. gestmidi_data_sort:
  4484.     lea    module_inf2(pc),a0    ; a0 = infos sur le module
  4485.     move.b    d0,(a2,d3.w)    ; Sauve l'octet dans le buffer
  4486.     tst.w    d2        ; Note Off
  4487.     beq    gestmidi_note_off
  4488.     cmp.w    #1,d2        ; Note On
  4489.     beq    gestmidi_note_on
  4490.     cmp.w    #2,d2        ; Polyphonic Aftertouch
  4491.     beq    gestmidi_polyphonic_aftertouch
  4492.     cmp.w    #3,d2        ; Control Change
  4493.     beq    gestmidi_control_change
  4494.     cmp.w    #4,d2        ; Program Change
  4495.     beq    gestmidi_program_change
  4496.     cmp.w    #5,d2        ; Channel Aftertouch
  4497.     beq    gestmidi_channel_aftertouch
  4498.     cmp.w    #6,d2        ; Pitch Bend
  4499.     beq    gestmidi_pitch_bend
  4500.     cmp.w    #$F0,d2        ; System Message: System Exclusive
  4501.     beq    gestmidi_sm_system_exclusive
  4502.     cmp.w    #$F1,d2        ; System Message: MIDI Time Code Quarter Frame
  4503.     beq    gestmidi_sm_midi_time_code_quarter_frame
  4504.     cmp.w    #$F2,d2        ; System Message: Song Position Pointer
  4505.     beq    gestmidi_sm_song_position_pointer
  4506.     cmp.w    #$F3,d2        ; System Message: Song Select
  4507.     beq    gestmidi_sm_song_select
  4508.     cmp.w    #$F4,d2        ; System Message: Undefined
  4509.     beq    gestmidi_sm_undefined
  4510.     cmp.w    #$F5,d2        ; System Message: Undefined
  4511.     beq    gestmidi_sm_undefined
  4512.     cmp.w    #$F6,d2        ; System Message: Tune Request
  4513.     beq    gestmidi_sm_tune_request
  4514.     cmp.w    #$F7,d2        ; System Message: End of Exclusive
  4515.     beq    gestmidi_sm_end_of_exclusive
  4516.     cmp.w    #$F8,d2        ; System Message: Timing Clock
  4517.     beq    gestmidi_sm_timing_clock
  4518.     cmp.w    #$F9,d2        ; System Message: Undefined
  4519.     beq    gestmidi_sm_undefined
  4520.     cmp.w    #$FA,d2        ; System Message: Start
  4521.     beq    gestmidi_sm_start
  4522.     cmp.w    #$FB,d2        ; System Message: Continue
  4523.     beq    gestmidi_sm_continue
  4524.     cmp.w    #$FC,d2        ; System Message: Stop
  4525.     beq    gestmidi_sm_stop
  4526.     cmp.w    #$FD,d2        ; System Message: Undefined
  4527.     beq    gestmidi_sm_undefined
  4528.     cmp.w    #$FF,d2        ; System Message: System Reset
  4529.     beq    gestmidi_sm_system_request
  4530.  
  4531. gestmidi_data_loop_end:
  4532.     bra    gestmidi_new_data
  4533. gestmidi_no_more_data:        ; *** Attention on a sauvé sr sur la pile avant!
  4534.     move.w    (sp)+,sr
  4535.  
  4536. ;--- Transforme les nouvelles données en notes du tracker --------------------
  4537.     lea    module_inf2(pc),a0    ; a0 = infos sur le module
  4538.     move.l    a3,a4        ; a4 = adresse de la piste courante
  4539.     lea    new_note_buffer(pc),a5    ; a5 = adresse du buffer de nouvelles notes
  4540.     move.w    mod_nbrtrack(a0),d4
  4541.     subq.w    #1,d4        ; d4 = compteur de boucles
  4542. gestmidi_conv_note_loop:
  4543.     tst.w    midi_ts_flags(a4)    ; La voie a subi des modifications?
  4544.     beq.s    gestmidi_conv_note_next
  4545.     move.l    midi_ts_pat_note(a4),1(a5)
  4546.     move.b    midi_ts_pat_volume(a4),5(a5)
  4547.     move.b    #1,(a5)        ; Flag mis pour la nouvelle note
  4548.     and.w    #$FFFE,midi_ts_flags(a4)    ; Mise à jour effectuée
  4549. gestmidi_conv_note_next:
  4550.     add.w    #midi_ts_next,a4
  4551.     addq.l    #6,a5
  4552.     dbra    d4,gestmidi_conv_note_loop
  4553.  
  4554.     movem.l    (sp)+,d0-a6
  4555.     rts
  4556.  
  4557.  
  4558.  
  4559. ;----------------------------------------------------------------------------;
  4560. ;    Note Off                        ;
  4561. ;----------------------------------------------------------------------------;
  4562. gestmidi_note_off:
  4563.     cmp.w    #2,d3        ; Attend 2 octets de donnée
  4564.     blt.s    gestmidi_data_loop_end
  4565.     clr.w    midi_nbr_bytes_recvd    ; On est prêt à recevoir un autre flux de données
  4566. gestmidi_note_off_2:
  4567.     tst.w    ((midi_in_noteoff_flag-2).l,d1.w*2)
  4568.     beq.s    .nonotoff        ; Flag = 0: Ignore totalement le message Note Off
  4569.  
  4570.     moveq    #0,d5
  4571.     move.b    1(a2),d5        ; d5 = la note à éteindre
  4572.     move.w    mod_nbrtrack(a0),d4
  4573.     subq.w    #1,d4        ; d4 = compteur de boucles
  4574.     move.l    a3,a4        ; a4 = adresse de la piste courante
  4575. .findnote_loop:            ; On va chercher la note
  4576.     cmp.w    midi_ts_channel(a4),d1    ; C'est le bon canal?
  4577.     bne.s    .endif1
  4578.     cmp.w    midi_ts_note(a4),d5    ; La bonne note?
  4579.     beq.s    .note_found
  4580. .endif1:    add.w    #midi_ts_next,a4
  4581.     dbra    d4,.findnote_loop
  4582.     bra.s    gestmidi_data_loop_end
  4583.  
  4584. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  4585. .note_found:
  4586.     clr.w    midi_ts_velocity(a4)    ; Vélocité à 0
  4587.     clr.w    midi_ts_note(a4)
  4588.     clr.w    midi_ts_pitch(a4)
  4589.  
  4590.     tst.w    ((midi_in_noteoff_flag-2).l,d1.w*2)
  4591.     bpl.s    .nonotoff        ; Flag = 1: on ne transcrit pas le message sur la partition
  4592.     move.l    #$00000A00,midi_ts_pat_note(a4)    ; Note Cut pur et dur
  4593.     clr.b    midi_ts_pat_volume(a4)
  4594.     or.w    #1,midi_ts_flags(a4)    ; Mise à jour
  4595. .nonotoff:
  4596.  
  4597.     bra    gestmidi_data_loop_end
  4598.  
  4599.  
  4600.  
  4601. ;----------------------------------------------------------------------------;
  4602. ;    Note On                        ;
  4603. ;----------------------------------------------------------------------------;
  4604. gestmidi_note_on:
  4605.     cmp.w    #2,d3        ; Attend 2 octets de donnée
  4606.     blt    gestmidi_data_loop_end
  4607.     clr.w    midi_nbr_bytes_recvd    ; On est prêt à recevoir un autre flux de données
  4608.     tst.w    d0        ; Vélocité nulle?
  4609.     beq.s    gestmidi_note_off_2    ; Oui, c'est un Note Off en fait
  4610.     moveq    #0,d5
  4611.     move.b    1(a2),d5        ; d5 = la nouvelle note
  4612.     move.w    mod_nbrtrack(a0),d4
  4613.     subq.w    #1,d4        ; d4 = compteur de boucles
  4614.     move.l    a3,a4        ; a4 = adresse de la piste courante
  4615. .findtrack_loop:            ; On va chercher la note
  4616.     cmp.w    midi_ts_channel(a4),d1    ; C'est le bon canal?
  4617.     bne.s    .endif1        ; Non, passe ton chemin
  4618.     cmp.w    midi_ts_note(a4),d5    ; Y a déjà cette note?
  4619.     beq.s    .track_found    ; Oui, on la remplace
  4620.     tst.w    midi_ts_velocity(a4)    ; La piste est libre?
  4621.     beq.s    .track_found    ; Oui, on y va
  4622. .endif1:    add.w    #midi_ts_next,a4
  4623.     dbra    d4,.findtrack_loop
  4624.     bra    gestmidi_data_loop_end
  4625.  
  4626. ; -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  4627. .track_found:
  4628.     move.w    d5,midi_ts_note(a4)    ; Enregistre la note
  4629.     move.w    d0,midi_ts_velocity(a4)    ; Sa vélocité
  4630.  
  4631.     tst.w    ((midi_in_velo_flag-2).l,d1.w*2)
  4632.     beq.s    .no_velo
  4633.     add.w    d0,d0        ; Conversion Vélocité -> Volume
  4634.     cmp.w    #255,d0        ; Volume un peu trop fort?
  4635.     ble.s    .velo_ok
  4636.     move.b    #255,d0        ; 255 maxi, bien sûr
  4637. .velo_ok:    move.b    d0,midi_ts_pat_volume(a4)    ; Conversion en notes de pattern
  4638. .no_velo:    move.b    d5,midi_ts_pat_note(a4)
  4639.     clr.w    midi_ts_pat_effect(a4)    ; Efface également l'effet, au cas
  4640.                 ; où il y aurait eu un Note Cut juste avant
  4641.     move.w    midi_ts_channel(a4),d5    ; Trouve l'instrument associé
  4642.     lea    midi_instr_map(pc),a5        ; à ce canal
  4643.     move.b    -1(a5,d5.w*2),midi_ts_pat_instr(a4)
  4644.     clr.w    midi_ts_pat_effect(a4)
  4645.  
  4646.     or.w    #1,midi_ts_flags(a4)    ; Mise à jour
  4647.     bra    gestmidi_data_loop_end
  4648.  
  4649.  
  4650.  
  4651. ;----------------------------------------------------------------------------;
  4652. ;    Polyphonic Aftertouch                    ;
  4653. ;----------------------------------------------------------------------------;
  4654. gestmidi_polyphonic_aftertouch:
  4655.     cmp.w    #2,d3        ; Attend 2 octets de donnée
  4656.     blt    gestmidi_data_loop_end
  4657.     clr.w    midi_nbr_bytes_recvd    ; On est prêt à recevoir un autre flux de données
  4658.     bra    gestmidi_data_loop_end
  4659.  
  4660.  
  4661.  
  4662. ;----------------------------------------------------------------------------;
  4663. ;    Control change                    ;
  4664. ;----------------------------------------------------------------------------;
  4665. gestmidi_control_change:
  4666.     cmp.w    #2,d3        ; Attend 2 octets de donnée
  4667.     blt    gestmidi_data_loop_end
  4668.     clr.w    midi_nbr_bytes_recvd    ; On est prêt à recevoir un autre flux de données
  4669.     bra    gestmidi_data_loop_end
  4670.  
  4671.  
  4672.  
  4673. ;----------------------------------------------------------------------------;
  4674. ;    Program Change                    ;
  4675. ;----------------------------------------------------------------------------;
  4676. gestmidi_program_change:
  4677.     cmp.w    #1,d3        ; Attend 1 octet de donnée
  4678.     blt    gestmidi_data_loop_end
  4679.     clr.w    midi_nbr_bytes_recvd    ; On est prêt à recevoir un autre flux de données
  4680.     bra    gestmidi_data_loop_end
  4681.  
  4682.  
  4683.  
  4684. ;----------------------------------------------------------------------------;
  4685. ;    Channel Aftertouch                    ;
  4686. ;----------------------------------------------------------------------------;
  4687. gestmidi_channel_aftertouch:
  4688.     cmp.w    #1,d3        ; Attend 1 octet de donnée
  4689.     blt    gestmidi_data_loop_end
  4690.     clr.w    midi_nbr_bytes_recvd    ; On est prêt à recevoir un autre flux de données
  4691.     bra    gestmidi_data_loop_end
  4692.  
  4693.  
  4694.  
  4695. ;----------------------------------------------------------------------------;
  4696. ;    Pitch Bend                        ;
  4697. ;----------------------------------------------------------------------------;
  4698. gestmidi_pitch_bend:
  4699.     cmp.w    #2,d3        ; Attend 2 octets de donnée
  4700.     blt    gestmidi_data_loop_end
  4701.     clr.w    midi_nbr_bytes_recvd    ; On est prêt à recevoir un autre flux de données
  4702.     bra    gestmidi_data_loop_end
  4703.  
  4704.  
  4705.  
  4706. ;----------------------------------------------------------------------------;
  4707. ;    System Message: System Exclusive                ;
  4708. ;----------------------------------------------------------------------------;
  4709. gestmidi_sm_system_exclusive:
  4710.     clr.w    midi_nbr_bytes_recvd    ; On est prêt à recevoir un autre flux de données
  4711.     bra    gestmidi_data_loop_end
  4712.  
  4713.  
  4714.  
  4715. ;----------------------------------------------------------------------------;
  4716. ;    System Message: MIDI Time Code Quarter Frame        ;
  4717. ;----------------------------------------------------------------------------;
  4718. gestmidi_sm_midi_time_code_quarter_frame:
  4719.     move.w    midi_old_status(pc),midi_current_status
  4720.     clr.w    midi_nbr_bytes_recvd    ; On est prêt à recevoir un autre flux de données
  4721.     bra    gestmidi_data_loop_end
  4722.  
  4723.  
  4724.  
  4725. ;----------------------------------------------------------------------------;
  4726. ;    System Message: Song Position Pointer            ;
  4727. ;----------------------------------------------------------------------------;
  4728. gestmidi_sm_song_position_pointer:
  4729.     cmp.w    #2,d3        ; Attend 2 octets de donnée
  4730.     blt    gestmidi_data_loop_end
  4731.     clr.w    midi_nbr_bytes_recvd    ; On est prêt à recevoir un autre flux de données
  4732.  
  4733.     move.w    midi_old_status(pc),midi_current_status
  4734.     bra    gestmidi_data_loop_end
  4735.  
  4736.  
  4737.  
  4738. ;----------------------------------------------------------------------------;
  4739. ;    System Message: Song Select                ;
  4740. ;----------------------------------------------------------------------------;
  4741. gestmidi_sm_song_select:
  4742.     cmp.w    #1,d3        ; Attend 1 octet de donnée
  4743.     blt    gestmidi_data_loop_end
  4744.     clr.w    midi_nbr_bytes_recvd    ; On est prêt à recevoir un autre flux de données
  4745.  
  4746.     move.w    midi_old_status(pc),midi_current_status
  4747.     bra    gestmidi_data_loop_end
  4748.  
  4749.  
  4750.  
  4751. ;----------------------------------------------------------------------------;
  4752. ;    System Message: Undefined                ;
  4753. ;----------------------------------------------------------------------------;
  4754. gestmidi_sm_undefined:
  4755.     move.w    midi_old_status(pc),midi_current_status
  4756.     clr.w    midi_nbr_bytes_recvd    ; On est prêt à recevoir un autre flux de données
  4757.     bra    gestmidi_data_loop_end
  4758.  
  4759.  
  4760.  
  4761. ;----------------------------------------------------------------------------;
  4762. ;    System Message: Tune Request                ;
  4763. ;----------------------------------------------------------------------------;
  4764. gestmidi_sm_tune_request:
  4765.     move.w    midi_old_status(pc),midi_current_status
  4766.     clr.w    midi_nbr_bytes_recvd    ; On est prêt à recevoir un autre flux de données
  4767.     bra    gestmidi_data_loop_end
  4768.  
  4769.  
  4770.  
  4771. ;----------------------------------------------------------------------------;
  4772. ;    System Message: End of Exclusive                ;
  4773. ;----------------------------------------------------------------------------;
  4774. gestmidi_sm_end_of_exclusive:
  4775.     move.w    midi_old_status(pc),midi_current_status
  4776.     clr.w    midi_nbr_bytes_recvd    ; On est prêt à recevoir un autre flux de données
  4777.     bra    gestmidi_data_loop_end
  4778.  
  4779.  
  4780.  
  4781. ;----------------------------------------------------------------------------;
  4782. ;    System Message: Timing Clock                ;
  4783. ;----------------------------------------------------------------------------;
  4784. gestmidi_sm_timing_clock:
  4785.     move.w    midi_old_status(pc),midi_current_status
  4786.     move.w    midi_old_nbrbytesrec(pc),midi_nbr_bytes_recvd    ; On est prêt à recevoir un autre flux de données
  4787.     tst.w    midi_in_sync_flag(pc)
  4788.     beq    gestmidi_data_loop_end
  4789.  
  4790.     cmp.w    #MIDI_IN_MAX_TCLK,midi_in_sync_cpt    ; On n'a pas trop de retard ?
  4791.     bgt.s    .too_late        ; Si oui, tant pis, abandonne
  4792.     addq.w    #1,midi_in_sync_cpt
  4793.  
  4794.     bra    gestmidi_data_loop_end
  4795.  
  4796. .too_late:
  4797.     move.w    #1,midi_in_sync_cpt
  4798.     bra    gestmidi_data_loop_end
  4799.  
  4800.  
  4801.  
  4802. ;----------------------------------------------------------------------------;
  4803. ;    System Message: Start                    ;
  4804. ;----------------------------------------------------------------------------;
  4805. gestmidi_sm_start:
  4806.     move.w    midi_old_status(pc),midi_current_status
  4807.     clr.w    midi_nbr_bytes_recvd    ; On est prêt à recevoir un autre flux de données
  4808.     tst.w    midi_in_sync_flag(pc)
  4809.     beq    gestmidi_data_loop_end
  4810.  
  4811.     bra    gestmidi_data_loop_end
  4812.  
  4813.  
  4814.  
  4815. ;----------------------------------------------------------------------------;
  4816. ;    System Message: Continue                ;
  4817. ;----------------------------------------------------------------------------;
  4818. gestmidi_sm_continue:
  4819.     move.w    midi_old_status(pc),midi_current_status
  4820.     clr.w    midi_nbr_bytes_recvd    ; On est prêt à recevoir un autre flux de données
  4821.     tst.w    midi_in_sync_flag(pc)
  4822.     beq    gestmidi_data_loop_end
  4823.  
  4824.     bra    gestmidi_data_loop_end
  4825.  
  4826.  
  4827.  
  4828. ;----------------------------------------------------------------------------;
  4829. ;    System Message: Stop                    ;
  4830. ;----------------------------------------------------------------------------;
  4831. gestmidi_sm_stop:
  4832.     move.w    midi_old_status(pc),midi_current_status
  4833.     clr.w    midi_nbr_bytes_recvd    ; On est prêt à recevoir un autre flux de données
  4834.     tst.w    midi_in_sync_flag(pc)
  4835.     beq    gestmidi_data_loop_end
  4836.  
  4837.     bra    gestmidi_data_loop_end
  4838.  
  4839.  
  4840.  
  4841. ;----------------------------------------------------------------------------;
  4842. ;    System Message: System Reset                ;
  4843. ;----------------------------------------------------------------------------;
  4844. gestmidi_sm_system_request:
  4845.     move.w    midi_old_status(pc),midi_current_status
  4846.     clr.w    midi_nbr_bytes_recvd    ; On est prêt à recevoir un autre flux de données
  4847.     bra    gestmidi_data_loop_end
  4848.  
  4849.  
  4850.  
  4851. *============================================================================*
  4852. *    Réinitialisation du Midi In                *
  4853. *============================================================================*
  4854. gestmidi_init_in:
  4855.     movem.l    d0/a0-a2,-(sp)
  4856.  
  4857.     move.w    #1,midi_current_channel    ; 1 par défaut
  4858.     move.w    #-1,midi_current_status    ; -1 = pas de status
  4859.     move.w    #-1,midi_old_status
  4860.     clr.w    midi_nbr_bytes_recvd        ; Aucune donnée reçue
  4861.  
  4862. ;--- Remet à 0 les status courant et la ligne de pattern à fabriquer ---------
  4863.     lea    midi_track_state(pc),a0
  4864.     moveq    #NBRVOIES_MAXI-1,d0
  4865. .init1loop:
  4866.     clr.w    midi_ts_channel(a0)    ; Efface les numéro de canal
  4867.     clr.w    midi_ts_note(a0)    ; remet à 0 l'activité des notes
  4868.     clr.w    midi_ts_velocity(a0)
  4869.     clr.w    midi_ts_pitch(a0)
  4870.     clr.w    midi_ts_flags(a0)
  4871.     clr.b    midi_ts_pat_note(a0)    ; Efface la note de pattern
  4872.     clr.b    midi_ts_pat_instr(a0)
  4873.     clr.b    midi_ts_pat_effect(a0)
  4874.     clr.b    midi_ts_pat_volume(a0)
  4875.     add.w    #midi_ts_next,a0
  4876.     dbra    d0,.init1loop
  4877.  
  4878. ;--- Vide le buffer Midi -----------------------------------------------------
  4879. .init2loop:
  4880.     move.w    #3,-(sp)        ; Périphérique: interface Midi
  4881.     move.w    #1,-(sp)        ; Bconstat
  4882.     trap    #13
  4883.     addq.l    #4,sp
  4884.     tst.w    d0
  4885.     beq.s    .init2end        ; Pas de nouvelles données Midi
  4886.     move.w    #3,-(sp)        ; Périphérique: interface Midi
  4887.     move.w    #2,-(sp)        ; Bconin
  4888.     trap    #13
  4889.     addq.l    #4,sp
  4890.     bra.s    .init2loop
  4891. .init2end:
  4892.  
  4893. ;--- Cherche l'adresse du bloc IOREC -----------------------------------------
  4894.     move.w    #2,-(sp)        ; MIDI
  4895.     move.w    #14,-(sp)        ; Iorec
  4896.     trap    #14
  4897.     addq.l    #4,sp
  4898.     move.l    d0,midi_iorec_adr    ; Récupère l'adresse du bloc
  4899.  
  4900.     movem.l    (sp)+,d0/a0-a2
  4901.     rts
  4902.  
  4903.     EndC
  4904.  
  4905.  
  4906.  
  4907.  
  4908.  
  4909. *≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈*
  4910.  
  4911.     Data
  4912.  
  4913. adr_labels:    Dc.w    next_t            ; Tout ça c'est pour le GfA
  4914.         Dc.l    nbrvoies,master_vol
  4915.         Dc.l    module_inf1+adr_samples,module_inf1+adr_module
  4916.         Dc.l    module_inf1+adr_instrset,module_inf1+adr_song
  4917.         Dc.l    module_inf1+adr_pattern
  4918.         Dc.l    module_inf2+mod_nbrtrack,mix_volume_e_t
  4919.         Dc.l    module_inf2+mod_songlen,module_inf2+mod_songrep
  4920.         Dc.l    module_inf2+mod_songpos,module_inf2+mod_numpat
  4921.         Dc.l    module_inf2+mod_linepos,module_inf2+mod_speed
  4922.         Dc.l    module_inf2+mod_nbrvbl
  4923.         Dc.l    info_track,repeatbuffer,flag_stop_voices
  4924.         Dc.l    mix_volume_t,flag_the_end,onoff_t,nbits_t,fech_t,curbal_t
  4925.         Dc.l    flag_mt_display,vblsize,module_inf2+mod_patrep,vblnumber
  4926.         Dc.l    replay_frequency
  4927.         Dc.l    module_inf1+adr_evol,module_inf1+adr_eton,module_inf1+adr_epan
  4928.         Dc.l    songrecord_state,songrecord_routine
  4929.         Dc.l    module_inf2+mod_tempo,interpol_t,adr_adr_inter
  4930.         Dc.l    current_play_mode,current_edit_mode
  4931.         Dc.l    midi_in_gfa_playline,midi_instr_map
  4932.         Dc.l    midi_track_state,midi_ts_next,new_note_buffer
  4933.         Dc.l    midi_in_noteoff_flag,midi_in_velo_flag
  4934.         Dc.l    midi_in_sync_flag,midi_in_sync_cpt,midi_in_on
  4935.         Dc.l    cpu_time_pourcent,flag_overflow
  4936.  
  4937. replay_frequency:    Dc.w    REPLAY_FREQ    ; Fréquence de restitution
  4938.  
  4939.         ; Table de sauts pour les effets. Certains sont
  4940.         ; inutilisés, donc on se tire directement
  4941. fx_table_de_sauts1:    ; 00xx - 0fxx
  4942.         Dc.l    fx_fin1,fx_fin1,fx_fin1,fx_fin1
  4943.         Dc.l    fx_fin1,fx_fin1,fx_fin1,fx_fin1
  4944.         Dc.l    fx_set_ftune,fx_predelay,fx_note_precut,fx_pos_jump
  4945.         Dc.l    fx_set_vib_wave,fx_break_pat,fx_set_trem_wave,fx_set_global_speed
  4946.         ; 10xx - 1fxx
  4947.         Dc.l    fx_arpeggio_init,fx_fine_porta_up,fx_fine_porta_down,fx_roll_and_vsl_init
  4948.         Dc.l    fx_fin1,fx_fin1,fx_fin1,fx_fin1
  4949.         Dc.l    fx_fin1,fx_fin1,fx_fin1,fx_fin1
  4950.         Dc.l    fx_fin1,fx_fin1,fx_fin1,fx_fin1
  4951.         ; a0xx - afxx
  4952.         Dc.l    fx_fin1,fx_fin1,fx_fin1,fx_fin1
  4953.         Dc.l    fx_fine_v_slup_l,fx_fine_v_sldown_l,fx_fine_mv_slup_l,fx_fine_mv_sldown_l
  4954.         Dc.l    fx_set_nbr_of_frames,fx_set_fine_speed,fx_pattern_delay,fx_fin1
  4955.         Dc.l    fx_fin1,fx_fin1,fx_fin1,fx_fin1
  4956.         ; b0xx - bfxx
  4957.         Dc.l    fx_tremor_init,fx_pattern_loop,fx_set_flags,fx_set_vol_env
  4958.         Dc.l    fx_set_ton_env,fx_set_pan_env,fx_set_vol_env_ko,fx_set_ton_env_ko
  4959.         Dc.l    fx_set_pan_env_ko,fx_fin1,fx_fine_sample_offset,fx_very_fine_sample_offset
  4960.         Dc.l    fx_inc_sample_pos,fx_dec_sample_pos,fx_init_autotempo,fx_init_autoperiod
  4961.         ; c0xx - cfxx
  4962.         Dc.l    fx_fin1,fx_fin1,fx_set_trk_lin_vol,fx_set_trk_exp_vol
  4963.         Dc.l    fx_fin1,fx_fin1,fx_fin1,fx_fin1
  4964.         Dc.l    fx_fine_t_v_slup_e,fx_fine_t_v_sldown_e,fx_fin1,fx_fin1
  4965.         Dc.l    fx_fin1,fx_fin1,fx_fin1,fx_fin1
  4966.  
  4967. fx_table_de_sauts1b:    ; 0xxx - fxxx
  4968.         Dc.l    fx_fin1,fx_fin1,fx_set_lin_volume,fx_set_exp_volume
  4969.         Dc.l    fx_set_balance,fx_set_lin_master_vol,fx_set_exp_master_vol,fx_roll_7_init
  4970.         Dc.l    fx_roll_and_vsl_and_sbl_init,fx_fin1,fx_fin1,fx_fin1
  4971.         Dc.l    fx_fin1,fx_fin1,fx_fin1,fx_fin1
  4972.  
  4973. fx_table_de_sauts2:    ; 00xx - 0fxx
  4974.         Dc.l    fx_fin_normale,fx_porta_up,fx_porta_down,fx_tone_porta
  4975.         Dc.l    fx_vibrato,fx_tone_porta_vib,fx_vib_tone_porta,fx_tremolo
  4976.         Dc.l    fx_fin_normale,fx_delay,fx_note_cut,fx_fin_normale
  4977.         Dc.l    fx_fin_normale,fx_fin_normale,fx_fin_normale,fx_fin_normale
  4978.         ; 10xx - 1fxx
  4979.         Dc.l    fx_arpeggio,fx_fin_normale,fx_fin_normale,fx_roll_and_vsl
  4980.         Dc.l    fx_v_slup_l,fx_v_sldown_l,fx_v_slup_e,fx_v_sldown_e
  4981.         Dc.l    fx_v_slup_l_tp,fx_v_sldown_l_tp,fx_v_slup_e_tp,fx_v_sldown_e_tp
  4982.         Dc.l    fx_v_slup_l_vib,fx_v_sldown_l_vib,fx_v_slup_e_vib,fx_v_sldown_e_vib
  4983.         ; a0xx - afxx
  4984.         Dc.l    fx_mv_slup_l,fx_mv_sldown_l,fx_fin_normale,fx_fin_normale
  4985.         Dc.l    fx_fin_normale,fx_fin_normale,fx_fin_normale,fx_fin_normale
  4986.         Dc.l    fx_fin_normale,fx_fin_normale,fx_fin_normale,fx_extra_fine_tone_porta
  4987.         Dc.l    fx_extra_fine_porta_up,fx_extra_fine_porta_down,fx_left_bal_move,fx_right_bal_move
  4988.         ; b0xx - bfxx
  4989.         Dc.l    fx_tremor,fx_fin_normale,fx_fin_normale,fx_fin_normale
  4990.         Dc.l    fx_fin_normale,fx_fin_normale,fx_fin_normale,fx_fin_normale
  4991.         Dc.l    fx_fin_normale,fx_fin_normale,fx_fin_normale,fx_fin_normale
  4992.         Dc.l    fx_fin_normale,fx_fin_normale,fx_autotempo,fx_autoperiod
  4993.         ; c0xx - cfxx
  4994.         Dc.l    fx_fin_normale,fx_fin_normale,fx_fin_normale,fx_fin_normale
  4995.         Dc.l    fx_t_v_slup_l,fx_t_v_sldown_l,fx_t_v_slup_e,fx_t_v_sldown_e
  4996.         Dc.l    fx_fin_normale,fx_fin_normale,fx_fin_normale,fx_fin_normale
  4997.         Dc.l    fx_fin_normale,fx_fin_normale,fx_fin_normale,fx_fin_normale
  4998.  
  4999. sin_table:                ; Table de 64 sinus (0->2pi)
  5000.         Dc.w    $00,$18,$31,$4a,$61,$78,$8d,$a1
  5001.         Dc.w    $b4,$c5,$d4,$e0,$eb,$f4,$fa,$fd
  5002.         Dc.w    $ff,$fd,$fa,$f4,$eb,$e0,$d4,$c5
  5003.         Dc.w    $b4,$a1,$8d,$78,$61,$4a,$31,$18
  5004.         Dc.w    -$00,-$18,-$31,-$4a,-$61,-$78,-$8d,-$a1
  5005.         Dc.w    -$b4,-$c5,-$d4,-$e0,-$eb,-$f4,-$fa,-$fd
  5006.         Dc.w    -$ff,-$fd,-$fa,-$f4,-$eb,-$e0,-$d4,-$c5
  5007.         Dc.w    -$b4,-$a1,-$8d,-$78,-$61,-$4a,-$31,-$18
  5008. square_table:            ; Table d'onde carrée de 64 éléments
  5009.         Dcb.w    32,$ff
  5010.         Dcb.w    32,-$ff
  5011. rampdown_table:            ; Table d'onde triangulaire de 64 éléments
  5012.     variable1:    Set    $ff
  5013.         Rept    64
  5014.         Dc.w    variable1
  5015.     variable1:    Set    variable1-8
  5016.         EndR
  5017.  
  5018.                 ; Table des périodes de chaque note,
  5019.                 ; avec les finetunes de 0 à +7
  5020. per_tab_load:    IncBin    'pertable.bin'
  5021. per_table:        Equ    per_tab_load+24*2    ; Décalage de 24 finetunes avant le C-0
  5022. vexp_2_lin:    IncBin    'vexp2lin.bin'    ; Les correspondances de volume pour instrument
  5023. vlin_2_exp:    IncBin    'vlin2exp.bin'
  5024. vexp_2_lin_master:    IncBin    'v_e2l_m.bin'    ; Pareil, pour le master
  5025. vexp_2_lin_track:    IncBin    'v_e2l_t.bin'    ; exp -> lin, pour le mix des pistes
  5026. vlin_2_exp_track:    IncBin    'v_l2e_t.bin'    ; lin -> exp, pour le mix des pistes
  5027.         Even
  5028. routine_dsp:    IncBin    'playdsp.p56'    ; Prog DSP
  5029. routine_dsp_lon:
  5030.         Even
  5031.  
  5032.  
  5033.  
  5034. *≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈*
  5035.  
  5036. ;--- Bloc de descritption de l'état actuel de chaque voie --------------------
  5037.         RsReset
  5038. onoff_t:        Rs.w    1    ; 0 = voie off, 1 = voie on
  5039. nbits_t:        Rs.w    1    ; 1 = 8 bits, 2 = 16 bits
  5040. fech_t:        Rs.w    1    ; Fréquence d'échantillonnage du sample (8363 Hz par défaut)
  5041. vol_t:        Rs.w    1    ; Volume courant (0-$800)
  5042. bal_t:        Rs.w    1    ; Balance courante ($000..$800..$FFF)
  5043. per_t:        Rs.w    1    ; Période courante (format "soundtracker" * $10)
  5044. adrsam_t:        Rs.l    1    ; Adresse du sample, paire
  5045. pos_t:        Rs.l    1    ; Position dans le sample
  5046. finepos_t:        Rs.w    1    ; Position précise (1/65536)
  5047. reppos_t:        Rs.l    1    ; Position de répétition du sample, paire
  5048. replen_t:        Rs.l    1    ; Longueur de bouclage du sample    , paire
  5049. rbuffer_t:        Rs.l    1    ; Adresse du buffer de répétition de l'instrument
  5050. protect_t:        Rs.w    1    ; *** pas d'utilité ici (sert pour les routines séparées)
  5051. interpol_t        Rs.w    1    ; 0 = pas d'interpolation pour le mixage de cette voie
  5052.     ; C'était tout ce dont la partie "mixage" avait besoin.
  5053.     ; Maintenant, ce dont le player a besoin :
  5054. c_n_t:        Rs.w    1    ; La note dans la ligne de commande          \
  5055. c_i_t:        Rs.w    1    ; L'instrument dans la ligne de commande      > * Ne pas dissocier
  5056. c_e_t:        Rs.w    1    ; L'effet+paramètre dans la ligne de commande/
  5057. c_v_t:        Rs.w    1    ; Le volume dans la ligne de commande       /
  5058. ninstr_t:        Rs.w    1    ; Numéro de l'instrument courant
  5059. norm_v_t:        Rs.w    1    ; Le volume par défaut du sample (0-$100)\ * Ne pas dissocier
  5060. norm_f_t:        Rs.w    1    ; Finetune du sample                     /
  5061. curnote_t:        Rs.w    1    ; La note courante
  5062. pernote_t:        Rs.w    1    ; Période courante (sans effet de vibrato)
  5063. vollnot_t:        Rs.w    1    ; Volume courant linéaire (sans tremolo) (0-$800)
  5064. volenot_t:        Rs.w    1    ; Volume courant exponentiel (sans tremolo)
  5065. portspd_t:        Rs.w    1    ; Vitesse du Portamento
  5066. tportspd_t:    Rs.w    1    ; Vitesse du Tone Portamento
  5067. note2sl_t:        Rs.w    1    ; Note à atteindre en cas de slide
  5068. per2sl_t:        Rs.w    1    ; Période de la note à atteindre en cas de tone porta
  5069. arpegcpt_t:    Rs.w    1    ; Compteur de l'arpeggio
  5070. vibspd_t:        Rs.b    1    ; Vitesse du vibrato
  5071. vibcpt_t:        Rs.b    1    ; Compteur du vibrato
  5072. vibamp_t:        Rs.b    1    ; Amplitude du vibrato
  5073. vibwav_t:        Rs.b    1    ; Forme d'onde du vibrato
  5074. tremspd_t:        Rs.b    1    ; Vitesse du tremolo
  5075. tremcpt_t:        Rs.b    1    ; Compteur du tremolo
  5076. tremamp_t:        Rs.b    1    ; Amplitude du tremolo
  5077. tremwav_t:        Rs.b    1    ; Forme d'onde du tremolo
  5078. rollspd_t:        Rs.b    1    ; Vitesse des roulements
  5079. rollcpt_t:        Rs.b    1    ; Compteur de roulements
  5080. rollnbr_t:        Rs.w    1    ; Nbr de roulements encore à jouer
  5081. delay_t:        Rs.w    1    ; Nbr de frames à attendre avant de jouer la note
  5082. cut_del_t:        Rs.w    1    ; Nbr de frames à attendre avant de couper la note
  5083. tremorc_t:        Rs.w    1    ; Compteur de tremor
  5084. tremor1_t:        Rs.b    1    ; Nbr de frames où la note n'est pas coupée
  5085. tremor2_t:        Rs.b    1    ; Période d'un tremor
  5086. ploopp_t:        Rs.w    1    ; Point de répétition pour l'effet Pattern loop
  5087. ploops_t:        Rs.w    1    ; Position      "       "      "      "     "
  5088. ploopn_t:        Rs.w    1    ; Nombre de répétitions pour l'effet Pattern loop
  5089. curbal_t:        Rs.w    1    ; Balance courante
  5090. instr_t:        Rs.w    1    ; Numéro de l'instrument courant
  5091. volsam_t:        Rs.w    1    ; Volume du sample courant
  5092. transp_t:        Rs.w    1    ; Transposition du sample courant
  5093. volslspd_t:    Rs.w    1    ; Vitesse du volume slide
  5094. fvolslspd_t:    Rs.w    1    ; Vitesse du fine volume slide
  5095. fportspd_t:    Rs.w    1    ; Vitesse du fine portamento
  5096. panslspd_t:    Rs.w    1    ; Vitesse du panning slide
  5097. nevol_t:        Rs.w    1    ; Numéro de l'enveloppe de volume
  5098. neton_t:        Rs.w    1    ; Numéro de l'enveloppe de tonalité
  5099. nepan_t:        Rs.w    1    ; Numéro de l'enveloppe de panning
  5100. pevol_t:        Rs.w    1    ; Position dans l'enveloppe de volume
  5101. peton_t:        Rs.w    1    ; Position dans l'enveloppe de tonalité
  5102. pepan_t:        Rs.w    1    ; Position dans l'enveloppe de panning
  5103. devol_t:        Rs.w    1    ; Décalage dans l'enveloppe de volume (32 pour l'Attack, 32 + ?? pour le Key Off)
  5104. deton_t:        Rs.w    1    ; Décalage dans l'enveloppe de tonalité
  5105. depan_t:        Rs.w    1    ; Décalage dans l'enveloppe de panning
  5106. ev_waitcpt_t:    Rs.w    1    ; Compteur de la commande Wait de l'enveloppe de volume
  5107. ev_loopcpt_t:    Rs.w    1    ; Compteur de boucle
  5108. ev_volume_t:    Rs.w    1    ; Volume courant
  5109. ev_volstep_t:    Rs.w    1    ; Pas du volume
  5110. ev_volspeed_t:    Rs.w    1    ; Vitesse du volume
  5111. ev_volcpt_t:    Rs.w    1    ; Compteur du volume
  5112. ev_tremoloflag_t:    Rs.b    1    ; Flag de tremolo (on/off)
  5113. ev_tremorflag_t:    Rs.b    1    ; Flag de tremor (on/off)
  5114. ev_tremolospeed_t:    Rs.b    1    ; Vitesse du tremolo
  5115. ev_tremolowidth_t:    Rs.b    1    ; Amplitude du tremolo
  5116. ev_tremolocpt_t:    Rs.b    1    ; Compteur du tremolo
  5117. ev_tremolotype_t:    Rs.b    1    ; Type de tremolo (0 = sin, 1 = carré, 2 = triangle)
  5118. ev_tremortime1_t:    Rs.b    1    ; Longueur du tremor Volume On
  5119. ev_tremortime2_t:    Rs.b    1    ; Longueur du tremor Volume Off
  5120. ev_tremorsection_t:    Rs.b    1    ; Section actuelle du tremor (0 = time1, 1 = time2)
  5121. ev_tremorcpt_t:    Rs.b    1    ; Compteur du tremor
  5122.         RsSet    (__rs+1)&-2    ; Equivaut à RsEven
  5123. et_waitcpt_t:    Rs.w    1    ; Compteur de la commande Wait de l'enveloppe de tonalité
  5124. et_loopcpt_t:    Rs.w    1    ; Compteur de boucle
  5125. et_tone_t:        Rs.w    1    ; Période courante
  5126. et_tonestep_t:    Rs.w    1    ; Pas de la période
  5127. et_tonespeed_t:    Rs.w    1    ; Vitesse de la période
  5128. et_tonecpt_t:    Rs.w    1    ; Compteur de la période
  5129. et_vibratoflag_t:    Rs.b    1    ; Flag de vibrato (on/off)
  5130. et_vibratospeed_t:    Rs.b    1    ; Vitesse du vibrato
  5131. et_vibratowidth_t:    Rs.b    1    ; Amplitude du vibrato
  5132. et_vibratocpt_t:    Rs.b    1    ; Compteur du vibrato
  5133. et_vibratotype_t:    Rs.b    1    ; Type de vibrato (0 = sin, 1 = carré, 2 = triangle)
  5134.         RsSet    (__rs+1)&-2    ; Equivaut à RsEven
  5135. ep_waitcpt_t:    Rs.w    1    ; Compteur de la commande Wait de l'enveloppe de panning
  5136. ep_loopcpt_t:    Rs.w    1    ; Compteur de boucle
  5137. ep_pan_t:        Rs.w    1    ; Panning courant
  5138. ep_panstep_t:    Rs.w    1    ; Pas du panning
  5139. ep_panspeed_t:    Rs.w    1    ; Vitesse du panning
  5140. ep_pancpt_t:    Rs.w    1    ; Compteur du panning
  5141.         RsSet    (__rs+1)&-2    ; Equivaut à RsEven
  5142. flag_new_note_t:    Rs.w    1    ; 1 si la note courante doit être "initialisée"
  5143.                 ; 0 si ça a déjà été fait (vbl suivante).
  5144. flag_autotempo_t:    Rs.w    1    ; 1 au 1er tick, 0 sinon.
  5145. flag_autoperiod_t:    Rs.w    1    ; 1 au 1er tick, 0 sinon.
  5146. mix_volume_t:    Rs.w    1    ; Volume normal linéaire: $1000
  5147. mix_volume_e_t:    Rs.w    1    ; Volume normal exponentiel: $C00
  5148. ltvolslspd_t:    Rs.w    1    ; Incrément du Linear track volume slide
  5149. etvolslspd_t:    Rs.w    1    ; Incrément de l'Exponential track volume slide
  5150. fetvolslspd_t:    Rs.w    1    ; Incrément du Fine exponential track volume slide
  5151. next_t:        Rs    0
  5152.  
  5153. ;--- Chunk de description des samples ----------------------------------------
  5154.         RsReset
  5155. chunkid_s:        Rs.l    1    ; 'SAMP'
  5156. chunksz_s:        Rs.l    1    ; Taille du chunk
  5157. number_s:        Rs.w    1    ; Numéro du sample
  5158. name_s:        Rs.b    28    ; Nom du sample
  5159. stereo_s:        Rs.w    1    ; 0 = mono, 1 = stereo
  5160. autobal_s:        Rs.w    1    ; Balance automatique, -1 = rien
  5161. nbits_s:        Rs.w    1    ; 1 = 8 bits, 2 = 16 bits
  5162. fech_s:        Rs.w    1    ; Fréquence d'échantillonnage du sample (8363 Hz par défaut)
  5163. length_s:        Rs.l    1    ; Longueur du sample
  5164. repeat_s:        Rs.l    1    ; Point de bouclage
  5165. replen_s:        Rs.l    1    ; Longueur de boucle
  5166. vol_s:        Rs.w    1    ; Volume   \ *** Ne pas dissocier
  5167. ftune_s:        Rs.w    1    ; Finetune /
  5168. codagev_s:        Rs.w    1    ; Version de codage
  5169. data_s:        Rs    0    ; Début des données du sample
  5170.  
  5171. ;--- Chunk de description des instruments ------------------------------------
  5172.         RsReset
  5173. chunkid_i:        Rs.l    1    ; 'INST'
  5174. chunksz_i:        Rs.l    1    ; Taille du chunk
  5175. number_i:        Rs.w    1    ; Numéro de l'instrument
  5176. name_i:        Rs.b    28    ; Nom de l'instrument
  5177. type_i:        Rs.w    1    ; Type de l'instrument (0 = sample)
  5178. vol_i:        Rs.w    1    ; Volume
  5179. autobal_i:        Rs.w    1    ; Autobalance
  5180. volenv_i:        Rs.w    1    ; Enveloppe de volume
  5181. tonenv_i:        Rs.w    1    ; Enveloppe de tonalité
  5182. panenv_i:        Rs.w    1    ; Enveloppe de panning
  5183.         Rs.b    10    ; Réservé
  5184. splnum_i:        Rs.b    128*2    ; Numéros de samples pour chaque note
  5185. transp_i:        Equ    splnum_i+1
  5186. next_i:        Rs    0
  5187.  
  5188. ;--- Chunk de description des patterns ---------------------------------------
  5189.         RsReset
  5190. chunkid_p:        Rs.l    1
  5191. chunksz_p:        Rs.l    1
  5192. number_p:        Rs.w    1
  5193. name_p:        Rs.b    16
  5194. codagev_p:        Rs.w    1
  5195. nlines_p:        Rs.w    1
  5196. ntrack_p:        Rs.w    1
  5197. data_p:        Rs    0
  5198.  
  5199. ;--- Chunk de description des enveloppes -------------------------------------
  5200.         RsReset
  5201. chunkid_e:        Rs.l    1    ; 'VENV', 'PENV' ou 'TENV'
  5202. chunksz_e:        Rs.l    1    ; Taille du chunk
  5203. number_e:        Rs.w    1    ; Numéro de l'enveloppe
  5204. name_e:        Rs.b    20    ; Nom de l'enveloppe
  5205. keyoffoffset_e:    Rs.w    1    ; Offset de la section Key Off par rapport à data_e
  5206. data_e:        Rs    0    ; Début des données de l'enveloppe
  5207.  
  5208. ;--- Diverses adresses -------------------------------------------------------
  5209.         RsReset
  5210. adr_samples:    Rs.l    NBRSAMPLES_MAXI    ; Adresse de 256 samples maxi (à partir de 0)
  5211. adr_pattern:    Rs.l    NBRPATTERNS_MAXI    ; Adresse de 256 patterns + 2 pour les patterns bidons
  5212. adr_module:    Rs.l    1    ; Adresse du module en mémoire
  5213. adr_instrset:    Rs.l    1    ; Adresse du descripteur des instruments (en partant de 0)
  5214. adr_evol:        Rs.l    NBRVOLENV_MAXI    ; Adresse de 64 enveloppes de volume
  5215. adr_eton:        Rs.l    NBRTONENV_MAXI    ; Adresse de 64 enveloppes de tonalité
  5216. adr_epan:        Rs.l    NBRPANENV_MAXI    ; Adresse de 64 enveloppes de panning
  5217. adr_song:        Rs.l    1    ; Adresse de la song
  5218. adr_next:        Rs    0
  5219.  
  5220. ;--- Bloc de renseignements sur le module en cours ---------------------------
  5221.         RsReset
  5222. mod_nbrtrack:    Rs.w    1    ; Nombre de pistes par pattern
  5223. mod_songlen:    Rs.w    1    ; Taille de la song
  5224. mod_songrep:    Rs.w    1    ; Point de répétition
  5225. mod_songpos:    Rs.w    1    ; Numéro de la position suivante dans la song
  5226. mod_numpat:    Rs.w    1    ; Numéro du pattern courant
  5227. mod_linepos:    Rs.w    1    ; Numéro de position de la ligne suivante
  5228. mod_cursongpos:    Rs.w    1    ; Numéro de la position actuelle
  5229. mod_curlinepos:    Rs.w    1    ; Numéro de la ligne actuelle
  5230. mod_flagnewpos:    Rs.w    1    ; -1 si la position a été changée par un Pos Jump, 0 sinon
  5231. mod_flagnewline:    Rs.w    1    ; -1 si la ligne a été changée par un Break Pattern, 0 sinon
  5232. mod_speed:        Rs.w    1    ; Vitesse courante (ticks/ligne)
  5233. mod_patrep:    Rs.w    1    ; Nombre de répétitions de la ligne
  5234. mod_nbrvbl:    Rs.w    1    ; Nombre de ticks écoulées depuis le début de la ligne
  5235. mod_tempo:        Rs.w    1    ; Tempo en BPM
  5236. mod_next:        Rs    0
  5237.  
  5238. ;--- Informations sur un sample à digitaliser --------------------------------
  5239.         RsReset
  5240. rec_adresse:    Rs.l    1    ; Adresse de début d'enregistrement
  5241. rec_longueur:    Rs.l    1    ; Longueur du sample à échantillonner
  5242. rec_position:    Rs.l    1    ; Position courante d'échantillonnage
  5243. rec_flag_loop:    Rs.w    1    ; bit 0 = Echantillonner en boucle (jusqu'à demande d'arrêt)
  5244.                 ; bit 1 = Indique si on a déjà bouclé
  5245. rec_nbits:        Rs.w    1    ; Nombre d'octets par sample (1 ou 2)
  5246. rec_canal:        Rs.w    1    ; Canal d'enregistrement (1=L, 2=R, 3=L+R).
  5247. rec_trigger:    Rs.w    1    ; Valeur mini à recevoir pour commencer l'éch. (/32768)
  5248. rec_frequence:    Rs.w    1    ; Fréquence CODEC (valeur.w à placer en $FFFF8934)
  5249.  
  5250.         IfNE    MIDI_IN
  5251.  
  5252. ;--- Pour chaque piste du tableau d'entrées Midi -----------------------------
  5253.         RsReset
  5254. midi_ts_channel:    Rs.w    1    ; Numéro du canal Midi auquel est associé cette piste
  5255. midi_ts_velocity:    Rs.w    1    ; Vélocité (0-128), (0 ou -1) = piste libre, -1 = Note off à l'instant
  5256. midi_ts_note:    Rs.w    1    ; Hauteur de la note
  5257. midi_ts_pitch:    Rs.w    1    ; Hauteur du pitch
  5258. midi_ts_flags:    Rs.w    1    ; Bit 0 = mise à jour de la note
  5259. midi_ts_pat_note:    Rs.b    1    ; \ Note équivalente dans le pattern
  5260. midi_ts_pat_instr:    Rs.b    1    ;  \
  5261. midi_ts_pat_effect:    Rs.w    1    ;  / *** Ne pas dissocier
  5262. midi_ts_pat_volume:    Rs.b    1    ; /
  5263.         RsSet    (__rs+1)&-2    ; Equivaut à RsEven
  5264. midi_ts_next:    Rs    0
  5265.  
  5266. ;--- Structure IOREC ---------------------------------------------------------
  5267.         RsReset
  5268. iorec_ibuf:    Rs.l    1    ; Adresse du buffer
  5269. iorec_ibufsz:    Rs.w    1    ; Taille du buffer
  5270. iorec_ibufhd:    Rs.w    1    ; Prochaine position d'écriture
  5271. iorec_ibuftl:    Rs.w    1    ; Prochaine position de lecture
  5272. iorec_ibuflow:    Rs.w    1    ; Masque pour Xon
  5273. iorec_ibufhi:    Rs.w    1    ; Masque pour Xoff
  5274.  
  5275.         EndC
  5276.  
  5277.  
  5278.  
  5279. *≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈*
  5280.  
  5281.     Bss
  5282.  
  5283. nbrvoies:        Ds.w    1    ; Nombre de voies à mixer
  5284. dsp_ability:    Ds.w    1    ; Numéro de programme pour le DSP
  5285. current_track:    Ds.w    1    ; Piste courante
  5286. dsp_plein:        Ds.w    1    ; A 0 si aucune voie n'a été envoyée.
  5287. master_vol:    Ds.w    1    ; Le master volume (0 - $1000), $100 pour 16 voies
  5288. vblsize:        Ds.w    1    ; Nbr de samples/VBL (1000 en moyenne) \ * Ne pas
  5289. vblsize_frac:    Ds.w    1    ; Précision fractionnaire              / dissocier !!!
  5290. vblcurrentsize:    Ds.w    1    ; Nbr de samples/VBL pour cette VBL   \ * Ne pas
  5291. vblcurrentsize_frac:    Ds.w    1    ; Compteur en précision fractionnaire / dissocier !!!
  5292. vblnumber:        Ds.w    1    ; Nbr de VBL pour tenir un tick
  5293. vblcpt:        Ds.w    1    ; Compteur de VBL
  5294. cpu_time_pourcent:    Ds.w    1    ; Pourcentage de temps machine occupé
  5295. new_note_buffer:    Ds.b    NBRVOIES_MAXI*6    ; Notes en attente pour la
  5296.                 ; prochaine ligne (1 flag + 5 octets de note)
  5297. flag_stop_voices:    Ds.w    1    ; 1 = Faire taire les voies, attendre le retour
  5298.                 ; à 0 avant de changer les paramètres de la song
  5299. flag_the_end:    Ds.w    1    ; 1 = On arrête le replay
  5300. flag_mt_display:    Ds.w    1    ; 1 = affiche les bandes de temps-machine
  5301. flag_new_notes:    Ds.w    1    ; 1 = On a des notes à rajouter (new_note_buffer)
  5302. flag_overflow:    Ds.w    1    ; 1 = il y a eu surcharge des voies.
  5303.                 ; Ce flag n'est pas remis automatiquement à 0
  5304. current_edit_mode:    Ds.w    1    ; 0 = rien, 1 = Edit
  5305. current_play_mode:    Ds.w    1    ; 0 = stop, 1 = Play song, 2 = Play Pattern
  5306. real_pattern_number:    Ds.w    1    ; Numéro réel du pattern courant (Edit Mode/Stop)
  5307. real_line_number:    Ds.w    1    ; Numéro réel de la ligne courante (Edit Mode/Stop)
  5308. sauvegarde_timer:    Ds.l    1    ; Adresse de l'ancien timer A, C ou D
  5309. adresse_interruption:    Ds.l    1    ; Adresse de l'interruption (doit contenir
  5310.                 ; soundtracking_kernel)
  5311. adr_adr_inter:    Ds.l    1    ; Contient adresse_interruption ou le vecteur DSP
  5312.  
  5313.         IfNE    MIDI_IN
  5314. midi_in_on:    Ds.w    1    ; 1 = Gestion MIDI IN
  5315. midi_in_gfa_playline:    Ds.w    1    ; 1 = Signale au GfA que le MIDI a reçu des notes
  5316.                 ; en mode Edit sans Play.
  5317. midi_in_sync_flag:    Ds.w    1    ; 1 = Syncronisation en entrée
  5318. midi_in_sync_cpt:    Ds.w    1    ; Compteur d'impulsions entre chaque ligne
  5319. midi_current_status:    Ds.w    1    ; Numéro du status Midi courant
  5320. midi_old_status:    Ds.w    1    ; Numéro du status Midi avant un System Message
  5321. midi_current_channel:    Ds.w    1    ; Numéro du canal Midi courant
  5322. midi_nbr_bytes_recvd:    Ds.w    1    ; Nombre d'octets de donnée déjà reçus
  5323. midi_old_nbrbytesrec:    Ds.w    1    ; Nombre d'octets reçus avant un System Message
  5324. midi_iorec_adr:    Ds.l    1    ; Adresse du bloc IOREC
  5325. midi_data_buffer:    Ds.b    MIDI_IN_DATA_BUF_LEN    ; Octet de status + octets des données
  5326. midi_instr_map:    Ds.w    MIDI_NBR_CHANNELS    ; Instrument du tracker assigné à chaque canal
  5327. midi_in_noteoff_flag:    Ds.w    MIDI_NBR_CHANNELS    ; 0 = Note Off totalement ignoré
  5328.                     ; 1 = Note Off pris en compte mais non transcrit sur la partition
  5329.                     ; -1 = Note Off mis sur les patterns
  5330. midi_in_velo_flag:    Ds.w    MIDI_NBR_CHANNELS    ; 0 = Vélocité ignorée
  5331.                     ; -1 = Vélocité mise sur les patterns
  5332. midi_track_state:    Ds.b    NBRVOIES_MAXI*midi_ts_next    ; Activité des pistes
  5333.         EndC
  5334.  
  5335. ;*** v--- Ne pas changer l'ordre de ce groupe ---v *** (à cause du GfA)
  5336. songrecord_state:    Ds.w    1    ; Etat de l'enregistrement d'un module via le DMA
  5337. songrecord_startpos:    Ds.w    1    ; Position de début de l'enregistrement
  5338. songrecord_startline:    Ds.w    1    ; Ligne de début de l'enregistrement
  5339. songrecord_endpos:    Ds.w    1    ; Position de fin de l'enregistrement
  5340. songrecord_endline:    Ds.w    1    ; Ligne de fin de l'enregistrement
  5341. songrecord_startadr:    Ds.l    1    ; Adresse de début du buffer
  5342. songrecord_endadr:    Ds.l    1    ; Adresse de fin du buffer
  5343. songrecord_state2:    Ds.w    1    ; 0 = On peut enregistrer au prochain passage
  5344.                 ; 1 = il reste 1 boucle à faire avant d'enregistrer
  5345. songrecord_lastadr:    Ds.l    1    ; Adresse courante du buffer quand l'enregistrement
  5346.                 ; se termine
  5347. songrecord_prediv:    Ds.w    1    ; Prédiviseur de fréquence DMA pour la vitesse de rec.
  5348. songrecord_recfreq:    Ds.w    1    ; Fréquence d'échantillonnage en Hz
  5349. songrecord_sprediv:    Ds.w    1    ; Sauvegarde de l'ancien prédiviseur
  5350. songrecord_srecfreq:    Ds.w    1    ; Sauvegarde de l'ancienne fréquence de replay
  5351. songrecord_realtime:    Ds.w    1    ; 0 = sans écoute, 1 = temps réel (synchro MIDI possible)
  5352. songrecord_bufpos:    Ds.l    1    ; Position dans le buffer d'enregistrement
  5353. songrecord_flag:    Ds.w    1    ; 0 = mode normal, 1 = mode d'enregistrement différé
  5354. songrecord_flag2:    Ds.w    1    ; 0 = pas de donnée reçue, 1 = on peut faire le dump
  5355.  
  5356. module_inf1:    Ds.b    adr_next
  5357. module_inf2:    Ds.b    mod_next
  5358. info_track:    Ds.b    NBRVOIES_MAXI*next_t    ; Informations sur les 32 voies (maxi)
  5359. sample_vide:    Ds.l    1    ; Un sample vide
  5360. repeatbuffer:    Ds.b    NBRSAMPLES_MAXI*1024    ; Buffers de répétition de 255 samples maxi + 1 vide
  5361.  
  5362.  
  5363.  
  5364. *≈≈≈ FIN ≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈*
  5365.