em00k

DMA Sample Player

Feb 19th, 2020
101
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; example multi sample engine
  2. ;
  3. ; sjasmplus z00m's fork
  4. ; em00k2020 / david saphier v1.0
  5. ;
  6.  
  7. z80dmaport  equ $6b
  8. covoxport   equ $ffdf
  9. buffer_size equ 8192
  10. scaler      equ 12  
  11. loop        equ $b2
  12. noloop      equ $82
  13.  
  14.     device zxspectrumnext
  15.    
  16.     org $8000
  17.    
  18.     ; macro to make initsample clear
  19.     macro initsample start, length, scalerrepeat
  20.         ld hl,start : ld de,length  : ld bc,scalerrepeat
  21.         call initdma
  22.     endm
  23.     ; macro to play a sample from the sample table
  24.     macro playsample samplenr
  25.         ld c,samplenr : call playsample
  26.     endm
  27.    
  28. start
  29.     ; addr fs sample, length of sample and $90 for initial scaler, $00 no loop
  30.     ; for the sample engine we only want to init the dma, so send a 0 l
  31.    
  32.     ei          ; 0             0                   x90 scaler x01 loop
  33.     initsample sampletable,sampletable-sampletable, $9001
  34.  
  35. miniloop:
  36.  
  37. samp = 0                                                ; sinple loop which goes through samples 0 - 9
  38.     rept 10                                             ; rept will repate the following code 10 times, increasing samp+1
  39.     playsample samp                                     ; each repeat
  40.     call wait
  41. samp = samp + 1
  42.     endr
  43.     jp miniloop
  44.    
  45. wait:  
  46.     ld b,60                                             ; small pause
  47. .wt halt : djnz .wt    
  48.     ret
  49.  
  50. scalers:
  51.     ; not used in the multisample demo
  52.     db scaler,scaler*2,scaler*3,scaler*4,scaler*5
  53.     db scaler*6,scaler*7,scaler*8,scaler*9,scaler*10,scaler*12 
  54.     db $ff
  55.  
  56. playsample:
  57.     ; sample table is bank x00 loop x00, samplestart x0000, length x0000
  58.     ;
  59.     ; dw $01dd
  60.     ld d,c : ld e,6 : mul                               ; get offest in sample table
  61.     ld hl,sampletable                                   ; start of sample table
  62.     add hl,de                                           ; add offset to samplestart address
  63.     ld a, (hl) : cp 1 : jr z,.loopedsample              ; chedk for loop
  64.     ld a,noloop : jr .noloopset    
  65. .loopedsample:
  66.     ld a,loop
  67. .noloopset:
  68.     ld (dmarepeat),a :  inc hl                          ; now at bank to set
  69.     ld a, (hl) : nextreg $57,a                          ; set mmu7/$e000 with bank in a
  70.     inc hl                                              ; now at sample start address x0000
  71.     ld c,(hl) : inc hl : ld a,(hl) : or $e0 : ld b,a    ; or start address with $e000
  72.     ld (dmaaddress),bc                                  ; store new address in dma code
  73.     inc hl : ld c,(hl) : inc hl : ld b,(hl)             ; now at length x0000
  74.     ld (dmadlength),bc                                  ; store length in dma length
  75.     ld bc,$6b : ld a,$87 : out (c),a                    ; reset dma                                        
  76.     jp dmaretrig                                        ; start dma
  77.     ret
  78.  
  79. initdma:
  80.  
  81.     ; hl = address de = dmalenght bc = scaler + repeat
  82.     ld (dmaaddress), hl : ld (dmadlength), de
  83.     ld a,b : ld (dmascaler),a
  84. dmaretrig:                                              ; send data to dma
  85.     ld hl,dmasample : ld b,dmaend-dmasample : ld c,z80dmaport : otir
  86.     ret
  87.  
  88. dmasample:
  89.     defb $c3                                            ;   r6-reset dma
  90.     defb $c7                                            ;   r6-reset port a timing
  91.     defb $ca                                            ;   r6-set port b timing same as port a
  92.     defb $7d                                            ;   r0-transfer mode, a -> b
  93. dmaaddress:                                
  94.     defw $e000                                          ;   r0-port a, start address
  95. dmadlength:                                
  96.     defw 8192                                           ;   r0-block length
  97.     defb $54                                            ;    01010100 r1-port a address incrementing, variable timing
  98.     defb $2                                             ;   r1-cycle length port b
  99.     defb $68                                            ;    01101000 r2-port b address fixed, variable timing
  100.     defb $22                                            ;   r2-cycle length port b 2t with pre-escaler
  101. dmascaler:                                 
  102.     defb 8*12                                           ;   r2-port b pre-escaler
  103.     defb $cd                                            ;    11001101 r4-burst mode
  104.     defw covoxport                                      ;   r4-port b, start address
  105. dmarepeat:                                              ;    $b2 for short burst $82 for one shot
  106.     defb loop                                           ;   r5-stop on end of block, rdy active low
  107.     defb $bb                                            ;    10111011 read mask follows
  108.     defb %00001000                                      ;   mask - only port a hi byte 
  109.     defb $cf                                            ;   r6-load
  110.     defb $b3                                            ;   r6-force ready
  111.     defb $87                                            ;   r6-enable dma        
  112. dmaend:
  113.  
  114. sampletable:
  115.    
  116.     ; bank, start, len
  117.     ; 8bk bank + loop , offset from bank start, lenth - must be a better way to store this.
  118.     ; bank x00 loop x00, samplestart x0000, length x0000
  119.     dw $0f01, 0000                  , 944               ; 0 mothership looped
  120.     dw $0f00, 0945                  , 1911              ; 1 steam      
  121.     dw $1000, 0000                  , 7313              ; 2 explode    
  122.     dw $1101, 0000                  , 2529              ; 3 zapzapdii  looped
  123.     dw $1100, 2529                  , 405               ; 4 dub1   
  124.     dw $1100, 2529+405              , 363               ; 5 dub2
  125.     dw $1100, 2529+405+363          , 382               ; 6 dub3
  126.     dw $1100, 2529+405+363+382      , 489               ; 7 dub4
  127.     dw $1101, 2529+405+363+382+489  , 917               ; 8 wawawawa   looped
  128.     dw $1201, 0000                  , 6014              ; 9 zzzzrrrttt looped
  129.     dw $ffff
  130.    
  131.     slot 7                                              ; slot 7 is mmu 7 @ 0xe000..0xffff
  132.     page $f : org $e000                                 ; page 15/$f is a next mmu bank 8kb nr $f , we have to org $e000
  133.     incbin "0.pcm"                                      ; as that is where we want this code to go
  134.     incbin "1.pcm"                                      ; and we only have 8kb per bank free
  135.     page $10 : org $e000                                ; next mmu bank $10, starting at $e000 again
  136.     incbin "2.pcm"  
  137.     page $11 : org $e000                                ; repeate for remaining samples
  138.     incbin "3.pcm"                                      ; these are small samples  
  139.     incbin "4.pcm"  
  140.     incbin "5.pcm"  
  141.     incbin "6.pcm"                                      ; unisgned 5512hz samples raw, no header.
  142.     incbin "7.pcm"  
  143.     incbin "8.pcm"
  144.     page $12 : org $e000
  145.     incbin "18.pcm"
  146.  
  147.     savenex open "sampleengine.nex", start , $bffe
  148.     savenex core 3, 0, 0      
  149.     savenex cfg  0, 0            
  150.     savenex auto
  151.     savenex close
RAW Paste Data