home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / software / testi / corsoasm / sorgenti8 / lezione14-5d.s < prev    next >
Text File  |  1995-09-29  |  7KB  |  244 lines

  1.  
  2. ; Corso Asm - LEZIONE xx:  ** EFFETTO FAKE-SURROND **
  3.             ; N.B.: funziona bene sui computer lenti per il
  4.             ;       ritardo tra le due voci per cassa.
  5.  
  6. ; debug, stesso di prima
  7.  
  8. WLMB    macro
  9. \@    btst    #6,$bfe001
  10.     bne.s    \@
  11.     endm
  12.  
  13. WRMB    macro
  14. \@    btst    #10,$dff016
  15.     bne.s    \@
  16.     endm
  17.  
  18.     SECTION    PlayLongSamples,CODE
  19.  
  20. Start:
  21.     bset    #1,$bfe001        ;spegne il filtro passa-basso
  22.                     ;>>>> PARAMETRI <<<<
  23.     lea    sample,a0        ;indirizzo sample
  24.     move.l    #sample_end-sample,d0    ;lunghezza sample in byte
  25.     move.w    #17897,d1        ;frequenza di lettura
  26.     moveq    #64,d2            ;volume
  27.  
  28.     moveq    #0,d3            ;suona voce 0
  29.     bsr.w    playlongsample_init
  30.     moveq    #3,d3            ;suona voce 3
  31.     bsr.w    playlongsample_init
  32.     WLMB
  33.     moveq    #1,d3            ;suona voce 1
  34.     bsr.s    playlongsample_init
  35.     moveq    #2,d3            ;suona voce 2
  36.     bsr.s    playlongsample_init
  37.     WRMB
  38.  
  39.     moveq    #0,d3            ;spegni voce 0 
  40.     bsr.w    playlongsample_restore
  41.     moveq    #1,d3            ;spegni voce 1
  42.     bsr.w    playlongsample_restore
  43.     moveq    #2,d3            ;spegni voce 2
  44.     bsr.w    playlongsample_restore
  45.     moveq    #3,d3            ;spegni voce 3
  46.     bsr.w    playlongsample_restore
  47.     rts
  48.  
  49.  
  50.  
  51. ***************************************
  52. *****  Play Long Sample Routines  *****
  53. ***************************************
  54.  
  55. PlayLongSample_init:
  56.         ;[a0=sample adr]
  57.         ;[d0.l=lunghezza.b sample, d1.w=frequenza, d2.w=volume]
  58.         ;[d3.w=voce (0..3)]
  59.         ;* L'AutoVettore Lv4 IRQ deve essere disponibile *
  60.  
  61. _LVOSupervisor    equ    -30
  62. Clock        equ    3546895
  63. AFB_68010    equ    0
  64. AttnFlags    equ    296
  65.  
  66.     movem.l    d0-d7/a0-a1/a6,-(sp)
  67.     and.w    #3,d3            ;al massimo 3 canali
  68.      lea    $dff000,a6
  69.     moveq    #1,d4
  70.     lsl.w    d3,d4
  71.     move.w    d4,d6
  72.     and.w    $2(a6),d4        ;maschera DMA della voce
  73.     move.w    #1<<7,d5
  74.     lsl.w    d3,d5
  75.     move.w    d5,d7
  76.     and.w    $1c(a6),d5        ;maschera INT della voce
  77.     add.w    d3,d3            ;d3=d3*2: esprime offset di word
  78.     lea    olddmas(pc),a1
  79.     move.w    d4,(a1,d3.w)        ;salva stato vecchio del DMA della voce
  80.     lea    oldints(pc),a1
  81.     move.w    d5,(a1,d3.w)        ;salva stato vecchio del INT della voce
  82.     move.w    d7,$9c(a6)        ;azzera eventuali IRQ
  83.     move.w    d6,$96(a6)        ;spegni DMA della voce
  84.     move.w    d7,$9a(a6)        ;spegni INT della voce
  85.     sub.l    a1,a1                ;FAST CLEAR An
  86.     move.l    4.w,a6
  87.     btst    #afb_68010,attnflags+1(a6)    ;68010+ ?
  88.     beq.s    .no010
  89.     lea    .getvbr(pc),a5
  90.     jsr    _LVOSupervisor(a6)
  91. .No010:    cmp.l    #lv4irq,$70(a1)
  92.     beq.s    .nochg
  93.     move.l    $70(a1),oldlv4        ;salva l'autovettore del livello 4
  94.     move.l    #lv4irq,$70(a1)        ;imposta il nuovo autovettore
  95. .NoChg:    lsl.w    #4-1,d3            ;d3=d3*8: ora esprime offset di 16 byte
  96.     lea    $dff0a0,a6
  97.     move.w    d2,$8(a6,d3.w)        ;imposta AUDxVOL
  98.     move.l    #clock,d2
  99.     divu.w    d1,d2            ;d2.w=clock/freq = periodo di camp.
  100.     move.w    d2,$6(a6,d3.w)        ;imposta AUDxPER
  101.     lea    $dff000,a6
  102.     or.w    #$8000,d7
  103.     move.w    d7,$9a(a6)        ;accende INT della voce
  104.     lea    plsregs(pc,d3.w),a1
  105.     movem.l    d0/a0,(a1)        ;registri fissi
  106.     movem.l    d0/a0,4*2(a1)        ;registri di lavoro
  107.     move.w    d7,$9c(a6)        ;forza IRQ della voce...
  108.     movem.l    (sp)+,d0-d7/a0-a1/a6
  109.     rts
  110. .GetVBR:
  111.     dc.l    $4e7a9801    ;movec    vbr,a1    ;base dei vettori di eccezione
  112.     rte
  113. ;--------------------------------------
  114. PLSRegs:    ;DEVONO STARE TRA _INIT E _IRQ PER IL MODO DI INDIRIZZAMENTO
  115.         ;USATO: XX(pc,Rn) CHE CONSENTE SOLO 8 BIT CON SEGNO AD "XX"
  116. PLSAud0Regs:    dc.l    0,0    ;lunghezza,puntatore - fissi
  117.         dc.l    0,0    ;lunghezza,puntatore - variabili
  118. PLSAud1Regs:    dc.l    0,0    ;lunghezza,puntatore - fissi
  119.         dc.l    0,0    ;lunghezza,puntatore - variabili
  120. PLSAud2Regs:    dc.l    0,0    ;lunghezza,puntatore - fissi
  121.         dc.l    0,0    ;lunghezza,puntatore - variabili
  122. PLSAud3Regs:    dc.l    0,0    ;lunghezza,puntatore - fissi
  123.         dc.l    0,0    ;lunghezza,puntatore - variabili
  124. ;--------------------------------------
  125. PlayLongSample_IRQ:
  126.         ;[a1=PLSAudxRegs]
  127.         ;[d3.w=voce]
  128.     movem.l    d0-d3/a0-a1/a6,-(sp)
  129.     and.w    #3,d3            ;al massimo 3 voci
  130.     move.w    d3,d2
  131.     lsl.w    #4,d3            ;d3=d3*16: esprime offset di 16 byte
  132.     lea    plsregs(pc,d3.w),a1
  133.     movem.l    4*2(a1),d0/a0        ;grabba i registri di lavoro
  134.     lea    $dff0a0,a6
  135.     move.l    a0,$0(a6,d3.w)        ;imposta AUDxLC
  136.     move.l    d0,d1            ;d1.l=lunghezza mancante
  137.     and.l    #~(128*1024-1),d1    ;mancano ancora piu' di 128 kB
  138.     bne.s    .long            ;se SI: vai a .long
  139.     move.l    d0,d1            ;se NO: usa lungh. mancante (< 128 kB)
  140. .Long:    lsr.l    #1,d1            ;trasforma la lungh. da suonare in WORD
  141.     move.w    d1,$4(a6,d3.w)        ;imposta AUDxLEN
  142.     add.l    #128*1024,a0        ;punta a0 al prossimo blocco
  143.     sub.l    #128*1024,d0        ;lunghezza MENO 128 kB
  144.     bhi.s    .noloop            ;d0 => 1 ? (manca ancora ALMENO 1 byte)
  145.     movem.l    (a1),d0/a0        ;se NO: reimposta registri originali
  146. .NoLoop:movem.l    d0/a0,4*2(a1)        ;salva comunque d0 e a0 nelle copie
  147.     move.w    #%1<<7,d0
  148.     lsl.w    d2,d0
  149.     move.w    d0,$dff09c        ;azzera IRQ della voce per non subire
  150.                     ;un nuovo interrupt appena uscito
  151.     moveq    #%1,d0
  152.     lsl.w    d2,d0
  153.     or.w    #$8200,d0        ;accende DMA della voce
  154.     move.w    d0,$dff096
  155.     movem.l    (sp)+,d0-d3/a0-a1/a6
  156.     rts
  157. ;--------------------------------------
  158. PlayLongSample_restore:
  159.         ;[d3.w=voce (0..3)]
  160.     movem.l    d0-d1/d3/a0/a6,-(sp)
  161.     and.w    #3,d3            ;al massimo 3 voci
  162.      lea    $dff000,a6
  163.     moveq    #1,d0
  164.     lsl.w    d3,d0
  165.     move.w    #1<<7,d1
  166.     lsl.w    d3,d1
  167.     move.w    d1,$9c(a6)        ;azzera eventuali IRQ della voce
  168.     move.w    d0,$96(a6)        ;spegne DMA della voce
  169.     move.w    d1,$9a(a6)        ;spegne INT della voce
  170.     move.w    $1c(a6),d0
  171.     and.w    #$0780,d0        ;spente tutte le voci = ultima voce ?
  172.     bne.s    .NoOFF
  173.     sub.l    a0,a0            ;se SI:...
  174.     move.l    4.w,a6
  175.     btst    #afb_68010,attnflags+1(a6)
  176.     beq.s    .no010
  177.     lea    .getvbr(pc),a5
  178.     jsr    _LVOSupervisor(a6)
  179. .No010:    move.l    oldlv4(pc),$70(a0)    ;...reimposta il vecchio autovettore
  180. .NoOFF:    lea    $dff000,a6
  181.     add.w    d3,d3            ;d3=d3*2: esprime offset di word
  182.     move.w    oldints(pc,d3.w),d0
  183.     or.w    #$8000,d0
  184.     move.w    d0,$9a(a6)        ;accende vecchi INT
  185.     move.w    olddmas(pc,d3.w),d0
  186.     or.w    #$8000,d0
  187.     move.w    d0,$96(a6)        ;accende vecchi DMA
  188.     movem.l    (sp)+,d0-d1/d3/a0/a6
  189.     rts
  190. .GetVBR:
  191.     dc.l    $4e7a8801    ;movec    vbr,a0    ;base dei vettori di eccezione
  192.     rte
  193. ;--------------------------------------
  194. OldINTs:dc.w    0,0,0,0
  195. OldDMAs:dc.w    0,0,0,0
  196. OldLv4:    dc.l    0
  197.  
  198.  
  199. ***************************************
  200. *****  Level 4 Interrupt Handler  *****
  201. ***************************************
  202.  
  203.     cnop    0,8
  204. Lv4IRQ:    
  205.     move.w    d3,-(sp)
  206.     pea    .exit(pc)        ;pusha il ritorno per l'RTS nello stack
  207.  
  208.     moveq    #3,d3
  209.     btst    #10-8,$dff01e        ;aud3 IRQ ?
  210.     bne.w    playlongsample_irq    ;se SI: bracha (seza ritorno) alla _IRQ
  211.  
  212.     moveq    #2,d3
  213.     btst    #9-8,$dff01e        ;aud2 IRQ ?
  214.     bne.w    playlongsample_irq
  215.  
  216.     moveq    #1,d3
  217.     btst    #8-8,$dff01e        ;aud1 IRQ ?
  218.     bne.w    playlongsample_irq
  219.  
  220.     moveq    #0,d3            ;aud0 IRQ ?
  221.     btst    #7,$dff01f
  222.     bne.w    playlongsample_irq
  223.  
  224. .Exit:    move.w    (sp)+,d3        ;anche ritorno per l'RTS della _IRQ
  225.     rte
  226.  
  227.  
  228.  
  229.  
  230.     SECTION    Sample,DATA_C
  231.  
  232.     ; MammaGamma by Alan Parsons Project (©1981)
  233. Sample:
  234.     incbin    "assembler2:sorgenti8/Mammagamma.17897"
  235. Sample_end:
  236.  
  237.     END
  238.  
  239.  
  240. Non c'è molto da dire... Non è real surround, ma gli assomiglia... Provate
  241. a ritardare di più le due voci con un loop o qualcosa del genere e sentite
  242. che effetti fà (arriva a fare l'effetto "sega elettrica" con un ritardo alto).
  243. ...Occhio a non ritardare troppo: generereste un'eco...
  244.