tristanseifert

PSG Note Write Routine

Aug 1st, 2013
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; ---------------------------------------------------------------------------
  2. ; Lifts frequency for a note from a LUT and writes it to the PSG chip.
  3. ;
  4. ; Input:
  5. ;  a: Note ($00 to $48)
  6. ; ix: Pointer to channel RAM
  7. ; ---------------------------------------------------------------------------
  8. PSG_SetChannelNote:
  9.     add     a, (ix+Chan_Pitch)                                  ; Add pitch
  10.     add     a, a                                                ; Multiply note by 2
  11.     ld      e, a                                                ; Copy multiplied note to e
  12.     ld      d, $0                                               ; Clear d
  13.     ld      hl, FrequencyPSG                                    ; PSG freq table to bc
  14.     add     hl, de                                              ; Advance to correct frequency data
  15.  
  16.     ld      d, (hl)                                             ; Fetch high byte
  17.     inc     hl                                                  ; Increment pointer
  18.     ld      e, (hl)                                             ; Fetch low byte
  19.  
  20.     ex      de, hl                                              ; HL <-> DE
  21.  
  22.     ld      d, $0                                               ; Set D to zero
  23.     ld      e, (ix+Chan_FreqDisplacement)                       ; Get frequency displacement to E
  24.     adc     hl, de                                              ; Add displacement to note in hl
  25.  
  26.     ex      de, hl                                              ; Swap HL to be DE
  27.  
  28.     ld      (ix+Chan_FreqHigh), d                               ; Write high frequency to track RAM
  29.     ld      (ix+Chan_FreqLow), e                                ; Write low frequency to track RAM
  30.    
  31.     ; We've got the frequency in de now, so prepare the register commands
  32.     ld      hl, PSG_ChannelToRegMap                             ; Load pointer to channel -> reg array
  33.  
  34.     ld      a, (ix+Chan_Number)                                 ; Get channel from track memory
  35.     sub     $7                                                  ; Turn it into 0-based index
  36.     add     l                                                   ; Add 0-based channel number to l
  37.  
  38.     ld      b, (hl)                                             ; Read register value
  39.     ld      a, e                                                ; Load low byte of frequency
  40.     and     $F                                                  ; Get low 4 bits only
  41.     or      b                                                   ; Apply register bitmask
  42.     ld      (PSGReg), a                                         ; Write first byte to PSG chip
  43.  
  44.     ld      a, e                                                ; Load low byte of frequency
  45.     and     $F0                                                 ; Get high byte of frequency only
  46.     rrca                                                        ; Rotate 4 bits
  47.     rrca                                                        ; ''
  48.     rrca                                                        ; ''
  49.     rrca                                                        ; ''
  50.     ld      e, a                                                ; Write the low nybble to E
  51.     ld      a, d                                                ; Copy high byte of frequency to accumulator
  52.     rrca                                                        ; Rotate 4 bits
  53.     rrca                                                        ; ''
  54.     rrca                                                        ; ''
  55.     rrca                                                        ; ''
  56.     or      e                                                   ; Apply low nybble to frequency value
  57.     ld      (PSGReg), a                                         ; Write second byte to PSG chip
  58.  
  59. 9:
  60.     ret
  61.  
  62. ; This alignment of the table ensures there won't be an overflow when adding the channel number
  63.     align $4
  64. PSG_ChannelToRegMap:
  65.     db      %10000000, %10100000, %11000000
  66.  
  67. ; ---------------------------------------------------------------------------
  68. ; PSG Frequency table
  69. ; ---------------------------------------------------------------------------
  70. FrequencyPSG:
  71.         ;   C         C#        D         D#        E         F
  72.         ;   F#        G         G#        A         A#        B
  73.     db  $03, $56, $03, $26, $02, $F9, $02, $CE, $02, $A5, $02, $80  ; 4 (01 - 06)
  74.     db  $02, $5C, $02, $3A, $02, $1A, $01, $FB, $01, $DF, $01, $C4  ; 4 (07 - 0C)
  75.     db  $01, $AB, $01, $93, $01, $7D, $01, $67, $01, $53, $01, $40  ; 5 (0D - 12)
  76.     db  $01, $2E, $01, $1D, $01, $0D, $00, $FE, $00, $EF, $00, $E2  ; 5 (13 - 18)
  77.     db  $00, $D6, $00, $C9, $00, $BE, $00, $B4, $00, $A9, $00, $A0  ; 6 (19 - 1E)
  78.     db  $00, $97, $00, $8F, $00, $87, $00, $7F, $00, $78, $00, $71  ; 6 (1F - 24)
  79.     db  $00, $6B, $00, $65, $00, $5F, $00, $5A, $00, $55, $00, $50  ; 7 (25 - 2A)
  80.     db  $00, $4B, $00, $47, $00, $43, $00, $40, $00, $3C, $00, $39  ; 7 (2B - 30)
  81.     db  $00, $36, $00, $33, $00, $30, $00, $2D, $00, $2B, $00, $28  ; 8 (31 - 36)
  82.     db  $00, $26, $00, $24, $00, $22, $00, $20, $00, $1F, $00, $1; 8 (37 - 3C)
  83.     db  $00, $1B, $00, $1A, $00, $18, $00, $17, $00, $16, $00, $15  ; 9 (3D - 42)
  84.     db  $00, $13, $00, $12, $00, $11, $00, $10, $00, $08, $00, $00  ; 9 (43 - 48)
Advertisement
Add Comment
Please, Sign In to add comment