;
; keysleds.inc: key and led handling
;
; Lights up the leds in ledbus according to
; the bits in memory location leds_busa_1,
; leds_busa_2 and leds_busb_1. Additionally
; reads the pressed key from keybus. The pressed
; key is stored in memory location last_key as
; a key code defined in constants.h.
;
; author: Marko Kanala, raato ]a t[ mulletronic.com
;
; 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).
;
do_keysleds:
; call pattern display 12 times / column to light up the
; pattern display leds
; note: pattern display column mux
; is tied to same port as key/led mux
decf led_scaler
bn change_led_column
bra do_patterndisplay
change_led_column:
btfss PORT_KEYBUS, KEYBUS_A_PIN
bra check_key_b
; decode keybus a
movlw KEY_S1 ; bus a starts from step key 1
addwf led_counter, W
; store pressed key in bus a
movwf irq_key
check_key_b:
btfss PORT_KEYBUS, KEYBUS_B_PIN
bra keys_checked
; key in keybus b was pressed
; decode keybus b
movlw KEY_BANKA ; bus b starts from bank a key
addwf led_counter, W
movwf lp_irq_temp ; store to temp
; check specially for keys that can be held down
movlw KEY_SHIFTFUNC
cpfseq lp_irq_temp ; is the bus b key shift ?
bra not_shift
bsf irq_downkey, DOWNKEY_SHIFTFUNC
bra keys_checked
not_shift:
movlw KEY_CLEAR ; clear ?
cpfseq lp_irq_temp
bra not_clear
bsf irq_downkey, DOWNKEY_CLEAR
bra keys_checked
not_clear:
movlw KEY_LASTSTEP ; laststep?
cpfseq lp_irq_temp
bra not_laststep
bsf irq_downkey, DOWNKEY_LASTSTEP
bra keys_checked
not_laststep:
movlw KEY_INSTRSEL ; instrsel ?
cpfseq lp_irq_temp
bra not_instrsel
bsf irq_downkey, DOWNKEY_INSTRSEL
bra keys_checked
not_instrsel:
movlw KEY_SHUFFLEFLAM ; shuffleflam ?
cpfseq lp_irq_temp
bra not_downkey
bsf irq_downkey, DOWNKEY_SHUFFLEFLAM
bra keys_checked
; note: downkeys do NOT generate key events
; and must be checked separately if so
; desired
not_downkey:
; store pressed key in bus b
movff lp_irq_temp, irq_key
keys_checked:
; if we're in the last key of the bus process the keypress(es)
movlw 15
cpfseq led_counter
bra keys_done
; compare the current key with last key
movlw KEY_NONE ; key pressed ?
xorwf irq_key, W
btfsc STATUS, Z
bra irq_no_key ; nope
movf irq_key, W ; new key pressed ?
xorwf last_key, W
btfsc STATUS, Z
bra lk_no_new_key ; nope
; current key differs
movf irq_key, W
movwf last_key
movwf keypress
; generate key event
bsf event, EVENT_KEY
bra irq_keycheckdone
irq_no_key:
clrf last_key ; no key was pressed
clrf keypress
bra irq_keycheckdone
lk_no_new_key:
clrf irq_key ; no NEW key was pressed
irq_keycheckdone:
; get the pressed downkeys
movff irq_downkey, downkeys
; clear downkey temp for next round
clrf irq_downkey
keys_done:
; increment led counter and rollover at 16
incf led_counter
movlw 16
cpfslt led_counter
; last led / key
clrf led_counter
; reset pattern display scaler counter
movlw 11
movwf led_scaler
; bsf port_ledbus, pat_disp_lit_pin ; clear lit pd
movlw -8
addwf led_counter, W ; W = led_counter - 8
bn first_half
; second half of the leds
lfsr FSR0, leds_busa_2
bra go_leds
first_half:
; check for lit leds in first half
lfsr FSR0, leds_busa_1
movf led_counter, W ; W = led_counter
go_leds:
call get_bit
movwf led_counter_tmp ; store "bit-byte"
; switch off bus a led
bsf PORT_LEDBUS, LEDBUS_A_PIN
; W = bit, note that we advance to bus b with post-increment
andwf POSTINC0, W
bz bus_a_not_lit
; led lit in bus a
bcf PORT_LEDBUS, LEDBUS_A_PIN
bus_a_not_lit:
movf led_counter_tmp, W
; switch off bus b led
bsf PORT_LEDBUS, LEDBUS_B_PIN
; W = bit
andwf INDF0, W
bz bus_b_not_lit
; led lit in bus b
bcf PORT_LEDBUS, LEDBUS_B_PIN
bus_b_not_lit:
; retain upper 4 bits of led mux (pattern display) and
; select the correct column from led 4067
swapf led_scaler, W
iorwf led_counter, W
movwf LAT_LEDMUX
; set pattern display immediately on column change
bra do_patterndisplay
External Labels :
get_bit