; ; mode_pattwrite.inc: handles the pattern write mode ; ; 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). ; ; called when pattern write mode is entered mode_pattwrite_enter: ; not needed as player.inc ignores these if ; we're in pattern write mode ; no pattern advance in write mode! ;movff currentbank, nextbank ;movff currentpattern, nextpattern ; no chain mode in write mode! ;CLEARMODE MODE_CHAIN SETDISPLAY s_pw_main ; see lcd.inc return ; called in continuous loop when in pattern write mode mode_pattwrite: ; refresh lcd display if needed call lcd_refresh ; do we have key events ? IFNOEVENT EVENT_KEY, pw_no_keyevents ; starts the sequencer KEYEVENT KEY_START, pw_start ; stops or continues the sequencer KEYEVENT KEY_STOPCONT, pw_stopcont ; select fill pattern or accent as instrument KEYEVENT KEY_ENTER, pw_enter ; changes scale KEYEVENT KEY_SCALE, pw_scale ; step keys enter the notes in write mode ; and change the pattern if not ; KEYEVENT KEY_S1, pw_stepkey ; bd / "enter name" ; KEYEVENT KEY_S2, pw_stepkey ; sd / "copy patt" ; KEYEVENT KEY_S3, pw_stepkey ; lt / "paste patt" ; KEYEVENT KEY_S4, pw_stepkey ; mt / "rol pattern" ; KEYEVENT KEY_S5, pw_stepkey ; ht / "ror pattern" ; KEYEVENT KEY_S6, pw_stepkey ; rs ; KEYEVENT KEY_S7, pw_stepkey ; hc / "dump pattern" ; KEYEVENT KEY_S8, pw_stepkey ; chh ; KEYEVENT KEY_S9, pw_stepkey ; ohh / "copy instr" ; KEYEVENT KEY_S10, pw_stepkey ; cc / "paste instr" ; KEYEVENT KEY_S11, pw_stepkey ; rc / "rol instr" ; KEYEVENT KEY_S12, pw_stepkey ; "ror instr" ; KEYEVENT KEY_S13, pw_stepkey ; "randomize instr" ; KEYEVENT KEY_S14, pw_stepkey ; ; KEYEVENT KEY_S15, pw_stepkey ; "dump all" ; KEYEVENT KEY_S16, pw_stepkey ; "settings" STEPKEYEVENT pw_stepkey KEYEVENT KEY_PATTPLAYWRITE, pw_pattplaywrite KEYEVENT KEY_TRACKPLAYWRITE, pw_trackplaywrite ; bank a key toggles the flam write mode KEYEVENT KEY_BANKA, pw_flamwritemode ; bank d key acts as a tap write KEYEVENT KEY_BANKD, pw_tapwrite pw_no_keyevents: ; no specific keyevents, check for downkeys IFKEYDOWN DOWNKEY_INSTRSEL, pw_instrseldown IFKEYDOWN DOWNKEY_CLEAR, pw_cleardown IFKEYDOWN DOWNKEY_LASTSTEP, pw_laststepdown IFKEYDOWN DOWNKEY_SHUFFLEFLAM, pw_shuffleflamdown pw_no_downkeys: ; no keyevents and no downkeys, all keys up ; set default display SETDISPLAY s_pw_main call pw_refreshleds call lcd_refreshbpm return ; all keyhandlers should call this afterwards pw_keydone: call pw_refreshleds pw_keydone_keepleds: CLEAREVENT EVENT_KEY return ; downkeyhandlers should call this afterwards pw_downkeydone: call pw_refreshleds pw_downkeydone_keepleds: return ; sets the leds according to the selected instrument ; and xors the current step to the step leds if ; we're in the running mode pw_refreshleds: LOADFSR1_CURRENTTRIGGERROW IFNOTINMODE MODE_FLAMWRITE, pw_refreshleds_noflam ; in flam write mode, show flams movlw PAT_FLAMS - PAT_TRIGS addwf FSR1L movff POSTINC1, leds_temp_1 ; steps 1 - 8 movff INDF1, leds_temp_2 ; steps 9 - 16 bra pw_refreshleds_skipaccents pw_refreshleds_noflam: movff POSTINC1, leds_temp_1 ; steps 1 - 8 movff INDF1, leds_temp_2 ; steps 9 - 16 pw_refreshleds_accents: ; blink accents ? ; note: if total accent is selected this is skipped movlw INSTR_ACCENT cpfslt selectedinst bra pw_refreshleds_skipaccents ; not total accent, instrument can be ; invidually accented - do blinks tstfsz blink bra pw_refreshleds_skipaccents movlw PAT_ACCENTS - PAT_TRIGS - 1 ; skip to pattern instr specific accents addwf FSR1L comf POSTINC1, W andwf leds_temp_1 comf INDF1, W andwf leds_temp_2 decf FSR1L pw_refreshleds_skipaccents: IFRUNNING pw_refreshleds_running pw_refreshleds_skip: ; write leds movff leds_temp_1, leds_busa_1 movff leds_temp_2, leds_busa_2 return pw_refreshleds_running: ; we are running, xor currentstep movf currentstep, W ; if currentstep is 0 bz pw_refreshleds_skip ; skip the xor movlw -9 addwf currentstep, W ; W = currentstep - 9 bn pw_lower_ledbus ; over 8, upper ledbus, W ok (0 - 7) call get_bit movwf temp movlw INSTR_ACCENT cpfslt selectedinst bra pw_upper_accoff ; always toggle if total accent selected ; or flam write mode active IFMODE MODE_FLAMWRITE, pw_upper_accoff ; not total accent or flam write mode incf FSR1L ; test accent movf temp, W andwf INDF1, W bz pw_upper_accoff ; accent is on => led always off comf temp, W andwf leds_temp_2 bra pw_refreshleds_instrs pw_upper_accoff: ; toggle bit movf temp, W xorwf leds_temp_2 ; triggers XOR currentstep bra pw_refreshleds_instrs pw_lower_ledbus: addlw 8 ; W = currentstep - 1 call get_bit movwf temp movlw INSTR_ACCENT cpfslt selectedinst bra pw_lower_accoff ; always toggle if total accent selected ; or flam write mode active IFMODE MODE_FLAMWRITE, pw_lower_accoff movf temp, W andwf INDF1, W bz pw_lower_accoff ; accent is on => led always off comf temp, W andwf leds_temp_1 bra pw_refreshleds_instrs pw_lower_accoff: ; toggle bit movf temp, W xorwf leds_temp_1 pw_refreshleds_instrs: ; show instrument specific length ; with blinking led if currentstep != currentstep_<instr> tstfsz blink bra pw_refreshleds_skip movf selectedinst, W INSTRCURRENTSTEPTOW 1 ; loads current step to W using FSR1 bz pw_refreshleds_skip ; skip if step == 0 cpfseq currentstep bra pw_i_ok bra pw_refreshleds_skip ; do not blink if currentstep pointers overlap pw_i_ok: movwf temp movlw -9 addwf temp, W ; W = step - 9 bn pw_i_lower_ledbus ; over 8, manipulate leds_busa_2, W = ok call get_bit xorwf leds_temp_2 ; xor to upper half bra pw_refreshleds_skip pw_i_lower_ledbus: ; below 9, manipulate leds_busa_1 addlw 8 ; W = step - 1 call get_bit xorwf leds_temp_1 ; xor to lower half bra pw_refreshleds_skip ;; shifted keys handled here ;pw_shiftdown: ; ; TODO ; bra pw_downkeydone ; instrument select pressed pw_instrseldown: ; instrsel + laststep selects instrument ; specific last step IFKEYDOWN DOWNKEY_LASTSTEP, pw_laststepdown_instr SETDISPLAY s_pw_instrsel call lcd_refreshbpm bra pw_downkeydone ; clear pressed pw_cleardown: ; clear current step from selected ; instrument if running IFNOTRUNNING pw_cleardown_notrunning ; set pattern as dirty SETEVENT EVENT_DIRTY LOADFSR1_CURRENTTRIGGERROW ; load current memory row to FSR1 movlw 9 cpfslt currentstep incf FSR1L ; advance a byte for step keys 9 - 16 call get_currentbit ; W = pattern memory bit for ; current step comf WREG ; complement bit andwf INDF1 ; retain all other bits except ; the one cleared movwf temp movlw INSTR_ACCENT cpfslt selectedinst bra pw_cleardown_notrunning ; if selectedinst != accent clear accents too ; clear accent movlw (PAT_ACCENTS - PAT_TRIGS) addwf FSR1L movf temp, W andwf INDF1 ; clear flam notes movlw (PAT_FLAMS - PAT_ACCENTS) addwf FSR1L movf temp, W andwf INDF1 pw_cleardown_notrunning: SETDISPLAY s_pw_clear call lcd_refreshbpm bra pw_downkeydone ; last step pressed pw_laststepdown: ; instrsel + laststep selects instrument ; specific last step IFKEYDOWN DOWNKEY_INSTRSEL, pw_laststepdown_instr SETDISPLAY s_pw_laststep call lcd_refreshbpm bra pw_downkeydone pw_laststepdown_instr: SETDISPLAY s_pw_laststepinstr bra pw_downkeydone ; shuffle/flam pressed pw_shuffleflamdown: SETDISPLAY s_pw_shuffleflam call pw_showshuffleflam bra pw_downkeydone_keepleds ; set led display to show shuffle / flam values pw_showshuffleflam: SHUFFLETOW 1 call get_bit movwf leds_busa_1 FLAMTOW 1 call get_bit movwf leds_busa_2 return ; toggle flam write mode pw_flamwritemode: TOGGLEMODE MODE_FLAMWRITE ; if flam write mode is set, ensure that ; total accent is not selected IFNOTINMODE MODE_FLAMWRITE, pw_flamwritemode_set movlw INSTR_ACCENT subwf selectedinst, W bnz pw_flamwritemode_set ; select bass drum movlw INSTR_BASSDRUM movwf selectedinst pw_flamwritemode_set: FORCEDISPLAYREFRESH bra pw_keydone ; starts the sequencer pw_start: call player_start bra pw_keydone ; stops or continues the sequencer pw_stopcont: IFRUNNING pw_stopcont_running ; sequencer is not running, we should continue call player_continue bra pw_keydone pw_stopcont_running: ; sequencer is running, clear the running mode call player_stop IFEVENTCALL EVENT_DIRTY, pw_write_flash ; write current if needed ; bcf mode, MODE_RUN bra pw_keydone ; selects the accent as current instrument if appropriate pw_enter: IFKEYDOWN DOWNKEY_INSTRSEL, pw_selectinstrument IFKEYDOWN DOWNKEY_CLEAR, pw_clear_accent ; toggle fill mode if no downkeys btg mode, MODE_FILL FORCEDISPLAYREFRESH bra pw_keydone ; clears accents if appropriate pw_clear_accent: movlw INSTR_ACCENT bra pw_clear ; toggles the steps according to a pressed ; step key and selected instrument pw_stepkey: ; instrsel + laststep pressed, set instr. specific last step IFKEYSDOWN DOWNKEY_INSTRSEL, DOWNKEY_LASTSTEP, pw_laststep_instr ; instrsel pressed, change instrument IFKEYDOWN DOWNKEY_INSTRSEL, pw_selectinstrument ; laststep pressed, select pattern length IFKEYDOWN DOWNKEY_LASTSTEP, pw_laststep ; shuffle/flam pressed, select appropriate values IFKEYDOWN DOWNKEY_SHUFFLEFLAM, pw_shuffleflam ; shift pressed, commands IFKEYDOWN DOWNKEY_SHIFTFUNC, pw_shiftcommand ; if running set the steps IFRUNNING pw_stepkey_skiprunning ; we are not running ; clear pressed, clear a row IFKEYDOWN DOWNKEY_CLEAR, pw_clearinstrument ; not running, nothing else pressed => set triggers pw_stepkey_skiprunning: ; set pattern as dirty SETEVENT EVENT_DIRTY LOADFSR1_CURRENTTRIGGERROW ; load current memory row to FSR1 movlw KEY_S9 cpfslt keypress incf FSR1L ; advance a byte for step keys 9 - 16 call get_stepbit ; W = pattern memory bit for ; current step key movwf temp ; temp = step bit pw_stepkey_tapwrite: ; pw_tapwrite calls this after FSR1 & temp set IFNOTINMODE MODE_FLAMWRITE, pw_stepkey_wr_notflam ; flam write, adjust fsr1 movlw PAT_FLAMS - PAT_TRIGS addwf FSR1L pw_stepkey_wr_notflam: movlw INSTR_ACCENT cpfslt selectedinst bra pw_stepkey_accentselected ; selectedinst < accent, handle normally movf temp, W andwf INDF1, W bz pw_stepkey_wasnoton ; if in flam write mode do not handle accents IFMODE MODE_FLAMWRITE, pw_stepkey_flamon ; bit was already on ; if step is on => set accent ; if step + accent is on => clear both movlw PAT_ACCENTS - PAT_TRIGS addwf FSR1L ; move FSR1 to accents movf temp, W andwf INDF1, W bz pw_stepkey_accentoff ; is accent on ? ; step + accent is on, clear both comf temp, W andwf INDF1 ; clears accent movlw -(PAT_ACCENTS - PAT_TRIGS) addwf FSR1L ; move back to steps pw_stepkey_flamon: comf temp, W andwf INDF1 ; clears step bra pw_keydone pw_stepkey_accentoff: ; step is on but accent off, set accent movf temp, W iorwf INDF1 bra pw_keydone pw_stepkey_wasnoton: ; no step and no accent => set step on movf temp, W iorwf INDF1 bra pw_keydone pw_stepkey_accentselected: ; selectedinst == accent, skip instr specific accent handling IFMODE MODE_FLAMWRITE, pw_keydone ; if in flam write mode, skip accent movf temp, W xorwf INDF1 bra pw_keydone ; changes the current instrument pw_selectinstrument: movlw KEY_ENTER cpfseq keypress bra pw_selectinstrument_notenter ; enter pressed, select accent ? IFMODE MODE_FLAMWRITE, pw_keydone movlw INSTR_ACCENT bra pw_selectinstrument_done pw_selectinstrument_notenter: movlw KEY_S12 cpfslt keypress bra pw_keydone ; only keys < s12 accepted decf keypress, W bn pw_selectinstrument_skip pw_selectinstrument_done: movwf selectedinst FORCEDISPLAYREFRESH pw_selectinstrument_skip: bra pw_keydone ; clears an invidual instrument pw_clearinstrument: movlw KEY_ENTER cpfseq keypress bra pw_clearinstrument_notenter ; enter pressed, clear accent ? IFMODE MODE_FLAMWRITE, pw_keydone movlw INSTR_ACCENT bra pw_clear pw_clearinstrument_notenter: movlw KEY_S12 cpfslt keypress ; only keys < s12 accepted bra pw_keydone decf keypress, W bn pw_clearinstrument_done ; now step key 1 == 0, accent 11 pw_clear: IFNOTINMODE MODE_FILL, pw_clear_p lfsr FSR1, fillpattern + PAT_TRIGS bra pw_clear_fp pw_clear_p: lfsr FSR1, pattern + PAT_TRIGS pw_clear_fp: ; store cleared instrument index ; for lcd display routine movwf display_arg addwf WREG ; 2 bytes / instrument addwf FSR1L ; advance to correct trigger ; row clrf POSTINC1 ; and .. clear clrf INDF1 ; set pattern as dirty SETEVENT EVENT_DIRTY ; should we clear accents too ? movlw INSTR_ACCENT cpfslt selectedinst bra pw_clearinstrument_acc ; skip if selectedinst == accent movlw (PAT_ACCENTS - PAT_TRIGS - 1) addwf FSR1L clrf POSTINC1 ; clear accents too clrf INDF1 ; clear flams too movlw (PAT_FLAMS - PAT_ACCENTS - 1) addwf FSR1L clrf POSTINC1 clrf INDF1 pw_clearinstrument_acc: SETDISPLAY s_pw_cleardone pw_clearinstrument_done: bra pw_keydone ; sets the pattern length pw_laststep: movf keypress, W movwf currentlength WTOLENGTH temp, 1 ; set pattern as dirty SETEVENT EVENT_DIRTY FORCEDISPLAYREFRESH bra pw_keydone ; sets the instrument specific last step pw_laststep_instr: decf keypress, W movwf temp IFMODE MODE_FILL, pw_laststep_instr_fill lfsr FSR1, pattern + PAT_LENGTHS bra pw_laststep_instr_pselected pw_laststep_instr_fill: lfsr FSR1, fillpattern + PAT_LENGTHS pw_laststep_instr_pselected: btfss selectedinst, 0 bra pw_laststep_instr_even ; odd instrument => store to lsb nybble bcf STATUS, C rrcf selectedinst, W ; instrument / 2 addwf FSR1L ; select correct patt reg movlw 0xf0 andwf INDF1, W ; XXXX0000 iorwf temp, W ; XXXXLLLL movwf INDF1 ; store bra pw_laststep_instr_done pw_laststep_instr_even: ; even instrument => store to msb nybble bcf STATUS, C rrcf selectedinst, W ; instrument / 2 addwf FSR1L ; select correct patt reg swapf temp ; LLLL0000 movlw 0x0f andwf INDF1, W ; 0000XXXX iorwf temp, W ; LLLLXXXX movwf INDF1 ; store pw_laststep_instr_done: ; set pattern as dirty SETEVENT EVENT_DIRTY FORCEDISPLAYREFRESH bra pw_keydone ; sets the shuffle and flam values ; step keys 1 - 8 select shuffle ; step keys 9 - 13 select flam pw_shuffleflam: movlw KEY_S9 cpfslt keypress bra pw_shuffleflam_flam ; > key 8, flam? ; step key < 9, setting shuffle movf keypress, W bz pw_shuffleflam_done ; keypress = none, skip ; shuffle value in (0 ... 7) decf WREG movwf currentshuffle ; store shuffle value WTOSHUFFLE temp, 1 bra pw_shuffleflam_done pw_shuffleflam_flam: movlw KEY_S14 cpfslt keypress bra pw_shuffleflam_done ; > key 13, skip movlw KEY_S8 cpfsgt keypress bra pw_shuffleflam_done ; < key 9, skip movf keypress, W bz pw_shuffleflam_done ; keypress = none, skip ; flam values in (0, 1, 2, 3, 4) addlw -KEY_S9 ; store flam value WTOFLAM temp, 1 pw_shuffleflam_done: ; set pattern as dirty SETEVENT EVENT_DIRTY FORCEDISPLAYREFRESH bra pw_keydone_keepleds ; changes and shows scale pw_scale: SETDISPLAY s_pw_scale FORCEDISPLAYREFRESH SCALETOW 1 movwf temp movlw SCALE_16TR cpfseq temp bra pw_scale_inc ; reloop scale to 0 movlw SCALE_16 bra pw_scale_store pw_scale_inc: ; increment scale to next value incf temp, W pw_scale_store: WTOSCALE temp, 1 ; set pattern as dirty SETEVENT EVENT_DIRTY bra pw_keydone ; switches between pattern play and -write modes pw_pattplaywrite: IFEVENTCALL EVENT_DIRTY, pw_write_flash ; write current if needed SETMODE MODE_PPLAY CLEARMODE MODE_PWRITE CLEARMODE MODE_FLAMWRITE call mode_pattplay_enter bra pw_keydone_keepleds ; switches to track play mode pw_trackplaywrite: IFEVENTCALL EVENT_DIRTY, pw_write_flash ; write current if needed SETMODE MODE_TPLAY CLEARMODE MODE_PWRITE CLEARMODE MODE_FLAMWRITE call mode_trackplay_enter bra pw_keydone_keepleds ; writes the currentbank/currentpattern pattern to the ; flash memory pw_write_flash: call i2c_flash_save CLEAREVENT EVENT_DIRTY return ; enters a trigger (or accent) to the current step pw_tapwrite: ; tap only when running IFNOTRUNNING pw_keydone ; set pattern as dirty SETEVENT EVENT_DIRTY movf selectedinst, W INSTRCURRENTSTEPTOW 1 ; calculate tap pos from instrument pos incf WREG ; tap sets on the _next_ step movwf temp ; 2 - 17 (!) movf selectedinst, W INSTRLENGTHTOW 1, temp2 ; 1 - 16 cpfsgt temp bra pw_tapwrite_noroll ; currentstep + 1 > instr len => roll to first step movlw 1 movwf temp pw_tapwrite_noroll: LOADFSR1_CURRENTTRIGGERROW ; load current memory row to FSR1 movlw 8 cpfsgt temp bra pw_tapwrite_lower incf FSR1L subwf temp, F pw_tapwrite_lower: decf temp, W call get_bit movwf temp ; temp = step bit bra pw_stepkey_tapwrite ; FSR1 = step byte, do the write ; -- Commands --> ; handles shifted edit commands ; ; s1 == enter name ; s2 == copy pattern ; s3 == paste pattern ; s4 == rol pattern ; s5 == ror pattern ; ... ; s7 == dump pattern ; ... ; s9 == copy instrument ; s10 == paste instrument ; s11 == rol instrument ; s12 == ror instrument ; s13 == random instrument ; ... ; s15 == dump all ; s16 == settings pw_shiftcommand: ; decode command KEYEVENT KEY_S1, pw_cmd_entername KEYEVENT KEY_S2, pw_cmd_copy_patt KEYEVENT KEY_S3, pw_cmd_paste_patt KEYEVENT KEY_S4, pw_cmd_rol_patt KEYEVENT KEY_S5, pw_cmd_ror_patt KEYEVENT KEY_S7, pw_cmd_dump_patt KEYEVENT KEY_S9, pw_cmd_copy_instr KEYEVENT KEY_S10, pw_cmd_paste_instr KEYEVENT KEY_S11, pw_cmd_rol_instr KEYEVENT KEY_S12, pw_cmd_ror_instr KEYEVENT KEY_S13, pw_cmd_random_instr KEYEVENT KEY_S15, pw_cmd_dump_all KEYEVENT KEY_S16, pw_cmd_settings bra pw_keydone ; enters the naming mode - step keys are used in the ; same way as the sms writing in cell phones ie. ; step key 1 == abc ; step key 2 == def ; ... ; step key 9 == number ; step key 14 == delete char ; step key 15 == previous char ; step key 16 == next char ; enter == done pw_cmd_entername: SETDISPLAY s_pw_entername ; text destination lfsr FSR1, pat_name ; FSR1 == pattern name (0x0100!) ; read keyboard call keyboard ; enter pressed SETEVENT EVENT_DIRTY IFRUNNING pw_cmd_entername_done_running ; if not running force flash write call pw_write_flash pw_cmd_entername_done_running: bra pw_keydone ; copies the current pattern (either non-fill OR fill pattern) ; to the copy buffer pw_cmd_copy_patt: call copy_patt_to_buf SETDISPLAY s_pw_pattbuffered FORCEDISPLAYREFRESH bra pw_keydone ; pastes the pattern from copy buffer to the current pattern pw_cmd_paste_patt: call copy_buf_to_patt SETEVENT EVENT_DIRTY SETDISPLAY s_pw_pattpasted FORCEDISPLAYREFRESH bra pw_keydone ; rotates the current pattern to the left pw_cmd_rol_patt: call rotate_pattern_left SETEVENT EVENT_DIRTY SETDISPLAY s_pw_pattrold FORCEDISPLAYREFRESH bra pw_keydone ; rotates the current pattern to the right pw_cmd_ror_patt: call rotate_pattern_right SETEVENT EVENT_DIRTY SETDISPLAY s_pw_pattrord FORCEDISPLAYREFRESH bra pw_keydone ; copies the current instrument (either from non-fill OR fill pattern) ; to the copy buffer pw_cmd_copy_instr: call copy_instr_to_buf SETDISPLAY s_pw_instrbuffered FORCEDISPLAYREFRESH bra pw_keydone ; pastes the instrument from copy buffer to the current instrument pw_cmd_paste_instr: call copy_buf_to_instr SETEVENT EVENT_DIRTY SETDISPLAY s_pw_instrpasted FORCEDISPLAYREFRESH bra pw_keydone ; rotates the current instrument to the left pw_cmd_rol_instr: call rotate_instr_trigs_left SETEVENT EVENT_DIRTY SETDISPLAY s_pw_instrrold FORCEDISPLAYREFRESH bra pw_keydone ; rotates the current instrument to the right pw_cmd_ror_instr: call rotate_instr_trigs_right SETEVENT EVENT_DIRTY SETDISPLAY s_pw_instrrord FORCEDISPLAYREFRESH bra pw_keydone ; randomizes the current instrument pw_cmd_random_instr: call randomize_instr SETEVENT EVENT_DIRTY SETDISPLAY s_pw_instrrandomized FORCEDISPLAYREFRESH bra pw_keydone ; dumps the whole sequencer memory to midi sysex pw_cmd_dump_all: ; clear the running mode call player_stop IFEVENTCALL EVENT_DIRTY, pw_write_flash ; write current if needed ; set lcd display call px_lcd_smemdump call midi_out_dump_all SETDISPLAY s_memdump FORCEDISPLAYREFRESH bra pw_keydone ; dumps the current pattern to midi sysex pw_cmd_dump_patt: ; clear the running mode call player_stop IFEVENTCALL EVENT_DIRTY, pw_write_flash ; write current if needed ; set lcd display call px_lcd_spattdump call midi_out_dump_patt SETDISPLAY s_pattdump FORCEDISPLAYREFRESH bra pw_keydone ; stops sequencer, goes to settings mode pw_cmd_settings: call player_stop SETSETTINGSMODE ; CLEARMODE MODE_PWRITE ; not necessary as settings mode == clrf mode call mode_settings_enter bra pw_keydone
lcd_refresh pw_refreshleds lcd_refreshbpm get_bit get_currentbit pw_showshuffleflam player_start player_continue player_stop get_stepbit mode_pattplay_enter mode_trackplay_enter i2c_flash_save keyboard pw_write_flash copy_patt_to_buf copy_buf_to_patt rotate_pattern_left rotate_pattern_right copy_instr_to_buf copy_buf_to_instr rotate_instr_trigs_left rotate_instr_trigs_right randomize_instr px_lcd_smemdump midi_out_dump_all px_lcd_spattdump midi_out_dump_patt mode_settings_enter