; ; lcd.inc: 16x2 led display handling routines ; ; displaytech 162 specified: ; "Clear" and "Return home" commands - 1.64ms ; Other commands ~50us ; Enable pulse atleast 220ns ; Enable cycle atleast 500ns ; ; 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). ; ; ; lcd screens s_none equ 0 ; empty lcd s_pw_main equ 1 ; pattern write / default s_pw_instrsel equ 2 ; - / instrument select pressed s_pw_laststep equ 3 ; - / last step pressed s_pw_clear equ 4 ; - / clear pressed s_pw_shuffleflam equ 5 ; - / shuffle/flam pressed s_pw_scale equ 6 ; - / scale pressed s_pw_laststepinstr equ 7 ; - / last step + instrsel pressed s_pw_cleardone equ 8 ; - / instrument cleared s_pw_pattbuffered equ 9 ; - / pattern copied to buffer s_pw_pattpasted equ 10 ; - / pattern copied from buffer s_pw_instrbuffered equ 11 ; - / instrument copied to buffer s_pw_instrpasted equ 12 ; - / instrument copied from buffer s_pw_instrrandomized equ 13 ; - / instrument randomized s_pw_instrrold equ 14 ; - / instrument rol:led s_pw_instrrord equ 15 ; - / instrument ror:red s_pw_pattrold equ 16 ; - / pattern rol:led s_pw_pattrord equ 17 ; - / pattern ror:red s_pw_entername equ 18 ; - / enter pattern name s_pp_main equ 20 ; pattern play / default s_pp_chaincleared equ 21 ; - / chain cleared s_pp_setchain equ 22 ; - / set chain s_pattdump equ 30 ; pattern dumped s_memdump equ 31 ; memory dumped s_tp_main equ 40 ; track play / default s_tw_main equ 50 ; track write / default s_tw_clearconfirm equ 51 ; - / confirm track clear s_tw_trackcleared equ 52 ; - / track cleared s_tw_measureinserted equ 53 ; - / measure inserted s_tw_entername equ 54 ; - / enter track name s_tw_measuredeleted equ 55 ; - / measure deleted s_s_main: equ 56 ; settings / default s_sysex equ 60 ; receiving sysex s_sysexdone equ 61 ; sysex done ; ; refreshes the lcd display according ; to the currentdisplay variable ; lcd_refresh: ; skip checks if display hasn't been changed DISPLAYNOTCHANGED lcd_refresh_nc ; handle different displays DISPLAY s_pw_main, pw_lcd_main DISPLAY s_pw_instrsel, pw_lcd_instrsel DISPLAY s_pw_laststep, pw_lcd_laststep DISPLAY s_pw_clear, pw_lcd_clear DISPLAY s_pw_shuffleflam, pw_lcd_shuffleflam DISPLAY s_pw_scale, pw_lcd_scale DISPLAY s_pw_laststepinstr, pw_lcd_laststepinstr DISPLAY s_pw_cleardone, pw_lcd_clear_done DISPLAY s_pp_main, pp_lcd_main DISPLAY s_pp_chaincleared, pp_lcd_chaincleared DISPLAY s_pp_setchain, pp_lcd_setchain DISPLAY s_pattdump, px_lcd_pattdump DISPLAY s_memdump, px_lcd_memdump DISPLAY s_pw_pattbuffered, pw_lcd_pattbuffered DISPLAY s_pw_pattpasted, pw_lcd_pattpasted DISPLAY s_pw_instrbuffered, pw_lcd_instrbuffered DISPLAY s_pw_instrpasted, pw_lcd_instrpasted DISPLAY s_pw_instrrandomized, pw_lcd_instrrandomized DISPLAY s_pw_instrrold, pw_lcd_instrrold DISPLAY s_pw_instrrord, pw_lcd_instrrord DISPLAY s_pw_pattrold, pw_lcd_pattrold DISPLAY s_pw_pattrord, pw_lcd_pattrord DISPLAY s_tp_main, tp_lcd_main DISPLAY s_tw_main, tw_lcd_main DISPLAY s_tw_clearconfirm, tw_lcd_clearconfirm DISPLAY s_tw_trackcleared, tw_lcd_trackcleared DISPLAY s_tw_measureinserted, tw_lcd_measureinserted DISPLAY s_pw_entername, pw_lcd_entername DISPLAY s_tw_entername, tw_lcd_entername DISPLAY s_tw_measuredeleted, tw_lcd_measuredeleted DISPLAY s_sysex, lcd_sysex DISPLAY s_sysexdone, lcd_sysexdone DISPLAY s_s_main, s_lcd_main lcd_refresh_nc: return ; pattern write / default display pw_lcd_main: ; A01:Pattern name movlw 0 call lcd_set_cursor movf currentbank, W addlw "A" ; "A" call lcd_send_char incf currentpattern, W call lcd_send_bcd ; "01" movlw ":" call lcd_send_char ; ":" lfsr FSR1, pat_name IFMODE MODE_FILL, pw_lcd_main_fill movlw 12 ; pad name to 12 chars ; "Pattern name" call lcd_send_text_fsr1 pw_lcd_main_cont: TABLE_ADDR text_patternwrite2 call lcd_send_text ; "W/" call lcd_send_instrument ; print instrument name IFMODE MODE_FLAMWRITE, pw_lcd_main_flam call lcd_send_bpm ; bpm DISPLAYREFRESHED return pw_lcd_main_fill: movlw 6 ; only 6 chars of name ; "Patter[Fill]" call lcd_send_text_fsr1 TABLE_ADDR text_fill call lcd_send_text ; "[Fill]" bra pw_lcd_main_cont pw_lcd_main_flam: ; "W/Bass dru[Flam]" TABLE_ADDR text_flam call lcd_send_text DISPLAYREFRESHED return ; pattern write / pattern copied to buffer pw_lcd_pattbuffered: btfsc mode, MODE_FILL bra pw_pattbuffered_fill TABLE_ADDR text_pattbuffered1 bra pw_pattbuffered_cont pw_pattbuffered_fill: TABLE_ADDR text_pattbuffered1fill pw_pattbuffered_cont: call lcd_send_text TABLE_ADDR text_pattbuffered2 call lcd_send_text DISPLAYREFRESHED DISPLAYDELAY time_lcd_medium return ; pattern write / pattern pasted from buffer pw_lcd_pattpasted: TABLE_ADDR text_pattpasted1 call lcd_send_text btfsc mode, MODE_FILL bra pw_pattpasted_fill TABLE_ADDR text_pattpasted2 bra pw_pattpasted_cont pw_pattpasted_fill: TABLE_ADDR text_pattpasted2fill pw_pattpasted_cont: call lcd_send_text DISPLAYREFRESHED DISPLAYDELAY time_lcd_medium return ; pattern write / instrument copied to buffer pw_lcd_instrbuffered: movlw LCD_LINE1 call lcd_set_cursor call lcd_send_instrument ; Instrument btfss mode, MODE_FILL bra pw_instrbuffered_nonfill TABLE_ADDR text_fill call lcd_send_text ; [Fill] bra pw_instrbuffered_line2 pw_instrbuffered_nonfill: movlw 4 ; pad with 4 blanks if not in fill mode call lcd_send_blanks pw_instrbuffered_line2: TABLE_ADDR text_instrbuffered2 call lcd_send_text DISPLAYREFRESHED DISPLAYDELAY time_lcd_medium return ; pattern write / instrument pasted from buffer pw_lcd_instrpasted: TABLE_ADDR text_instrpasted1 call lcd_send_text ; Buffer pasted to movlw LCD_LINE2 call lcd_set_cursor call lcd_send_instrument ; Bass drum btfss mode, MODE_FILL bra pw_instrpasted_nonfill TABLE_ADDR text_fill2 call lcd_send_text ; [Fill] bra pw_instrpasted_cont pw_instrpasted_nonfill: movlw 6 ; pad with 4 blanks if not in fill mode call lcd_send_blanks pw_instrpasted_cont: DISPLAYREFRESHED DISPLAYDELAY time_lcd_medium return ; pattern write / instrument randomized pw_lcd_instrrandomized: movlw LCD_LINE1 call lcd_set_cursor call lcd_send_instrument ; Instrument btfss mode, MODE_FILL bra pw_instrrandomized_nonfill TABLE_ADDR text_fill call lcd_send_text ; [Fill] pw_instrrandomized_nonfill: TABLE_ADDR text_instrrandomized2 call lcd_send_text DISPLAYREFRESHED DISPLAYDELAY time_lcd_medium return ; pattern write / instrument rotated left pw_lcd_instrrold: movlw LCD_LINE1 call lcd_set_cursor call lcd_send_instrument ; Instrument btfss mode, MODE_FILL bra pw_instrroldfill TABLE_ADDR text_fill call lcd_send_text ; [Fill] pw_instrroldfill: TABLE_ADDR text_instrrold2 call lcd_send_text DISPLAYREFRESHED DISPLAYDELAY time_lcd_medium return ; pattern write / instrument rotated right pw_lcd_instrrord: movlw LCD_LINE1 call lcd_set_cursor call lcd_send_instrument ; Instrument btfss mode, MODE_FILL bra pw_instrrordfill TABLE_ADDR text_fill call lcd_send_text ; [Fill] pw_instrrordfill: TABLE_ADDR text_instrrord2 call lcd_send_text DISPLAYREFRESHED DISPLAYDELAY time_lcd_medium return ; pattern write / pattern rotated left pw_lcd_pattrold: btfsc mode, MODE_FILL bra pw_pattrold_fill TABLE_ADDR text_pattrold1 bra pw_pattrold_cont pw_pattrold_fill: TABLE_ADDR text_pattrold1fill pw_pattrold_cont: call lcd_send_text TABLE_ADDR text_pattrold2 call lcd_send_text DISPLAYREFRESHED DISPLAYDELAY time_lcd_medium return ; pattern write / pattern rotated right pw_lcd_pattrord: btfsc mode, MODE_FILL bra pw_pattrord_fill TABLE_ADDR text_pattrord1 bra pw_pattrord_cont pw_pattrord_fill: TABLE_ADDR text_pattrord1fill pw_pattrord_cont: call lcd_send_text TABLE_ADDR text_pattrord2 call lcd_send_text DISPLAYREFRESHED DISPLAYDELAY time_lcd_medium return ; pattern write / enter pattern name pw_lcd_entername: ; A01:Pattern name movlw 0 call lcd_set_cursor movf currentbank, W addlw "A" ; "A" call lcd_send_char incf currentpattern, W call lcd_send_bcd ; "01" movlw ":" call lcd_send_char ; ":" lfsr FSR1, pat_name movlw 12 ; pad name to 12 chars ; "Pattern name" call lcd_send_text_fsr1 TABLE_ADDR text_entername call lcd_send_text ; "Enter to save " DISPLAYREFRESHED return ; pattern write / instrument select pressed pw_lcd_instrsel: TABLE_ADDR text_instrsel call lcd_send_text ; Select instr. bra pw_lcd_main_cont ; second line as with main ; pattern write / last step pressed pw_lcd_laststep: TABLE_ADDR text_laststep call lcd_send_text ; Last step: xx LENGTHTOW 1 call lcd_send_bcd bra pw_lcd_main_cont ; second line as with main ; pattern write / last step + instrument select pressed pw_lcd_laststepinstr: TABLE_ADDR text_laststep_instr call lcd_send_text ; "Instr. last step" movlw LCD_LINE2 call lcd_set_cursor movlw " " call lcd_send_char movlw " " call lcd_send_char call lcd_send_instrument ; " Snare drum: xx" movlw ":" call lcd_send_char movlw " " call lcd_send_char ; get instrument last step to W using ; FSR1 and temp movf selectedinst, W INSTRLENGTHTOW 1, temp call lcd_send_bcd DISPLAYREFRESHED return ; pattern write / shuffle flam pressed pw_lcd_shuffleflam: TABLE_ADDR text_shuffleflam call lcd_send_text ; Shuffle: x SHUFFLETOW 1 call lcd_send_digit TABLE_ADDR text_shuffleflam2 call lcd_send_text ; Flam: y FLAMTOW 1 call lcd_send_digit DISPLAYREFRESHED return ; pattern write / clear pressed pw_lcd_clear: IFRUNNING pw_lcd_clear_running ; sequencer stopped, show info text TABLE_ADDR text_clear_stop call lcd_send_text ; Select instr. TABLE_ADDR text_clear_stop2 call lcd_send_text ; to clear DISPLAYREFRESHED return pw_lcd_clear_running: TABLE_ADDR text_clear_run call lcd_send_text call lcd_refreshbpm DISPLAYREFRESHED return ; pattern write / instrument cleared in stop mode ; Note: display_arg should specify the instrument ; index of the cleared instrument. pw_lcd_clear_done: movlw LCD_LINE1 call lcd_set_cursor movf display_arg, W call lcd_send_instrument_wreg ; "Snare drum" clrf display_arg movlw 6 call lcd_send_blanks ; "Snare drum " TABLE_ADDR text_clear_stop_done2 call lcd_send_text ; " ... cleared! " DISPLAYREFRESHED call lcd_delay_short return ; pattern write / scale pressed pw_lcd_scale: TABLE_ADDR text_scale call lcd_send_text ; Selected scale: ; movlw LCD_LINE2 ; call lcd_set_cursor ; movlw 1 ; call lcd_send_bcd ; movlw LCD_LINE2 + 6 ; call lcd_set_cursor ; SCALETOW 1 ; call lcd_send_bcd ;; call lcd_send_digit ; DISPLAYREFRESHED ; call lcd_delay_medium ; return ; resolve selected scale SCALETOW 1 movwf temp movlw SCALE_16 cpfseq temp bra pw_lcd_scale_not16 ; scale == 1/16th notes TABLE_ADDR text_scale_16 bra pw_lcd_scale_line2 pw_lcd_scale_not16: movlw SCALE_32 cpfseq temp bra pw_lcd_scale_not32 ; scale == 1/32th notes TABLE_ADDR text_scale_32 bra pw_lcd_scale_line2 pw_lcd_scale_not32: movlw SCALE_8TR cpfseq temp bra pw_lcd_scale_not8tr ; scale == 1/8th triplets TABLE_ADDR text_scale_8tr bra pw_lcd_scale_line2 pw_lcd_scale_not8tr: ; scale must be 1/16th triplets TABLE_ADDR text_scale_16tr pw_lcd_scale_line2: call lcd_send_text ; 1/16 notes DISPLAYREFRESHED ; wait for a bit call lcd_delay_medium return ; pattern play / default display pp_lcd_main: ; A01:Pattern name movlw 0 call lcd_set_cursor movf currentbank, W addlw "A" ; "A" call lcd_send_char incf currentpattern, W call lcd_send_bcd ; "01" movlw ":" call lcd_send_char ; ":" lfsr FSR1, pat_name IFMODE MODE_FILL, pp_lcd_main_fill movlw 12 ; pad name to 12 chars ; "Pattern name" call lcd_send_text_fsr1 pp_lcd_main_cont: ; if next pattern != current pattern show (if running) ; "Next: A02 234b" IFNOTRUNNING pp_lcd_main_nonext movf nextpattern, W cpfseq currentpattern bra pp_lcd_main_next movf nextbank, W cpfseq currentbank bra pp_lcd_main_next pp_lcd_main_nonext: movlw LCD_LINE2 call lcd_set_cursor movlw 12 pp_lcd_main_nextcont: call lcd_send_blanks call lcd_send_bpm ; bpm DISPLAYREFRESHED return pp_lcd_main_fill: movlw 6 ; only 6 chars of name ; "Patter[Fill]" call lcd_send_text_fsr1 TABLE_ADDR text_fill call lcd_send_text ; "[Fill]" bra pp_lcd_main_cont pp_lcd_main_next: TABLE_ADDR text_next call lcd_send_text ; "Next: " movf nextbank, W addlw "A" ; "A" call lcd_send_char incf nextpattern, W call lcd_send_bcd ; "02" movlw 3 ; 3 blanks before bpm bra pp_lcd_main_nextcont ; pattern play / (chain cleared) scale pressed pp_lcd_chaincleared: TABLE_ADDR text_chaincleared call lcd_send_text ; Chain cleared! movlw LCD_LINE2 call lcd_set_cursor movlw 12 call lcd_send_blanks call lcd_send_bpm DISPLAYREFRESHED ; wait for a bit call lcd_delay_medium return ; pattern play / (set chain) last step pressed pp_lcd_setchain: TABLE_ADDR text_setchain call lcd_send_text ; Program chain: TABLE_ADDR text_setchain2 call lcd_send_text ; Step keys append DISPLAYREFRESHED return ; receiving sysex lcd_sysex: TABLE_ADDR text_sysex call lcd_send_text TABLE_ADDR text_sysex2 call lcd_send_text DISPLAYREFRESHED return ; sysex done lcd_sysexdone: TABLE_ADDR text_sysexdone call lcd_send_text TABLE_ADDR text_sysexdone2 call lcd_send_text DISPLAYREFRESHED DISPLAYDELAY time_lcd_long return ; pattern dump started px_lcd_spattdump: TABLE_ADDR text_spattdump call lcd_send_text ; Cur.pattern dump TABLE_ADDR text_spattdump2 call lcd_send_text ; = Please wait! = DISPLAYREFRESHED return ; memory dump started px_lcd_smemdump: TABLE_ADDR text_smemdump call lcd_send_text ; Full memory dump TABLE_ADDR text_smemdump2 call lcd_send_text ; = Please wait! = DISPLAYREFRESHED return ; pattern dumped px_lcd_pattdump: TABLE_ADDR text_pattdump call lcd_send_text ; Current pattern TABLE_ADDR text_pattdump2 call lcd_send_text ; sent to midi! DISPLAYREFRESHED DISPLAYDELAY time_lcd_long return ; memory dumped px_lcd_memdump: TABLE_ADDR text_memdump call lcd_send_text ; Full memory dump TABLE_ADDR text_memdump2 call lcd_send_text ; sent to midi! DISPLAYREFRESHED DISPLAYDELAY time_lcd_long return ; track play / default view ; ; T01:my demo song ; 001/003:A02 x2 tp_lcd_main: movlw LCD_LINE1 call lcd_set_cursor movlw "T" ; T call lcd_send_char incf currenttrack, W call lcd_send_bcd ; T01 movlw ":" call lcd_send_char ; T01: lfsr FSR1, track_name IFMODE MODE_FILL, tp_lcd_main_fill movlw 12 call lcd_send_text_fsr1 ; T01:my demo song bra tp_lcd_main_cont tp_lcd_main_fill: movlw 6 ; only 6 chars of track name ; "my dem[Fill]" call lcd_send_text_fsr1 TABLE_ADDR text_fill call lcd_send_text ; "[Fill]" tp_lcd_main_cont: movlw LCD_LINE2 call lcd_set_cursor lfsr FSR1, currentmeasure call lcd_send_bcd3_fsr1_inc ; 001 movlw "/" call lcd_send_char ; 001/ lfsr FSR1, currenttracklen call lcd_send_bcd3_fsr1 ; 001/003 movlw ":" call lcd_send_char ; 001/003: movf currentmeasuredata, W DECODE_BANK_FROM_MEASURE addlw "A" call lcd_send_char ; 001/003:A movf currentmeasuredata, W DECODE_PATTERN_FROM_MEASURE incf WREG call lcd_send_bcd ; 001/003:A01 movlw 3 call lcd_send_blanks movf currentmeasuredata, W DECODE_REPEAT_FROM_MEASURE bz tp_main_nor movlw "x" call lcd_send_char ; 001/003:A01 x movf currentmeasuredata, W DECODE_REPEAT_FROM_MEASURE incf WREG call lcd_send_digit ; 001/003:A01 x2 tp_main_nor: movlw 2 call lcd_send_blanks DISPLAYREFRESHED return ; track write / default view ; ; Edit T01 001/002 ; A02: pattern x2 tw_lcd_main: TABLE_ADDR text_trackwrite call lcd_send_text ; Edit movlw "T" ; Edit T call lcd_send_char incf currenttrack, W call lcd_send_bcd ; Edit T01 movlw 1 call lcd_send_blanks lfsr FSR1, currentmeasure call lcd_send_bcd3_fsr1_inc ; Edit T01 001 movlw "/" call lcd_send_char ; Edit T01 001/ lfsr FSR1, currenttracklen call lcd_send_bcd3_fsr1 ; Edit T01 001/003 movlw LCD_LINE2 call lcd_set_cursor movf editedmeasuredata, W DECODE_BANK_FROM_MEASURE addlw "A" call lcd_send_char ; A movf editedmeasuredata, W DECODE_PATTERN_FROM_MEASURE incf WREG call lcd_send_bcd ; A01 movlw ":" call lcd_send_char ; A01: lfsr FSR1, pat_name movf editedmeasuredata, W DECODE_REPEAT_FROM_MEASURE bz tw_main_nor ; no repeat ? movlw 9 call lcd_send_text_fsr1 ; A01:pattern n movlw 1 call lcd_send_blanks ; print 9 chars of pattern name movlw "x" call lcd_send_char ; A01:pattern n x movf editedmeasuredata, W DECODE_REPEAT_FROM_MEASURE incf WREG call lcd_send_digit ; A01:pattern n x2 DISPLAYREFRESHED return tw_main_nor: movlw 12 call lcd_send_text_fsr1 ; A01:pattern name DISPLAYREFRESHED return ; track write / confirm track clear view tw_lcd_clearconfirm: TABLE_ADDR text_clearconfirm1 call lcd_send_text ; Clear track incf currenttrack, W call lcd_send_bcd ; 01 movlw 1 call lcd_send_blanks movlw '?' call lcd_send_char ; ? TABLE_ADDR text_clearconfirm2 call lcd_send_text ; Enter to confirm DISPLAYREFRESHED return ; track write / track cleared view tw_lcd_trackcleared: TABLE_ADDR text_trackcleared1 call lcd_send_text ; Track incf currenttrack, W call lcd_send_bcd ; 01 movlw 8 call lcd_send_blanks TABLE_ADDR text_trackcleared2 call lcd_send_text ; cleared! DISPLAYREFRESHED DISPLAYDELAY time_lcd_medium return ; A01 inserted ; to measure 003 tw_lcd_measureinserted: movlw LCD_LINE1 call lcd_set_cursor movf editedmeasuredata, W DECODE_BANK_FROM_MEASURE addlw "A" call lcd_send_char ; A movf editedmeasuredata, W DECODE_PATTERN_FROM_MEASURE incf WREG call lcd_send_bcd ; A01 TABLE_ADDR text_measureinserted1 call lcd_send_text ; inserted TABLE_ADDR text_measureinserted2 call lcd_send_text ; to measure lfsr FSR1, currentmeasure call lcd_send_bcd3_fsr1_inc ; 001 DISPLAYREFRESHED DISPLAYDELAY time_lcd_short return ; track write / measure deleted tw_lcd_measuredeleted: TABLE_ADDR text_measuredeleted1 ; Measure call lcd_send_text TABLE_ADDR text_measuredeleted2 ; deleted call lcd_send_text DISPLAYREFRESHED DISPLAYDELAY time_lcd_short return ; track write / enter track name tw_lcd_entername: ; T01:Track name movlw 0 call lcd_set_cursor movlw 'T' call lcd_send_char ; T incf currenttrack, W call lcd_send_bcd ; T01 movlw ":" call lcd_send_char ; T01: lfsr FSR1, track_name movlw 12 ; pad name to 12 chars ; "Track name" call lcd_send_text_fsr1 TABLE_ADDR text_entername call lcd_send_text ; "Enter to save " DISPLAYREFRESHED return ; ; "Din sync input ?" ; " OFF" ; s_lcd_main: ; write selected setting to upper row movlw 0 call lcd_set_cursor TABLE_ADDR text_settings swapf selected_setting, W ; selected * 16 addwf TBLPTRL btfsc STATUS, C incf TBLPTRH call lcd_send_text_nocursor movf select_pressed, W bz s_lcd_main_noselect ; select pressed TABLE_ADDR text_settings_select call lcd_send_text bra s_lcd_main_done s_lcd_main_noselect: ; not in selection mode movlw 5 ; 5 == "midi channel" cpfseq selected_setting bra s_lcd_main_notchannel s_lcd_main_channel: ; selected setting is midi channel movlw LCD_LINE2 call lcd_set_cursor movlw 14 call lcd_send_blanks ; 14 blanks movf settings_midi_channel, W call lcd_send_bcd ; "01" bra s_lcd_main_done s_lcd_main_notchannel: ; print out current on/off status of the setting movf selected_setting, W call get_bit andwf settings, W bz s_lcd_main_off s_lcd_main_on: ; setting is on TABLE_ADDR text_settings_on call lcd_send_text bra s_lcd_main_done s_lcd_main_off: ; settings is off TABLE_ADDR text_settings_off call lcd_send_text s_lcd_main_done: DISPLAYREFRESHED return ; ; =-> general lcd screen functions ; LCD_LINE1 equ 0x00 ; beginning of the line 1 LCD_LINE2 equ 0x40 ; beginning of the line 2 ; ; initializes lcd display ; lcd_init: ; we should wait for power up delay call lcd_delay105ms ; clear rs bcf PORT_LCD, LCD_RS_PIN ; set function movlw b'00000011' ; 0x03 call lcd_send_nybble call lcd_delay5ms ; wait for 5ms ; set function, 2nd movlw b'00000011' ; 0x03 call lcd_send_nybble call lcd_delay2ms ; set function, 3rd movlw b'00000011' ; 0x03 call lcd_send_nybble call lcd_delay2ms ; set 4-bit mode movlw b'00000010' ; 0x02 call lcd_send_nybble call lcd_delay2ms ; ; we are now in 4-bit mode and commands ; should work ok ; ; 2x16 chars / font movlw b'00101000' ; 0x28 call lcd_send_command call lcd_delay2ms ; auto-increment movlw b'00000110' ; 0x06 call lcd_send_command call lcd_delay2ms ; set display on movlw b'00001100' ; 0x0f (0x0d) call lcd_send_command call lcd_delay2ms ; send cgram characters TABLE_ADDR cgram movlw 0 call lcd_send_cgram ; clear lcd call lcd_clear call lcd_delay2ms return ; ; set lcd cursor on ; lcd_cursor_on: movlw b'00001110' call lcd_send_command call lcd_delay2ms return ; ; set lcd cursor off ; lcd_cursor_off: movlw b'00001100' call lcd_send_command call lcd_delay2ms return ; ; clears lcd ; lcd_clear: movlw b'00000001' ; 0x01 call lcd_send_command call lcd_delay2ms ; wait atleast 1.64ms return ; ; set lcd cursor position ; lcd_set_cursor: iorlw 0x80 call lcd_send_command return ; ; sends text from table pointer (program memory) ; to lcd ; ; the actual string must be preceeded ; with a cursor position ; ie. ; mytext: db 0x40, "My text", 0 ; ; goes to cursor position 0x40 (= second line) lcd_send_text: ; get cursor pos tblrd*+ movf TABLAT, W lcd_send_text_posw: call lcd_set_cursor lcd_send_text_nocursor: lcd_send_text_loop: tblrd*+ ; get character movf TABLAT, W bz lcd_send_text_end ; end of string call lcd_send_char ; send character bra lcd_send_text_loop lcd_send_text_end: return ; ; sends blanks (" ") to lcd. Number ; of blanks sent is specified with ; WREG. ; ; bcd_temp and W are thrashed. lcd_send_blanks: movwf bcd_temp lcd_send_blanks_loop: movlw " " call lcd_send_char decfsz bcd_temp bra lcd_send_blanks_loop return ; ; sends text from FSR1 (data memory) ; to lcd ; ; the number of characters to be written ; should be loaded to WREG - string can ; be terminated with 0 and then the ; output string is padded with whitespace ; to match the length in WREG. ; ; thrashes bcd_temp ; lcd_send_text_fsr1: movwf bcd_temp lcd_send_text_fsr1_loop: movf POSTINC1, W ; get character bz lcd_send_text_fsr1_end ; end of string call lcd_send_char ; send character decfsz bcd_temp bra lcd_send_text_fsr1_loop lcd_send_text_fsr1_end: tstfsz bcd_temp bra lcd_send_text_fsr1_pad return lcd_send_text_fsr1_pad: ; pad with whitespace for bcd_temp amount movlw " " call lcd_send_char decfsz bcd_temp bra lcd_send_text_fsr1_pad return ; ; prints a char from WREG to lcd ; lcd_send_char: bsf PORT_LCD, LCD_RS_PIN ; rs to high on characters movwf lcd_temp swapf lcd_temp, W ; upper nybble first call lcd_send_nybble movf lcd_temp, W ; lower nybble call lcd_send_nybble bcf PORT_LCD, LCD_RS_PIN ; rs to low call lcd_delay ; delay atleast 50us return ; ; prints a digit (lower 4 bits) from WREG to lcd ; lcd_send_digit: andlw 0x0f ; %00001111 addlw -0x0a ; > 10 ? btfsc STATUS, C addlw 0x07 ; += 7 if > 10 addlw 0x3a ; += 0x3a bra lcd_send_char ; ; encodes bcd from WREG and prints the result ; to lcd ; lcd_send_bcd: movwf bcd_temp clrf bcd_result_0 swapf bcd_temp, W addwf bcd_temp, W andlw 0x0f btfsc STATUS, DC addlw 0x16 btfsc STATUS, DC addlw 0x06 addlw 0x06 btfss STATUS, DC addlw -0x06 btfsc bcd_temp, 4 addlw 0x16 - 1 + 0x6 btfss STATUS, DC addlw -0x06 btfsc bcd_temp, 5 addlw 0x30 btfsc bcd_temp, 6 addlw 0x60 btfsc bcd_temp, 7 addlw 0x20 addlw 0x60 rlcf bcd_result_0, F btfss bcd_result_0, 0 addlw -0x60 movwf bcd_result_1 btfsc bcd_temp,7 incf bcd_result_0, F movf bcd_result_1, W swapf bcd_result_1, W call lcd_send_digit movf bcd_result_1, W call lcd_send_digit return ; ; prints a 3 digit value from a two byte value in FSR1. ; ; for example if FSR1 points to 01 01 a value "257" is sent ; to the LCD. Note: supports only numbers between 0 - 511 ; ; thrashes lcd_temp, bcd_temp ; lcd_send_bcd3_fsr1: movff POSTINC1, bcd_result_0 movf INDF1, W bra lcd_send_bcd3_fsr1_s ; call this to print out value + 1 lcd_send_bcd3_fsr1_inc: movff POSTINC1, bcd_result_0 infsnz INDF1, W ; increment value from fsr1 incf bcd_result_0 ; to bcd_result_x by one lcd_send_bcd3_fsr1_s: clrf bcd_temp movwf bcd_result_1 movf bcd_result_0, W bz lcd_send_bcd3_fsr1_below256 ; 256 - 511 incf bcd_temp incf bcd_temp movlw 56 addwf bcd_result_1, W ; 210 -> 266 -> 10 bnc lcd_send_bcd3_fsr1_go incf bcd_temp sublw 100 bra lcd_send_bcd3_fsr1_go lcd_send_bcd3_fsr1_below256: movf bcd_result_1, W lcd_send_bcd3_fsr1_go: movwf lcd_temp ; 0 - 255 movlw 100 lcd_send_bcd3_fsr1_hundreds: subwf lcd_temp ; 0 - 155 btfss STATUS, C bra lcd_send_bcd3_fsr1_fin incf bcd_temp ; +100 bra lcd_send_bcd3_fsr1_hundreds lcd_send_bcd3_fsr1_fin: addwf lcd_temp, W ; 55 movwf bcd_result_0 movf bcd_temp, W call lcd_send_digit ; "2.. movf bcd_result_0, W call lcd_send_bcd ; ..55" return ; ; prints out the name of the ; currently selected instrument ; to the current cursor position ; ; thrashes lcd_temp lcd_send_instrument: movf selectedinst, W bra lcd_send_instrument_wreg ; ; prints out the name of the specified ; instrument to the current cursor ; position ; ; instrument index is specified with ; WREG. ; ; thrashes lcd_temp, bcd_temp lcd_send_instrument_wreg: movwf bcd_temp TABLE_ADDR text_instruments rlncf bcd_temp, W ; * 2 rlncf WREG ; * 4 movwf lcd_temp rlncf bcd_temp, W addwf lcd_temp ; * 6 rlncf lcd_temp, W ; * 12 addwf TBLPTRL btfsc STATUS, C incf TBLPTRH ; TBLPTR == instr text call lcd_send_text_nocursor return ; ; refreshes the bpm (tempo var) to ; lcd display if needed ; lcd_refreshbpm: IFNOEVENT EVENT_TEMPOCHANGE, lcd_no_tempo_changed ; if in flam write mode the flam-text overwrites the bpm text IFMODE MODE_FLAMWRITE, lcd_no_tempo_changed ; tempo changed, redraw bpm counter call lcd_send_bpm CLEAREVENT EVENT_TEMPOCHANGE lcd_no_tempo_changed: return ; ; prints out the bpm (tempo var) to lcd ; lower right corner with "bpm" suffix ; ; note: if EVENT_DINRUN is set the ; bpm is not printed. ; lcd_send_bpm: movlw LCD_LINE2 + 12 ; row 2, char 12 call lcd_set_cursor IFEVENT EVENT_DINRUN, lcd_send_bpm_blanks clrf bcd_result_0 ; hundreds movf tempo, W addlw 30 ; tempo range 30 - 285 ; so tempo 0 == 30 bpm btfss STATUS, C bra lcd_send_bpm_ok incf bcd_result_0 incf bcd_result_0 ; over 255, hundreds == 2 addlw 56 ; correction for overflow lcd_send_bpm_ok: call lcd_send_number_hundreds_set movlw 0 ; "bpm" character call lcd_send_char return lcd_send_bpm_blanks: movlw 4 call lcd_send_blanks return ; ; encodes a number in W to three digit ; decimal and send the number to lcd. ; lcd_send_number: clrf bcd_result_0 ; hundreds lcd_send_number_hundreds_set: movwf bcd_temp lcd_numb_find_pos: movf bcd_temp, W bnn lcd_below_128 ; number is over 128 incf bcd_result_0 ; hundreds+=1 movlw 100 subwf bcd_temp bra lcd_numb_find_pos lcd_below_128: movlw 99 cpfsgt bcd_temp ; number > 99 ? bra lcd_below_100 incf bcd_result_0 ; hundreds+=1 decf bcd_temp subwf bcd_temp ; number -= 100 bra lcd_below_128 lcd_below_100: tstfsz bcd_result_0 bra lcd_numb1 movlw " " ; pad with space if necessary call lcd_send_char bra lcd_numb2 lcd_numb1: movf bcd_result_0, W call lcd_send_digit lcd_numb2: movf bcd_temp, W ; rest is below 100, "bcd-ready" call lcd_send_bcd return ; sends full 8 bit command from W to lcd in 4-bit mode lcd_send_command: movwf lcd_temp swapf lcd_temp, W ; upper nybble first bcf PORT_LCD, LCD_RS_PIN ; rs to low on commands call lcd_send_nybble movf lcd_temp, W ; lower nybble call lcd_send_nybble call lcd_delay ; delay atleast 50us return ; ; sends cgram data from tblptr to ; cursor position in W ; ; note: thrashes bcd_temp ; lcd_send_cgram: iorlw 0x40 ; set cursor to cgram call lcd_send_command movlw 8 ; 8 rows / character movwf bcd_temp lcd_cgram_loop: TBLRD*+ movf TABLAT, W call lcd_send_char ; send character data decfsz bcd_temp bra lcd_cgram_loop return ; sends 4 (low) bits from W to lcd lcd_send_nybble: bcf PORT_LCD, LCD_D7_PIN bcf PORT_LCD, LCD_D6_PIN bcf PORT_LCD, LCD_D5_PIN bcf PORT_LCD, LCD_D4_PIN btfsc WREG, 3 bsf PORT_LCD, LCD_D7_PIN btfsc WREG, 2 bsf PORT_LCD, LCD_D6_PIN btfsc WREG, 1 bsf PORT_LCD, LCD_D5_PIN btfsc WREG, 0 bsf PORT_LCD, LCD_D4_PIN call lcd_strobe return ; strobe lcd enable lcd_strobe: bsf PORT_LCD_EN, LCD_EN_PIN call lcd_delay bcf PORT_LCD_EN, LCD_EN_PIN call lcd_delay return ;;; delay routines --> ; ; ~100us delay ; lcd_delay: movlw 1 ; custom delay, WREG * 256 iteration delay lcd_delay_custom: movwf lcd_delay_h clrf lcd_delay_l lcd_ldelay_loop: clrwdt ; 256 * 0.1us = 25.6us decfsz lcd_delay_l ; 255 * 0.1us + 0.3us = 25.8us bra lcd_ldelay_loop ; 255 * 0.2us = 51us ; =~ 102.4us / iteration decfsz lcd_delay_h bra lcd_ldelay_loop return ; =~ ; ; ~105ms delay ; lcd_delay105ms: call lcd_delay15ms call lcd_delay15ms call lcd_delay15ms call lcd_delay15ms call lcd_delay15ms call lcd_delay15ms call lcd_delay15ms return ; ; ~15ms delay ; lcd_delay15ms: movlw 146 bra lcd_delay_custom ; ; ~5ms delay ; lcd_delay5ms: movlw 49 bra lcd_delay_custom ; ; ~1.8ms delay ; lcd_delay2ms: movlw 18 bra lcd_delay_custom ; ; ~0.5s delay, breaks with keypress ; lcd_delay_short: bra lcd_delay_long2 ; ; ~1s delay, breaks with keypress ; lcd_delay_medium: call lcd_delay_long2 bra lcd_delay_long2 ; ; ~1.5s long delay, breaks with keypress ; lcd_delay_long: call lcd_delay_long2 call lcd_delay_long2 bra lcd_delay_long2 ; help decay, breaks with keypress ;lcd_delay_help: ; bra lcd_delay_long2 ; waits ~520ms or keypress lcd_delay_long2: clrf lcd_delay_z lcd_ldelay_long_loop: ; if no key is pressed just delay IFNOEVENTCALL EVENT_KEY, lcd_delay2ms decfsz lcd_delay_z bra lcd_ldelay_long_loop return
lcd_set_cursor lcd_send_char lcd_send_bcd lcd_send_text_fsr1 lcd_send_text lcd_send_instrument lcd_send_bpm lcd_send_blanks lcd_send_digit lcd_refreshbpm lcd_send_instrument_wreg lcd_delay_short lcd_delay_medium lcd_send_bcd3_fsr1_inc lcd_send_bcd3_fsr1 lcd_send_text_nocursor get_bit lcd_delay105ms lcd_send_nybble lcd_delay5ms lcd_delay2ms lcd_send_command lcd_send_cgram lcd_clear lcd_delay lcd_send_number_hundreds_set lcd_strobe lcd_delay15ms lcd_delay_long2