Sona 0.50 Source

Sona 0.50/src-z80/status.z80

;****************************************************************************
; UpdatePlaybackStatus
;
; Checks if BGM, SFX and PCM are playing, and updates the status flags that
; the 68000 sees accordingly. Called every so often from the main loop.
;----------------------------------------------------------------------------
; modifies ... a,bc,de,hl,iy,a'
;****************************************************************************

UpdatePlaybackStatus:
    PollPcm
    
    ld      hl, StreamBgmFirst          ; Go through every BGM stream and
    ld      bc, (NUM_BGMSTREAMS<<8)|$80 ; check their stack level. If any
CheckForBgmPlayingLoop:                 ; stream is playing the stack level
    ld      a, (hl)                     ; will be >= 0 and hence the MSB of
    and     c                           ; the C register will be cleared.
    ld      c, a                        ;
    ld      a, l                        ; We could have just set/reset a
    add     a, SIZEOF_STREAM            ; flag on playing and stopping a BGM
    ld      l, a                        ; but the latter isn't immediately
    PollPcm                             ; obvious (as streams can stop at
    djnz    CheckForBgmPlayingLoop      ; different times) and whatever it'd
                                        ; take to account for it would likely
                                        ; eat up more space than this.
    
    ld      iy, StreamSfxFirst          ; Get the stack level for each SFX
    ld      b, (iy+0*SIZEOF_STREAM)     ; stream into registers B, D and E
    ld      d, (iy+1*SIZEOF_STREAM)     ; (one for each stream). We only care
    ld      e, (iy+2*SIZEOF_STREAM)     ; about the upper bit (it's set if
                                        ; the relevant stream is not playing)
    
    PollPcm
    
    ld      a, c                        ; By this point the upper bit of
    rlc     b                           ; each register (C,B,D,E) will have
    rra                                 ; whether BGM/SFX are playing or not.
    rlc     d                           ;
    rra                                 ; Put them together into the upper
    rlc     e                           ; bits of the A register, exploiting
    rra                                 ; the carry flag.
    
    xor     $F0                         ; The above results rely on the MSB
                                        ; of the stack levels which will be
                                        ; set when *not* playing, which is
                                        ; the opposite of what we want. Flip
                                        ; the bits to correct this.
    
    ld      hl, PcmChInUse              ; Now throw in the bits indicating
    or      (hl)                        ; which of the PCM channels are
                                        ; currently in use (useful for lip
                                        ; syncing, etc.)
    
    ld      (PlaybackStatus), a         ; Save status flags
    ret                                 ; End of subroutine