Sona 0.50 Source

Sona 0.50/src-z80/instruments.z80

;****************************************************************************
; LoadInstrList
;
; Loads new instruments into the instrument list. The instrument addresses
; are copied from 68000 area to our internal list. Only the specified range
; is overwritten.
;----------------------------------------------------------------------------
; input a .... first instrument ID
; input b .... number of instruments
; input c .... instrument list bank
; input hl ... instrument list address
;----------------------------------------------------------------------------
; modifies ... a,bc,de,hl,a'
;----------------------------------------------------------------------------
; From the 68000 side, each instrument is a 32-bit value with the address
; in 68000 space. The list and the instruments *must* reside in cartridge
; area in order to be usable.
;****************************************************************************

LoadInstrList:
    ld      (LoadInstrListId), a        ; Store first ID
    
    ld      a, b                        ; Move loop counter into A since we
                                        ; need to use it to save it for later
    
    or      a                           ; List is empty? Do nothing then
    ret     z
    
LoadInstrListLoop:
    push    af                          ; Store loop counter for later to
                                        ; free up registers
    
    ReadRomByte                         ; Read 68000 address of next entry
    ReadRomByte                         ; (we skip the first byte since it's
    ld      e, b                        ; unaddressable and we keep it there
    ReadRomByte                         ; just for alignment's sake)
    ld      d, b                        ;
    ReadRomByte                         ; B = bits 23-16
                                        ; D = bits 15-8
                                        ; E = bits 7-0
    
    PollPcm
    
    push    hl                          ; Save current pointer for later
                                        ; since we really need to free up
                                        ; some registers
    
    ld      a, e                        ; Convert the 68000 address to our
    ld      e, b                        ; internal address+bank format
    ex      de, hl                      ;
    ToAddrBank                          ; A = 68000 window bank
                                        ; H = Z80 address (high)
                                        ; L = Z80 address (low)
    
LoadInstrListId: equ $+1
    ld      de, InstrList               ; Store address into the
    ex      de, hl                      ; instrument list
    ld      (hl), e
    inc     h
    ld      (hl), d
    inc     h
    ld      (hl), a
    
    PollPcm
    
    inc     l                           ; Advance onto the next instrument,
    ld      a, l                        ; so update the list pointer
    ld      (LoadInstrListId), a
    
    PollPcm
    
    pop     hl                          ; Restore address and loop count,
    pop     af                          ; and keep iterating until we've
    dec     a                           ; gone through all entries
    jr      nz, LoadInstrListLoop
    
    ret                                 ; End of subroutine

;****************************************************************************
; ReplaceInstrument [SONAOP_REPLINSTR]
;
; Replaces an instrument from the instrument list with data embedded in the
; stream. Any references to the replaced instrument ID will now point to the
; embedded data within this stream.
;----------------------------------------------------------------------------
; input c ..... current bank
; input hl .... current address
;----------------------------------------------------------------------------
; output c .... new bank
; output hl ... new address
;----------------------------------------------------------------------------
; modifies .... a,bc,de,hl,a'
;****************************************************************************

ReplaceInstrument:
    call    ReadInstrumentId            ; Get instrument ID to replace
    ld      a, b
    ex      af, af'
    
    call    ReadAddressArg              ; Get address of instrument data
    ld      b, a
    
    ex      af, af'                     ; Store that address in the
    ld      l, a                        ; instrument list
    ld      h, InstrList>>8
    ld      (hl), e
    inc     h
    ld      (hl), d
    inc     h
    ld      (hl), b
    
    ret                                 ; End of subroutine