;
; 9090.inc: support file for tr-9090 style trigger circuit
;
; Thanks a lot for Trevor for making his firmware publicly
; available.
;
; RB0 to RB5 - trigger data lines
; RB6 - trigger volume dac clock strobe
; RB7 - first (a) 40174 trigger latch
; RA2 - second (b) 40174 trigger latch
; RA3 - inhibit line for volume dac multiplexers
;
; For macros see xoxmacros.h
;
; 29.7.2005: works ok!
;
; LICENSE
; Creative Commons Attribution-NonCommercial-ShareALike 2.5
;
; You are free:
;
; * to copy, distribute, display, and perform the work
; * to make derivative works
;
; Under the following conditions:
;	
; 1. Attribution. You must attribute the work in the manner specified by the 
;    author or licensor.
; 2. Noncommercial. You may not use this work for commercial purposes.
; 3. Share Alike. If you alter, transform, or build upon this work, you may 
;    distribute the resulting work only under a license identical to this one.
;
; * For any reuse or distribution, you must make clear to others the license 
;   terms of this work.
; * Any of these conditions can be waived if you get permission from the 
;   copyright holder.
;
; Your fair use and other rights are in no way affected by the above.
;
; This is a human-readable summary of the Legal Code.
; See full license at http://creativecommons.org/licenses/by-nc-sa/2.5/legalcode
;
; Copyright: Marko Kanala (raato@mulletronic.com).
;

;;; not used:
;;; RA4: MIDI LED (sink; 0V = LED on)
;;; RB0/INT: MIDI input  
;;; RB7: sync output - to Q87

; 9090 dac multiplexer values
MPX_BDRUM		equ		b'00010011'
MPX_SDRUM		equ		b'00010000'
MPX_LTOM		equ		b'00010001'
MPX_MTOM		equ		b'00010010'
MPX_HTOM		equ		b'00000100'
MPX_RSHOT		equ		b'00111100'
MPX_HCLAP		equ		b'00001100'
MPX_HIHAT		equ		b'00010101'
MPX_CRASH		equ		b'00010110'
MPX_RIDE		equ		b'00010111'

;
; Plays the triggers according to triggers_a
;  and triggers_b registers.  The original
;  9090 circuit is used.
;
; TODO: should probably be rewritten to parse
;  the triggers directly from the pattern data
;
tr_do_triggers:
	; clear lcd enable to be able to mess with port b
	bcf		PORT_LCD_EN, LCD_EN_PIN

	; set total accent off
	clrf	totalaccent

	; clear triggers for next round
	clrf	triggers_a
	clrf	triggers_b	
	; ... and flams 
	clrf	flam_a
	clrf	flam_b

	; clear midi volumes
	clrf	midi_bdrum
	clrf	midi_sdrum
	clrf	midi_ltom
	clrf	midi_mtom
	clrf	midi_htom
	clrf	midi_rshot
	clrf	midi_hclap
	clrf	midi_chihat
	clrf	midi_ohihat
	clrf	midi_crash
	clrf	midi_ride

	; tr_acc sets the total accent if it's on
	LOADPATTOFSR	2, PAT_ACCENT
	IFTRIGONNOFLAMCALL	currentstep_accent, tr_acc

	; load [fill]pattern + PAT_TRIGS to FSR2
	LOADPATTOFSR	2, PAT_TRIGS

	; check pattern triggers
	IFTRIGONCALL	currentstep_bdrum, tr_bd, FLAMREG_BASSDRUM, TRIG_BASSDRUM
	IFTRIGONCALL	currentstep_sdrum, tr_sd, FLAMREG_SNAREDRUM, TRIG_SNAREDRUM
	IFTRIGONCALL	currentstep_ltom, tr_lt, FLAMREG_LOWTOM, TRIG_LOWTOM
	IFTRIGONCALL	currentstep_mtom, tr_mt, FLAMREG_MIDTOM, TRIG_MIDTOM
	IFTRIGONCALL	currentstep_htom, tr_ht, FLAMREG_HITOM, TRIG_HITOM
	IFTRIGONCALL	currentstep_rshot, tr_rs, FLAMREG_RIMSHOT, TRIG_RIMSHOT
	IFTRIGONCALL	currentstep_hclap, tr_hc, FLAMREG_HANDCLAP, TRIG_HANDCLAP
	IFTRIGONCALL	currentstep_chihat, tr_chh, FLAMREG_HIHAT, TRIG_HIHAT
	IFTRIGONCALL	currentstep_ohihat, tr_ohh, FLAMREG_HIHAT, TRIG_HIHAT
	IFTRIGONCALL	currentstep_crash, tr_cc, FLAMREG_CRASH, TRIG_CRASH
	IFTRIGONCALL	currentstep_ride, tr_rc, FLAMREG_RIDE, TRIG_RIDE
	; if open hihat voice is on disable closed hihat flam
	btfss	TRIGREG_HIHATSEL, TRIG_HIHATSEL 
	; ... by setting the flam to open hihat
	bsf		FLAMREG_HIHATSEL, TRIG_HIHATSEL

tr_checklatches:
;	; triggers set from pattern, should we trig the
;	;  9090 latches ?
;	tstfsz	triggers_a
;	bra		tr_set
;	tstfsz	triggers_b
;	bra		tr_set
	; just set the latches always
	bra		tr_set
	return					; nope, just return
tr_set:
	; trigger regs set, triggers should be latched
	call	tr_set_trigger_latches

	; reset and activate timer 3
	;  for 2ms delay	
	movlw	trig_width_high
	movwf	TMR3H
	movlw	trig_width_low
	movwf	TMR3L
	bsf		T3CON, TMR3ON		; enable timer 
	return

; sets the trigger latches according
;  to triggers_a and triggers_b regs.
tr_set_trigger_latches:
	; inhibit muxes
	bsf		TRIGMUXINH_PORT, TRIGMUXINH_PIN
	; latches low to wait for clock pulse
	bcf		TRIGLATCHA_PORT, TRIGLATCHA_PIN	
	bcf		TRIGLATCHB_PORT, TRIGLATCHB_PIN

	; if din sync is set to off don't set START on din sync start/stop
	IFSETTINGOFF	SETTING_DIN_OUT, tr_set_triggers_stop 
	IFMODE	MODE_RUN, tr_set_triggers_run
	; if we're not running set the STARTSTOP bit
tr_set_triggers_stop:
	bsf		TRIGREG_STARTSTOP, TRIG_STARTSTOP
tr_set_triggers_run:

	movlw	2
	call	tr_delay		; delay 1.1us
							;  that allows 4051 inhibit to set
	; write latch a
	movlw	b'11000000'
	andwf	PORT_TRIG, W	; keep rb6 and rb7
	iorwf	triggers_a, W	; xxtttttt
	movwf	PORT_TRIG
	nop
	nop
	nop

	; set latch
	bsf		TRIGLATCHA_PORT, TRIGLATCHA_PIN
	movlw	5
	call	tr_delay		; delay 1.7us

	; write latch b
	movlw	b'11000000'
	andwf	PORT_TRIG, W	; keep rb6 and rb7
	iorwf	triggers_b, W	; xxtttttt
	movwf	PORT_TRIG
	nop
	nop
	nop

	; set latch
	bsf		TRIGLATCHB_PORT, TRIGLATCHB_PIN
	nop
	nop
	nop

	; trigger latches now set
	; note: we must maintain the state of the trigger
	;       registers for closed hihat to work as the
	;	    hihat select is maintained in TMR3.
	return

;
; sets the trigger latches off.
;  the trigger pulses are timed
;  to be ~2ms with timer 3.
;
tr_clear_triggers:
	; disable timer 3 for next round
	bcf		T3CON, TMR3ON
	; make sure triggers are off and
	;  retain hihat select
	btfsc	TRIGREG_HIHATSEL, TRIG_HIHATSEL
	bra 	tr_clear_triggers_hhs
	clrf	triggers_a
	clrf	triggers_b
	; do triggers
	bra 	tr_set_trigger_latches
tr_clear_triggers_hhs:
	clrf	triggers_a
	clrf	triggers_b
	bsf		TRIGREG_HIHATSEL, TRIG_HIHATSEL
	bra 	tr_set_trigger_latches

; checks if any flam sound should be played
;  and triggers the flam sounds accordingly
tr_do_flams:
	; flam_a and flam_b should be set to correct
	;  trigger values in tr_do_triggers
	movff	flam_a, triggers_a
	movff	flam_b,	triggers_b
	bra 	tr_checklatches

; total accent on
tr_acc:
	incf	totalaccent
	return

; bass drum trigger on
tr_bd:
	; set bass drum trigger
	bsf		TRIGREG_BASSDRUM, TRIG_BASSDRUM
	; set bass drum volume
	; note: this depends on the value of FSR2
	;       which is already set in IFTRIGONCALL
	TRIGSETVOL	MPX_BDRUM, vol_base_bdrum, vol_acc_bdrum, midi_bdrum
	return

; snare drum trigger on
tr_sd:
	bsf		TRIGREG_SNAREDRUM, TRIG_SNAREDRUM
	TRIGSETVOL	MPX_SDRUM, vol_base_sdrum, vol_acc_sdrum, midi_sdrum
	return

; low tom drum trigger on
tr_lt:
	bsf		TRIGREG_LOWTOM, TRIG_LOWTOM
	TRIGSETVOL	MPX_LTOM, vol_base_ltom, vol_acc_ltom, midi_ltom
	return

; mid tom trigger on
tr_mt:
	bsf		TRIGREG_MIDTOM, TRIG_MIDTOM
	TRIGSETVOL	MPX_MTOM, vol_base_mtom, vol_acc_mtom, midi_mtom
	return

; hi tom trigger on
tr_ht:
	bsf		TRIGREG_HITOM, TRIG_HITOM
	TRIGSETVOL	MPX_HTOM, vol_base_htom, vol_acc_htom, midi_htom
	return

; rim shot trigger on
tr_rs:
	bsf		TRIGREG_RIMSHOT, TRIG_RIMSHOT
	TRIGSETVOL	MPX_RSHOT, vol_base_rshot, vol_acc_rshot, midi_rshot
	return

; hand clap trigger on
tr_hc:
	bsf		TRIGREG_HANDCLAP, TRIG_HANDCLAP
	TRIGSETVOL	MPX_HCLAP, vol_base_hclap, vol_acc_hclap, midi_hclap
	return

; closed hihat trigger on
tr_chh:
	; TODO: proper HIHAT ACCENT
	bsf		TRIGREG_HIHAT, TRIG_HIHAT
	; select closed hihat
	bsf		TRIGREG_HIHATSEL, TRIG_HIHATSEL
	TRIGSETVOL	MPX_HIHAT, vol_base_chihat, vol_acc_chihat, midi_chihat
	return

; open hihat trigger on
tr_ohh:
	; TODO: proper HIHAT ACCENT
	bsf		TRIGREG_HIHAT, TRIG_HIHAT
	; select open hihat
	bcf		TRIGREG_HIHATSEL, TRIG_HIHATSEL
	TRIGSETVOL	MPX_HIHAT, vol_base_ohihat, vol_acc_ohihat, midi_ohihat
	return

; crash trigger on
tr_cc:
	bsf		TRIGREG_CRASH, TRIG_CRASH
	TRIGSETVOL	MPX_CRASH, vol_base_crash, vol_acc_crash, midi_crash
	return

; ride trigger on
tr_rc:
	bsf		TRIGREG_RIDE, TRIG_RIDE
	TRIGSETVOL	MPX_RIDE, vol_base_ride, vol_acc_ride, midi_ride
	return

; delays W * 0.2us + 0.7us
tr_delay:
	clrwdt				; 0.1us
	decfsz	WREG		; 0.1us / 0.3us
	bra 	tr_delay	; 0.2us
	return				; 0.2us

External Labels :

tr_set_trigger_latches
tr_delay