; ; mode_traplay.inc: handles track play mode ; ; author: Marko Kanala, raato ]a t[ mulletronic.com ; ; Play mode: ; ; T01:my demo song ; 001/003:A02 x2 ; ; Edit mode: ; ; Edit T01 001/002 ; A02: pattern x2 ; ; ; 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). ; ; called when the track play mode is entered mode_trackplay_enter: SETDISPLAY s_tp_main ; see lcd.inc ; load first measure call i2c_flash_read_measure CLEARMODE MODE_FILL CLEARMODE MODE_CHAIN return ; called in continuous loop when in track play mode mode_trackplay: ; if the last step of the pattern has been ; reached read the next pattern from the ; flash memory if needed IFEVENTCALL EVENT_LASTSTEP, tp_handleflash ; refresh lcd display if needed call lcd_refresh ; do we have key events ? IFNOEVENT EVENT_KEY, tp_no_keyevents ; starts the sequencer KEYEVENT KEY_START, tp_start ; stops or continues the sequencer KEYEVENT KEY_STOPCONT, tp_stopcont ; trigger a fill KEYEVENT KEY_ENTER, tp_fill ; KEYEVENT KEY_S1, tp_stepkey ; KEYEVENT KEY_S2, tp_stepkey ; KEYEVENT KEY_S3, tp_stepkey ; KEYEVENT KEY_S4, tp_stepkey ; KEYEVENT KEY_S5, tp_stepkey ; KEYEVENT KEY_S6, tp_stepkey ; KEYEVENT KEY_S7, tp_stepkey ; KEYEVENT KEY_S8, tp_stepkey ; KEYEVENT KEY_S9, tp_stepkey ; KEYEVENT KEY_S10, tp_stepkey ; KEYEVENT KEY_S11, tp_stepkey ; KEYEVENT KEY_S12, tp_stepkey ; KEYEVENT KEY_S13, tp_stepkey ; KEYEVENT KEY_S14, tp_stepkey ; KEYEVENT KEY_S15, tp_stepkey ; KEYEVENT KEY_S16, tp_stepkey STEPKEYEVENT tp_stepkey KEYEVENT KEY_SCALE, tp_nextmeasure KEYEVENT KEY_PATTPLAYWRITE, tp_pattplaywrite KEYEVENT KEY_TRACKPLAYWRITE, tp_trackplaywrite tp_no_keyevents: ; no specific keyevents, check for downkeys ; hoax to generate a key events from downkeys IFKEYNOTDOWN DOWNKEY_LASTSTEP, tp_laststeplifted IFKEYDOWN DOWNKEY_LASTSTEP, tp_laststeppressed tp_laststepchecked: tp_no_downkeys: ; no keyevents and no downkeys, all keys up ; set default display SETDISPLAY s_tp_main call tp_refreshleds ; call lcd_refreshbpm return ; all keyhandlers should call this afterwards tp_keydone: call tp_refreshleds tp_keydone_keepleds: CLEAREVENT EVENT_KEY return ; called when laststep downkey is pressed tp_laststeppressed: ; call tp_prevmeasure only, if the laststep downkey ; was lifted before btfsc downkeypresses, DOWNKEY_LASTSTEP bra tp_laststepchecked bsf downkeypresses, DOWNKEY_LASTSTEP bra tp_prevmeasure ; called when laststep downkey is not pressed tp_laststeplifted: bcf downkeypresses, DOWNKEY_LASTSTEP bra tp_laststepchecked ; lights up the led for selected track tp_refreshleds: movlw 1<<LED_START ; preserve start-led andwf LEDREG_START ; and clear bus b clrf leds_busb_2 movlw 8 cpfslt currenttrack bra tp_refreshleds_upper movf currenttrack, W call get_bit movwf leds_temp_1 clrf leds_temp_2 IFRUNNING tp_refreshleds_running bra tp_refreshleds_write tp_refreshleds_upper: subwf currenttrack, W call get_bit clrf leds_temp_1 movwf leds_temp_2 IFRUNNING tp_refreshleds_running bra tp_refreshleds_write tp_refreshleds_running: movf currentstep, W ; if currentstep is 0 bz tp_refreshleds_write ; skip the xor movlw -9 addwf currentstep, W ; W = currentstep - 9 bn tp_r_lower_ledbus ; over 8, upper ledbus, W ok (0 - 7) call get_bit xorwf leds_temp_2 ; leds XOR currentstep bra tp_refreshleds_write tp_r_lower_ledbus: addlw 8 ; W = currentstep - 1 call get_bit xorwf leds_temp_1 tp_refreshleds_write: movff leds_temp_1, leds_busa_1 movff leds_temp_2, leds_busa_2 return ; switches between track play and -write modes tp_trackplaywrite: SETMODE MODE_TWRITE CLEARMODE MODE_TPLAY call mode_trackwrite_enter bra tp_keydone_keepleds ; switches between pattern play and -write modes tp_pattplaywrite: SETMODE MODE_PPLAY CLEARMODE MODE_TPLAY call mode_pattplay_enter bra tp_keydone_keepleds ; changes the current track tp_stepkey: IFRUNNING tp_keydone ; only allow the change when stopped movlw 16 movwf temp decf keypress, W bn tp_keydone ; accept only keys 0 ... cpfsgt temp bra tp_keydone ; to 15 FORCEDISPLAYREFRESH movwf currenttrack CLRF16 currentmeasure CLRF16 nextmeasure clrf currentrepeat ; fetch track name and length call i2c_flash_read_trackmeta ; fetch first measure call i2c_flash_read_measure bra tp_keydone ; moves to prev measure if stopped tp_prevmeasure: IFRUNNING tp_keydone ; check if we can go back one step tstfsz nextmeasure ; xx__ == 0 bra tp_prevmeasure_dec tstfsz nextmeasure + 1 ; __xx == 0 bra tp_prevmeasure_dec ; position == 0, rollover to the last position movff currenttracklen, nextmeasure movff currenttracklen + 1, nextmeasure + 1 tp_prevmeasure_dec: DECF16 nextmeasure ; note: this discards current edit which is fine call i2c_flash_read_measure movff nextmeasure, currentmeasure movff nextmeasure + 1, currentmeasure + 1 FORCEDISPLAYREFRESH bra tp_keydone ; moves to next measure if stopped tp_nextmeasure: IFRUNNING tp_keydone INCF16 nextmeasure ; if currentmeasure == currenttracklen ; rollover to position 1 movf nextmeasure, W cpfseq currenttracklen bra tw_nextmeasure_ok movf nextmeasure + 1, W cpfseq currenttracklen + 1 bra tp_nextmeasure_ok clrf nextmeasure clrf nextmeasure + 1 tp_nextmeasure_ok: call i2c_flash_read_measure ; update currentmeasure movff nextmeasure, currentmeasure movff nextmeasure + 1, currentmeasure + 1 FORCEDISPLAYREFRESH bra tp_keydone ; starts the sequencer tp_start: movf currentmeasuredata, W DECODE_BANK_FROM_MEASURE movwf currentbank movf currentmeasuredata, W DECODE_PATTERN_FROM_MEASURE movwf currentpattern movff currentpattern, nextpattern movff currentbank, nextbank ; load first pattern from flash call i2c_flash_read ; reset repeat counter clrf repeatcounter ; and start call player_start bra tp_keydone ; stops / continues tp_stopcont: FORCEDISPLAYREFRESH IFRUNNING pp_stopcont_running ; sequencer is not running, we should continue call player_continue bra tp_keydone tp_stopcont_running: ; sequencer is running, stop the player call player_stop bra tp_keydone ; changes the fill pattern as a active pattern tp_fill: SETMODE MODE_FILL FORCEDISPLAYREFRESH bra tp_keydone ; called always when last step of the pattern has been ; triggered ; If incremented nextmeasure points to a different pattern than ; the current the pattern is loaded to the current tp_handleflash: CLEAREVENT EVENT_LASTSTEP ; check if repeats are played movf currentmeasuredata, W DECODE_REPEAT_FROM_MEASURE ; W = repeat cpfseq repeatcounter ; repeat counter != current repeat ; ; advance only if all repeats are played ; otherwise just return return INCF16 nextmeasure ; if currentmeasure == currenttracklen ; rollover to position 1 movf nextmeasure, W cpfseq currenttracklen bra tp_handleflash_nm_ok movf nextmeasure + 1, W cpfseq currenttracklen + 1 bra tp_handleflash_nm_ok clrf nextmeasure clrf nextmeasure + 1 tp_handleflash_nm_ok: lfsr FSR1, nextmeasuredata ; read measure from "nextmeasure" call i2c_flash_read_measure_fsr1 movf INDF1, W ; nextmeasuredata cpfseq currentmeasuredata ; do we need a new pattern ? bra tp_handleflash_loadpat return tp_handleflash_loadpat: ; pattern is changed in next measure, ; decode nextmeasuredata to nextbank/nextpattern ; and load movf INDF1, W DECODE_BANK_FROM_MEASURE movwf nextbank movf INDF1, W DECODE_PATTERN_FROM_MEASURE movwf nextpattern call i2c_flash_read return
i2c_flash_read_measure lcd_refresh tp_refreshleds get_bit mode_trackwrite_enter mode_pattplay_enter i2c_flash_read_trackmeta i2c_flash_read player_start player_continue player_stop i2c_flash_read_measure_fsr1