9946f14ccfd9 — Laurens Holst 3 years ago
PitchBend: Implement pitch bend support on all channels.
M src/COM.asm +1 -0
@@ 66,6 66,7 @@ COM_Main:
 	INCLUDE "modules/Not.asm"
 	INCLUDE "modules/Or.asm"
 	INCLUDE "modules/Attenuate.asm"
+	INCLUDE "modules/PitchBend.asm"
 
 	ENDS
 

          
M src/modules/OPLLChannel.asm +3 -1
@@ 9,7 9,8 @@ OPLLChannel: MACRO ?msxMusic, ?channel
 	sustain: Or sustainVelocity.value, channel.controllers + 69
 	volumeControllers: Attenuate channel.controllers + 7, channel.controllers + 11
 	volume: Attenuate channel.note.velocity, volumeControllers.value
-	opllTone: OPLLTone ?msxMusic, ?channel, instrument.value, volume.value, gate.value, channel.note.trigger, channel.note.key, Constants_instance + 0, sustain.value
+	pitchBend: PitchBend channel.pitchBend + 1, channel.pitchBend, channel.note.key, Constants_instance + 0, Constants_instance + 2, Constants_instance + 0
+	opllTone: OPLLTone ?msxMusic, ?channel, instrument.value, volume.value, gate.value, channel.note.trigger, pitchBend.note, pitchBend.noteFraction, sustain.value
 	Update:
 		call instrument.Update
 		call gate.Update

          
@@ 17,5 18,6 @@ OPLLChannel: MACRO ?msxMusic, ?channel
 		call sustain.Update
 		call volumeControllers.Update
 		call volume.Update
+		call pitchBend.Update
 		jp opllTone.Update
 	ENDM

          
M src/modules/PSGEnvelopeChannel.asm +3 -1
@@ 5,9 5,11 @@ PSGEnvelopeChannel: MACRO ?psg, ?channel
 	channel: Channel
 	shape: Clamp channel.program, Constants_instance + 0, Constants_instance + 7
 	gate: Or channel.note.gate, channel.controllers + 64
-	psgEnvelope: PSGEnvelope ?psg, ?channel, shape.value, channel.note.key, Constants_instance + 0, gate.value
+	pitchBend: PitchBend channel.pitchBend + 1, channel.pitchBend, channel.note.key, Constants_instance + 0, Constants_instance + 2, Constants_instance + 0
+	psgEnvelope: PSGEnvelope ?psg, ?channel, shape.value, pitchBend.note, pitchBend.noteFraction, gate.value
 	Update:
 		call shape.Update
 		call gate.Update
+		call pitchBend.Update
 		jp psgEnvelope.Update
 	ENDM

          
M src/modules/PSGNoiseChannel.asm +3 -1
@@ 4,8 4,10 @@ 
 PSGNoiseChannel: MACRO ?psg, ?channel
 	channel: Channel
 	gate: Or channel.note.gate, channel.controllers + 64
-	psgNoise: PSGNoise ?psg, ?channel, channel.note.key, Constants_instance + 0, gate.value
+	pitchBend: PitchBend channel.pitchBend + 1, channel.pitchBend, channel.note.key, Constants_instance + 0, Constants_instance + 2, Constants_instance + 0
+	psgNoise: PSGNoise ?psg, ?channel, pitchBend.note, pitchBend.noteFraction, gate.value
 	Update:
 		call gate.Update
+		call pitchBend.Update
 		jp psgNoise.Update
 	ENDM

          
M src/modules/PSGToneChannel.asm +3 -1
@@ 6,10 6,12 @@ PSGToneChannel: MACRO ?psg, ?channel
 	gate: Or channel.note.gate, channel.controllers + 64
 	volumeControllers: Attenuate channel.controllers + 7, channel.controllers + 11
 	volume: Attenuate channel.note.velocity, volumeControllers.value
-	psgTone: PSGTone ?psg, ?channel, channel.note.key, Constants_instance + 0, gate.value, volume.value
+	pitchBend: PitchBend channel.pitchBend + 1, channel.pitchBend, channel.note.key, Constants_instance + 0, Constants_instance + 2, Constants_instance + 0
+	psgTone: PSGTone ?psg, ?channel, pitchBend.note, pitchBend.noteFraction, gate.value, volume.value
 	Update:
 		call gate.Update
 		call volumeControllers.Update
 		call volume.Update
+		call pitchBend.Update
 		jp psgTone.Update
 	ENDM

          
A => src/modules/PitchBend.asm +56 -0
@@ 0,0 1,56 @@ 
+;
+;
+;
+PitchBend: MACRO ?bend, ?bendFraction, ?key, ?keyFraction, ?range, ?rangeFraction
+	noteFraction:
+		db 0
+	note:
+		db 0
+	Update:
+		ld a,(?rangeFraction)
+		add a,a
+		ld c,a
+		ld a,(?range)
+		ld b,a       ; bc = range as 8.8
+		ld a,(?bendFraction)
+		add a,a
+		ld l,a
+		ld a,(?bend)
+		ld h,a
+		add hl,hl
+		add hl,hl    ; hl = bend as 0.16
+		jr nc,Negative
+	Positive:
+		muluw hl,bc  ; dehl = offset as 16.16
+		ld a,(?keyFraction)
+		add a,a
+		ld l,a
+		ld a,(?key)
+		rl h         ; round
+		ld h,a
+		adc hl,de
+		jp p,PositiveNoClamp
+		ld hl,7FFEH
+	PositiveNoClamp:
+		srl l
+		ld (noteFraction),hl
+		ret
+	Negative:
+		ex de,hl
+		ld hl,0FFF8H
+		sbc hl,de
+		muluw hl,bc  ; dehl = offset as 16.16
+		ld a,(?keyFraction)
+		add a,a
+		ld l,a
+		ld a,(?key)
+		rl h         ; round
+		ld h,a
+		sbc hl,de
+		jp p,NegativeNoClamp
+		ld hl,0000H
+	NegativeNoClamp:
+		srl l
+		ld (noteFraction),hl
+		ret
+	ENDM