; Author: Pawel Jablonski ; E-mail: pj@xirx.net ; WWW: xirx.net ; GIT: git.xirx.net ; ; License: You can use this code however you like ; but leave information about the original author. ; Code is free for non-commercial and commercial use. map ../../../bin/rom/rom.map ; Start message const keyHelpHeader "Keymap:" ; Piano key description const keyHelp00 " ! @ $ % ^ * ( " const keyHelp01 "c#2 d#2 f#2 g#2 a#2 c#3 d#3 " const keyHelp02 " 1 2 3 4 5 6 7 8 9 0 " const keyHelp03 "c2 d2 e2 f2 g2 a2 b2 c3 d3 e3 " const keyHelp04 " Q W E T Y I O P " const keyHelp05 "f#3 g#3 a#3 c#4 d#4 f#4 g#4 a#4" const keyHelp06 " q w e r t y u i o p " const keyHelp07 "f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 " const keyHelp08 " S D G H J L " const keyHelp09 " c#5 d#5 f#5 g#5 a#5 c#6 " const keyHelp10 " a s d f g h j k l " const keyHelp11 "b4 c5 d5 e5 f5 g5 a5 b5 c6 " const keyHelp12 " Z C V B " const keyHelp13 "d#6 f#6 g#6 a#6 " const keyHelp14 " z x c v b n m " const keyHelp15 "d6 e6 f6 g6 a6 b6 c7 " ; Bottom help message const keyHelpExit "ESC - Exit +- Duration: " const keyHelpClear " " const keyHelpMs "0ms" ; Tone numbers connected to keyboard keys const tone2x 0, 17, 0, 0, 22, 24, 0, 0, 31, 0, 29, 0, 0, 0, 0, 0 const tone3x 32, 16, 18, 20, 21, 23, 25, 27, 28, 30, 0, 0, 0, 0, 0, 0 const tone4x 19, 0, 74, 70, 55, 38, 0, 58, 60, 46, 62, 0, 65, 0, 0, 48 const tone5x 50, 34, 0, 53, 41, 0, 72, 36, 0, 43, 67, 0, 0, 0, 26, 0 const tone6x 0, 51, 73, 69, 54, 37, 56, 57, 59, 45, 61, 63, 64, 76, 75, 47 const tone7x 49, 33, 39, 52, 40, 44, 71, 35, 68, 42, 66, 0, 0, 0, 0, 0 ; Set tone duration var toneDuration ; First label is the entry point .entry: call .main ret ; No arguments ; No return .main: push A push B ; Set default tone duration str 50, *toneDuration ; Print start messages call .printKeyHelp ; Print current tone duration call .printMs ; Stop playing sounds call .xSpeakerClear ; Set sound values to default mov 8, A call .xSpeakerSetFill mov 15, A call .xSpeakerSetVolume .main_loop: call .xKeyboardGetChar ; Exit if clicked key is ESC cmp 0x1b, A je .main_end ; Check for increse tone duration command cmp '=', A je .main_durationPlus cmp '+', A je .main_durationPlus ; Check for decrese tone duration command cmp '-', A je .main_durationMinus cmp '_', A je .main_durationMinus ; Play tone based on clicked key call .playTone jmp .main_loop ; Increse tone duration .main_durationPlus: ldr *toneDuration, B cmp 250, B ; 250 <= B jle .main_loop add 5, B str B, *toneDuration ; Print current tone duration call .printMs jmp .main_loop ; Decrese tone duration .main_durationMinus: ldr *toneDuration, B cmp 5, B ; 5 >= B jge .main_loop sub 5, B str B, *toneDuration ; Print current tone duration call .printMs jmp .main_loop .main_end: pop B pop A ret ; No arguments ; No return .printKeyHelp: push A push B push X push Y ; Load address to start message mov low(*keyHelpHeader), X mov high(*keyHelpHeader), Y ; Print start message call .xStringPrint call .xStringNewLine ; Load address to mov low(*keyHelp00), X mov high(*keyHelp00), Y ; Reset loop counter clr B .printKeyHelp_loop: ; New line call .xStringNewLine ; Check if it is an even or odd line mov B, A and 0x1, A cmp 0x1, A jne .printKeyHelp_loop_white ; Set foregound color to green mov 0x0a, A call .xLcdSetForeground jmp .printKeyHelp_loop_print .printKeyHelp_loop_white: ; Set foreground color to default mov 0x0f, A call .xLcdSetForeground .printKeyHelp_loop_print: ; Print line call .xStringPrint ; Move address to next line add 40, X incc Y ; Calc keyboard row number mov B, A and 0x3, A cmp 0x3, A jne .printKeyHelp_loop_noNewLine ; New line if it is a keyboard row was printed call .xStringNewLine .printKeyHelp_loop_noNewLine: ; Repeat print lines 15+1 times loope 15, B, .printKeyHelp_loop ; Set foreground color to default mov 0x0f, A call .xLcdSetForeground call .xStringNewLine call .xStringNewLine ; Load address to bottom message mov low(*keyHelpExit), X mov high(*keyHelpExit), Y ; Print bottom message call .xStringPrint ; Refresh the screen call .xLcdRefresh pop Y pop X pop B pop A ret ; No arguments ; No return .printMs: push A push X push Y ; Move print start at begin of the tone duration field mov 34, A call .xStringSetCursorX ; Load address to empty value mov low(*keyHelpClear), X mov high(*keyHelpClear), Y ; Clear field by empty value call .xStringPrint ; Move print start at begin of the tone duration field call .xStringSetCursorX ; Load tone duration ldr *toneDuration, A ; Print new tone duration call .xStringPrintU8 ; Load address to second part of tone duration string mov low(*keyHelpMs), X mov high(*keyHelpMs), Y ; Print second part of tone duration string call .xStringPrint ; Refresh the screen call .xLcdRefresh pop Y pop X pop A ret ; Arguments ; A - keyboard key ; No return .playTone: push A push X push Y ; Make sure the key is beetwen 0x20 and 0x7f cmp 0x20, A ; 0x20 > A jg .playTone_end cmp 0x7f, A ; 0x7f < A jl .playTone_end ; Make offset sub 0x20, A ; Load address to tone table mov low(*tone2x), X mov high(*tone2x), Y ; Add offset to tone add A, X incc Y ; Load tone number ldr A ; Do not play empty tone cmp 0, A ; 0 == A je .playTone_end call .xSpeakerSetNote ; Load tone duration ldr *toneDuration, A ; Write tone duration call .xSpeakerSetTime ; Stop playing sounds call .xSpeakerClear ; Add and play tone from buffer call .xSpeakerAddNote .playTone_end: pop Y pop X pop A ret