Bisqwit

DMC-aware delay code

Dec 19th, 2012
426
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;;;;;;;;;;;;;;;;;;;;;;;;
  2. ; Delays A:X clocks+overhead
  3. ; Time: 256*A+X+33 clocks (including JSR)
  4. ; Written by Joel Yliluoma. Clobbers A. Preserves X,Y. Has relocations.
  5. ; This part is verified to work correctly.
  6. ;;;;;;;;;;;;;;;;;;;;;;;;
  7. :       ; do 256 cycles.        ; 5 cycles done so far. Loop is 2+1+ 2+3+ 1 = 9 bytes.
  8.         sbc #1                  ; 2 cycles - Carry was set from cmp
  9.         pha                     ; 3 cycles
  10.          lda #(256-25-10-2-4)   ; +2
  11.          jsr delay_a_25_clocks
  12.         pla                     ; 4 cycles
  13. delay_256a_x_33_clocks:
  14.         cmp #1                  ; +2; 2 cycles overhead
  15.         Jcs :-                  ; +2; 4 cycles overhead
  16.         ; 0-255 cycles remain, overhead = 4
  17.         txa                     ; +2; 6; +27 = 33
  18.         ; 15 + JSR + RTS overhead for the code below. JSR=6, RTS=6. 15+12=27
  19.         ;          ;    Cycles        Accumulator     Carry flag
  20.         ;          ; 0  1  2  3  4       (hex)        0 1 2 3 4
  21.         sec        ; 0  0  0  0  0   00 01 02 03 04   1 1 1 1 1
  22. :       sbc #5     ; 2  2  2  2  2   FB FC FD FE FF   0 0 0 0 0
  23.         Jcs :-     ; 4  4  4  4  4   FB FC FD FE FF   0 0 0 0 0
  24.         lsr a      ; 6  6  6  6  6   7D 7E 7E 7F 7F   1 0 1 0 1
  25.         Jcc :+     ; 8  8  8  8  8   7D 7E 7E 7F 7F   1 0 1 0 1
  26. :       sbc #$7E   ;10 11 10 11 10   FF FF 00 00 01   0 0 1 1 1
  27.         Jcc :+     ;12 13 12 13 12   FF FF 00 00 01   0 0 1 1 1
  28.         Jeq :+     ;      14 15 14         00 00 01       1 1 1
  29.         Jne :+     ;            16               01           1
  30. :       rts        ;15 16 17 18 19   (thanks to dclxvi for the algorithm)
  31. ;;;;;;;;;;;;;;;;;;;;;;;;
  32. ; Delays A clocks + overhead
  33. ; Preserved: X, Y
  34. ; Time: A+25 clocks (including JSR)  (13+6+6)
  35. ; This part is verified to work correctly.
  36. ;;;;;;;;;;;;;;;;;;;;;;;;
  37. :       sbc #7          ; carry set by CMP
  38. delay_a_25_clocks:
  39.     cmp #7      ;2
  40.     Jcs :-          ;2    do multiples of 7
  41.     ;               ; Cycles          Accumulator            Carry           Zero
  42.     lsr a           ; 0 0 0 0 0 0 0   00 01 02 03 04 05 06   0 0 0 0 0 0 0   ? ? ? ? ? ? ?
  43.     Jcs :+          ; 2 2 2 2 2 2 2   00 00 01 01 02 02 03   0 1 0 1 0 1 0   1 1 0 0 0 0 0
  44. :       Jeq @zero       ; 4 5 4 5 4 5 4   00 00 01 01 02 02 03   0 1 0 1 0 1 0   1 1 0 0 0 0 0
  45.     lsr a           ; : : 6 7 6 7 6   :: :: 01 01 02 02 03   : : 0 1 0 1 0   : : 0 0 0 0 0
  46.     Jeq :+          ; : : 8 9 8 9 8   :: :: 00 00 01 01 01   : : 1 1 0 0 1   : : 1 1 0 0 0
  47.     Jcc :+          ; : : : : A B A   :: :: :: :: 01 01 01   : : : : 0 0 1   : : : : 0 0 0
  48. @zero:  Jne :+          ; 7 8 : : : : C   00 01 :: :: :: :: 01   0 1 : : : : 1   1 1 : : : : 0
  49. :       rts             ; 9 A B C D E F   00 01 00 00 01 01 01   0 1 1 1 0 0 1   1 1 1 1 0 0 0
  50. ; ^ (thanks to dclxvi for the algorithm)
  51.  
  52.  
  53. ; Input: X:A = number of cycles to delay
  54. ; Overhead: 80 cycles
  55. ; For use in Castlevania II.
  56. PCMawareDelay:
  57.     ; Sound_PCMsampleActive may be:
  58.     ;      #$00 = no PCM sound
  59.     ;      #$5D = something   0E 7F F3 17  WaveLength=71 or 65, Count=$7F, Addr=$FCC0, Len=369 (ends at $FE31)
  60.     ;      #$5E = something   0F 00 F0 0B  WaveLength=53 or 49, Count=$00, Addr=$FC00, Len=177 (ends at $FCB1)
  61.     ;      #$5F = something   0F 00 F9 0A  WaveLength=53 or 49, Count=$00, Addr=$FE40, Len=161 (ends at $FEE1)
  62.     ;
  63.     ;NTSC:
  64.     ; Sample 5D:     Ratio: 71*8/4 = 568/4 = 142 (3-4 cycles stolen from SPRDMA)
  65.     ; Samples 5E,5F: Ratio: 53*8/4 = 424/4 = 106 (3-4 cycles stolen from SPRDMA)
  66.     ;PAL:
  67.     ; Sample 5D:     Ratio: 65*8/4 = 520/4 = 130 (3-4 cycles stolen from SPRDMA)
  68.     ; Samples 5E,5F: Ratio: 49*8/4 = 392/4 =  98 (3-4 cycles stolen from SPRDMA)
  69.  
  70.     sta delay_ptr+0     ;3
  71.     stx delay_ptr+1     ;3
  72.  
  73.     .if PAL=0
  74.         LEN_5D    = 142
  75.         LEN_other = 106
  76.     .else
  77.         LEN_5D    = 130
  78.         LEN_other = 98
  79.     .endif
  80.     STEAL=1
  81.  
  82. @pcm_loop:
  83.     lda $4015       ;4
  84.     and #$10        ;2
  85.     Jeq @no_pcm     ;3 = 15
  86.                 ;-1
  87.     lda Sound_PCMsampleActive ;4
  88.     cmp #$5D        ;2
  89.     Jeq @pcm_5D     ;3
  90. ;;;;;;;;;;;;;;;;;;;
  91. @pcm_other:         ;-1, 22 so far
  92.     ldy #LEN_other      ;2
  93.     Jne @pcm_common     ;3, 27
  94. @pcm_5D:            ; 23 so far
  95.     ldy #LEN_5D     ;2, 25
  96.     nop         ;+2 to balance the cycles
  97. ;;;;;;;;;;;;;;;;;;;
  98. @pcm_common:            ; 27 so far
  99.     lda delay_ptr+1     ;3
  100.     Jne @pcm_ok_quick   ;3 = 33
  101.                 ;-1
  102.     cpy delay_ptr+0     ;3
  103.     Jcs @trailer        ;3 = 38
  104.                 ;-1
  105.     Jcc @pcm_ok     ;3 = 40
  106.  
  107. @pcm_ok_quick:          ; 33 so far
  108.     php
  109.     plp         ;+7
  110. @pcm_ok:            ; 40 so far
  111.     lda delay_ptr+0     ;3
  112.     sty delay_ptr+0     ;3
  113.     sec         ;2
  114.     sbc delay_ptr+0     ;3
  115.     sta delay_ptr+0     ;3
  116.     lda delay_ptr+1     ;3
  117.     sbc #0          ;2
  118.     sta delay_ptr+1     ;3
  119.     tya         ;2
  120.     sbc #(25+63+STEAL)  ;2   ; the "63" from below goes here.
  121.     jsr delay_a_25_clocks   ;0
  122.     jmp @pcm_loop       ;3 = 69, MINUS 6 from beginning = 63 per loop
  123.  
  124. @no_pcm:                ;15 so far
  125.     php
  126.     plp ;+7
  127.     php
  128.     plp ;+7
  129.     php
  130.     plp ;+7
  131.     nop ;+2   = +23
  132. @trailer:               ;38 so far
  133.     lda delay_ptr+1         ;3
  134.     ldx delay_ptr+0         ;3
  135.     jmp delay_256a_x_33_clocks  ;3
  136.     ; Total overhead: 40+3+3+3 + 33 = 80 cycles.
  137.  
  138. ;;;;;;;;;;;;;;;;;;;
RAW Paste Data