home *** CD-ROM | disk | FTP | other *** search
/ Groovy Bytes: Behind the Moon / groovybytes.iso / GROOVY / SND_TOOL / CRYS250.ZIP / CRYS26.ASM < prev    next >
Encoding:
Assembly Source File  |  1995-01-11  |  71.7 KB  |  4,351 lines

  1. ;**************************************************************************
  2. ;*    mini player de mod sur le PC speaker ou le port parallèle ou même
  3. ;*     une sound blaster
  4. ;* Programmé par Sébastien Granjoux
  5. ;* Commencé en février 93
  6. ;* Dernière modif 11/01/95
  7. ;*
  8.  
  9. IDEAL
  10. P386N
  11.  
  12. INCLUDE "CRYSTAL.INC"
  13.  
  14.  
  15. PUBLIC    CutVoice
  16. PUBLIC    MasterVol
  17.  
  18. PUBLIC    FLOADMOD
  19. PUBLIC    MLOADMOD
  20. PUBLIC    OLOADMOD
  21. PUBLIC    MAKEMOD
  22.  
  23. PUBLIC    UNLOADMOD
  24. PUBLIC  STARTMOD
  25. PUBLIC    STOPMOD
  26. PUBLIC    SETMOD
  27. PUBLIC    DETECTSND
  28.  
  29. PUBLIC    CHANGEVOL
  30.  
  31. PUBLIC    Nb_voice
  32. PUBLIC    Voix1
  33. PUBLIC    Timer
  34. PUBLIC    TAB_ARPEGE
  35. PUBLIC    Partition
  36. PUBLIC    Position
  37. PUBLIC    Ligne
  38. PUBLIC    Music
  39. PUBLIC    Instruments
  40. PUBLIC    Sequence
  41. PUBLIC    Tempo
  42. PUBLIC    Speed
  43.  
  44. SEGMENT CSEG PARA PRIVATE USE16 'CODE'
  45.  
  46. ASSUME    cs:CSEG,ds:CSEG
  47.  
  48. BUF_LEN        EQU 512*2*2
  49.  
  50. BUF_SOUND    DB BUF_LEN DUP(?)
  51.         DB BUF_LEN DUP(?)
  52. BUF_SOUNDBIS    DB BUF_LEN DUP(?)
  53.  
  54. Ptr_sound       DW OFFSET BUF_SOUND+BUF_LEN
  55. Page_sound    DW OFFSET BUF_SOUND
  56. Page_end    DD ?
  57.  
  58. SAMPLE_BORDER    EQU    732+32    ;permet d'éviter les grésillements
  59.  
  60. STRUC INSTRUMENT
  61.     iname    DB 22 DUP (0)
  62.     length  DW 0
  63.     volume  DB 0
  64.     fintune DB 0
  65.     adrseg    DW 0    ; correspond à l'adresse de répétition au début
  66.     lenrep  DW 0
  67.     adr    DW 0    ; non utilisé
  68. ENDS
  69.  
  70. Instruments INSTRUMENT 31 DUP (?)
  71. Nb_instrument    DB ?
  72. Nb_voice    DW 0204h    ;puissance de deux et nombre de voix
  73.  
  74. Sequence    DB 130 DUP (?)      ;sequence
  75. Partition       DW ?
  76.  
  77. Music        DB 20 DUP(?)
  78.  
  79. ;***************************************************************************
  80. ;*    Charge un fichier MOD en mémoire
  81. ;*
  82. ;* Entrée:
  83. ;*    DS:DX    adresse longue du nom du fichier mod
  84. ;*
  85. ;* Sortie:
  86. ;*    AX    code d'erreur si C=1
  87. ;*
  88.  
  89. PROC    Floadmod FAR
  90. LOCAL    posseq:WORD,pospat:WORD,nulsamp:WORD=locvar
  91.  
  92.     mov     al,00h
  93. usemodfile:
  94.     enter    locvar,0
  95.     push    ds
  96.     push    si
  97.     push    di
  98.  
  99.     lds    dx,[ss:bp+6]
  100.  
  101.     mov     ah,3dh        ;ouvre la fichier
  102.     call    fileint
  103.     jc      @@error
  104.  
  105.     mov    bx,ax
  106.  
  107.     mov    ax,CSEG
  108.     mov    ds,ax
  109.  
  110.     mov    [word ptr cs:Ligne],1024
  111.     mov    [word ptr cs:Position],255
  112.     mov     [byte ptr cs:Tempo],06h
  113.     mov    [byte ptr cs:PatternDelay],0
  114.     mov    [word ptr cs:Time],0100h
  115.     mov    [word ptr cs:Speed],256
  116.  
  117.     mov    ah,3fh
  118.     mov    cx,20
  119.     mov    dx,OFFSET Music
  120.     call    fileint
  121.     jc    @@error
  122.  
  123.     mov    ax,4200h
  124.     xor    cx,cx
  125.     mov    dx,438h
  126.     call    fileint
  127.     jc    @@error
  128.  
  129.     mov    ah,3fh
  130.     mov    cx,4
  131.     mov    dx,OFFSET Sequence
  132.     call    fileint
  133.     jc    @@error
  134.     mov    [Nb_voice],0204h
  135.     cmp    [dword ptr ds:OFFSET Sequence],'.K.M'
  136.     je    @@mod31
  137.     cmp    [dword ptr ds:OFFSET Sequence],'4TLF'
  138.     je    @@mod31
  139.     cmp    [dword ptr ds:OFFSET Sequence],'8TLF'
  140.     je    @@mod31
  141.     cmp    [dword ptr ds:OFFSET Sequence],'NHC8'
  142.         je    @@mode8
  143.     cmp    [dword ptr ds:OFFSET Sequence],'NHC6'
  144.     je    @@mode6
  145.     mov    [Nb_instrument],15
  146.     mov    [posseq],1d6h
  147.     mov    [pospat],258h
  148.     jmp    @@loadinst
  149. @@mode6:
  150.     mov    [Nb_voice],0006h
  151.     jmp    @@mod31
  152. @@mode8:
  153.     mov    [Nb_voice],0308h
  154. @@mod31:
  155.     mov    [Nb_instrument],31
  156.     mov    [posseq],3b6h
  157.     mov    [pospat],43ch
  158.  
  159. @@loadinst:
  160.  
  161.     mov     ax,4200h    ; se place sur les instruments
  162.     xor    cx,cx
  163.     mov    dx,20
  164.     call    fileint
  165.     jc    @@error
  166.  
  167.     mov    cl,[Nb_instrument]
  168.     mov    di,OFFSET Instruments
  169. @@next_inst:
  170.     shl    ecx,16
  171.     mov     ah,3fh
  172.     mov    cx,30
  173.     mov    dx,di
  174.     call    fileint
  175.     jc    @@error
  176.  
  177.     rol    [(INSTRUMENT PTR ds:di).length],8    ; passe en notation intel
  178.     cmp    [(INSTRUMENT PTR ds:di).length],32768-SAMPLE_BORDER/2
  179.     jb    @@no_big_sample
  180.     mov    ax,TOO_BIG_SAMP
  181.     stc
  182.     jmp    @@error
  183. @@no_big_sample:
  184.     shl    [(INSTRUMENT PTR ds:di).length],1
  185.  
  186.     rol    [word ptr ((INSTRUMENT PTR ds:di).volume)],8
  187.     sar    [(INSTRUMENT PTR ds:di).fintune],4
  188.  
  189.     rol    [(INSTRUMENT PTR ds:di).lenrep],8
  190.     shl    [(INSTRUMENT PTR ds:di).lenrep],1
  191.     cmp    [(INSTRUMENT PTR ds:di).lenrep],2
  192.     jbe    @@no_repeat
  193.  
  194.     rol    [(INSTRUMENT PTR ds:di).adrseg],8
  195.     shl    [(INSTRUMENT PTR ds:di).adrseg],1
  196.  
  197.     mov    ax,[(INSTRUMENT PTR ds:di).length]
  198.     sub    ax,[(INSTRUMENT PTR ds:di).lenrep]
  199.     mov    [(INSTRUMENT PTR ds:di).adrseg],ax
  200.  
  201.     jmp    @@end_inst
  202.  
  203. @@no_repeat:
  204.  
  205.     mov    ax,[(INSTRUMENT PTR ds:di).length]
  206.     dec    ax
  207.     mov    [(INSTRUMENT PTR ds:di).adrseg],ax
  208.  
  209. @@end_inst:
  210.     add    di,SIZE INSTRUMENT
  211.     shr    ecx,16
  212.     dec    cl
  213.     jne    @@next_inst
  214.  
  215.     mov    ax,4200h
  216.     xor    cx,cx
  217.     mov    dx,[posseq]
  218.     call    fileint
  219.     jc    @@error
  220.  
  221.     mov    si,OFFSET Sequence
  222.     mov     ah,3fh  ;lecture sequence
  223.     mov     cx,130
  224.     mov     dx,si
  225.     call    fileint
  226.     shl     ebx,16   ;compte le nombre de pattern dans la sequence
  227.  
  228.  
  229.     mov     cl,128    ; pour certain mod [ds:si] n'est pas significatif (PRELUDE)
  230.     add     si,2
  231. @@nb_pattern:
  232.     lods    [byte ptr ds:si]
  233.     cmp     bl,al
  234.     jae     @@no_new_pattern
  235.     mov     bl,al
  236. @@no_new_pattern:
  237.     dec     cl
  238.     jne     @@nb_pattern
  239.  
  240.     inc     bl
  241.     cmp    bl,64
  242.     jbe    @@no_too_many_pat
  243.     mov    ax,TOO_MANY_PAT
  244.     stc
  245.     jmp    @@error
  246. @@no_too_many_pat:
  247.     mov    al,[ds:OFFSET Nb_voice]
  248.     mul    bl
  249.     mov    cl,4
  250.     shl    ax,cl
  251.     mov    bx,ax
  252.  
  253.     push    ds
  254.     mov     ah,48h  ;reserve de la place pour les patterns
  255.     int    21h
  256.         jc      @@error
  257.     mov    [Partition],ax
  258.     mov    ds,ax
  259.  
  260.     mov    cx,bx
  261.     shl    ecx,20
  262.  
  263.     shr    ebx,16    ;se place sur les patterns
  264.     mov    ax,4200h
  265.     xor    cx,cx
  266.     mov    dx,[pospat]
  267.     call    fileint
  268.  
  269.     mov     ah,3fh        ; lecture des patterns
  270.     shr    ecx,16
  271.     xor    dx,dx
  272.     call    fileint
  273.     jc      @@error
  274.  
  275.     shr     cx,2        ; adaptation des notes
  276.     xor     si,si        ;  inversion des voix
  277.  
  278. @@frequence:
  279.     rol     ecx,16
  280.     lods    [dword ptr ds:si]
  281.     rol     ax,8
  282.     rol    eax,16
  283.     mov     [dword ptr ds:si-4],eax
  284.     rol     ecx,16
  285.     dec    cx
  286.     jne    @@frequence
  287.  
  288.  
  289.     shl    ebx,16
  290.  
  291.     mov    bx,SAMPLE_BORDER  ;créer un sample nul
  292.     add    bx,15
  293.     shr    bx,4
  294.     mov    ah,48h
  295.     int    21h
  296.     jc    @@error
  297.  
  298.     push    di
  299.     mov    es,ax
  300.     mov    [nulsamp],ax
  301.  
  302.     mov    cx,SAMPLE_BORDER
  303.     rep    movsb
  304.  
  305.     pop    di
  306.     pop    es        ; chargement des samples
  307.  
  308.     mov    di,OFFSET Instruments
  309.     mov     cl,[es:Nb_instrument]           ;lecture des samples
  310. @@sample:
  311.     shl     ecx,16
  312.     mov    cx,[(INSTRUMENT PTR es:di).length]
  313.     or    cx,cx
  314.     jne    @@res_mem
  315.  
  316.     mov    ax,[nulsamp]
  317.     mov    [(INSTRUMENT PTR es:di).adrseg],ax
  318.     mov    [(INSTRUMENT PTR es:di).lenrep],32
  319.     mov    [(INSTRUMENT PTR es:di).length],32
  320.     jmp    @@no_sample
  321. @@res_mem:
  322.     mov    bx,cx
  323.     add    bx,SAMPLE_BORDER
  324.     add    bx,15
  325.     shr    bx,4
  326.     mov    ah,48h
  327.     int    21h
  328.     jc    @@error
  329.  
  330.     shr    ebx,16
  331.     mov    ds,ax
  332.     mov     ah,3fh
  333.     xor    dx,dx
  334.     call    fileint
  335.     jc      @@error
  336.     shl    ebx,16
  337.  
  338.     mov    cx,SAMPLE_BORDER
  339.     mov    si,[(INSTRUMENT PTR es:di).adrseg]
  340.     mov    bx,[(INSTRUMENT PTR es:di).length]
  341.  
  342.     cmp    [(INSTRUMENT PTR es:di).lenrep],2
  343.     ja    @@next_byte
  344.     mov    [byte ptr ds:si],0
  345.     mov    [(INSTRUMENT PTR es:di).lenrep],32
  346. @@next_byte:
  347.     lodsb
  348.     mov    [ds:bx],al
  349.     inc    bx
  350.     dec    cx
  351.     jne    @@next_byte
  352.  
  353.     mov    [(INSTRUMENT PTR es:di).adrseg],ds
  354.  
  355.     dec    bx
  356.     cmp    bx,si
  357.     jne    @@no_sample
  358.     add    [(INSTRUMENT PTR es:di).length],32
  359.  
  360. @@no_sample:
  361.     add     di,SIZE INSTRUMENT
  362.     shr     ecx,16
  363.     dec     cl
  364.     jne     @@sample
  365.  
  366.     shr    ebx,16
  367.     mov     ah,3eh  ;fermeture du fichier
  368.     call    fileint
  369.     jc      @@error
  370.  
  371.     xor    ax,ax
  372.     clc
  373. @@error:
  374.     pop    di
  375.     pop    si
  376.     pop    ds
  377.  
  378.     leave
  379.     ret    4
  380.  
  381. ENDP
  382.  
  383. filepos        DD    0
  384. filestart    DD    0
  385. Handle        DW    0
  386.  
  387. ;***************************************************************************
  388. ;*
  389. ;*    Cette fonction permet de préparer un fichier mod déjà chargé en
  390. ;*    mémoire à être jouer
  391. ;*
  392. ;* Entrée:
  393. ;*    dans la pile adresse de la zone où on a déjà charger le mod
  394.  
  395. PROC    Mloadmod FAR
  396. LOCAL    posseq:WORD,pospat:WORD,nulsamp:WORD=locvar
  397.  
  398.     mov    al,3
  399.     jmp    usemodfile
  400.  
  401. ENDP
  402.  
  403. ;***************************************************************************
  404. ;*
  405. ;*    Cette fonction permet de préparer un fichier mod placé en overlay
  406. ;*    à être jouer
  407. ;*
  408. ;* Entrée:
  409. ;*    dans la pile position de l'overlay par rapport au début du fichier
  410.  
  411. PROC    Oloadmod FAR
  412. LOCAL    posseq:WORD,pospat:WORD,nulsamp:WORD=locvar
  413.  
  414.     mov    al,4
  415.     jmp    usemodfile
  416.  
  417. ENDP
  418.  
  419. ;***************************************************************************
  420. ;*    Cette procédure remplace les fonctions de DOS pour l'acces aux
  421. ;*    fichier et permette d'accéder à un fichier déjà chargé en mémoire
  422. ;*    de manière transparente,les arguments sont les même que les
  423. ;*    fonctions DOS correspondante sauf pour open où DS:DX ne représente
  424. ;*    pas le nom du fichier mais l'adresse où est déjà chargé le fichier
  425. ;*    et AL doit contenir 3 pour avoir un mode en lecture avec ce nouveau
  426. ;*    mode,deplus on ne peut avoir qu'un fichier ouvert dans ce mode
  427. ;* ATTENTION la fonction seek ne peut se déplacer par rapport à la fin
  428. ;*    du fichier,deplus les fichiers sont limité à 1Mo, et les lecture
  429. ;*    ne peuvent lire des blocs de plus de 65520 octet
  430.  
  431.  
  432. PROC    fileint
  433.  
  434.     cmp     ah,3dh
  435.     jne    @@not_open
  436.  
  437.     cmp    al,03h
  438.     je    @@openmem
  439.     cmp    al,04h
  440.     je    @@openovl
  441.     int    21h
  442.     ret
  443.  
  444. @@openovl:
  445.     push    ds
  446.     mov    [word ptr cs:OFFSET filestart],dx
  447.     mov    [word ptr cs:OFFSET filestart+2],ds
  448.  
  449.     mov    ah,51h
  450.     int    21h
  451.     jc    @@ovl_error
  452.     mov    ds,bx
  453.     mov    ax,[ds:2Ch]
  454.     mov    ds,ax
  455.     push    es
  456.     mov    dx,di
  457.     mov    es,ax
  458.     xor    di,di
  459.     mov    cx,8000h
  460.     xor    al,al
  461. @@next_envstr:
  462.     repne    scasb
  463.     cmp    [byte ptr es:di],0
  464.     jne    @@next_envstr
  465.     pop    es
  466.     mov    ax,[ds:di+1]
  467.     xchg    di,dx
  468.     or    ax,ax
  469.     je    @@ovl_error
  470.     add    dx,3
  471.     mov        ax,3d00h
  472.     int    21h
  473.     jnc    @@ok
  474. @@ovl_error:
  475.     pop    ds
  476.     mov    [cs:filestart],0
  477.     ret
  478. @@ok:
  479.     mov    bx,ax
  480.     mov    ax,4200h
  481.     mov    dx,[word ptr cs:OFFSET filestart]
  482.     mov    cx,[word ptr cs:OFFSET filestart+2]
  483.     int    21h
  484.     jc    @@ovl_error
  485.     pop    ds
  486.     mov    ax,bx
  487.     ret
  488.  
  489. @@openmem:
  490.     cmp    [cs:Handle],0
  491.     jne    @@no_handle
  492.  
  493.     mov    ax,dx
  494.     and    ax,0fh
  495.     mov    [word ptr cs:OFFSET filepos],ax
  496.     mov    [word ptr cs:OFFSET filestart],ax
  497.     mov    ax,ds
  498.     shr    dx,4
  499.     add    ax,dx
  500.     mov    [word ptr cs:OFFSET filepos+2],ax
  501.     mov    [word ptr cs:OFFSET filestart+2],ax
  502.  
  503.     mov    ax,0ffffh
  504.     mov    [cs:Handle],ax
  505.     clc
  506.     ret
  507.  
  508. @@no_handle:
  509.     stc
  510.     mov    ax,4
  511.     ret
  512.  
  513. @@not_open:
  514.     cmp    bx,[cs:Handle]
  515.     je    @@memint
  516.     cmp    ax,4200h
  517.     jne    @@no_begin_seek
  518.     add    dx,[cs:OFFSET filestart]
  519.     adc    cx,[cs:OFFSET filestart+2]
  520. @@no_begin_seek:
  521.     int    21h
  522.     ret
  523.  
  524. @@memint:
  525.     cmp    ah,3fh
  526.     je    @@fread
  527.     cmp    ah,42h
  528.     je    @@fseek
  529.     cmp    ah,3eh
  530.     je    @@fclose
  531.  
  532.     int    21h
  533.     ret
  534.  
  535. @@fclose:
  536.  
  537.     mov    [cs:filestart],0
  538.     mov    [cs:Handle],0
  539.     clc
  540.     ret
  541.  
  542. @@fread:
  543.     push    cx
  544.     push    di
  545.     push    si
  546.     push    es
  547.     push    ds
  548.     mov    ax,ds
  549.     mov    di,dx
  550.     shr    di,4
  551.     add    ax,di
  552.     mov    es,ax
  553.  
  554.     lds    ax,[dword ptr cs:OFFSET filepos]
  555.     mov    si,ax
  556.  
  557.     add    ax,cx
  558.     mov    di,ax
  559.     and    ax,0fh
  560.     mov    [word ptr cs:OFFSET filepos],ax
  561.     shr    di,4
  562.     add    [word ptr cs:OFFSET filepos+2],di
  563.  
  564.     mov    di,dx
  565.     and    di,000fh
  566.  
  567.     rep    movsb
  568.  
  569.     pop    ds
  570.     pop    es
  571.     pop    si
  572.     pop    di
  573.     pop    cx
  574.  
  575.     clc
  576.     ret
  577.  
  578. @@fseek:
  579.     cmp    al,0
  580.     jne    @@from_current
  581.     mov    ax,[word ptr cs:OFFSET filestart]
  582.     mov    [word ptr cs:OFFSET filepos],ax
  583.     mov    ax,[word ptr cs:OFFSET filestart+2]
  584.     mov    [word ptr cs:OFFSET filepos+2],ax
  585. @@from_current:
  586.     push    cx
  587.     add    dx,[word ptr cs:OFFSET filepos]
  588.     adc    cx,0
  589.     mov    ax,dx
  590.     and    ax,0fh
  591.     mov    [word ptr cs:OFFSET filepos],ax
  592.     shr    dx,4
  593.     shl    cx,12
  594.     or    dx,cx
  595.     add    [word ptr cs:OFFSET filepos+2],dx
  596.     pop    cx
  597.  
  598.     mov    ax,[word ptr cs:OFFSET filepos+2]
  599.     mov    dx,ax
  600.     shl    ax,4
  601.     or    ax,[word ptr cs:OFFSET filepos]
  602.     shr    dx,12
  603.  
  604.     clc
  605.     ret
  606. ENDP
  607.  
  608. ;***************************************************************************
  609. ;*      Libère la mémoire prise par la fonction loadmod utilise en ds:di
  610. ;*      l'adresse des instruments et en ds:si l'adresse de la partition
  611.  
  612. PROC    Unloadmod FAR
  613.  
  614.     push    ds
  615.     push    es
  616.     push    si
  617.     push    di
  618.     mov    ax,CSEG
  619.     mov    ds,ax
  620.  
  621.     mov     ax,[Partition]
  622.     mov    es,ax
  623.     mov    ah,49h
  624.     int    21h
  625.  
  626.     mov    di,OFFSET Instruments
  627.     mov    cl,[Nb_instrument]
  628. @@sample:
  629.     mov     ax,[(INSTRUMENT PTR ds:di).adrseg]
  630.     or    ax,ax
  631.     je      @@no_sample
  632.     mov     es,ax
  633.     mov    ah,49h
  634.     int     21h
  635. @@no_sample:
  636.     add       di,SIZE INSTRUMENT
  637.     dec    cl
  638.     jne    @@sample
  639.  
  640.     pop    di
  641.     pop    si
  642.     pop    es
  643.     pop    ds
  644.  
  645.     ret
  646.  
  647. ENDP
  648.  
  649. STRUC DEVICE
  650.     detect    DB 18 DUP (0)
  651.     init    DW 0
  652.     start    DW 0
  653.     sound    DW 0
  654.     stop    DW 0
  655.     make    DW 0
  656.     port    DW 0
  657.     irq    DB 0
  658.     dma    DB 0
  659. ENDS
  660.  
  661. Devices:        DEVICE <'$',OFFSET setnul,OFFSET soundnul,OFFSET soundnul,OFFSET soundnul,OFFSET soundnul,0,0,0>
  662.         DEVICE <'$',OFFSET setspk,OFFSET startspk,OFFSET soundspk,OFFSET stopspk,OFFSET makespk,0,0,0>
  663.         DEVICE <'DACs=p$',OFFSET setlpt,OFFSET startlpt,OFFSET soundlpt,OFFSET stoplpt,OFFSET makelpt,0,0,0>
  664.         DEVICE <'BLASTERs=ApIiDd$',OFFSET setsb,OFFSET startsb,0,OFFSET stopsb,OFFSET makelpt,0,0,1>
  665.         DEVICE <'ULTRASNDs=p,d,i$',OFFSET setgus,OFFSET startgus,OFFSET soundgus1,OFFSET stopgus,OFFSET makegus,0,0,0>
  666.  
  667.  
  668. ;**************************************************************************
  669. ;*    Cette routine recherche la présence d'une carte sonore dans les
  670. ;*    variables d'environnement et renvoit la carte trouvé avec ses
  671. ;*    paramètre
  672. ;*
  673. ;* Entrée:
  674. ;*    AL    numero de la carte voulus
  675. ;*
  676. ;* Sortie:
  677. ;*    AL    numero de la carte trouvé
  678. ;*    DL    irq utilisé
  679. ;*    DH    dma utilisé
  680. ;*    BX    port utilisé
  681.  
  682. PROC    Detectsnd FAR
  683. LOCAL    port:WORD,irq:BYTE,dma:BYTE,dev:BYTE=varloc
  684.  
  685.     enter    varloc,0
  686.         push    es
  687.     push    ds
  688.     push    di
  689.         push    si
  690.  
  691.         lds    di,[ss:bp+18]
  692.         mov    al,[ds:di]
  693.         mov    [dev],al
  694.         mov    ax,CSEG
  695.     mov    ds,ax
  696.     ASSUME    ds:CSEG
  697.  
  698.     mov    ah,62h
  699.         int    21h
  700.     mov    es,bx
  701.     mov    bx,[es:2Ch]
  702.     mov    es,bx
  703.  
  704.     mov    cx,0ffffh
  705.     movzx    bx,[dev]
  706.  
  707.     shl    bx,5    ; car SIZE DEVICE=32
  708.     add    bx,OFFSET Devices
  709.     cmp    bx,OFFSET Devices+32*5
  710.     jae    @@not_found
  711.  
  712. @@search_dev:
  713.     xor    di,di
  714. @@next_var:
  715.     mov    si,bx
  716.     lodsb
  717. @@get_next:
  718.     scasb
  719.         je    @@find_one
  720. @@not_dev:
  721.         dec    di
  722.     xor    al,al
  723.         repne    scasb
  724.     cmp    [byte ptr es:di],0
  725.         je    @@not_found
  726.     jmp    @@next_var
  727.  
  728. @@find_one:
  729.     repe    cmpsb
  730.         dec    di
  731.         lodsb
  732.         cmp    al,'='
  733.         jne    @@not_dev
  734. @@search_char:
  735.     cmp    [byte ptr es:di],0
  736.     je    @@not_dev
  737.     mov    ah,[es:di]
  738.         inc    di
  739.     cmp    ah,'a'
  740.     jb    @@no_maj
  741.         cmp    ah,'z'
  742.         ja    @@no_maj
  743.         sub    ah,20h
  744. @@no_maj:
  745.     cmp     ah,al
  746.     jne    @@search_char
  747. @@get_par:
  748.     lodsb
  749.         cmp    al,'p'
  750.     je    @@get_info
  751.         cmp    al,'i'
  752.     je    @@get_info
  753.     cmp    al,'d'
  754.         je    @@get_info
  755.         cmp    al,'$'
  756.         je    @@find_all
  757.         jmp    @@search_char
  758. @@get_info:
  759.         mov    ah,[es:di]
  760.     inc    di
  761.     or    ah,ah
  762.         je    @@not_dev
  763.     cmp    ah,'0'
  764.     jb    @@get_info
  765.     cmp    ah,'9'
  766.     ja    @@get_info
  767.  
  768.         dec    di
  769.     cmp    al,'p'
  770.     je    @@get_port
  771.         cmp    al,'i'
  772.     je    @@get_irq
  773.         cmp    al,'d'
  774.     je    @@get_dma
  775. @@get_port:
  776.     xor    dx,dx
  777.     xor    ah,ah
  778. @@next_digit:
  779.     mov    al,[es:di]
  780.         sub    al,'0'
  781.         jl    @@no_digit
  782.     cmp    al,'9'
  783.         jbe    @@under10
  784.     sub    al,6
  785.         cmp    al,10
  786.         jb    @@no_digit
  787.     cmp    al,16
  788.     jae    @@no_digit
  789. @@under10:
  790.         shl     dx,4
  791.     add    dx,ax
  792.     inc    di
  793.     jmp        @@next_digit
  794.  
  795. @@no_digit:
  796.     mov    [port],dx
  797.         jmp    @@get_par
  798.  
  799. @@get_dma:
  800.     mov    al,[es:di]
  801.         sub    al,'0'
  802.     mov    [dma],al
  803.         jmp    @@get_par
  804.  
  805. @@get_irq:
  806.     mov    ax,[es:di]
  807.         sub    ax,'00'
  808.     cmp    ah,9
  809.         ja    @@no_2digit
  810.     mov    al,ah
  811.         add    al,10
  812. @@no_2digit:
  813.     mov    [irq],al
  814.         jmp    @@get_par
  815.  
  816. @@find_all:
  817.  
  818.     sub    bx,OFFSET Devices
  819.         shr    bx,5
  820.  
  821.         lds    di,[ss:bp+18]
  822.         mov    [ds:di],bl
  823.  
  824.     mov    bx,[port]
  825.         lds    di,[ss:bp+14]
  826.     mov    [ds:di],bx
  827.  
  828.     mov    dl,[irq]
  829.         lds    di,[ss:bp+10]
  830.     mov    [ds:di],dl
  831.  
  832.     mov     dh,[dma]
  833.         lds    di,[ss:bp+6]
  834.         mov    [ds:di],dh
  835.  
  836. @@found:
  837.     pop    si
  838.     pop    di
  839.         pop    ds
  840.     pop    es
  841.     leave
  842.     clc
  843.     ret    4*4
  844.  
  845. @@not_found:
  846.     cmp    [dev],5
  847.     jne    @@error
  848.  
  849.     sub    bx,32
  850.     cmp    bx,OFFSET Devices+32*2
  851.     jae    @@search_dev
  852.  
  853.     lds    di,[ss:bp+18]
  854.     mov    [byte ptr ds:di],1    ; si on a rien trouvé utilise le speaker
  855.     jmp    @@found
  856.  
  857. @@error:
  858.     sub    bx,OFFSET Devices
  859.     shr    bx,5
  860.     mov    al,bl
  861.  
  862.     pop    si
  863.     pop    di
  864.     pop    ds
  865.     pop    es
  866.         leave
  867.     stc
  868.  
  869.     ret    4*4
  870.  
  871. ENDP
  872.  
  873. DEFAULT_FRQ    EQU 186
  874.  
  875. Used_device    DW 0
  876.  
  877. Play_rate    DW 0
  878. Voicelen    DW 0
  879.  
  880. LOW_NOTE    EQU    1Ch
  881. HIGH_NOTE    EQU    1AC0h
  882.  
  883. Notes        DW HIGH_NOTE+39 DUP (?)        ;tables de conversion des note amiga
  884. Volume_tab    DB 65*256 DUP (?)       ;tables de multiplication
  885.  
  886.  
  887. ;***************************************************************************
  888. ;*    Cette fonction initialise les tables du programme suivant les
  889. ;*    paramètre passé par le programme principale
  890. ;*
  891. ;* Entrée:
  892. ;*
  893. ;*    Dans la pile en suivant cet ordre (en pascal)
  894. ;*
  895. ;*      CX    frequence en centaine de Hz (0 valeur par défaut)
  896. ;*      BL    numero de l'appareil de sortie du son
  897. ;*      BH    numero du port de l'appareil
  898. ;*    DL    numero de l'irq (0 valeur par défaut)
  899.  
  900. PROC    Setmod FAR
  901.  
  902.     push    bp
  903.     mov    bp,sp
  904.  
  905.     push    ds
  906.     push    es
  907.     push    si
  908.     push    di
  909.     mov    ax,CSEG
  910.     mov    ds,ax
  911.     ASSUME  cs:CSEG
  912.  
  913.     mov    [cs:Ptr_sound],OFFSET BUF_SOUND+BUF_LEN
  914.     mov    [cs:Page_sound],OFFSET BUF_SOUND
  915.  
  916.     mov     dl,[ss:bp+6]
  917.     mov     ax,[ss:bp+8]
  918.     mov    bl,[ss:bp+10]
  919.     mov    cx,[ss:bp+12]
  920.  
  921.     mov    [byte ptr cs:OFFSET start_mksnd],01eh
  922.  
  923.     xor    bh,bh    ;car SIZE DEVICE=32
  924.     shl    bx,5
  925.     add    bx,OFFSET Devices
  926.     mov    [Used_device],bx
  927.  
  928.     mov    [(DEVICE PTR ds:bx).port],ax
  929. ;    or    dl,dl
  930. ;    je    @@default
  931.     mov    [(DEVICE PTR ds:bx).irq],dl
  932. ;@@default:
  933.     mov    [(DEVICE PTR ds:bx).dma],dh
  934.  
  935.     or    cx,cx
  936.     jne    @@no_default
  937.     mov     cx,DEFAULT_FRQ
  938. @@no_default:
  939.  
  940.     mov    ax,cx        ;multiplit dx par 5.5
  941.     shr    cx,1
  942.     lea    ax,[eax*4+eax]
  943.     add    ax,cx
  944.     mov    [Play_rate],ax
  945.  
  946.     mov    dx,ax
  947.     shl    ax,8
  948.     shr    dx,8
  949.     mov    cx,703
  950.     div    cx
  951.     inc    ax
  952.     and    ax,0fffeh
  953.     shl    ax,1
  954.     mov    [Voicelen],ax
  955.  
  956.     call    [(DEVICE PTR ds:bx).init]
  957.     jc    @@error
  958.  
  959.     mov    bx,[Used_device]
  960.     mov    ax,ds
  961.     mov    es,ax
  962.     mov     di,OFFSET Voices
  963.     mov    si,[(DEVICE PTR ds:bx).make]
  964.     mov    cx,(LEN_VOICES) shr 2
  965.     rep    movsd
  966.  
  967.     mov    dx,3
  968.     mov    ax,8d1h        ; 4/(2.79365e-7*frequence)
  969.     div    [Play_rate]
  970.     shl    ax,2
  971.     mov    cx,ax
  972.  
  973.     mov    bx,LOW_NOTE-17
  974. @@next_note:
  975.     mov    dx,cx
  976.     shr    dx,8
  977.     mov    ax,cx
  978.     shl    ax,8
  979.     cmp    dx,bx
  980.         jae    @@overflow
  981.     div     bx        ; divise 1024*(2.79365e-7*frequence)
  982. @@put_note:
  983.     shl    bx,1
  984.     mov    [ds:bx+OFFSET Notes],ax
  985.     shr    bx,1
  986.     inc    bx
  987.     cmp    bx,HIGH_NOTE+39
  988.     jne    @@next_note
  989.  
  990.     mov     cl,[ds:OFFSET Nb_voice]
  991.     mov    al,SIZE VOIX
  992.     mul    cl
  993.     add    ax,OFFSET Voix1
  994.     mov    [cs:OFFSET nbvoicetest+2],ax
  995.  
  996.     mov    ah,[ds:OFFSET Nb_voice]
  997.     xor    al,al
  998.     mov    [word ptr ds:OFFSET Ligne],ax
  999.  
  1000.     mov    di,OFFSET Volume_tab    ;remplit la table de multiplication
  1001.     mov    bl,0
  1002. @@fill_tab:
  1003.     mov    bh,0
  1004.     mov    ax,880
  1005.     mul    bx
  1006.     add    ax,1024
  1007.  
  1008.     mov    dh,15
  1009. @@next_dec:
  1010.     shl    ax,1
  1011.     jc    @@find_dec
  1012.     dec    dh
  1013.     jne    @@next_dec
  1014. @@find_dec:
  1015.     mov    dl,ah
  1016.     shl    dx,4
  1017.     shl    bx,1
  1018.     mov    [ds:OFFSET GUS_VOLUME2+bx],dx
  1019.     shr    bx,1
  1020. @@fill_line:
  1021.     mov    al,bh
  1022.     imul    bl
  1023.     sar    ax,6
  1024.     idiv    cl
  1025.     mov    [ds:di],al
  1026.     inc    di
  1027.     inc    bh
  1028.     jne    @@fill_line
  1029.     inc     bl
  1030.     cmp    bl,64
  1031.     jbe    @@fill_tab
  1032.  
  1033.     call    far Makemod
  1034.     sub    [cs:Ptr_sound],BUF_LEN
  1035.  
  1036.     mov    ax,NO_ERROR
  1037.     clc
  1038.  
  1039. @@error:
  1040.     pop    di
  1041.     pop    si
  1042.     pop    es
  1043.     pop    ds
  1044.  
  1045.     leave
  1046.  
  1047.     ret    8
  1048.  
  1049. @@overflow:
  1050.     mov    ax,0ffffh
  1051.     jmp    @@put_note
  1052.  
  1053. ENDP
  1054.  
  1055.  
  1056. STRUC VOIX
  1057.     endsamp DW 33
  1058.     volume    DB 0
  1059.     finetu    DB 0
  1060.     adrvoc    DP 0
  1061.     lenrep    DW 32        ; evite un bug
  1062.     play    DW 0        ; note joué
  1063.     newnote    DW 0        ; note d'arrivé (vibrato et portamento)
  1064.     oldnote DW 0        ; note précédente (portamento)
  1065.     effet   DW 0
  1066.     note1   DW 0
  1067.     note2   DW 0
  1068.     oldport DW 0
  1069.     amplit    DW 0
  1070.     vitesse DB 0
  1071.     temp    DB 0
  1072.     tremolo DB 0
  1073.     tremvit DB 0
  1074.     oldvol    DB 0
  1075.     compte    DB 0
  1076.     inst    DB 0
  1077.     gusinf    DB 0    ;bit 3 new vol,2 nul vol,1 change adr,0 new inst
  1078.     extra    DB 0
  1079.     effnb    DB 0
  1080.     looppos DW 0
  1081. ENDS
  1082.  
  1083. Voix1           VOIX <>
  1084. Voix2           VOIX <>
  1085. Voix3           VOIX <>
  1086. Voix4           VOIX <>
  1087. Voix5        VOIX <>
  1088. Voix6        VOIX <>
  1089. Voix7        VOIX <>
  1090. Voix8        VOIX <>
  1091.  
  1092. Ligne        DD 1024
  1093. Position    DW 255
  1094. Tempo           DB 06h
  1095. PatternDelay    DB 0
  1096. Time        DW 0100h
  1097. Speed        DW 256
  1098. MasterVol    DB 255
  1099.  
  1100. Effets          DW OFFSET set_arpeggio
  1101.         DW OFFSET set_portamento_up
  1102.         DW OFFSET set_portamento_down
  1103.         DW OFFSET set_portamento_tone
  1104.         DW OFFSET set_vibrato
  1105.         DW OFFSET set_portamento_volume
  1106.         DW OFFSET set_vibrato_volume
  1107.         DW OFFSET set_tremolo
  1108.         DW OFFSET set_nul_effect
  1109.         DW OFFSET set_play_end_part
  1110.         DW OFFSET set_volume_slide
  1111.         DW OFFSET position_jump
  1112.         DW OFFSET set_volume
  1113.         DW OFFSET pattern_break
  1114.         DW OFFSET set_extended_effect
  1115.         DW OFFSET set_speed
  1116.  
  1117. ;***************************************************************************
  1118. ;*      Change le volume globale de la musique
  1119. ;*
  1120. ;* Entrée:
  1121. ;*    AL    nouveau volume
  1122. ;*
  1123.  
  1124. PROC    Changevol FAR
  1125.  
  1126.     push    bp
  1127.     mov    bp,sp
  1128.  
  1129.     push    ds
  1130.     mov    ax,CSEG
  1131.     mov    ds,ax
  1132.     ASSUME    ds:CSEG
  1133.  
  1134.     mov     al,[ss:bp+6]
  1135.     mov    [ds:MasterVol],al
  1136.  
  1137.     mov    cx,[ds:Nb_voice]
  1138.     mov    bx,OFFSET Voix1
  1139. @@next_voice:
  1140.     or    [(VOIX PTR ds:bx).gusinf],8h
  1141.     add    bx,SIZE VOIX
  1142.     dec    cl
  1143.     jne    @@next_voice
  1144.     pop    ds
  1145.  
  1146.     leave
  1147.  
  1148.     ret    2
  1149.  
  1150. ENDP
  1151.  
  1152. ;**************************************************************************
  1153. ;*      calcul les sons
  1154.  
  1155. PROC PMAKEMOD FAR
  1156. ENDP
  1157. PROC _Makemod FAR
  1158. ENDP
  1159.  
  1160. PROC Makemod FAR
  1161.  
  1162. start_mksnd:
  1163.     push    ds    ;Attention cet octet est modifié par le programme
  1164.     push    es
  1165.     push    bp
  1166.     push    si
  1167.     push    di
  1168.     mov    ax,CSEG
  1169.     mov    ds,ax
  1170.  
  1171.     cli
  1172.     mov    ax,[ds:OFFSET Ptr_sound]
  1173.     mov    bx,[ds:OFFSET Page_sound]
  1174.     sti
  1175. buf_sound10:
  1176.     mov    bp,OFFSET BUF_SOUND+BUF_LEN    ;ATTENTION en fait on doit avoir OFFSET BUF_SOUND+BUF_LEN shl 16
  1177.     shl    ebp,16
  1178.     mov    bp,[word ptr ds:OFFSET Voicelen]
  1179.     add    bp,bx
  1180. buf_sound1:
  1181.     cmp    bp,OFFSET BUF_SOUND+BUF_LEN
  1182.     ja    @@loop
  1183.     cmp    ax,bx
  1184.     jb    @@ok
  1185.     cmp    ax,bp
  1186.     ja    @@ok
  1187. @@fin:
  1188.  
  1189.     pop    di
  1190.     pop    si
  1191.     pop    bp
  1192.     pop    es
  1193.     pop    ds
  1194.     ret
  1195. @@loop:
  1196.     and    bp,65535-BUF_LEN    ;0fbffh
  1197.     cmp    ax,bx
  1198.     ja    @@fin
  1199.     cmp    ax,bp
  1200.     jbe    @@fin
  1201.     rol    ebp,16
  1202.  
  1203. @@ok:
  1204.     mov    [Page_end],ebp
  1205.  
  1206.     mov    ax,[ds:Speed]
  1207.     sub     [ds:Time],ax
  1208.     jg    @@no_new_note
  1209.  
  1210.  
  1211.     mov    si,OFFSET Voix1
  1212.  
  1213.     mov     al,[cs:OFFSET Tempo]
  1214.     mov    [ds:OFFSET Time+1],al
  1215.  
  1216.     cmp    [byte ptr ds:OFFSET PatternDelay],0
  1217.     je    @@no_delay
  1218.     dec    [byte ptr ds:OFFSET PatternDelay]
  1219.     jmp    @@no_new_note
  1220.  
  1221. @@no_delay:
  1222.  
  1223.     les    di,[ds:OFFSET Ligne]
  1224.  
  1225.     mov    ah,[ds:OFFSET Nb_voice]
  1226.     xor    al,al
  1227.  
  1228.         cmp    di,ax
  1229.     jb     @@same_pattern
  1230.  
  1231. ;    dec    ax
  1232. ;    and    di,ax
  1233.     xor    di,di
  1234.     mov     bx,[ds:OFFSET Position]
  1235.     inc     bl
  1236.     cmp     bl,[byte ptr ds:OFFSET Sequence]
  1237.     jb     @@not_end_seq
  1238.  
  1239.      xor    bl,bl
  1240.  
  1241. @@not_end_seq:
  1242.      mov    [ds:OFFSET Position],bx
  1243.      mov    al,[byte ptr ds:OFFSET Sequence+2+bx]
  1244.      mov    cl,[ds:OFFSET Nb_voice]
  1245.      mul    cl
  1246.      shl    ax,4
  1247.      add    ax,[ds:OFFSET Partition]
  1248.      mov    [word ptr ds:OFFSET Ligne+2],ax
  1249.      mov    es,ax
  1250.  
  1251. @@same_pattern:
  1252.  
  1253.  
  1254. @@autre_voix:
  1255.  
  1256.     mov     edx,[dword ptr es:di]   ;charge la voix
  1257.  
  1258.     mov     ebx,edx
  1259.     and     ebx,100000f0h
  1260.     je      @@meme_inst
  1261.  
  1262.     rol    ebx,8
  1263.     shr    bh,4
  1264.     or    bl,bh
  1265.     xor    bh,bh
  1266.  
  1267.     cmp    bl,[(VOIX ptr ds:si).inst]
  1268.     je    @@same_inst
  1269.     mov    [(VOIX ptr ds:si).inst],bl
  1270.     mov    [(VOIX ptr ds:si).gusinf],01h
  1271. @@same_inst:
  1272.     or    [(VOIX ptr ds:si).gusinf],00ch    ; nouvel instrument
  1273.  
  1274.     shl    bx,5
  1275.     add     bx,OFFSET Instruments-SIZE INSTRUMENT ;ATTENTION ON CONSIDERE QUE LA STRUCTURE
  1276.                       ;CONTENANT LES INSTRUMENTS A UNE TAILLE DE
  1277.                       ;32 octets
  1278.  
  1279.     mov    eax,[dword ptr (INSTRUMENT ptr ds:bx).adrseg]
  1280.     mov    [(dword ptr (VOIX ptr ds:si).adrvoc)+4],eax
  1281.     mov    eax,[dword ptr (INSTRUMENT PTR ds:bx).length]
  1282.     mov    [dword ptr ds:si],eax
  1283.  
  1284. @@meme_inst:
  1285.     mov     bx,dx
  1286.     mov     [(VOIX PTR ds:si).extra],dh
  1287.     and     bx,000fh
  1288.     mov    [(VOIX PTR ds:si).effnb],bl
  1289.     shl     bx,1
  1290.     mov     bx,[word ptr ds:OFFSET Effets+bx]
  1291.     mov    [(VOIX PTR ds:si).effet],bx
  1292.  
  1293.     rol     edx,16
  1294.  
  1295.     mov    ax,[(VOIX PTR ds:si).play]
  1296.     mov    [(VOIX PTR ds:si).oldnote],ax
  1297.  
  1298.     and    dx,00fffh
  1299.     je      @@no_note
  1300.  
  1301.     mov    [(dword ptr (VOIX ptr ds:si).adrvoc)],0
  1302.     or    [(VOIX ptr ds:si).gusinf],2
  1303.  
  1304.     mov    al,[(VOIX PTR ds:si).finetu]
  1305.     shl    al,1
  1306.     add    al,[(VOIX PTR ds:si).finetu]
  1307.     shl    al,1
  1308.     cbw
  1309.     sub    dx,ax
  1310.     mov    [(VOIX ptr cs:si).newnote],dx
  1311.     mov    [(VOIX ptr cs:si).play],dx
  1312.  
  1313. @@no_note:
  1314.  
  1315.     add     di,4
  1316.     add     si,SIZE VOIX
  1317.  
  1318. nbvoicetest:
  1319.     cmp      si,OFFSET Voix5        ; Code automodifié
  1320.     jb      @@autre_voix
  1321.  
  1322.     mov     [word ptr ds:OFFSET Ligne],di
  1323.  
  1324.     mov    al,SIZE VOIX
  1325.     mov    cl,[ds:OFFSET Nb_voice]
  1326.     mul    cl
  1327.     sub     si,ax
  1328.  
  1329. @@no_new_note:
  1330.  
  1331. LEN_VOICES    EQU    1024
  1332.  
  1333. Voices:
  1334.     DB LEN_VOICES DUP (?)    ;zone où l'on place la routine correspondant
  1335.                 ;à l'appareil utilisé
  1336.  
  1337. ENDP
  1338.  
  1339. ;***************************************************************************
  1340. ;*    Procédure d'initialisation des différents effets
  1341.  
  1342. PROC    set_nul_effect
  1343.  
  1344.     mov    [(VOIX ptr ds:di).effnb],0eh
  1345.     mov    [(VOIX ptr ds:di).effet],OFFSET retour
  1346.     ret
  1347. ENDP
  1348.  
  1349.  
  1350. PROC    set_arpeggio
  1351.     mov    al,[(VOIX ptr ds:di).extra]
  1352.  
  1353.     or    al,al
  1354.     je        set_nul_effect
  1355.  
  1356.     mov    cx,[(VOIX PTR ds:di).newnote]
  1357.  
  1358.     mov     bx,OFFSET TAB_ARPEGE-2
  1359. @@not_find:
  1360.     add     bx,2
  1361.     cmp     cx,[ds:bx]
  1362.     jb      @@not_find
  1363.  
  1364.     sub    cx,[ds:bx]
  1365.     neg    cx
  1366.     mov    [(VOIX ptr ds:di).note1],cx
  1367.     mov    [(VOIX ptr ds:di).note2],cx
  1368.     mov     cx,bx
  1369.     shl     eax,12
  1370.     shr    ax,11
  1371.     add     bx,ax
  1372.     mov     ax,[ds:bx]
  1373.  
  1374.     add     [(VOIX ptr ds:di).note1],ax
  1375.     shr     eax,15
  1376.     and    ax,001eh
  1377.     mov     bx,cx
  1378.     add     bx,ax
  1379.     mov     ax,[ds:bx]
  1380.     add     [(VOIX ptr ds:di).note2],ax
  1381.     mov     [(VOIX ptr ds:di).effet],OFFSET arpeggio
  1382.  
  1383.     ret
  1384.  
  1385. ENDP
  1386.  
  1387. PROC    set_portamento_up
  1388.  
  1389.     mov    al,[(VOIX ptr ds:di).extra]
  1390.     xor    ah,ah
  1391.     mov     [(VOIX ptr ds:di).note1],ax
  1392.     mov     [(VOIX ptr ds:di).effet],OFFSET portamento_up
  1393.  
  1394.     ret
  1395.  
  1396. ENDP
  1397.  
  1398. PROC    set_portamento_down
  1399.  
  1400.     mov    al,[(VOIX ptr ds:di).extra]
  1401.     xor    ah,ah
  1402.     mov    [(VOIX ptr ds:di).note1],ax
  1403.     mov    [(VOIX ptr ds:di).effet],OFFSET portamento_down
  1404.  
  1405.     ret
  1406.  
  1407. ENDP
  1408.  
  1409. PROC    set_portamento_tone
  1410.  
  1411.     mov    dx,[(VOIX ptr ds:di).oldnote]
  1412.     mov    [(VOIX ptr ds:di).play],dx;
  1413.     mov    al,[(VOIX ptr ds:di).extra]
  1414.     or    al,al
  1415.     je    @@same
  1416.     xor    ah,ah
  1417.     mov     [(VOIX ptr ds:di).oldport],ax        ; la partie haute est toujours à 0
  1418. @@same:
  1419.  
  1420.     cmp       dx,[(VOIX ptr ds:di).newnote]
  1421.     jb      @@tone_down
  1422.     mov     [(VOIX ptr ds:di).effet],OFFSET portamento_tone_up
  1423.     ret
  1424.  
  1425. @@tone_down:
  1426.     mov     [(VOIX ptr ds:di).effet],OFFSET portamento_tone_down
  1427.     ret
  1428.  
  1429. ENDP
  1430.  
  1431. PROC    set_vibrato
  1432.  
  1433.     mov    al,[(VOIX ptr ds:di).extra]
  1434.     or    al,al
  1435.     je    @@same
  1436.     mov    ah,al
  1437.     and    al,0fh
  1438.     shr    ah,2
  1439.     and    ah,3ch
  1440.     mov    [(VOIX ptr ds:di).vitesse],ah
  1441.     xor    ah,ah
  1442.     mov    [(VOIX ptr ds:di).amplit],ax
  1443.     mov    [(VOIX PTR ds:di).temp],ah
  1444.  
  1445. @@same:
  1446.     mov    [(VOIX ptr ds:di).effet],OFFSET vibrato
  1447.  
  1448.     ret
  1449.  
  1450. ENDP
  1451.  
  1452. PROC    set_portamento_volume
  1453.  
  1454.     mov    dx,[(VOIX ptr ds:di).oldnote]
  1455.     mov    [(VOIX ptr ds:di).play],dx
  1456.     cmp       dx,[(VOIX ptr ds:di).newnote]
  1457.     jb      @@tone_down
  1458.  
  1459.     mov    al,[(VOIX ptr ds:di).extra]
  1460.     test    al,0f0h
  1461.     je    @@up_vol_down
  1462.     shr    al,4
  1463.     mov    [(VOIX ptr ds:di).extra],al
  1464.     mov    [(VOIX ptr ds:di).effet],OFFSET portamento_up_volume_up
  1465.     ret
  1466.  
  1467. @@up_vol_down:
  1468.     mov    [(VOIX ptr ds:di).extra],al
  1469.     mov    [(VOIX ptr ds:di).effet],OFFSET portamento_up_volume_down
  1470.     ret
  1471.  
  1472.     ret
  1473.  
  1474. @@tone_down:
  1475.     mov    al,[(VOIX ptr ds:di).extra]
  1476.     test    al,0f0h
  1477.     je    @@down_vol_down
  1478.     shr    al,4
  1479.     mov    [(VOIX ptr ds:di).extra],al
  1480.     mov    [(VOIX ptr ds:di).effet],OFFSET portamento_down_volume_up
  1481.     ret
  1482.  
  1483. @@down_vol_down:
  1484.     mov    [(VOIX ptr ds:di).extra],al
  1485.     mov    [(VOIX ptr ds:di).effet],OFFSET portamento_down_volume_down
  1486.     ret
  1487.  
  1488. ENDP
  1489.  
  1490.  
  1491. PROC    set_vibrato_volume
  1492.  
  1493.     mov    al,[(VOIX ptr ds:di).extra]
  1494.     test    al,0f0h
  1495.     je    @@vol_down
  1496.     shr    al,4
  1497.     mov    [(VOIX ptr ds:di).extra],al
  1498.     mov    [(VOIX ptr ds:di).effet],OFFSET vibrato_volume_up
  1499.     ret
  1500.  
  1501. @@vol_down:
  1502.     mov    [(VOIX ptr ds:di).extra],al
  1503.     mov    [(VOIX ptr ds:di).effet],OFFSET vibrato_volume_down
  1504.     ret
  1505.  
  1506. ENDP
  1507.  
  1508. PROC    set_tremolo
  1509.  
  1510.     mov    al,[(VOIX ptr ds:di).extra]
  1511.     or    al,al
  1512.     je    @@same
  1513.     mov    ah,al
  1514.     and    al,0fh
  1515.     shr    ah,2
  1516.     and    ah,3ch
  1517.     mov    [(VOIX ptr ds:di).tremvit],ah
  1518.     xor    ah,ah
  1519.     mov    [(VOIX ptr ds:di).note1],ax
  1520.     mov    [(VOIX PTR ds:di).tremolo],ah
  1521.     mov    al,[(VOIX PTR ds:di).volume]
  1522.     mov    [(VOIX PTR ds:di).oldvol],al
  1523. @@same:
  1524.     mov    [(VOIX ptr ds:di).effet],OFFSET tremolo
  1525.  
  1526.     ret
  1527.  
  1528. ENDP
  1529.  
  1530. PROC    set_play_end_part
  1531.  
  1532.     xor    eax,eax
  1533.     mov    ah,[(VOIX ptr ds:di).extra]
  1534.     cmp    ax,[(VOIX ptr ds:di).endsamp]
  1535.     jb    @@ok
  1536.     mov    ax,[(VOIX ptr ds:di).endsamp]
  1537. @@ok:
  1538.     mov    [(dword ptr (VOIX ptr ds:di).adrvoc)],eax
  1539.     or    [(VOIX ptr ds:di).gusinf],2    ; ne changer que curadr
  1540.  
  1541.     mov    [(VOIX ptr ds:di).effet],OFFSET retour
  1542.     ret
  1543.  
  1544. ENDP
  1545.  
  1546. PROC    set_volume_slide
  1547.  
  1548.     mov    al,[(VOIX ptr ds:di).extra]
  1549.     test    al,0f0h
  1550.     je    @@vol_down
  1551.     shr    al,4
  1552.     mov    [(VOIX ptr ds:di).extra],al
  1553.     mov    [(VOIX ptr ds:di).effet],OFFSET volume_up
  1554.     ret
  1555.  
  1556. @@vol_down:
  1557.     mov    [(VOIX ptr ds:di).extra],al
  1558.     mov    [(VOIX ptr ds:di).effet],OFFSET volume_down
  1559.     ret
  1560.  
  1561. ENDP
  1562.  
  1563. PROC    position_jump
  1564.  
  1565.     mov    al,[(VOIX ptr ds:di).extra]
  1566.     dec    al
  1567.     mov    [ds:OFFSET Position],al
  1568.     mov    ah,[ds:OFFSET Nb_voice]
  1569.     xor    al,al
  1570.     mov    [word ptr ds:OFFSET Ligne],ax
  1571.  
  1572.     mov    [(VOIX ptr ds:di).effet],OFFSET retour
  1573.  
  1574.     ret
  1575.  
  1576. ENDP
  1577.  
  1578. PROC    set_volume
  1579.  
  1580.     mov    al,[(VOIX ptr ds:di).extra]
  1581.     cmp    al,40h
  1582.     jbe    @@volume_ok
  1583.     mov    al,40h
  1584. @@volume_ok:
  1585.     or    [(VOIX ptr ds:di).gusinf],8
  1586.     mov    [(VOIX ptr ds:di).volume],al
  1587.     mov    [(VOIX ptr ds:di).effet],OFFSET retour
  1588.     ret
  1589.  
  1590. ENDP
  1591.  
  1592.  
  1593. PROC    pattern_break
  1594.  
  1595.     mov    al,[(VOIX ptr ds:di).extra]
  1596.     add    al,64
  1597.     mov    cl,[ds:OFFSET Nb_voice]
  1598.     mul    cl
  1599.     mov    cl,2
  1600.     shl    ax,cl
  1601.     mov    [ds:OFFSET Ligne],ax
  1602.  
  1603.     mov     [(VOIX ptr ds:di).effet],OFFSET retour
  1604.     ret
  1605.  
  1606. ENDP
  1607.  
  1608. Effets_etendus    DW OFFSET set_nul_effect
  1609.         DW OFFSET set_fine_portamento_up
  1610.         DW OFFSET set_fine_portamento_down
  1611.         DW OFFSET set_nul_effect
  1612.         DW OFFSET set_nul_effect
  1613.         DW OFFSET set_nul_effect
  1614.         DW OFFSET set_loop
  1615.         DW OFFSET set_nul_effect
  1616.         DW OFFSET set_nul_effect
  1617.         DW OFFSET set_retrig_sample
  1618.         DW OFFSET set_fine_slide_volume_up
  1619.         DW OFFSET set_fine_slide_volume_down
  1620.         DW OFFSET set_cut_note
  1621.         DW OFFSET set_delay_note
  1622.         DW OFFSET set_pattern_delay
  1623.         DW OFFSET set_nul_effect
  1624.  
  1625. PROC    set_extended_effect
  1626.  
  1627.     mov    al,[(VOIX ptr ds:di).extra]
  1628.     mov    bl,al
  1629.     and    ax,0fh
  1630.     shr    bx,4
  1631.     and    bx,0fh
  1632.     mov     [(VOIX ptr ds:di).effnb],bl
  1633.     add    [(VOIX ptr ds:di).effnb],10h
  1634.     shl    bx,1
  1635.     mov    bx,[ds:bx+OFFSET Effets_etendus]
  1636.     jmp    bx
  1637. ENDP
  1638.  
  1639. PROC    set_fine_portamento_up
  1640.  
  1641.     mov    bx,[(VOIX ptr ds:di).play]
  1642.     sub     bx,ax
  1643.     cmp     bx,LOW_NOTE
  1644.     jae     @@suite
  1645.     mov     bx,LOW_NOTE
  1646. @@suite:
  1647.     mov     [(VOIX ptr ds:di).effet],OFFSET retour
  1648.     mov     [(VOIX ptr ds:di).play],bx
  1649.  
  1650.     ret
  1651. ENDP
  1652.  
  1653. PROC    set_fine_portamento_down
  1654.  
  1655.     mov    bx,[(VOIX PTR ds:di).play]
  1656.     add     bx,ax
  1657.     cmp     bx,HIGH_NOTE
  1658.     jbe     @@suite
  1659.     mov     bx,HIGH_NOTE
  1660. @@suite:
  1661.     mov     [(VOIX ptr ds:di).effet],OFFSET retour
  1662.     mov     [(VOIX ptr ds:di).play],bx
  1663.  
  1664.     ret
  1665.  
  1666. ENDP
  1667.  
  1668. PROC set_loop
  1669.  
  1670.     or    al,al
  1671.     je    @@setloop
  1672.  
  1673.     cmp    [(VOIX ptr ds:di).compte],0
  1674.     je    @@begin_loop
  1675.     dec    [(VOIX ptr ds:di).compte]
  1676.     je    @@end_loop
  1677.  
  1678. @@loop:
  1679.     mov    ax,[(VOIX PTR ds:di).looppos]
  1680.     mov    [ds:OFFSET Ligne],ax
  1681.  
  1682. @@end_loop:
  1683.     mov    [(VOIX ptr ds:di).looppos],0
  1684.     mov     [(VOIX ptr ds:di).effet],OFFSET retour
  1685.     ret
  1686.  
  1687. @@begin_loop:
  1688.     mov    [(VOIX ptr ds:di).compte],al
  1689.     jmp    @@loop
  1690.  
  1691. @@setloop:
  1692.     mov     ax,[ds:OFFSET Ligne]
  1693.     sub    ax,16
  1694.     mov    [(VOIX PTR ds:di).looppos],ax
  1695.     mov    [(VOIX PTR ds:di).effet],OFFSET retour
  1696.     ret
  1697.  
  1698. ENDP
  1699.  
  1700. PROC set_retrig_sample
  1701.  
  1702.     xor    ah,ah
  1703.     mov    [(VOIX PTR ds:di).note1],ax
  1704.     mov    [(VOIX PTR ds:di).effet],OFFSET retrig_sample
  1705.  
  1706.     ret
  1707.  
  1708. ENDP
  1709.  
  1710. PROC set_fine_slide_volume_up
  1711.  
  1712.     mov     ah,[(VOIX ptr ds:di).volume]
  1713.     add     ah,al
  1714.     cmp     ah,40h
  1715.     jbe     @@ok
  1716.     mov     ah,40h
  1717. @@ok:
  1718.     mov     [(VOIX ptr ds:di).volume],ah
  1719.         or    [(VOIX ptr ds:di).gusinf],8
  1720.     mov    [(VOIX ptr ds:di).effet],OFFSET retour
  1721.  
  1722.     ret
  1723.  
  1724. ENDP
  1725.  
  1726. PROC set_fine_slide_volume_down
  1727.  
  1728.     mov     ah,[(VOIX ptr ds:di).volume]
  1729.     sub     ah,al
  1730.     jge     @@ok
  1731.     xor     ah,ah
  1732. @@ok:
  1733.     mov     [(VOIX ptr ds:di).volume],ah
  1734.         or    [(VOIX ptr ds:di).gusinf],8
  1735.     mov    [(VOIX ptr ds:di).effet],OFFSET retour
  1736.  
  1737.     ret
  1738.  
  1739. ENDP
  1740.  
  1741. PROC set_cut_note
  1742.  
  1743.     xor    ah,ah
  1744.     mov    [(VOIX PTR ds:di).note1],ax
  1745.     mov    [(VOIX PTR ds:di).effet],OFFSET cut_note
  1746.  
  1747.     ret
  1748.  
  1749. ENDP
  1750.  
  1751. PROC set_delay_note
  1752.  
  1753.     xor    ah,ah
  1754.     mov    [(VOIX PTR ds:di).note1],ax
  1755.     xchg    ah,[(VOIX PTR ds:di).volume]
  1756.         or    [(VOIX PTR ds:di).gusinf],8
  1757.     mov    [(VOIX PTR ds:di).oldvol],ah
  1758.     mov    [(VOIX PTR ds:di).effet],OFFSET delay_note
  1759.  
  1760.     ret
  1761.  
  1762. ENDP
  1763.  
  1764. PROC    set_pattern_delay
  1765.  
  1766.     mov    [ds:PatternDelay],al
  1767.     mov    [(VOIX PTR ds:di).effet],OFFSET retour
  1768.  
  1769.     ret
  1770.  
  1771. ENDP
  1772.  
  1773. PROC    set_speed
  1774.  
  1775.     mov    al,[(VOIX ptr ds:di).extra]
  1776.     cmp    al,20h
  1777.     jae    @@change_speed
  1778.  
  1779.     mov     [ds:OFFSET Tempo],al
  1780.     mov     [(VOIX ptr ds:di).effet],OFFSET retour
  1781.     ret
  1782.  
  1783. @@change_speed:
  1784.     shl    ax,8
  1785.     xor    dx,dx
  1786.     mov    bx,100
  1787.     div    bx
  1788.     mov    [ds:OFFSET Speed],ax
  1789.     mov    [(VOIX ptr ds:di).effet],OFFSET retour
  1790.     ret
  1791.  
  1792. ENDP
  1793.  
  1794. ;***************************************************************************
  1795. ;*      Procedures gerant les differents effets
  1796.  
  1797. PROC retour
  1798.     ret
  1799. ENDP
  1800.  
  1801. TAB_ARPEGE:
  1802.         DW  1AC0h,1940h,17D0h,1680h,1530h
  1803.         DW  1400h,12E0h,11D0h,10D0h,0FE0h
  1804.         DW  0F00h,0E28h,0D60h,0CA0h,0BE8h
  1805.         DW  0B40h,0A98h,0A00h,0970h,08E8h
  1806.         DW  868h,7F0h,780h,714h,6B0h,650h
  1807.         DW  5F4h,5A0h,54Ch,500h,4B8h,474h
  1808.         DW  43Ah,3F8h,3C0h,38Ah
  1809. ;TAB_ARPEGE:    DW  358h,328h,2fah,2d0h,2a6h,280h
  1810.         DW  25ch,23ah,21ah,1fch,1e0h,1c5h
  1811.         DW  1ach,194h,17dh,168h,153h,140h
  1812.         DW  12eh,11dh,10dh,0feh,0f0h,0e2h
  1813.         DW  0d6h,0cah,0beh,0b4h,0aah,0a0h
  1814.         DW  097h,08fh,087h,07fh,078h,071h
  1815.         DW  06Bh,065h,05Fh,05Ah,055h,050h
  1816.         DW  04Bh,047h,043h,03Fh,03Ch,038h
  1817.         DW  035h,032h,02Fh,02Dh,02Ah,028h
  1818.         DW  025h,023h,021h,01Fh,01Eh,01Ch
  1819.         DW  000h,01Ch,01Ch,01Ch,01Ch,01Ch
  1820.         DW  01Ch,01Ch,01Ch,01Ch,01Ch,01Ch
  1821.         DW  01Ch,01Ch,01Ch,01Ch
  1822.  
  1823. PROC    arpeggio
  1824.  
  1825.     mov    ax,[(VOIX ptr ds:di).play]
  1826.     xchg    ax,[(VOIX ptr ds:di).note1]
  1827.     xchg    ax,[(VOIX ptr ds:di).note2]
  1828.     mov    [(VOIX ptr ds:di).play],ax
  1829.  
  1830.     ret
  1831. ENDP
  1832.  
  1833. PROC portamento_up
  1834.  
  1835.     mov    ax,[(VOIX ptr ds:di).play]
  1836.     sub     ax,[(VOIX ptr ds:di).note1]
  1837.     jc    @@bug1992
  1838.     cmp     ax,LOW_NOTE
  1839.     jae     @@suite
  1840. @@bug1992:
  1841.     mov     ax,LOW_NOTE
  1842.     mov     [(VOIX ptr ds:di).effet],OFFSET retour
  1843. @@suite:
  1844.     mov     [(VOIX ptr ds:di).play],ax
  1845.  
  1846.     ret
  1847.  
  1848. ENDP
  1849.  
  1850. PROC portamento_down
  1851.  
  1852.     mov    ax,[(VOIX ptr ds:di).play]
  1853.     add     ax,[(VOIX ptr ds:di).note1]
  1854.     cmp     ax,HIGH_NOTE
  1855.     jbe     @@suite
  1856.     mov     ax,HIGH_NOTE
  1857.     mov     [(VOIX ptr ds:di).effet],OFFSET retour
  1858. @@suite:
  1859.     mov     [(VOIX ptr ds:di).play],ax
  1860.  
  1861.     ret
  1862.  
  1863. ENDP
  1864.  
  1865. PROC portamento_tone_up
  1866.  
  1867.     mov     bx,[(VOIX ptr ds:di).newnote]
  1868.     mov     ax,[(VOIX ptr ds:di).play]
  1869.     sub     ax,[(VOIX ptr ds:di).oldport]
  1870.     jc    @@bug1992
  1871.     cmp     ax,bx
  1872.     jae     @@suite
  1873. @@bug1992:
  1874.     mov     ax,bx
  1875.     mov     [(VOIX ptr ds:di).effet],OFFSET retour
  1876. @@suite:
  1877.     mov     [(VOIX ptr ds:di).play],ax
  1878.  
  1879.     ret
  1880.  
  1881. ENDP
  1882.  
  1883. PROC portamento_tone_down
  1884.  
  1885.     mov     ax,[(VOIX ptr ds:di).play]
  1886.     add     ax,[(VOIX ptr ds:di).oldport]
  1887.     mov     bx,[(VOIX ptr ds:di).newnote]
  1888.     cmp     ax,bx
  1889.     jbe     @@suite
  1890.     mov     ax,bx
  1891.     mov     [(VOIX ptr ds:di).effet],OFFSET retour
  1892. @@suite:
  1893.     mov     [(VOIX ptr ds:di).play],ax
  1894.  
  1895.     ret
  1896. ENDP
  1897.  
  1898. SINUS           DB  000h,018h,031h,04ah,061h,078h,08dh,0a1h
  1899.         DB  0b4h,0c5h,0d4h,0e0h,0ebh,0f4h,0fah,0fdh
  1900.         DB  0ffh,0fdh,0fah,0f4h,0ebh,0e0h,0d4h,0c5h
  1901.         DB  0b4h,0a1h,08dh,078h,061h,04ah,031h,018h
  1902.  
  1903. PROC vibrato
  1904.  
  1905.     mov    al,[(VOIX ptr ds:di).temp]
  1906.     shr    al,2
  1907.     and    al,1fh
  1908.     mov    bx,OFFSET SINUS
  1909.     xlat
  1910.     xor    ah,ah
  1911.     mul    [(VOIX PTR ds:di).amplit]
  1912.     shr    ax,6
  1913.     mov    bx,[(VOIX PTR ds:di).newnote]
  1914.     cmp    [(VOIX PTR ds:di).temp],0
  1915.     jg    @@add
  1916.     neg    ax
  1917. @@add:
  1918.     add    bx,ax
  1919.     mov    [(VOIX PTR ds:di).play],bx
  1920.     mov    al,[(VOIX PTR ds:di).vitesse]
  1921.     add    [(VOIX PTR ds:di).temp],al
  1922.  
  1923.     ret
  1924.  
  1925. ENDP
  1926.  
  1927. PROC portamento_up_volume_up
  1928.  
  1929.     mov     ax,[(VOIX ptr ds:di).play]
  1930.     sub     ax,[(VOIX ptr ds:di).oldport]
  1931.     mov     bx,[(VOIX ptr ds:di).newnote]
  1932.     cmp     ax,bx
  1933.     jae     @@suite
  1934.     mov     ax,bx
  1935.     mov     [(VOIX ptr ds:di).effet],OFFSET retour
  1936. @@suite:
  1937.     mov     [(VOIX ptr ds:di).play],ax
  1938.  
  1939.     jmp    volume_up
  1940.  
  1941. ENDP
  1942.  
  1943. PROC portamento_down_volume_up
  1944.  
  1945.     mov     ax,[(VOIX ptr ds:di).play]
  1946.     add     ax,[(VOIX ptr ds:di).oldport]
  1947.     mov     bx,[(VOIX ptr ds:di).newnote]
  1948.     cmp     ax,bx
  1949.     jbe     @@suite
  1950.     mov     ax,bx
  1951.     mov     [(VOIX ptr ds:di).effet],OFFSET retour
  1952. @@suite:
  1953.     mov     [(VOIX ptr ds:di).play],ax
  1954.  
  1955.     jmp    volume_up
  1956. ENDP
  1957.  
  1958. PROC portamento_up_volume_down
  1959.  
  1960.     mov     ax,[(VOIX ptr ds:di).play]
  1961.     sub     ax,[(VOIX ptr ds:di).oldport]
  1962.     mov     bx,[(VOIX ptr ds:di).newnote]
  1963.     cmp     ax,bx
  1964.     jae     @@suite
  1965.     mov     ax,bx
  1966.     mov     [(VOIX ptr ds:di).effet],OFFSET retour
  1967. @@suite:
  1968.     mov     [(VOIX ptr ds:di).play],ax
  1969.  
  1970.     jmp    volume_down
  1971.  
  1972. ENDP
  1973.  
  1974. PROC portamento_down_volume_down
  1975.  
  1976.     mov     ax,[(VOIX ptr ds:di).play]
  1977.     add     ax,[(VOIX ptr ds:di).oldport]
  1978.     mov     bx,[(VOIX ptr ds:di).newnote]
  1979.     cmp     ax,bx
  1980.     jbe     @@suite
  1981.     mov     ax,bx
  1982.     mov     [(VOIX ptr ds:di).effet],OFFSET retour
  1983. @@suite:
  1984.     mov     [(VOIX ptr ds:di).play],ax
  1985.  
  1986.     jmp    volume_down
  1987. ENDP
  1988.  
  1989. PROC vibrato_volume_up
  1990.  
  1991.     mov    al,[(VOIX ptr ds:di).temp]
  1992.     shr    al,2
  1993.     and    al,1fh
  1994.     mov    bx,OFFSET SINUS
  1995.     xlat
  1996.     xor    ah,ah
  1997.     mul    [(VOIX PTR ds:di).amplit]
  1998.     shr    ax,6
  1999.     mov    bx,[(VOIX PTR ds:di).newnote]
  2000.     cmp    [(VOIX PTR ds:di).temp],0
  2001.     jg    @@add
  2002.     neg    ax
  2003. @@add:
  2004.     add    bx,ax
  2005.     mov    [(VOIX PTR ds:di).play],bx
  2006.     mov    al,[(VOIX PTR ds:di).vitesse]
  2007.     add    [(VOIX PTR ds:di).temp],al
  2008.  
  2009.     jmp    volume_up
  2010.  
  2011.     ret
  2012.  
  2013. ENDP
  2014.  
  2015. PROC vibrato_volume_down
  2016.  
  2017.     mov    al,[(VOIX ptr ds:di).temp]
  2018.     shr    al,2
  2019.     and    al,1fh
  2020.     mov    bx,OFFSET SINUS
  2021.     xlat
  2022.     xor    ah,ah
  2023.     mul    [(VOIX PTR ds:di).amplit]
  2024.     shr    ax,6
  2025.     mov    bx,[(VOIX PTR ds:di).newnote]
  2026.     cmp    [(VOIX PTR ds:di).temp],0
  2027.     jg    @@add
  2028.     neg    ax
  2029. @@add:
  2030.     add    bx,ax
  2031.     mov    [(VOIX PTR ds:di).play],bx
  2032.     mov    al,[(VOIX PTR ds:di).vitesse]
  2033.     add    [(VOIX PTR ds:di).temp],al
  2034.  
  2035.     jmp    volume_down
  2036.  
  2037.     ret
  2038.  
  2039. ENDP
  2040.  
  2041. PROC tremolo
  2042.  
  2043.     mov    al,[(VOIX ptr ds:di).tremolo]
  2044.     shr    al,2
  2045.     and    al,1fh
  2046.     mov    bx,OFFSET SINUS
  2047.     xlat
  2048.     xor    ah,ah
  2049.     mul    [(VOIX PTR ds:di).note1]
  2050.     shr    ax,6
  2051.  
  2052.     mov    bl,[(VOIX PTR ds:di).oldvol]
  2053.     cmp    [(VOIX PTR ds:di).tremolo],0
  2054.     jg    @@add
  2055.     neg    ax
  2056. @@add:
  2057.     or    [(VOIX PTR ds:di).gusinf],8
  2058.     mov    bh,[(VOIX PTR ds:di).tremvit]
  2059.     add    [(VOIX PTR ds:di).tremolo],bh
  2060.     add    bx,ax
  2061.     jl    @@volume_min
  2062.     cmp    bl,40h
  2063.     ja    @@volume_max
  2064.  
  2065.     mov    [(VOIX PTR ds:di).volume],bl
  2066.     ret
  2067.  
  2068. @@volume_min:
  2069.     mov    [(VOIX PTR ds:di).volume],0
  2070.     ret
  2071.  
  2072. @@volume_max:
  2073.     mov    [(VOIX PTR ds:di).volume],40h
  2074.     ret
  2075. ENDP
  2076.  
  2077. PROC volume_up
  2078.         or    [(VOIX ptr ds:di).gusinf],8
  2079.     mov     al,[(VOIX ptr ds:di).volume]
  2080.     add     al,[(VOIX ptr ds:di).extra]
  2081.     cmp     al,40h
  2082.     jbe     @@ok
  2083.     mov     al,40h
  2084. @@ok:
  2085.     mov     [(VOIX ptr ds:di).volume],al
  2086.  
  2087.     ret
  2088.  
  2089. ENDP
  2090.  
  2091. PROC volume_down
  2092.         or    [(VOIX ptr ds:di).gusinf],8
  2093.     mov     al,[(VOIX ptr ds:di).volume]
  2094.     sub     al,[(VOIX ptr ds:di).extra]
  2095.     jge     @@ok
  2096.     xor     al,al
  2097. @@ok:
  2098.     mov     [(VOIX ptr ds:di).volume],al
  2099.  
  2100.     ret
  2101.  
  2102. ENDP
  2103.  
  2104. PROC    retrig_sample
  2105.  
  2106.     dec    [(VOIX PTR ds:di).note1]
  2107.     je    @@retrig
  2108.     ret
  2109.  
  2110. @@retrig:
  2111.     mov    [(dword ptr (VOIX PTR ds:di).adrvoc)],0
  2112.     or      [(VOIX ptr ds:di).gusinf],02h
  2113.     mov    al,[(VOIX PTR ds:di).extra]
  2114.     mov    [(byte ptr (VOIX PTR ds:di).note1)],al
  2115.  
  2116.     ret
  2117.  
  2118. ENDP
  2119.  
  2120. PROC    cut_note
  2121.  
  2122.     dec    [(VOIX PTR ds:di).note1]
  2123.     je    @@cut_note
  2124.     ret
  2125.  
  2126. @@cut_note:
  2127.         or    [(VOIX PTR ds:di).gusinf],8
  2128.     mov    [(VOIX PTR ds:di).volume],0
  2129.     mov    [(VOIX PTR ds:di).effet],OFFSET retour
  2130.  
  2131.     ret
  2132.  
  2133. ENDP
  2134.  
  2135.  
  2136. PROC    delay_note
  2137.  
  2138.     dec    [(VOIX PTR ds:di).note1]
  2139.     je    @@delay_note
  2140.     ret
  2141.  
  2142. @@delay_note:
  2143.         or    [(VOIX PTR ds:di).gusinf],8
  2144.     mov    al,[(VOIX PTR ds:di).oldvol]
  2145.     mov    [(VOIX PTR ds:di).volume],al
  2146.     mov    [(VOIX PTR ds:di).effet],OFFSET retour
  2147.  
  2148.     ret
  2149.  
  2150. ENDP
  2151.  
  2152.  
  2153.  
  2154. Old_int        DD ?
  2155. Compteur    DW 1
  2156. Timer        DD 0
  2157. Compteur0    DW ?
  2158.  
  2159. ;**************************************************************************
  2160. ;*    Remet le pc à l'heure grace à Timer et Compteur0
  2161.  
  2162. PROC    resettime
  2163.  
  2164.     mov    eax,[ds:Timer]
  2165.     xor    ebx,ebx
  2166.     mov    bx,[ds:Compteur0]
  2167.     mul    ebx
  2168.     mov    ebx,1193180
  2169.     div    ebx
  2170.     xor    edx,edx
  2171.     mov    ebx,60
  2172.     div     ebx
  2173.     push    dx
  2174.     xor    edx,edx
  2175.     div    ebx
  2176.     push    dx
  2177.     push    ax
  2178.  
  2179.     mov    ah,2ch
  2180.     int    21h
  2181.  
  2182.     pop    ax
  2183.     add    ch,al
  2184.     pop    ax
  2185.     add    cl,al
  2186.     pop    ax
  2187.     add    dh,al
  2188.     cmp    dh,60
  2189.     jb    @@ok
  2190.     inc    cl
  2191.     sub    dh,60
  2192. @@ok:
  2193.     cmp    cl,60
  2194.     jb    @@ok2
  2195.     inc    ch
  2196.     sub    cl,60
  2197. @@ok2:
  2198.     mov    ah,2dh
  2199.     int    21h
  2200.  
  2201.  
  2202.     ret
  2203.  
  2204. ENDP
  2205.  
  2206. ;**************************************************************************
  2207. ;*      initialise le son
  2208.  
  2209. PROC    Startmod FAR
  2210.  
  2211.     push    ds
  2212.     push    es
  2213.     push    si
  2214.     push    di
  2215.  
  2216.     mov    ax,CSEG
  2217.     mov    ds,ax
  2218.  
  2219.     mov    bx,[Used_device]
  2220.  
  2221.     in    al,21h            ;arrête un maximum d'interruption
  2222.     mov    [ds:Int_Mask],al
  2223.     or    al,11111100b
  2224.     mov    ah,254
  2225.     mov    cl,[(DEVICE PTR ds:bx).irq]
  2226.     rol    ah,cl
  2227.     and    al,ah
  2228.         and    al,7Fh    ;testgus2
  2229.     push    ax
  2230.  
  2231.     mov    dx,[(DEVICE ptr ds:bx).start]
  2232.     call    dx
  2233.  
  2234.     pop    ax
  2235.     out    21h,al
  2236.  
  2237.         mov    [cs:Started],1
  2238.  
  2239.     pop    di
  2240.     pop    si
  2241.     pop    es
  2242.     pop    ds
  2243.  
  2244.     ret
  2245.  
  2246. ENDP
  2247.  
  2248. ;*************************************************************************
  2249. ;*      termine le son
  2250.  
  2251. PROC    Stopmod FAR
  2252.  
  2253.     push    ds
  2254.     push    si
  2255.     push    di
  2256.     mov    ax,CSEG
  2257.     mov    ds,ax
  2258.  
  2259.     cmp    [Started],1
  2260.     jne    @@no_stop
  2261.  
  2262.     cli
  2263.     mov    bx,[Used_device]
  2264.     mov    dx,[(DEVICE ptr ds:bx).stop]
  2265.     call    dx
  2266.  
  2267.     mov    al,[cs:Int_Mask]
  2268.     out    21h,al
  2269.     sti
  2270. @@no_stop:
  2271.  
  2272.     pop    di
  2273.     pop    si
  2274.     pop    ds
  2275.  
  2276.     ret
  2277.  
  2278. ENDP
  2279.  
  2280. ;***************************************************************************
  2281. ;*    Routine permettant d'enlever le son
  2282.  
  2283. PROC    setnul
  2284.  
  2285.     mov    [byte ptr cs:OFFSET start_mksnd],0cbh
  2286.  
  2287.     ret
  2288.  
  2289. ENDP
  2290.  
  2291. PROC    soundnul
  2292.  
  2293.     ret
  2294.  
  2295. ENDP
  2296.  
  2297. ;***************************************************************************
  2298. ;*    Routines sonores pour un DAC sur le port parallèle
  2299.  
  2300. LPT_ADR        EQU    8
  2301.  
  2302. ;**************************************************************************
  2303. ;*    Routine d'initialisation du DAC
  2304.  
  2305. PROC    setlpt
  2306.  
  2307.     mov    bx,[(DEVICE ptr ds:bx).port]
  2308.     mov    ax,40h
  2309.     mov    es,ax
  2310.     shl    bx,1
  2311.     mov    ax,[es:bx+LPT_ADR-2]
  2312.         or    ax,ax
  2313.         je    @@no_lpt
  2314.     mov    [ds:OFFSET port_dac+1],ax
  2315.  
  2316.     shr    [Voicelen],1
  2317.     clc
  2318.  
  2319.     ret
  2320.  
  2321. @@no_lpt:
  2322.     mov    ax,DAC_NOT_FOUND
  2323.         stc
  2324.         ret
  2325.  
  2326. ENDP
  2327.  
  2328. ;***************************************************************************
  2329. ;*    Passe en mode fin d'interruption automatique
  2330. ;*
  2331.  
  2332. PROC    setautoeoi
  2333.  
  2334.     mov    al,11h
  2335.     out    20h,al
  2336.     jmp    $+2
  2337.     jmp    $+2
  2338.     mov    al,8h
  2339.     out    21h,al
  2340.     jmp    $+2
  2341.     jmp    $+2
  2342.     mov    al,4h
  2343.     out    21h,al
  2344.     jmp    $+2
  2345.     jmp    $+2
  2346.     mov    al,3h
  2347.     out    21h,al
  2348.     jmp    $+2
  2349.     jmp    $+2
  2350.  
  2351.     ret
  2352.  
  2353. ENDP
  2354.  
  2355. ;***************************************************************************
  2356. ;*    Revient dans le mode fin d'interruption normale
  2357.  
  2358. PROC    reseteoi
  2359.  
  2360.     mov    al,11h
  2361.     out    20h,al
  2362.     jmp    $+2
  2363.     jmp    $+2
  2364.     mov    al,8h
  2365.     out    21h,al
  2366.     jmp    $+2
  2367.     jmp    $+2
  2368.     mov    al,4h
  2369.     out    21h,al
  2370.     jmp    $+2
  2371.     jmp    $+2
  2372.     mov    al,1h
  2373.     out    21h,al
  2374.     jmp    $+2
  2375.     jmp    $+2
  2376.  
  2377.     ret
  2378.  
  2379. ENDP
  2380.  
  2381. ;***************************************************************************
  2382. ;*    Cette routine permet de commencer l'envoit du son sur un DAC
  2383. ;*    il y a dans BX l'adresse de l'appareil selectionner
  2384.  
  2385. PROC    startlpt
  2386.  
  2387.     push    bx
  2388.  
  2389.     mov     ax,3508h
  2390.     int     21h
  2391.     mov     [word ptr cs:OFFSET Old_int],bx
  2392.     mov     [word ptr cs:OFFSET Old_int+2],es
  2393.  
  2394.     cli
  2395.     pop    bx
  2396.  
  2397.     mov    al,00110110b
  2398.     out     43h,al
  2399.     jmp    $+2
  2400.     jmp    $+2
  2401.  
  2402.     mov    dx,1
  2403.     xor    ax,ax
  2404.     div    [ds:Play_rate]
  2405.  
  2406.     mov    [ds:Compteur0],ax
  2407.     out     40h,al
  2408.     jmp    $+2
  2409.     jmp    $+2
  2410.     mov     al,ah
  2411.     out     40h,al
  2412.     jmp    $+2
  2413.     jmp    $+2
  2414.  
  2415.     mov    dx,[(DEVICE ptr ds:bx).sound]
  2416.     mov     ax,cs
  2417.     mov     ds,ax
  2418.     mov     ax,2508h
  2419.     int     21h
  2420.  
  2421.     call    setautoeoi
  2422.  
  2423.     sti
  2424.  
  2425.     ret
  2426. ENDP
  2427.  
  2428. ;**************************************************************************
  2429. ;*    cette procédure est en fait un bloc que l'on doit mettre à
  2430. ;*    l'adresse Voices
  2431.  
  2432. PROC    makelpt FAR
  2433.  
  2434.  
  2435.     mov    cx,[Nb_voice]
  2436.         sub    cl,2
  2437.     push    cx
  2438.  
  2439.     mov    di,OFFSET Voix1
  2440.     mov     dx,[Voix1.effet]
  2441.     call    dx
  2442.  
  2443.         mov    di,[ds:OFFSET Page_sound]
  2444.  
  2445.     mov    bx,[Voix1.play]
  2446.     shl    bx,1
  2447.     xor    edx,edx
  2448.     mov    dx,[word ptr ds:bx+OFFSET Notes]
  2449.  
  2450.     ror    edx,10
  2451.     mov    cx,[Voix1.endsamp]
  2452.     les    esi,[Voix1.adrvoc]
  2453.     mov    bx,[Voix1.lenrep]
  2454.     cmp    si,cx
  2455.     jbe    @@ok1
  2456. @@adjust1:
  2457.  
  2458.     sub    si,bx
  2459.     cmp    si,cx
  2460.     ja    @@adjust1
  2461. @@ok1:
  2462.  
  2463.     mov    bx,OFFSET Volume_tab
  2464.     mov    al,[MasterVol]
  2465.     mul    [Voix1.volume]
  2466.     add    bh,ah
  2467.  
  2468. @@voix1:
  2469.     add     esi,edx
  2470.     mov    al,[byte ptr es:si]
  2471.     adc    esi,edx
  2472.     xlat
  2473.     mov    ah,al
  2474.     mov    al,[byte ptr es:si]
  2475.     adc    si,0
  2476.     xlat
  2477.     mov    [ds:di],ax
  2478.     add    di,2
  2479.  
  2480.     cmp    di,bp
  2481.     jne    @@voix1
  2482.     rol    ebp,16
  2483. buf_sound2:
  2484.     mov    di,OFFSET BUF_SOUND
  2485. buf_sound3:
  2486.     cmp    bp,OFFSET BUF_SOUND+BUF_LEN
  2487.     jne    @@voix1
  2488.  
  2489.  
  2490.     mov    [dword ptr OFFSET Voix1.adrvoc],esi
  2491.  
  2492.     pop    cx
  2493.     mov    di,OFFSET Voix2
  2494. @@next_voice:
  2495.     push    cx
  2496.     mov     dx,[(VOIX ptr ds:di).effet]
  2497.     call    dx
  2498.  
  2499.     mov    bx,[(VOIX ptr ds:di).play]
  2500.     shl    bx,1
  2501.     xor    edx,edx
  2502.     mov    dx,[word ptr ds:bx+OFFSET Notes]
  2503.     ror    edx,10
  2504.     mov    cx,[(VOIX ptr ds:di).endsamp]
  2505.     les    esi,[(VOIX ptr ds:di).adrvoc]
  2506.     mov    bx,[(VOIX ptr ds:di).lenrep]
  2507.     cmp    si,cx
  2508.     jbe    @@ok2
  2509. @@adjust2:
  2510.     sub    si,bx
  2511.     cmp    si,cx
  2512.     ja    @@adjust2
  2513. @@ok2:
  2514.  
  2515.     mov    bx,OFFSET Volume_tab
  2516.     mov    al,[MasterVol]
  2517.     mul    [(VOIX ptr ds:di).volume]
  2518.     add    bh,ah
  2519.  
  2520.     push    di
  2521.  
  2522.     mov    ebp,[ds:OFFSET Page_end]
  2523.     mov    di,[ds:OFFSET Page_sound]
  2524. @@voix2:
  2525.     add     esi,edx
  2526.     mov    al,[byte ptr es:si]
  2527.     adc    esi,edx
  2528.     xlat
  2529.     mov    ah,al
  2530.     mov    al,[byte ptr es:si]
  2531.     adc    si,0
  2532.     xlat
  2533.     add    [ds:di],ax
  2534.     add    di,2
  2535.  
  2536.     cmp    di,bp
  2537.     jne    @@voix2
  2538.     rol    ebp,16
  2539. buf_sound4:
  2540.     mov    di,OFFSET BUF_SOUND
  2541. buf_sound5:
  2542.     cmp    bp,OFFSET BUF_SOUND+BUF_LEN
  2543.     jne    @@voix2
  2544.  
  2545.  
  2546.         pop    di
  2547.     mov    [dword ptr ((VOIX ptr ds:di).adrvoc)],esi
  2548.         add    di,SIZE VOIX
  2549.         pop    cx
  2550.         dec    cl
  2551.         jne    @@next_voice
  2552.  
  2553.     mov     dx,[(VOIX ptr ds:di).effet]
  2554.     call    dx
  2555.  
  2556.     mov    bx,[(VOIX ptr ds:di).play]
  2557.     shl    bx,1
  2558.     xor    edx,edx
  2559.     mov    dx,[word ptr ds:bx+OFFSET Notes]
  2560.     ror    edx,10
  2561.     mov    cx,[(VOIX ptr ds:di).endsamp]
  2562.     les    esi,[(VOIX ptr ds:di).adrvoc]
  2563.     mov    bx,[(VOIX ptr ds:di).lenrep]
  2564.     cmp    si,cx
  2565.     jbe    @@ok4
  2566. @@adjust4:
  2567.     sub    si,bx
  2568.     cmp    si,cx
  2569.     ja    @@adjust4
  2570. @@ok4:
  2571.  
  2572.     mov    bx,OFFSET Volume_tab
  2573.     mov    al,[MasterVol]
  2574.     mul    [(VOIX ptr ds:di).volume]
  2575.     add    bh,ah
  2576.  
  2577.     push    di
  2578.         mov    ebp,[ds:OFFSET Page_end]
  2579.     mov    di,[ds:OFFSET Page_sound]
  2580. @@voix4:
  2581.     add     esi,edx
  2582.     mov    al,[byte ptr es:si]
  2583.     adc    esi,edx
  2584.     xlat
  2585.     mov    ah,al
  2586.     mov    al,[byte ptr es:si]
  2587.     adc    si,0
  2588.     xlat
  2589.     add    ax,[ds:di]
  2590.     sub    ah,128
  2591.     sub    al,128
  2592.     mov    [ds:di],ax
  2593.     add    di,2
  2594.  
  2595.     cmp    di,bp
  2596.     jne    @@voix4
  2597.     rol    ebp,16
  2598. buf_sound8:
  2599.     mov    di,OFFSET BUF_SOUND
  2600. buf_sound9:
  2601.     cmp    bp,OFFSET BUF_SOUND+BUF_LEN
  2602.     jne    @@voix4
  2603.  
  2604.         pop    di
  2605.     mov    [dword ptr ((VOIX ptr ds:di).adrvoc)],esi
  2606.  
  2607. @@fin4voice:
  2608.  
  2609.     shr    ebp,16
  2610.     and    bp,65535-BUF_LEN
  2611.     mov    [word ptr ds:OFFSET Page_sound],bp
  2612.  
  2613. @@fin:
  2614.     pop    di
  2615.     pop    si
  2616.     pop    bp
  2617.     pop    es
  2618.     pop    ds
  2619.  
  2620.     ret
  2621.  
  2622. ENDP
  2623.  
  2624. nop
  2625.  
  2626. ;***************************************************************************
  2627. ;*      interruption 8 permettant d'envoyer le son sur un port parallèle
  2628.  
  2629. PROC    soundlpt FAR
  2630.  
  2631.       push      ax
  2632.       push      bx
  2633.  
  2634.       inc       [dword ptr cs:OFFSET Timer]
  2635.  
  2636.       mov       bx,[cs:OFFSET Ptr_sound]
  2637.       inc    bx
  2638.       and       bx,65535-BUF_LEN
  2639.       mov       [cs:OFFSET Ptr_sound],bx
  2640.       mov       al,[cs:bx]
  2641.  
  2642.       push    dx
  2643. port_dac:
  2644.       mov    dx,378h
  2645.       out       dx,al
  2646.       pop    dx
  2647.  
  2648.       pop       bx
  2649.       dec       [cs:Compteur]
  2650.       jz        @@int08
  2651.  
  2652.       pop       ax
  2653.       iret
  2654.  
  2655. @@int08:
  2656.     mov    ax,[cs:Play_rate]
  2657.         mov    [cs:Compteur],ax
  2658.  
  2659.       pop    ax
  2660.       jmp    [dword ptr cs:Old_int]
  2661.  
  2662.       mov    ax,[cs:Voicelen]
  2663.       mov       [cs:Compteur],ax
  2664.       pushad
  2665.       call    Makemod
  2666.       popad
  2667.       pop    ax
  2668.       iret
  2669.  
  2670. ENDP
  2671.  
  2672. ;***************************************************************************
  2673. ;*    Cette routine permet d'arreter l'envoit du son sur un DAC
  2674.  
  2675. PROC    stoplpt
  2676.  
  2677.     mov     al,00110110b
  2678.     out     43h,al
  2679.         xor    al,al
  2680.     out     40h,al
  2681.     out     40h,al
  2682.  
  2683.     call    reseteoi
  2684.  
  2685.     call    resettime
  2686.  
  2687.     mov     ax,2508h
  2688.     lds     dx,[dword ptr cs:OFFSET Old_int]
  2689.     int     21h
  2690.  
  2691.     ret
  2692.  
  2693. ENDP
  2694.  
  2695.  
  2696. UsedIrq     DB 0
  2697.  
  2698.  
  2699. ;***************************************************************************
  2700. ;*    Cette routine remplace d'interruption 5 et est appelé quand la
  2701. ;*    restitution de la musique à été interromput
  2702.  
  2703. PROC    Sbend
  2704.  
  2705.     push    ax
  2706.     push    bx
  2707.     push    dx
  2708.  
  2709.     mov    bx,[cs:Used_device]
  2710.     mov    dx,[(DEVICE PTR cs:bx).port]
  2711.     add    dx,0eh
  2712.     in    al,dx
  2713.     sub    dx,2
  2714.  
  2715.     mov    ax,[cs:Sb_len]
  2716.     add    [cs:Ptr_sound],ax
  2717.     and     [cs:Ptr_sound],65535-BUF_LEN
  2718.  
  2719.     mov    al,20h
  2720.     out    20h,al
  2721.  
  2722.     pop    dx
  2723.     pop    bx
  2724.     pop    ax
  2725.  
  2726.     iret
  2727. ENDP
  2728.  
  2729. ;***************************************************************************
  2730. ;*    Cette routine remplace d'interruption 5
  2731.  
  2732. PROC    Sbint
  2733.  
  2734.     push    ax
  2735.     push    bx
  2736.     push    dx
  2737.  
  2738.     mov    bx,[cs:Used_device]
  2739.     mov    dx,[(DEVICE PTR cs:bx).port]
  2740.     add    dx,0eh
  2741.     in    al,dx
  2742.     sub    dx,2
  2743.  
  2744. @@wait1:
  2745.     in    al,dx
  2746.     or    al,al
  2747.     js    @@wait1
  2748.     mov    al,14h
  2749.     out    dx,al
  2750.  
  2751. @@wait2:
  2752.     in    al,dx
  2753.     or    al,al
  2754.     js    @@wait2
  2755.     mov    ax,[cs:Sb_len]
  2756.     add    [cs:Ptr_sound],ax
  2757.     and     [cs:Ptr_sound],65535-BUF_LEN
  2758.     dec    ax
  2759.     out     dx,al
  2760.  
  2761. @@wait3:
  2762.     in    al,dx
  2763.     or    al,al
  2764.     js    @@wait3
  2765.     mov    al,ah
  2766.     out    dx,al
  2767.  
  2768.     mov    al,20h
  2769.     out    20h,al
  2770.  
  2771.     pop    dx
  2772.     pop    bx
  2773.     pop    ax
  2774.  
  2775.     iret
  2776. ENDP
  2777.  
  2778. Sb_freq    DB ?
  2779. Page_DMA DB ?
  2780. Int_Mask DB ?
  2781. Started    DB 0
  2782. Sb_len  DW ?
  2783.  
  2784.  
  2785. ;***************************************************************************
  2786. ;*    routine permettant d'initialiser le son sur la soundblaster
  2787.  
  2788. PROC    setsb
  2789.  
  2790.     mov    dx,[(DEVICE ptr ds:bx).port]
  2791. @@next_try:
  2792.     add    dx,6
  2793.     mov    al,1
  2794.     out    dx,al
  2795.     mov    cx,256    ;compte des moutons pendant au moins 3µs
  2796. @@compte:
  2797.     loop    @@compte
  2798.     dec    al
  2799.     out    dx,al
  2800.     add    dx,4
  2801.     mov    cx,64
  2802. @@test:
  2803.     in    al,dx
  2804.     cmp    al,0aah
  2805.     je    @@ok
  2806.     loop    @@test
  2807.     stc
  2808.     mov    ax,SB_NOT_FOUND
  2809.     ret
  2810. @@ok:
  2811.     sub    dx,0ah
  2812.     mov    [(DEVICE ptr ds:bx).port],dx
  2813.     push    dx
  2814.  
  2815.     mov    al,[(DEVICE PTR ds:bx).irq]
  2816.     add    al,8
  2817.     mov    ah,35h
  2818.     int    21h
  2819.     mov    [word ptr cs:OFFSET Old_int],bx
  2820.     mov    [word ptr cs:OFFSET Old_int+2],es
  2821.     shr    [Voicelen],1
  2822.  
  2823.     mov    ax,[Voicelen]
  2824.  
  2825.     xor    cl,cl
  2826. @@search_msb:
  2827.     inc    cl
  2828.     shr    ax,1
  2829.     jne    @@search_msb
  2830.     sub        cl,2
  2831.     mov    ax,1
  2832.     shl    ax,cl
  2833.     mov    [Sb_len],ax
  2834.  
  2835.     mov    al,5          ;masque le canal 1
  2836.     out    0ah,al
  2837.  
  2838.     xor    dx,dx
  2839.     mov    ax,0D68Dh    ;1000000*65536/1193180
  2840.     div    [Play_rate]
  2841.     neg    ax
  2842.     mov    ah,al
  2843.  
  2844.     pop    dx
  2845.     add    dx,0ch
  2846. @@wait2:
  2847.     in    al,dx
  2848.     or    al,al
  2849.     js    @@wait2
  2850.     mov    al,40h
  2851.     out    dx,al
  2852.  
  2853. @@wait3:
  2854.     in    al,dx
  2855.     or    al,al
  2856.     js    @@wait3
  2857.     mov    al,ah
  2858.     out    dx,al        ; regle la fréquence
  2859.  
  2860. @@wait4:
  2861.     in    al,dx
  2862.     or    al,al
  2863.     js    @@wait4
  2864.     mov    al,14h
  2865.     out    dx,al        ; met en marche le transfert
  2866.  
  2867. @@wait5:
  2868.     in    al,dx
  2869.     or    al,al
  2870.     js    @@wait5
  2871.     mov    ax,[ds:Sb_len]
  2872.     dec    ax
  2873.     out    dx,al
  2874.  
  2875. @@wait6:
  2876.     in    al,dx
  2877.     or    al,al
  2878.     js    @@wait6
  2879.     mov    al,ah
  2880.     out    dx,al
  2881.  
  2882. @@wait7:            ; Arrête le transfert
  2883.     in    al,dx
  2884.     or    al,al
  2885.     js    @@wait7
  2886.     mov    al,0D0h
  2887.     out    dx,al
  2888.  
  2889.  
  2890.     xor    al,al         ;efface la bascule interne
  2891.     out    0ch,al
  2892.  
  2893.     mov    al,59h
  2894.     out    0bh,al        ;choix du mode
  2895.  
  2896.     mov    ax,cs
  2897.     mov     cx,ax
  2898.     shr    ch,4
  2899.     shl    ax,4
  2900.     add    ax,OFFSET BUF_SOUND
  2901.     cmp    ax,65536-BUF_LEN
  2902.     jb    @@ok1
  2903.     add    ax,BUF_LEN*2
  2904.     adc    ch,0
  2905.     add    [word ptr cs:buf_sound1+2],BUF_LEN*2
  2906.     add    [word ptr cs:buf_sound2+1],BUF_LEN*2
  2907.     add    [word ptr cs:buf_sound3+2],BUF_LEN*2
  2908.     add    [word ptr cs:buf_sound4+1],BUF_LEN*2
  2909.     add    [word ptr cs:buf_sound5+2],BUF_LEN*2
  2910.     add    [word ptr cs:buf_sound8+1],BUF_LEN*2
  2911.     add    [word ptr cs:buf_sound9+2],BUF_LEN*2
  2912.     add    [word ptr cs:buf_sound10+1],BUF_LEN*2
  2913.     add    [cs:Page_sound],BUF_LEN*2
  2914.     add    [cs:Ptr_sound],BUF_LEN*2
  2915. @@ok1:
  2916.  
  2917.     out    2,al        ; place l'adresse de base
  2918.     mov    al,ah
  2919.     out    2,al
  2920.     mov    al,ch
  2921.     out    83h,al
  2922.     mov    ax,BUF_LEN
  2923.     dec    ax
  2924.     out    3,al        ; place la longueur du bloc
  2925.     mov    al,ah
  2926.     out    3,al
  2927.  
  2928.     clc
  2929.  
  2930.     ret
  2931.  
  2932. ENDP
  2933.  
  2934. ;***************************************************************************
  2935. ;*    routine permettant de démarrer l'envoit du son sur la soundblaster
  2936.  
  2937. PROC    startsb
  2938.  
  2939.     cli
  2940.  
  2941.     mov    dx,OFFSET Sbint
  2942.     mov    al,[(DEVICE PTR ds:bx).irq]
  2943.     add    al,8
  2944.     mov    ah,25h
  2945.     int    21h
  2946.  
  2947.     sti
  2948.  
  2949.     mov    dx,[(DEVICE PTR ds:bx).port]
  2950.     add    dx,0ch
  2951. @@wait1:
  2952.     in    al,dx
  2953.     or    al,al
  2954.     js    @@wait1
  2955.     mov    al,0d1h
  2956.     out    dx,al            ; allume le haut parleur
  2957.  
  2958. @@wait2:
  2959.     in    al,dx
  2960.     or    al,al
  2961.     js    @@wait2
  2962.     mov    al,0d4h
  2963.     out    dx,al            ; poursuit le transfert DMA
  2964.  
  2965.     mov    al,1
  2966.     out    0ah,al        ; autorise le canal
  2967.  
  2968.     ret
  2969.  
  2970. ENDP
  2971.  
  2972. ;***************************************************************************
  2973. ;*    Cette routine permet d'arreter l'envoit du son sur une soundblaster
  2974.  
  2975. PROC    stopsb
  2976.  
  2977.     mov    dx,[(DEVICE ptr ds:bx).port]
  2978.     add    dx,0ch
  2979.  
  2980. @@wait1:
  2981.     in    al,dx
  2982.     or    al,al
  2983.     js    @@wait1
  2984.     mov    al,0D0h
  2985.     out    dx,al        ; Stop le transfert DMA
  2986.  
  2987. @@wait:
  2988.     in    al,dx
  2989.     or    al,al
  2990.     js    @@wait
  2991.     mov    al,0d3h
  2992.     out    dx,al        ; éteint le haut parleur
  2993.  
  2994.     mov    al,5          ;masque le canal 1
  2995.     out    0ah,al
  2996.  
  2997.     mov    ah,25h
  2998.     mov    al,[(DEVICE PTR ds:bx).irq]
  2999.     add    al,8
  3000.     lds    dx,[dword ptr cs:OFFSET Old_int]
  3001.     int    21h
  3002.  
  3003.     ret
  3004.  
  3005. ENDP
  3006.  
  3007.  
  3008. ;***************************************************************************
  3009. ;*    routine permettant d'initialiser le speaker
  3010.  
  3011. PROC    setspk
  3012.  
  3013.     shr    [Play_rate],1
  3014.     shr    [Voicelen],1
  3015.     clc
  3016.  
  3017.     ret
  3018. ENDP
  3019.  
  3020. ;***************************************************************************
  3021. ;*    routine permettant de démarrer l'envoit du son sur le speaker
  3022.  
  3023. PROC    startspk
  3024.  
  3025.     push    bx
  3026.  
  3027.     mov     ax,3508h
  3028.     int     21h
  3029.     mov     [word ptr cs:OFFSET Old_int],bx
  3030.     mov     [word ptr cs:OFFSET Old_int+2],es
  3031.  
  3032.     cli
  3033.     pop    bx
  3034.  
  3035.     mov    al,00110110b
  3036.     out     43h,al
  3037.     jmp    $+2
  3038.     jmp    $+2
  3039.  
  3040.     mov    dx,1
  3041.     xor    ax,ax
  3042.     div    [ds:Play_rate]
  3043.     shr    ax,1
  3044.  
  3045.     mov    [ds:Compteur0],ax
  3046.     out     40h,al
  3047.     jmp    $+2
  3048.     jmp    $+2
  3049.     mov     al,ah
  3050.     out     40h,al
  3051.     jmp    $+2
  3052.     jmp    $+2
  3053.  
  3054.     mov    al,10010000b  ;10010000b
  3055.     out     43h,al
  3056.     jmp    $+2
  3057.     jmp    $+2
  3058.     in      al,61h
  3059.     jmp    $+2
  3060.     jmp    $+2
  3061.     or      al,11b
  3062.     out     61h,al
  3063.     jmp    $+2
  3064.     jmp    $+2
  3065.  
  3066.  
  3067.     mov    dx,[(DEVICE ptr ds:bx).sound]
  3068.     mov     ax,cs
  3069.     mov     ds,ax
  3070.     mov     ax,2508h
  3071.     int     21h
  3072.  
  3073.     call    setautoeoi
  3074.  
  3075.     mov    al,20h
  3076.     out    20h,al
  3077.  
  3078.     sti
  3079.  
  3080.     ret
  3081.  
  3082. ENDP
  3083.  
  3084. ;**************************************************************************
  3085. ;*    cette procédure est en fait un bloc que l'on doit mettre à
  3086. ;*    l'adresse Voices
  3087.  
  3088. PROC    makespk FAR
  3089.  
  3090.     mov    cx,[Nb_voice]
  3091.     sub    cl,2
  3092.         push    cx
  3093.  
  3094.  
  3095.     mov    di,OFFSET Voix1
  3096.     mov     dx,[Voix1.effet]
  3097.     call    dx
  3098.         mov    di,[ds:OFFSET Page_sound]
  3099.  
  3100.     mov    bx,[Voix1.play]
  3101.     shl    bx,1
  3102.     xor    edx,edx
  3103.     mov    dx,[word ptr ds:bx+OFFSET Notes]
  3104.     ror    edx,10
  3105.     mov    cx,[Voix1.endsamp]
  3106.     les    esi,[Voix1.adrvoc]
  3107.     mov    bx,[Voix1.lenrep]
  3108.     cmp    si,cx
  3109.     jbe    @@ok1
  3110. @@adjust1:
  3111.     sub    si,bx
  3112.     cmp    si,cx
  3113.     ja    @@adjust1
  3114. @@ok1:
  3115.  
  3116.     mov    bx,OFFSET Volume_tab
  3117.     mov    al,[MasterVol]
  3118.     mul    [Voix1.volume]
  3119. ;    add    al,[Voix1.volume]
  3120.     add    bh,ah
  3121.  
  3122. @@voix1:
  3123.     add     esi,edx
  3124.     mov    al,[byte ptr es:si]
  3125.     adc    esi,edx
  3126.     xlat
  3127.     mov    ah,al
  3128.     mov    al,[byte ptr es:si]
  3129.     adc    si,0
  3130.     xlat
  3131.     mov    [ds:di],ax
  3132.     add    di,4
  3133.  
  3134.     cmp    di,bp
  3135.     jne    @@voix1
  3136.     rol    ebp,16
  3137.     mov    di,OFFSET BUF_SOUND
  3138.     cmp    bp,OFFSET BUF_SOUND+BUF_LEN
  3139.     jne    @@voix1
  3140.  
  3141.     mov    [dword ptr OFFSET Voix1.adrvoc],esi
  3142.  
  3143.         pop    cx
  3144.         mov    di,OFFSET Voix2
  3145. @@next_voice:
  3146.     push    cx
  3147.     mov     dx,[(VOIX ptr ds:di).effet]
  3148.     call    dx
  3149.  
  3150.     mov    bx,[(VOIX ptr ds:di).play]
  3151.     shl    bx,1
  3152.     xor    edx,edx
  3153.     mov    dx,[word ptr ds:bx+OFFSET Notes]
  3154.     ror    edx,10
  3155.     mov    cx,[(VOIX ptr ds:di).endsamp]
  3156.     mov    bx,OFFSET Volume_tab
  3157.     mov    al,[MasterVol]
  3158.     mul    [(VOIX ptr ds:di).volume]
  3159. ;    add    al,[(VOIX ptr ds:di).volume]
  3160.     add    bh,ah
  3161.     mov    ax,[(VOIX ptr ds:di).lenrep]
  3162.     push    di
  3163.     les    esi,[(VOIX ptr ds:di).adrvoc]
  3164.     cmp    si,cx
  3165.     jbe    @@ok2
  3166. @@adjust2:
  3167.     sub    si,ax
  3168.     cmp    si,cx
  3169.     ja    @@adjust2
  3170. @@ok2:
  3171.  
  3172.     mov    ebp,[ds:OFFSET Page_end]
  3173.     mov    di,[ds:OFFSET Page_sound]
  3174.  
  3175. @@voix2:
  3176.     add     esi,edx
  3177.     mov     al,[byte ptr es:si]
  3178.     adc    esi,edx
  3179.     xlat
  3180.     mov    ah,al
  3181.     mov    al,[byte ptr es:si]
  3182.     adc    si,0
  3183.     xlat
  3184.     add     [ds:di],ax
  3185.     add    di,4
  3186.  
  3187.     cmp    di,bp
  3188.     jne    @@voix2
  3189.     rol    ebp,16
  3190.     mov    di,OFFSET BUF_SOUND
  3191.     cmp    bp,OFFSET BUF_SOUND+BUF_LEN
  3192.     jne    @@voix2
  3193.  
  3194.  
  3195.     pop    di
  3196.     mov    [dword ptr ((VOIX ptr ds:di).adrvoc)],esi
  3197.     add    di,SIZE VOIX
  3198.  
  3199.     pop    cx
  3200.     dec    cl
  3201.     jne    @@next_voice
  3202.  
  3203.     mov     dx,[(VOIX ptr ds:di).effet]
  3204.     call    dx
  3205.  
  3206.     mov    bx,[(VOIX ptr ds:di).play]
  3207.     shl    bx,1
  3208.     xor    edx,edx
  3209.     mov    dx,[word ptr ds:bx+OFFSET Notes]
  3210.     ror    edx,10
  3211.     mov    cx,[(VOIX ptr ds:di).endsamp]
  3212.     les    esi,[(VOIX ptr ds:di).adrvoc]
  3213.     mov    bx,[(VOIX ptr ds:di).lenrep]
  3214.     cmp    si,cx
  3215.     jbe    @@ok4
  3216. @@adjust4:
  3217.     sub    si,bx
  3218.     cmp    si,cx
  3219.     ja    @@adjust4
  3220. @@ok4:
  3221.  
  3222.     mov    bx,OFFSET Volume_tab
  3223.     mov    al,[MasterVol]
  3224.     mul    [(VOIX ptr ds:di).volume]
  3225. ;    add    al,[(VOIX ptr ds:di).volume]
  3226.     add    bh,ah
  3227.     push    di
  3228.     mov    ebp,[ds:OFFSET Page_end]
  3229.     mov    di,[ds:OFFSET Page_sound]
  3230.  
  3231. @@voix4:
  3232.     add     esi,edx
  3233.     mov     al,[byte ptr es:si]
  3234.     adc    esi,edx
  3235.     xlat
  3236.     mov    ah,al
  3237.     mov    al,[byte ptr es:si]
  3238.     adc    si,0
  3239.     xlat
  3240.     add     ax,[ds:di]
  3241.     mov    [ds:di],ah
  3242.     mov    [ds:di+1],ah
  3243.     mov    ah,al
  3244.     mov    [ds:di+2],ax
  3245.     add    di,4
  3246.  
  3247.     cmp    di,bp
  3248.     jne    @@voix4
  3249.     rol    ebp,16
  3250.     mov    di,OFFSET BUF_SOUND
  3251.     cmp    bp,OFFSET BUF_SOUND+BUF_LEN
  3252.     jne    @@voix4
  3253.  
  3254.     pop    di
  3255.     mov    [dword ptr ((VOIX ptr ds:di).adrvoc)],esi
  3256.  
  3257. @@fin4voix:
  3258.  
  3259.     shr    ebp,16
  3260.     and    bp,65535-BUF_LEN
  3261.     mov    [word ptr ds:OFFSET Page_sound],bp
  3262.  
  3263. @@fin:
  3264.     pop    di
  3265.     pop    si
  3266.     pop    bp
  3267.     pop    es
  3268.     pop    ds
  3269.  
  3270.     ret
  3271.  
  3272. ENDP
  3273.  
  3274. ;***************************************************************************
  3275. ;*      interruption 8 permettant d'envoyer le son sur le speaker
  3276.  
  3277. PROC    soundspk FAR
  3278.  
  3279.       push      ax
  3280.       push      bx
  3281.  
  3282.       inc    [dword ptr cs:OFFSET Timer]
  3283.  
  3284.       mov    bx,[cs:OFFSET Ptr_sound]
  3285.       inc       bx
  3286.       and       bx,65535-BUF_LEN
  3287.       mov       [cs:OFFSET Ptr_sound],bx
  3288.       mov       al,[cs:bx]
  3289.  
  3290.       mov       bx,OFFSET VOLUME
  3291.       xlat      [cs:bx]
  3292.  
  3293.       out       42h,al
  3294.  
  3295.       pop    bx
  3296.       dec       [cs:Compteur]
  3297.       jz        @@int08
  3298.  
  3299.       pop       ax
  3300.       iret
  3301.  
  3302. @@int08:
  3303.     mov    ax,[cs:Play_rate]
  3304.         mov    [cs:Compteur],ax
  3305.  
  3306.       pop    ax
  3307.       jmp    [dword ptr cs:Old_int]
  3308.  
  3309.       mov    ax,[cs:Voicelen]
  3310.       mov       [cs:Compteur],ax
  3311.       pushad
  3312.       call    Makemod
  3313.       popad
  3314.       pop    ax
  3315.       iret
  3316.  
  3317. ENDP
  3318.  
  3319. Flag    DB 0
  3320.  
  3321. ;***************************************************************************
  3322. ;*    cette routine permet d'arreter l'envoit du son sur le speaker
  3323.  
  3324. PROC    stopspk
  3325.  
  3326.     in    al,61h
  3327.     and     al,11111100b
  3328.     out    61h,al
  3329.  
  3330.     mov     al,00110110b
  3331.     out     43h,al
  3332.         xor    al,al
  3333.     out     40h,al
  3334.     out     40h,al
  3335.  
  3336.     call    reseteoi
  3337.  
  3338.     call    resettime
  3339.  
  3340.     mov     ax,2508h
  3341.     lds     dx,[dword ptr cs:OFFSET Old_int]
  3342.     int     21h
  3343.  
  3344.     mov    al,20h
  3345.     out    20h,al
  3346.  
  3347.     ret
  3348.  
  3349. ENDP
  3350.  
  3351. VOLUME          DB 20h,1fh,1eh,1dh,1ch,1bh,1ah,19h
  3352.         DB 18h,17h,16h,15h,14h,13h,12h,11h
  3353.         DB 11h,10h,10h,0fh,0fh,0eh,0eh,0dh
  3354.         DB 0dh,0dh,0ch,0ch,0ch,0ch,0bh,0bh
  3355.         DB 0bh,0bh,0ah,0ah,0ah,0ah,0ah,09h
  3356.         DB 09h,09h,09h,09h,09h,09h,09h,09h
  3357.         DB 08h,08h,08h,08h,08h,08h,08h,08h
  3358.         DB 08h,08h,08h,08h,07h,07h,07h,07h
  3359.         DB 07h,07h,07h,06h,06h,06h,06h,06h
  3360.         DB 06h,06h,06h,06h,06h,06h,05h,05h
  3361.         DB 05h,05h,05h,05h,05h,05h,05h,05h
  3362.         DB 04h,04h,04h,04h,04h,04h,04h,04h
  3363.         DB 04h,04h,03h,03h,03h,03h,03h,03h
  3364.         DB 03h,03h,03h,03h,02h,02h,02h,02h
  3365.         DB 02h,02h,02h,02h,02h,01h,01h,01h
  3366.         DB 01h,01h,01h,01h,01h,01h,01h,01h
  3367.         DB 40h,40h,40h,40h,40h,40h,40h,40h
  3368.         DB 40h,40h,3fh,3fh,3fh,3fh,3fh,3fh
  3369.         DB 3fh,3fh,3fh,3fh,3fh,3fh,3eh,3eh
  3370.         DB 3eh,3eh,3eh,3eh,3eh,3eh,3eh,3eh
  3371.         DB 3dh,3dh,3dh,3dh,3dh,3dh,3dh,3dh
  3372.         DB 3dh,3ch,3ch,3ch,3ch,3ch,3ch,3ch
  3373.         DB 3ch,3ch,3ch,3bh,3bh,3bh,3bh,3bh
  3374.         DB 3bh,3bh,3bh,3bh,3bh,3ah,3ah,3ah
  3375.         DB 3ah,3ah,3ah,3ah,3ah,3ah,3ah,39h
  3376.         DB 39h,39h,39h,39h,39h,39h,39h,39h
  3377.         DB 39h,38h,38h,38h,38h,38h,38h,38h
  3378.         DB 38h,37h,37h,37h,37h,37h,36h,36h
  3379.         DB 36h,36h,35h,35h,35h,35h,34h,34h
  3380.         DB 34h,33h,33h,32h,32h,31h,31h,30h
  3381.         DB 30h,2fh,2eh,2dh,2ch,2bh,2ah,29h
  3382.         DB 28h,27h,26h,25h,24h,23h,22h,21h
  3383.  
  3384. ;***************************************************************************
  3385. ;*    Routines sonores pour la Gravis ultra sound
  3386.  
  3387. STRUC GUSDATA
  3388.  
  3389.     action        DB    ?
  3390.             DW      ?
  3391.             DB      ?
  3392.     note        DW    ?
  3393.     volume        DW    ?
  3394.     repadr        DD    ?
  3395.     endadr        DD    ?
  3396.     curadr        DD    ?
  3397.             DD    ?
  3398.             DD    ?
  3399.             DD    ?
  3400.  
  3401. ENDS
  3402.  
  3403. GusMem    DD    0
  3404.  
  3405. GusSample DD 32 DUP (?)    ; Adresse des samples dans la mémoire de la GUS
  3406.  
  3407. ;***************************************************************************
  3408. ;*    Routine permettant d'écrire un octet dans la GUS
  3409. ;*
  3410. ;* Entrée:
  3411. ;*    DX    adresse de port de la GUS
  3412. ;*    EBX    adresse où écrire
  3413. ;*    AL    donné à écrire
  3414.  
  3415. PROC    putgus
  3416.  
  3417.     push    cx
  3418.  
  3419.     mov    cl,al
  3420.     mov    al,43h
  3421.     out    dx,al
  3422.  
  3423.     inc    dx
  3424.     mov    eax,ebx
  3425.     out    dx,ax
  3426.  
  3427.     dec    dx
  3428.     mov    al,44h
  3429.     out    dx,al
  3430.  
  3431.     add    dx,2
  3432.     shr    eax,16
  3433.     out    dx,al
  3434.  
  3435.     add    dx,2
  3436.     mov    al,cl
  3437.     out    dx,al
  3438.  
  3439.     sub    dx,4
  3440.  
  3441.     pop    cx
  3442.  
  3443.     ret
  3444.  
  3445. ENDP
  3446.  
  3447. ;***************************************************************************
  3448. ;*    Routine permettant de lire un octet de la RAM de la GUS
  3449. ;*
  3450. ;* Entrée:
  3451. ;*    DX    adresse de port de la GUS
  3452. ;*    EBX    adresse à lire
  3453. ;*
  3454. ;* Sortie:
  3455. ;*    AL    octet lus
  3456.  
  3457. PROC    getgus
  3458.  
  3459.     mov    al,43h
  3460.     out    dx,al
  3461.  
  3462.     inc    dx
  3463.     mov    eax,ebx
  3464.     out    dx,ax
  3465.  
  3466.     dec    dx
  3467.     mov    al,44h
  3468.     out    dx,al
  3469.  
  3470.     add    dx,2
  3471.     shr    eax,16
  3472.     out    dx,al
  3473.  
  3474.     add    dx,2
  3475.     in    al,dx
  3476.  
  3477.     sub    dx,4
  3478.  
  3479.     ret
  3480.  
  3481. ENDP
  3482.  
  3483. ;***************************************************************************
  3484. ;*    Envoit une commande à la GUS
  3485. ;*
  3486. ;* Entrée:
  3487. ;*    DX    adresse de port de la GUS
  3488. ;*    AL    commande à envoyer
  3489. ;*    AH    argument de la commande
  3490.  
  3491. PROC    putcom
  3492.  
  3493.  
  3494.     out    dx,al
  3495.  
  3496.     add    dx,2
  3497.     mov    al,ah
  3498.     out    dx,al
  3499.  
  3500.     sub    dx,2
  3501.  
  3502.     ret
  3503.  
  3504. ENDP
  3505.  
  3506. ;***************************************************************************
  3507. ;*    Routine d'initialisation de la GUS
  3508.  
  3509. PROC    setgus
  3510.  
  3511.     add    [(DEVICE ptr ds:bx).port],103h
  3512.         mov    dx,[(DEVICE ptr ds:bx).port]
  3513.  
  3514.     push    bx
  3515.  
  3516.     mov    ax,4ch        ;Reset de la GUS
  3517.     call    putcom
  3518.  
  3519.     add    dx,4
  3520.     REPT    14
  3521.     in    al,dx
  3522.     ENDM
  3523.     sub    dx,4
  3524.  
  3525.     mov    ax,14ch
  3526.     call    putcom
  3527.  
  3528.     add    dx,4
  3529.     REPT    14
  3530.     in    al,dx
  3531.     ENDM
  3532.     sub    dx,4
  3533.  
  3534.     xor    ebx,ebx        ; Test la mémoire de la GUS
  3535. @@test_mem:
  3536.  
  3537.     mov    al,0AAh        ; Ecrit 55AAh en 00000h
  3538.     call    putgus
  3539.     inc    ebx
  3540.     mov    al,055h
  3541.     call    putgus
  3542.  
  3543.     call    getgus        ; Lit 16 bits en 00000h
  3544.     mov    ch,al
  3545.     dec    ebx
  3546.     call    getgus
  3547.     mov     cl,al
  3548.  
  3549.         add    ebx,256*1024
  3550.     cmp    ebx,(1024+256)*1024
  3551.         je    @@enough_mem
  3552.     cmp    cx,55aah
  3553.     je    @@test_mem
  3554.  
  3555. @@enough_mem:
  3556.     sub    ebx,256*1024
  3557.     mov    [GusMem],ebx
  3558.     jnz    @@find_gus
  3559.  
  3560.     pop    bx
  3561.     mov    ax,GUS_NOT_FOUND    ;Pas de gus
  3562.     stc
  3563.     ret
  3564.  
  3565. @@find_gus:
  3566.  
  3567.     pop    bx
  3568.     mov    [(DEVICE ptr ds:bx).port],dx
  3569.     mov    [ds:OFFSET port_gus1+1],dx
  3570.     mov    [ds:OFFSET port_gus2+1],dx
  3571.  
  3572.     mov    ax,0041h    ; couche le DMA
  3573.     call    putcom
  3574.  
  3575.     mov    ax,0045h    ; couche les timers
  3576.     call    putcom
  3577.  
  3578.     mov    ax,0049h    ; pas de sampling
  3579.     call    putcom
  3580.  
  3581.     mov    ax,0cd0eh
  3582.     call    putcom
  3583.  
  3584.     mov    [ds:Play_rate],2422
  3585.     mov    al,SIZE GUSDATA            ;32*nombre de voix
  3586.     mov    cl,[byte ptr ds:OFFSET Nb_voice]
  3587.     mul    cl
  3588.     mov    [ds:Voicelen],ax
  3589. ;    sub    ax,4
  3590. ;    sub    [ds:Ptr_sound],ax
  3591. ;    and     [ds:Ptr_sound],65535-BUF_LEN
  3592.  
  3593.     mov    si,OFFSET Instruments
  3594.     mov    di,OFFSET GusSample+4
  3595.     xor    ebx,ebx
  3596.     mov    cl,[ds:Nb_instrument]
  3597. @@next_inst:
  3598.     push    cx
  3599.  
  3600.     mov    [ds:di],ebx
  3601.     push    di
  3602.     push    si
  3603.  
  3604.     mov    ax,[(INSTRUMENT ptr ds:si).adrseg]
  3605.     mov    es,ax
  3606.     xor    di,di
  3607.     mov    cx,[(INSTRUMENT ptr ds:si).length]
  3608.  
  3609.     or    cx,cx
  3610.     je    @@no_inst
  3611.  
  3612.     add    cx,SAMPLE_BORDER
  3613.  
  3614.     xor    si,si
  3615. @@next_byte:
  3616.     lods    [byte ptr es:si]
  3617.     call    putgus
  3618.     inc    ebx
  3619.     dec    cx
  3620.     jne    @@next_byte
  3621.  
  3622. @@no_inst:
  3623.     pop    si
  3624.     pop    di
  3625.     pop    cx
  3626.  
  3627.     add    si,SIZE INSTRUMENT
  3628.     add    di,4
  3629.  
  3630.     dec    cl
  3631.     jne    @@next_inst
  3632.  
  3633.     cmp    ebx,[GusMem]
  3634. ;    ja    @@not_enough_mem
  3635.  
  3636.     clc
  3637.  
  3638.     ret
  3639.  
  3640. @@not_enough_mem:
  3641.  
  3642.     mov    ax,NOT_ENOUGH_GUS
  3643.     stc
  3644.         ret
  3645. ENDP
  3646.  
  3647.  
  3648.  
  3649. ;***************************************************************************
  3650. ;*    Commence à envoyer les données sur la GUS
  3651.  
  3652. PROC startgus
  3653.  
  3654.     mov    dx,[(DEVICE ptr ds:bx).port]
  3655.     push    bx
  3656.  
  3657.     mov    ch,31
  3658. @@next_voices:
  3659.     dec    dx
  3660.     mov    al,ch
  3661.     out    dx,al
  3662.     inc    dx
  3663.  
  3664.     mov    ax,0800h    ; 800h loop enable
  3665.     call    putcom        ; voice mode
  3666.  
  3667.  
  3668. ;        mov    cl,ch
  3669. ;    and    cl,1
  3670. ;        mov    ax,0F0ch
  3671. ;        add    ah,cl
  3672. ;    and    ah,0Fh
  3673. ;    call    putcom        ; pan register
  3674.  
  3675.     mov    cl,ch
  3676.     inc    cl
  3677.     and    cl,2
  3678.     mov    ax,040ch
  3679.     jz    @@right
  3680.     mov    ah,0Bh
  3681. @@right:
  3682.     call    putcom        ; pan register 4 et 11
  3683.  
  3684.     mov    ax,20dh        ; stop les volumes ramps
  3685.     call    putcom
  3686.  
  3687.     mov    ax,3f06h    ;changement de volume rapide
  3688.     call    putcom
  3689.  
  3690.     mov    al,9
  3691.     out    dx,al        ; volume à 0
  3692.     inc    dx
  3693.     xor    ax,ax
  3694.     out    dx,ax
  3695.     dec    dx
  3696.  
  3697.     dec    ch
  3698.     jge    @@next_voices
  3699.  
  3700.     mov    ax,34ch        ;Allume le haut parleur
  3701.     call    putcom
  3702.  
  3703.     sub    dx,103h
  3704.     mov    al,1h
  3705.     out    dx,al
  3706.     add    dx,103h
  3707.  
  3708.     mov     ax,3508h
  3709.     int     21h
  3710.     mov     [word ptr cs:OFFSET Old_int],bx
  3711.     mov     [word ptr cs:OFFSET Old_int+2],es
  3712.  
  3713.     pop    bx
  3714.     cli
  3715.  
  3716.     mov    al,00110110b  ;00110110b
  3717.     out     43h,al
  3718.  
  3719.     mov    ax,5d37h        ; interruption à 50Hz
  3720.     mov    [ds:Compteur0],ax
  3721.     out     40h,al
  3722.     mov     al,ah
  3723.     out     40h,al
  3724.  
  3725.     mov    dx,[(DEVICE ptr ds:bx).sound]
  3726.     mov     ax,cs
  3727.     mov     ds,ax
  3728.     mov     ax,2508h
  3729.     int     21h
  3730.  
  3731.     call    setautoeoi
  3732.  
  3733.     mov    al,20h
  3734.     out    20h,al
  3735.  
  3736.     sti
  3737.  
  3738.     ret
  3739.  
  3740. ENDP
  3741.  
  3742. ;***************************************************************************
  3743. ;*    Procédure qui place les données du son dans le buffer
  3744.  
  3745. PROC    makegus FAR
  3746.  
  3747.     mov    cx,[Nb_voice]
  3748.     mov    di,OFFSET Voix1
  3749.     mov    si,[ds:OFFSET Page_sound]
  3750. @@next_voice:
  3751.     push    cx
  3752.  
  3753.     mov     dx,[(VOIX ptr ds:di).effet]
  3754.     call    dx
  3755.  
  3756.     mov    bx,[(VOIX ptr ds:di).play]
  3757.     shl    bx,1
  3758.     xor    edx,edx
  3759.     mov    dx,[word ptr ds:bx+OFFSET Notes]
  3760.     mov    [(GUSDATA ptr ds:si).note],dx
  3761.     ror    edx,10
  3762.  
  3763.     mov    cx,[(VOIX ptr ds:di).endsamp]
  3764.     les    ebp,[(VOIX ptr ds:di).adrvoc]
  3765.     mov    bx,[(VOIX ptr ds:di).lenrep]
  3766.     cmp    bp,cx
  3767.     jbe    @@ok1
  3768. @@adjust1:
  3769.     sub    bp,bx
  3770.     cmp    bp,cx
  3771.     ja    @@adjust1
  3772. @@ok1:
  3773.  
  3774.     mov      al,[MasterVol]
  3775.     mul    [(VOIX ptr ds:di).volume]
  3776.     mov    bl,ah
  3777.     xor    bh,bh
  3778.     shl    bx,1
  3779.     mov    ax,[OFFSET GUS_VOLUME2+bx]
  3780.     mov    [(GUSDATA ptr ds:si).volume],ax
  3781.  
  3782.     mov    bl,[(VOIX ptr ds:di).inst]
  3783.     and    bx,1fh
  3784.     mov    [(VOIX ptr ds:di).inst],bl
  3785.     shl    bx,2
  3786.     mov    ch,[(VOIX ptr ds:di).gusinf]
  3787.     mov    [(VOIX ptr ds:di).gusinf],0
  3788.     mov    [(GUSDATA ptr ds:si).action],ch
  3789.  
  3790.     test    ch,01h
  3791.     jz    @@no_loadadr1
  3792.  
  3793.     xor    eax,eax
  3794.     mov    ax,[(VOIX ptr ds:di).endsamp]
  3795.     add    eax,[ds:bx+OFFSET GusSample]
  3796.     mov    [(GUSDATA ptr ds:si).endadr],eax
  3797.  
  3798.     xor    eax,eax
  3799.     mov    ax,[(VOIX ptr ds:di).endsamp]
  3800.     sub    ax,[(VOIX ptr ds:di).lenrep]
  3801.     add    eax,[ds:bx+OFFSET GusSample]
  3802.     mov    [(GUSDATA ptr ds:si).repadr],eax
  3803.  
  3804. @@no_loadadr1:
  3805.  
  3806.     test    ch,02h
  3807.     jz    @@no_loadcur1
  3808.  
  3809.     mov    eax,[(dword ptr (VOIX ptr ds:di).adrvoc)]
  3810.     and    eax,0ffffh
  3811.     add    eax,[ds:bx+OFFSET GusSample]
  3812.     mov    [(GUSDATA ptr ds:si).curadr],eax
  3813.  
  3814. @@no_loadcur1:
  3815.  
  3816.     mov    cx,820
  3817. @@voix1:
  3818.     add     ebp,edx
  3819.     adc    bp,0
  3820.     dec    cx
  3821.     jne    @@voix1
  3822.  
  3823.     mov    [dword ptr ((VOIX ptr ds:di).adrvoc)],ebp
  3824.  
  3825.     add    si,SIZE GUSDATA
  3826.     add    di,SIZE VOIX
  3827.     pop    cx
  3828.     dec    cl
  3829.     jne    @@next_voice
  3830.  
  3831.     and    si,65535-BUF_LEN
  3832.     mov    [word ptr ds:OFFSET Page_sound],si
  3833.  
  3834. @@fin:
  3835.     pop    di
  3836.     pop    si
  3837.     pop    bp
  3838.     pop    es
  3839.     pop    ds
  3840.  
  3841.     ret
  3842.  
  3843.  
  3844. ENDP
  3845.  
  3846.  
  3847. ;***************************************************************************
  3848. ;*      interruption 8 permettant d'envoyer le son sur la gus
  3849.  
  3850. PROC    soundgus1 FAR
  3851.  
  3852.     push    ax
  3853.     push    bx
  3854.     push    cx
  3855.     push    dx
  3856.  
  3857.     mov    ax,4A9h        ; interruption à 1kHz
  3858.     out     40h,al
  3859.     mov     al,ah
  3860.     out     40h,al
  3861.  
  3862.     inc       [dword ptr cs:OFFSET Timer]
  3863.  
  3864.     push    ds
  3865.     xor    ax,ax
  3866.     mov    ds,ax
  3867.     mov    [word ptr ds:20h],OFFSET soundgus2
  3868.     pop    ds
  3869.  
  3870.     mov    bx,[cs:OFFSET Ptr_sound]
  3871.  
  3872. port_gus1:
  3873.     mov    dx,323h
  3874.  
  3875.     mov    cl,[byte ptr cs:OFFSET Nb_voice]
  3876.     dec    cl
  3877. @@next_voice:
  3878.     dec    dx
  3879.     mov    al,cl
  3880.     out    dx,al
  3881.  
  3882.     inc    dx
  3883.  
  3884.     test    [(GUSDATA ptr cs:bx).action],4
  3885.     jz    @@no_voice_off
  3886.  
  3887.     mov    al,09h
  3888.     out    dx,al
  3889.  
  3890.     inc    dx
  3891.     mov    al,[cs:OFFSET GUS_VOLUME2]
  3892.     out    dx,al
  3893.     dec    dx
  3894.  
  3895.     mov    al,89h
  3896.     out    dx,al
  3897.  
  3898.     add    dx,2
  3899.     in    al,dx
  3900.     mov    ah,al
  3901.     sub    dx,2
  3902.  
  3903.         mov    al,7
  3904.     out    dx,al
  3905.  
  3906.         xor    al,al
  3907.     mov    ch,[cs:OFFSET GUS_VOLUME2+1]
  3908.  
  3909.     cmp    ch,ah
  3910.     ja    @@inc_vol
  3911.         mov    al,40h
  3912.     xchg    ch,ah
  3913. @@inc_vol:
  3914.  
  3915.     add    dx,2
  3916.         xchg    al,ah
  3917.     out    dx,al
  3918.     sub    dx,2
  3919.  
  3920.     mov    al,8
  3921.     out    dx,al
  3922.  
  3923.     add    dx,2
  3924.     mov    al,ch
  3925.     out    dx,al
  3926.     sub    dx,2
  3927.  
  3928.     mov    al,0dh
  3929.     out    dx,al
  3930.  
  3931.     add    dx,2
  3932.     mov    al,ah
  3933.     out    dx,al
  3934.     sub    dx,2
  3935.  
  3936. @@no_voice_off:
  3937.  
  3938.     add    bx,SIZE GUSDATA
  3939.  
  3940.     dec    cl
  3941.     jns    @@next_voice
  3942.  
  3943.     pop    dx
  3944.     pop    cx
  3945.     pop    bx
  3946.     pop    ax
  3947.  
  3948.     dec       [cs:Compteur]
  3949.         jz        @@int08
  3950.  
  3951.     iret
  3952.  
  3953. @@int08:
  3954.     push    ax
  3955.     mov    ax,3
  3956.         mov    [cs:Compteur],ax
  3957.  
  3958.         pop    ax
  3959.     jmp    [dword ptr cs:Old_int]
  3960.  
  3961.  
  3962. ENDP
  3963.  
  3964.  
  3965.  
  3966. PROC    soundgus2 FAR
  3967.  
  3968.     push    eax
  3969.     push    bx
  3970.     push    cx
  3971.     push    dx
  3972.  
  3973.     mov    ax,588Eh    ; interruption à 50Hz
  3974.     out     40h,al
  3975.     mov     al,ah
  3976.     out     40h,al
  3977.  
  3978.     push    ds
  3979.     xor    ax,ax
  3980.     mov    ds,ax
  3981.     mov    [word ptr ds:20h],OFFSET soundgus1
  3982.     pop    ds
  3983.  
  3984.     mov    bx,[cs:OFFSET Ptr_sound]
  3985.  
  3986. port_gus2:
  3987.     mov    dx,323h
  3988.  
  3989.     mov    cl,[byte ptr cs:OFFSET Nb_voice]
  3990.     dec    cl
  3991. @@next_voice:
  3992.     dec    dx
  3993.     mov    al,cl
  3994.     out    dx,al
  3995.  
  3996.     inc    dx
  3997.  
  3998.     mov    ch,[(GUSDATA ptr cs:bx).action]
  3999.  
  4000.     test    ch,1
  4001.     jz    @@no_new_inst
  4002.  
  4003.     mov    al,05h
  4004.     out    dx,al
  4005.  
  4006.     inc    dx
  4007.     mov    eax,[(GUSDATA ptr cs:bx).endadr]
  4008.     rol    eax,9
  4009.     out    dx,ax
  4010.     dec    dx
  4011.  
  4012.     mov    al,04h
  4013.     out    dx,al
  4014.  
  4015.     inc    dx
  4016.     ror    eax,16
  4017.     out    dx,ax
  4018.     dec    dx
  4019.  
  4020.     mov    al,03h
  4021.     out    dx,al
  4022.  
  4023.     inc    dx
  4024.     mov    eax,[(GUSDATA ptr cs:bx).repadr]
  4025.     rol    eax,9
  4026.     out    dx,ax
  4027.     dec    dx
  4028.  
  4029.     mov    al,02h
  4030.     out    dx,al
  4031.  
  4032.     inc    dx
  4033.     ror    eax,16
  4034.     out    dx,ax
  4035.     dec    dx
  4036.  
  4037. @@no_new_inst:
  4038.  
  4039.     test    ch,2
  4040.     jz    @@no_loadcur
  4041.  
  4042.     mov    al,0
  4043.     out    dx,al
  4044.  
  4045.     add    dx,2
  4046.     mov    al,3
  4047.     out    dx,al
  4048.     sub    dx,2
  4049.  
  4050.         REPT    6
  4051.         in    al,dx
  4052.         ENDM
  4053.  
  4054.     mov    al,0bh
  4055.     out    dx,al
  4056.  
  4057.     inc    dx
  4058.     mov    eax,[(GUSDATA ptr cs:bx).curadr]
  4059.     shl    eax,9
  4060.     out    dx,ax
  4061.     dec    dx
  4062.  
  4063.     mov    al,0ah
  4064.     out    dx,al
  4065.  
  4066.     inc    dx
  4067.     ror    eax,16
  4068.     out    dx,ax
  4069.     dec    dx
  4070.  
  4071.         mov    al,0
  4072.     out    dx,al
  4073.  
  4074.     add    dx,2
  4075.     mov    al,8
  4076.     out    dx,al
  4077.     sub    dx,2
  4078.  
  4079.         REPT    6
  4080.         in    al,dx
  4081.     ENDM
  4082.  
  4083. @@no_loadcur:
  4084.  
  4085.     test    ch,8
  4086.     jnz    @@ramp_vol
  4087.  
  4088.     jmp    @@ok_vol
  4089.  
  4090. @@ramp_vol:
  4091.  
  4092.     mov    al,89h
  4093.     out    dx,al
  4094.  
  4095.     add    dx,2
  4096.     in    al,dx
  4097.     mov    ah,al
  4098.     sub    dx,2
  4099.  
  4100.         mov    al,7
  4101.     out    dx,al
  4102.  
  4103.         xor    al,al
  4104.     mov    ch,[byte ptr ((GUSDATA ptr cs:bx).volume)+1]
  4105.  
  4106.         cmp    ch,ah
  4107.     ja    @@inc_vol
  4108.     mov    al,40h
  4109.         xchg    ch,ah
  4110. @@inc_vol:
  4111.  
  4112.     add    dx,2
  4113.         xchg    al,ah
  4114.     out    dx,al
  4115.     sub    dx,2
  4116.  
  4117.     mov    al,8
  4118.     out    dx,al
  4119.  
  4120.     add    dx,2
  4121.     mov    al,ch
  4122.     out    dx,al
  4123.     sub    dx,2
  4124.  
  4125.     mov    al,09h
  4126.         out    dx,al
  4127.  
  4128.         inc    dx
  4129.     mov    al,[byte ptr ((GUSDATA ptr cs:bx).volume)]
  4130.     out    dx,al
  4131.         dec    dx
  4132.  
  4133.     mov    al,0dh
  4134.     out    dx,al
  4135.  
  4136.     add    dx,2
  4137.         mov    al,ah
  4138.     out    dx,al
  4139.     sub    dx,2
  4140.  
  4141. @@ok_vol:
  4142.     mov    al,1
  4143.     out    dx,al
  4144.  
  4145.     inc    dx
  4146.     mov    ax,[(GUSDATA ptr cs:bx).note]
  4147.     out    dx,ax
  4148.     dec    dx
  4149.  
  4150.     add    bx,SIZE GUSDATA
  4151.  
  4152.     dec    cl
  4153.     jns    @@next_voice
  4154.  
  4155.     and    bx,65535-BUF_LEN
  4156.     mov    [cs:OFFSET Ptr_sound],bx
  4157.  
  4158.     pop    dx
  4159.     pop    cx
  4160.     pop    bx
  4161.     pop    eax
  4162.  
  4163.     iret
  4164.  
  4165. ENDP
  4166.  
  4167.  
  4168. ;***************************************************************************
  4169. ;*    cette routine permet d'arreter l'envoit du son sur la gus
  4170.  
  4171. PROC    stopgus
  4172.  
  4173.     mov    dx,[(DEVICE ptr ds:bx).port]
  4174.  
  4175.     mov    ax,14ch        ;Eteint le haut parleur
  4176.     call    putcom
  4177.  
  4178.     sub    dx,103h
  4179.     mov    al,3
  4180.     out    dx,al
  4181.     add    dx,103h
  4182.  
  4183.     mov    cl,31
  4184. @@next_voices:
  4185.     dec    dx
  4186.     mov    al,cl
  4187.     out    dx,al
  4188.     inc    dx
  4189.  
  4190.     mov    ax,0300h    ; 800h loop enable
  4191.     call    putcom        ; voice mode
  4192.  
  4193.  
  4194.     mov    ax,030dh        ; stop les volumes ramps
  4195.     call    putcom
  4196.  
  4197.     dec    cl
  4198.     jns    @@next_voices
  4199.  
  4200.     mov     al,00110110b
  4201.     out     43h,al
  4202.         xor    al,al
  4203.     out     40h,al
  4204.     out     40h,al
  4205.  
  4206.     call    reseteoi
  4207.  
  4208.     call    resettime
  4209.  
  4210.         push    ds
  4211.     mov     ax,2508h
  4212.     lds     dx,[dword ptr cs:OFFSET Old_int]
  4213.     int     21h
  4214.  
  4215.     mov    al,20h
  4216.     out    20h,al
  4217.  
  4218.     pop    ds
  4219.  
  4220.     ret
  4221.  
  4222. ENDP
  4223.  
  4224.  
  4225.  
  4226. GUS_VOLUME2    dw 28000,40048,43216,43856,44496,47104,47424,47696,48000,48272
  4227.         dw 48544,48832,49120,51312,51440,51584,51712,51840,51968,52096
  4228.         dw 52208,52336,52464,52592,52704,52848,52960,53072,53200,55328
  4229.         dw 55392,55456,55504,55568,55648,55696,55744,55824,55872,55920
  4230.         dw 55984,56032,56096,56144,56208,56272,56320,56384,56448,56512
  4231.         dw 56544,56608,56688,56720,56784,56832,56896,56928,57008,57040
  4232.         dw 57120,57168,57232,57280,57280
  4233.  
  4234. CutVoice    DB 00h
  4235.  
  4236. AMPLI:
  4237.     DB    080h,07ch,079h,076h,073h,070h,06dh,06ah,068h,066h,063h,061h,05fh,05dh,05bh,059h
  4238.     DB    057h,056h,054h,052h,051h,04fh,04dh,04ch,04ah,049h,048h,046h,045h,044h,042h,041h
  4239.     DB    040h,03fh,03eh,03ch,03bh,03ah,039h,038h,037h,036h,035h,034h,033h,032h,031h,030h
  4240.     DB    02fh,02eh,02dh,02dh,02ch,02bh,02ah,029h,028h,028h,027h,026h,025h,025h,024h,023h
  4241.     DB    022h,022h,021h,020h,01fh,01fh,01eh,01dh,01dh,01ch,01bh,01bh,01ah,01ah,019h,018h
  4242.     DB    018h,017h,017h,016h,015h,015h,014h,014h,013h,013h,012h,011h,011h,010h,010h,0fh
  4243.     DB    0fh,0eh,0eh,0dh,0dh,0ch,0ch,0bh,0bh,0ah,0ah,09h,09h,08h,08h,08h
  4244.     DB    07h,07h,06h,06h,05h,05h,04h,04h,04h,03h,03h,02h,02h,01h,01h,01h
  4245.     DB    0feh,0feh,0feh,0fdh,0fdh,0fch,0fch,0fbh,0fbh,0fbh,0fah,0fah,0f9h,0f9h,0f8h,0f8h
  4246.     DB    0f7h,0f7h,0f7h,0f6h,0f6h,0f5h,0f5h,0f4h,0f4h,0f3h,0f3h,0f2h,0f2h,0f1h,0f1h,0f0h
  4247.     DB    0f0h,0efh,0efh,0eeh,0eeh,0edh,0ech,0ech,0ebh,0ebh,0eah,0eah,0e9h,0e8h,0e8h,0e7h
  4248.     DB    0e7h,0e6h,0e5h,0e5h,0e4h,0e4h,0e3h,0e2h,0e2h,0e1h,0e0h,0e0h,0dfh,0deh,0ddh,0ddh
  4249.     DB    0dch,0dbh,0dah,0dah,0d9h,0d8h,0d7h,0d7h,0d6h,0d5h,0d4h,0d3h,0d2h,0d2h,0d1h,0d0h
  4250.     DB    0cfh,0ceh,0cdh,0cch,0cbh,0cah,0c9h,0c8h,0c7h,0c6h,0c5h,0c4h,0c3h,0c1h,0c0h,0bfh
  4251.     DB    0beh,0bdh,0bbh,0bah,0b9h,0b7h,0b6h,0b5h,0b3h,0b2h,0b0h,0aeh,0adh,0abh,0a9h,0a8h
  4252.     DB    0a6h,0a4h,0a2h,0a0h,09eh,09ch,099h,097h,095h,092h,08fh,08ch,089h,086h,083h,080h
  4253.  
  4254.  
  4255. SCREEN_POS    DW 640+640+640
  4256.  
  4257. ;***************************************************************************
  4258. ;*    Ecrit un nombre en EAX sur 32 bits en chaine de caractère
  4259. ;*    correspondant à se représentation hexadécimal
  4260. ;*
  4261. ;* Entrée:
  4262. ;*    EDX    nombre à convertir
  4263.  
  4264. PROC    writelong
  4265.  
  4266.     push    es
  4267.     mov    ax,0b800h
  4268.     mov    es,ax
  4269.     mov    di,[cs:SCREEN_POS]
  4270.     add    di,16
  4271.  
  4272.     mov    ax,'╩h'
  4273.     std
  4274.     stosw
  4275.         inc    di
  4276.  
  4277.     mov    cl,4
  4278. @@next_digit:
  4279.     movzx    ax,dl
  4280.     shr    edx,8
  4281.     shl    ax,4
  4282.     shr    al,4
  4283.     xchg    al,ah
  4284.     and    ax,0f0fh
  4285.     add    ax,3030h
  4286.     cmp    al,3Ah
  4287.     jb    @@al_ok
  4288.     add    al,7
  4289. @@al_ok:
  4290.     cmp    ah,3Ah
  4291.     jb    @@ah_ok
  4292.     add    ah,7
  4293. @@ah_ok:
  4294.     xchg    al,ah
  4295.     dec    di
  4296.     stosb
  4297.     dec    di
  4298.     mov    al,ah
  4299.     stosb
  4300.     dec    cl
  4301.     jne    @@next_digit
  4302.  
  4303.     cld
  4304.  
  4305.     add    di,19
  4306.     mov    al,' '
  4307.     stosb
  4308.     inc    di
  4309.  
  4310.     pop    es
  4311.  
  4312.     cmp    di,4000
  4313.     jb    @@ok
  4314.     mov    di,0
  4315. @@ok:
  4316.     mov    [cs:SCREEN_POS],di
  4317.  
  4318.  
  4319.     ret
  4320.  
  4321. ENDP
  4322.  
  4323. ;************************************************************
  4324. ;*    Ecrit un caractère à l'écran AL=caractère à écrire
  4325.  
  4326. PROC    writechar
  4327.  
  4328.     push    es
  4329.     push    di
  4330.     mov    di,0B800h
  4331.     mov    es,di
  4332.     mov    di,[cs:SCREEN_POS]
  4333.     stosb
  4334.     inc    di
  4335.     cmp    di,40000
  4336.     jb    @@ok
  4337.     xor    di,di
  4338. @@ok:
  4339.     mov    [cs:SCREEN_POS],di
  4340.     pop    di
  4341.     pop    es
  4342.  
  4343.     ret
  4344.  
  4345. ENDP
  4346.  
  4347. ENDS
  4348.  
  4349. END
  4350.  
  4351.