;****************************************************************************
; AddPitch
; Adds up together two pitch values.
;----------------------------------------------------------------------------
; input hl .... 1st operand (long form)
; input bc .... 2nd operand (long form)
;----------------------------------------------------------------------------
; output hl ... result (long form)
;----------------------------------------------------------------------------
; modifies .... a,bc,hl
;----------------------------------------------------------------------------
; notes: high byte is octave, low byte is semitone+fraction.
; Low byte must be 0..191 for this routine to work correctly.
;
; It does *not* prevent pitch from going out of range (this is intentional,
; as it allow chaining multiple additions/substractions and the end result
; may not need clamping).
;****************************************************************************
AddPitch:
PollPcm
ld a, l ; Add both semitones
add a, c
jr c, AddPitchCarry ; Carried onto next octave?
cp 12<<4
jr nc, AddPitchCarry
AddPitchFixed:
ld l, a ; Store semitone
PollPcm
ld a, h ; Add both octaves
add a, b
ld h, a
ret ; End of subroutine
AddPitchCarry:
sub 12<<4 ; Fix semitone
inc h ; Bump up octave
jr AddPitchFixed ; Resume calculation
;****************************************************************************
; SubPitch
; Substracts together two pitch values.
;----------------------------------------------------------------------------
; input hl .... 1st operand (long form)
; input bc .... 2nd operand (long form)
;----------------------------------------------------------------------------
; output hl ... result (long form)
;----------------------------------------------------------------------------
; modifies .... a,bc,hl
;----------------------------------------------------------------------------
; notes: high byte is octave, low byte is semitone+fraction.
; Low byte must be 0..191 for this routine to work correctly.
;
; It does *not* prevent pitch from going out of range (this is intentional,
; as it allow chaining multiple additions/substractions and the end result
; may not need clamping).
;****************************************************************************
SubPitch:
PollPcm
ld a, l ; Substract both semitones
sub c
jr c, SubPitchCarry ; Borrowed into previous octave?
SubPitchFixed:
ld l, a ; Store semitone
PollPcm
ld a, h ; Substract both octaves
sub b
ld h, a
ret ; End of subroutine
SubPitchCarry:
add 12<<4 ; Fix semitone
dec h ; Bump down octave
jr SubPitchFixed ; Resume calculation
;****************************************************************************
; AddOrSubPitch
; Calls either AddPitch or SubPitch depending on the value of A.
;----------------------------------------------------------------------------
; input a ..... 0 = AddPitch, else SubPitch
; input hl .... 1st operand (long form)
; input bc .... 2nd operand (long form)
;----------------------------------------------------------------------------
; output hl ... result (long form)
;----------------------------------------------------------------------------
; modifies .... a,bc,hl
;----------------------------------------------------------------------------
; notes: high byte is octave, low byte is semitone+fraction.
; Low byte must be 0..191 for this routine to work correctly.
;
; It does *not* prevent pitch from going out of range (this is intentional,
; as it allow chaining multiple additions/substractions and the end result
; may not need clamping).
;****************************************************************************
AddOrSubPitch:
or a
jr z, AddPitch
jr SubPitch