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

  1.  
  2. ; Corso Asm - LEZIONE xx:  ** SUONA SAMPLE MOLTO LUNGHI SOTTO OS **
  3.  
  4.  
  5.     SECTION    PlayLongSamples_OS,CODE
  6.  
  7. Start:
  8.     bset    #1,$bfe001
  9.  
  10.     lea    sample,a0
  11.     move.l    #sample_end-sample,d0
  12.     move.w    #17897,d1
  13.     moveq    #64,d2
  14.     bsr.s    playlongsample_init
  15.  
  16. WLMB:    btst    #6,$bfe001
  17.     bne.s    wlmb
  18.     btst    #10,$dff016
  19.     bne.s    wlmb
  20.  
  21.     bsr.w    playlongsample_restore
  22.     rts
  23.  
  24.  
  25. ***************************************
  26. *****  Play Long Sample Routines  *****
  27. ***************************************
  28.  
  29. PlayLongSample_init:
  30.         ;[a0=sample adr]
  31.         ;[d0.l=lunghezza.b sample, d1.w=frequenza, d2.w=volume]
  32.  
  33. Clock        equ    3546895
  34. NT_Interrupt    equ    2
  35. LN_Type        equ    8
  36. LN_Pri        equ    9
  37. LN_Name        equ    10
  38. IS_Data        equ    14
  39. IS_Code        equ    18
  40. IS_SIZE        equ    22
  41. _LVOSetIntVector    equ    -162
  42.  
  43.     movem.l    d0/d2/a1/a6,-(sp)
  44.     movem.l    d0/a0,plsregs
  45.     movem.l    d0/a0,plsregs+4*2
  46.     movem.l    d1-d2,-(sp)
  47.     move.l    4.w,a6                ;base di exec in a6
  48.     lea    aud1int_node(pc),a1        ;struttura/nodo dell'interrupt
  49.     move.b    #nt_interrupt,ln_type(a1)    ;tipo di nodo: interrrupt
  50.     move.l    #aud1int_name,ln_name(a1)    ;nome del nodo public
  51.     move.l    #aud1int_data,is_data(a1)    ;punta ai dati (a1-scratch)
  52.     move.l    #aud1int_code,is_code(a1)    ;punta al codice (a5-scratch)
  53.     moveq    #8,d0                ;bit di INTENA/INTREQ (AUD1)
  54.     jsr    _LVOSetIntVector(a6)
  55.     move.l    d0,oldaud1int_node        ;d0.l=nodo precedente
  56.     movem.l    (sp)+,d1-d2
  57.     lea    $dff000,a6
  58.     move.w    d2,$a8(a6)
  59.     move.w    d2,$b8(a6)
  60.     move.w    d2,$c8(a6)
  61.     move.w    d2,$d8(a6)
  62.     move.l    #clock,d2
  63.     divu.w    d1,d2
  64.     move.w    d2,$a6(a6)
  65.     move.w    d2,$b6(a6)
  66.     move.w    d2,$c6(a6)
  67.     move.w    d2,$d6(a6)
  68.     move.w    $2(a6),olddma
  69.     move.w    $1c(a6),oldint
  70.     move.w    #$8100,$9a(a6)
  71.     move.w    #$8100,$9c(a6)
  72.     movem.l    (sp)+,d0/d2/a1/a6
  73.     rts
  74. ;--------------------------------------
  75. PlayLongSample_restore:
  76.     movem.l    d0/a1/a6,-(sp)
  77.     move.l    4.w,a6
  78.     move.l    oldaud1int_node(pc),a1        ;reimposta nodo precedente
  79.     moveq     #8,d0                ;bit di INTENA/INTREQ (AUD1)
  80.     jsr    _LVOSetIntVector(a6)
  81.     lea    $dff000,a6
  82.     move.w    #$0780,$9c(a6)            ;spegne tutte le richieste IRQ
  83.     move.w    #$0100,$9a(a6)
  84.     move.w    oldint(pc),d0
  85.     or.w    #$8000,d0
  86.     move.w    d0,$9a(a6)
  87.     move.w    #$000f,$96(a6)
  88.     move.w    olddma(pc),d0
  89.     or.w    #$8000,d0
  90.     move.w    d0,$96(a6)
  91.     movem.l    (sp)+,d0/a1/a6
  92.     rts
  93. ;--------------------------------------
  94. PlayLongSample_IRQ:            ;<<< questa routine e' identica
  95.     movem.l    d0-d1/a0-a1/a6,-(sp)
  96.     lea    $dff000,a6
  97.     movem.l    plsregs+4*2(pc),d0/a0
  98.     move.l    a0,$a0(a6)
  99.     move.l    a0,$b0(a6)
  100.     move.l    a0,$c0(a6)
  101.     move.l    a0,$d0(a6)
  102.     move.l    d0,d1
  103.     and.l    #~(128*1024-1),d1
  104.     bne.s    .long
  105.     move.l    d0,d1
  106. .Long:    lsr.l    #1,d1
  107.     move.w    d1,$a4(a6)
  108.     move.w    d1,$b4(a6)
  109.     move.w    d1,$c4(a6)
  110.     move.w    d1,$d4(a6)
  111.     add.l    #128*1024,a0
  112.     sub.l    #128*1024,d0
  113.     bhi.s    .noloop
  114.     movem.l    plsregs(pc),d0/a0
  115. .NoLoop:movem.l    d0/a0,plsregs+4*2
  116.     move.w    #$820f,$96(a6)
  117.     movem.l    (sp)+,d0-d1/a0-a1/a6
  118.     rts
  119. ;--------------------------------------
  120. OldDMA:    dc.w    0
  121. OldInt:    dc.w    0
  122. OldAud1Int_Node:dc.l    0
  123. Aud1Int_Node:
  124.     blk.b    is_size        ;lunghezza InterruptStructure
  125.     even
  126. Aud1Int_Name:
  127.     dc.b    "PlayLongSampleIRQ",0
  128.     even
  129. Aud1Int_Data:
  130. PLSRegs:dc.l    0,0    ;lunghezza,puntatore - fissi
  131.     dc.l    0,0    ;lunghezza,puntatore - variabili
  132.  
  133.     cnop   0,8
  134. Aud1Int_Code:
  135.     move.w    #$0100,$dff09c
  136.     bsr.w    playlongsample_irq
  137.     rts
  138.  
  139.  
  140.  
  141.     SECTION    Sample,DATA_C
  142.  
  143.     ; MammaGamma by Alan Parsons Project (©1981)
  144. Sample:
  145.     incbin    "assembler2:sorgenti8/Mammagamma.17897"
  146. Sample_end:
  147.  
  148.     END
  149.  
  150.  
  151. Questa volta non e' cambiato quasi nulla rispetto al sorgente precedente:
  152. abbiamo solo allocato l'handler di interrupt con l'exec library, in modo
  153. da rendere tutto un po' piu' "friendly" nei confronti del sistema operativo.
  154.  
  155. N.B.:    e' stato utilizzato l'interrupt del canale 1, poiche', per le pseudo
  156.     priorita' software dell'exec, e' il primo a essere rilevato nello
  157.     handler interno in ROM di livello 4.
  158.  
  159. P.S.:    una precisazione per quanto riguarda la differenza tra Server Chain
  160.     ed Handler di interrupt per l'exec: certi interrupt (VERTB, COPER,
  161.     PORTS, EXTER e NMI) sono piu' utili di altri e vengono usati spesso
  162.     sia dall'OS che dai task utente; l'exec deve pertanto dare la
  163.     possibilita' a tutti di avere delle proprie routine in interrupt, e
  164.     forma quindi delle "catene" di routine aventi diversa e specificabile
  165.     priorita' di esecuzione gestite da un unico handler.
  166.     Tutti gli altri interrupt del Paula (TBE, DSKBLK, SOFT, BLIT, AUD0-3,
  167.     RBF e DSKSYNC) non sono visti come server chain ma come handler: ognuno
  168.     puo' impossessarsi del dato interrupt completamente, senza linkarsi
  169.     o dividerselo con nessun altro task.
  170.     Nel nostro caso, abbiamo alloccato l'interrupt del canale 1, quello a
  171.     priorita' software maggiore, per l'exec (...e non chiedetemi perche'),
  172.     con _LVOSetIntVector perche' richiede un handler, non un server;
  173.     inoltre, nel caso degli handler, la priorita' del nodo della struturra
  174.     dell'interrupt non necessita di essere impostata poiche' non
  175.     vi sono altri server nella chain, si e' soli.
  176.  
  177. P.P.S.:    tutte le note del sorgente precedente - a parte quelle variate -
  178.     valgono anche per questo.
  179.  
  180.     N.B.:    gli EQU provengono dagli include "exec/interrupt.i" ed
  181.         "LVO1.3/exec_lib.i".
  182.