;
; 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
External Labels :
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