📄 jw002.asm
字号:
; Display board firmware, to allow the JW-002 display board to be; used with the PJRC MP3 Player: http://www.pjrc.com/tech/mp3/; The JW-002 display board may be purchased from PJRC.COM, with; this firmware installed and an adaptor board with 12 pushbuttons; and two cables to allow it to connect directly to the PJRC MP3; player circuit board's 4-pin connector.; The JW-002 display board may also be purchased directly from; Earth Computer Tech, at: http://www.flat-panel.com/jw002.htm; Earth will offer quantity discounts, so for applications other; than use with the PJRC MP3 player, Earth may be a better choice; for purchasing the display. They provide the JW-002 without; the extra parts needed for use with the PJRC MP3 player board.; This JW-002 firmware source code has been placed in the public domain.; This code is provided in the hope that it will be useful, but; it is provided without any warranty; without even the implied; warranty of merchantability or fitness for a particular purpose. ;TODO: handle pushbutton "ghosts" (eg if you press #2, #3 and #4; at same time, #10 appears as a ghost). ;configurable (but hard-coded) settings .equ location, 0x0000 ;stand-alone build ;.equ location, 0x8000 ;to run under PAULMON2 (see below) ;.equ baud_const, 255 ;57600 baud .equ baud_const, 253 ;19200 baud ;.equ baud_const, 250 ;9600 baud; ****************************************************************** ;internal memory allocation .equ reg0, 0 .equ reg1, 1 .equ reg2, 2 .equ reg3, 3 .equ reg4, 4 .equ reg5, 5 .equ reg6, 6 .equ reg7, 7 .equ rx_buf_head, 0x08 ;1 byte .equ rx_buf_tail, 0x09 ;1 byte .equ tx_buf_head, 0x0A ;1 byte .equ tx_buf_tail, 0x0B ;1 byte .equ x_pos, 0x0C ;1 byte, current x char position .equ y_pos, 0x0D ;1 byte, current y char position .equ font, 0x0E ;1 byte, current font to use .equ cmd_len, 0x0F ;1 byte, # of chars revc .equ cmd_buf, 0x10 ;16 byte command buffer .equ hscroll_en, 0x20 ;1 byte .equ mode_bits, 0x21 ;3 bytes .equ vscroll_offset, 0x24 ;1 byte, current y scroll offset .equ pb_scan_state, 0x25 ;1 byte .equ char_buf, 0x26 ;5 bytes, buffer of current char .equ pb_state, 0x2b ;12 bytes, pushbutton state .equ pb_config, 0x37 ;12 bytes, config for each button .equ pb_event_head, 0x43 ;1 byte .equ pb_event_tail, 0x44 ;1 byte .equ lcd_on_timer, 0x45 ;1 byte .equ redraw_addr, 0x46 ;2 bytes .equ hscroll_speed, 0x49 ;1 byte .equ hscroll_t0_count, 0x4a ;1 byte .equ hscroll_fill_row, 0x4b ;1 byte .equ hscroll_font0, 0x4c ;1 byte .equ hscroll_font1, 0x4d ;1 byte .equ hscroll_font2, 0x4e ;1 byte .equ hscroll_font3, 0x4f ;1 byte .equ hscroll_font4, 0x50 ;1 byte .equ hscroll_font5, 0x51 ;1 byte .equ hscroll_font6, 0x52 ;1 byte .equ hscroll_font7, 0x53 ;1 byte .equ hscroll_end0, 0x54 ;1 byte .equ hscroll_end1, 0x55 ;1 byte .equ hscroll_end2, 0x56 ;1 byte .equ hscroll_end3, 0x57 ;1 byte .equ hscroll_end4, 0x58 ;1 byte .equ hscroll_end5, 0x59 ;1 byte .equ hscroll_end6, 0x5a ;1 byte .equ hscroll_end7, 0x5b ;1 byte .equ hscroll_pos0, 0x5c ;1 byte .equ hscroll_pos1, 0x5d ;1 byte .equ hscroll_pos2, 0x5e ;1 byte .equ hscroll_pos3, 0x5f ;1 byte .equ hscroll_pos4, 0x60 ;1 byte .equ hscroll_pos5, 0x61 ;1 byte .equ hscroll_pos6, 0x62 ;1 byte .equ hscroll_pos7, 0x63 ;1 byte .equ stack, 0x64 ;28 byte stack ;bit mapped memory allocation (4 bytes) ;hscroll_en* must start at 0 .equ hscroll_en0, 0 .equ hscroll_en1, 1 .equ hscroll_en2, 2 .equ hscroll_en3, 3 .equ hscroll_en4, 4 .equ hscroll_en5, 5 .equ hscroll_en6, 6 .equ hscroll_en7, 7 .equ wrap_mode, 8 .equ vscroll_mode, 9 .equ ignore_input_mode, 10 .equ cin_serviced, 11 .equ tx_intr_expected, 12 .equ update_mode, 13 .equ hscroll_fill_en, 14 .equ hscroll_redraw, 15 .equ turn_lcd_on, 16 ;external data memory .equ rx_buf_page, 0 ;256 byte rx buffer, 0000 to 00FF .equ tx_buf_page, 1 ;256 byte tx buffer, 0100 to 01FF .equ pb_strings_page, 2 ;512 bytes, strings, 0200 to 03FF .equ display_cache, 4 ;5 columns * 24 characters * 8 rows = ;960 bytes, display cache 0400 to 07FF ;redraw routine assumes 1k boundary alignment .equ hscroll_buffer, 8 ;8x256 byte bufferx for horizontal scrolling rows .equ pb_events_page, 0x10 ;256 byte event buffer, 0800 to 08FF .equ fonts_start_page, 0x11 ;28416 bytes for fonts, 1100 to 7FFF ;this allows 22 fonts to be stored .equ num_rom_fonts, 4 ;4 fonts included in ROM ;memory mapped interface to the LCD display controller chips .equ left_cmd_wr, 0xFF00 .equ left_cmd_rd, 0xFF01 .equ left_data_wr, 0xFF02 .equ left_data_rd, 0xFF03 .equ right_cmd_wr, 0xFF04 .equ right_cmd_rd, 0xFF05 .equ right_data_wr, 0xFF06 .equ right_data_rd, 0xFF07 ;connections to the 8051 port pins .equ pb_xmit_1, 0xB2 ;p3.2 .equ pb_xmit_2, 0xB3 ;p3.3 .equ pb_xmit_3, 0x97 ;p1.7 .equ pb_recv_1, 0x93 ;p1.3 .equ pb_recv_2, 0x92 ;p1.2 .equ pb_recv_3, 0x94 ;p1.4 .equ pb_recv_4, 0x90 ;p1.0 .equ led_pin, 0x91 ;clear to turn on LED .equ watchdog_pin, 0xB5 ;toggle to clear watchdog timer .equ bank_pin1, 0x95 ;ROM memory bank selects .equ bank_pin2, 0x96;pushbutton config;; autorepeat delay: no autorepeat, 400 ms, 650 ms, 900 ms; autorepeat speed: 3/sec, 5/sec, 8/sec, 12/sec; xmit press event; xmit depress event;***********************************************************************;** **;** Main Program **;** **;*********************************************************************** .org location ljmp begin .org location+11 ljmp timer0_isr .org location+35 ljmp uart_intr.org location+256.db 0xA5,0xE5,0xE0,0xA5 ;signiture bytes.db 35,255,0,0 ;id.db 0,0,0,0 ;reserved.db 0,0,0,0 ;reserved.db 0,0,0,0 ;reserved.db 0,0,0,0 ;reserved.db 0,0,0,0 ;user defined.db 255,255,255,255 ;length and checksum (255=unused).db "JW-002 LCD Firmware",0.org location+256+64 ;executable code begins here; To allow for program development with PAULMON2, the JW-002 display; board needs several modifications.;; 1: Program PAULMON2 (pm21_8.obj) into the flash chip.;; 2: Disable the watchdog timer: short C1.;; 3: Disconnect the flash chip's CE pin from ground and connect it to; A15. The wide trace that runs under the upper left corner of the ; PLCC socket is ground and only connects to CE, so this is the; trace to cut. A15 may be found on a via 0.25 inches away from; the corner of this trace near the PLCC socket.;; 4: Connect PSEN and RD to an AND gate. The two unused NAND gates; in IC2 may be used, if the pins are lifted away from the board.;; 5: Disconnect IC7's CE (pin 22) and connect it to the AND gate output.;; With these changes, this code may be built at 8000 and downloaded to; the board. Memory from 0000 to 7FFF will be both code memory (the; flash chip with PAULMON2) and data memory (32k SRAM, IC8), and the; firmware will use the SRAM starting at 0000 for fonts. The code; allows 32 fonts, but care should be taken not to use more than the; first 22 fonts, as the 23rd font will begin to overwrite the program; at 8000.begin: mov sp, #stack mov ie, #0 mov psw, #0 lcall retinow lcall retinow setb update_mode lcall init_display lcall move_cursor_home mov font, #0 mov cmd_len, #0 setb wrap_mode setb vscroll_mode clr ignore_input_mode clr hscroll_fill_en clr hscroll_redraw mov hscroll_fill_row, #0 mov hscroll_en, #0 mov hscroll_font0, #0 mov hscroll_font1, #0 mov hscroll_font2, #0 mov hscroll_font3, #0 mov hscroll_font4, #0 mov hscroll_font5, #0 mov hscroll_font6, #0 mov hscroll_font7, #0 mov hscroll_speed, #0x06 mov hscroll_pos0, #0 mov hscroll_pos1, #0 mov hscroll_pos2, #0 mov hscroll_pos3, #0 mov hscroll_pos4, #0 mov hscroll_pos5, #0 mov hscroll_pos6, #0 mov hscroll_pos7, #0 mov hscroll_end0, #0 mov hscroll_end1, #0 mov hscroll_end2, #0 mov hscroll_end3, #0 mov hscroll_end4, #0 mov hscroll_end5, #0 mov hscroll_end6, #0 mov hscroll_end7, #0 mov hscroll_t0_count, #0 lcall init_uart_intr lcall timer0_setup lcall copy_fonts_to_sram mov a, #location >> 8 jz main_loop mov dptr, #mesg_abort lcall pstrmain_loop: jnb turn_lcd_on, main_event lcall display_onmain_event: lcall get_event jz main_cont lcall print_eventmain_cont: jb hscroll_redraw, main_hscroll_redraw lcall cin jnc main_got_char sjmp main_loop main_got_char: ;lcall cout ;uncomment for echo of input characters mov r2, amain1: mov a, cmd_len ;check if continuing multi-byte cmd jz main2 ;if cmd_len > 0, this byte is to be treated at part of ;a multi-byte command, and not regular input mov a, #cmd_buf add a, cmd_len mov r0, a mov a, r2 mov @r0, a inc cmd_len acall exec_cmd ajmp main_loopmain2: mov a, r2 ;check for 0x5C command cjne a, #0x5C, main3 ;the '\' character, 0x5C, begin a command mov r0, #cmd_buf mov a, r2 mov @r0, a mov cmd_len, #1 ;all '\' commands are at least two characters, so don't call exec_cmd ajmp main_loopmain3: mov a, r2 ;check for control character add a, #224 jc main4 mov r0, #cmd_buf mov a, r2 mov @r0, a mov cmd_len, #1 acall exec_cmd ajmp main_loopmain4: jb ignore_input_mode, main_loop ;check ignore input mode mov a, r2 lcall lookup_char lcall cache_char ajmp main_loopmain_hscroll_redraw: mov dph, #(hscroll_buffer - 1)main_hscroll_redraw_next_row: inc dph mov a, dph cjne a, #(hscroll_buffer + 8), main_hscroll_redraw_startmain_hscroll_redraw_exit: clr hscroll_redraw ajmp main_loopmain_hscroll_redraw_start: anl a, #00000111b acall check_hscroll_en jnc main_hscroll_redraw_next_row mov a, #0 ;save params mov c, wrap_mode rrc a mov c, vscroll_mode rrc a orl a, x_pos mov r2, a mov r4, y_pos mov r3, font mov x_pos, #0 ;init params mov a, dph anl a, #00000111b mov y_pos, a add a, #hscroll_pos0 ;get first char location mov r0, a mov dpl, @r0 clr c subb a, #(hscroll_pos0 - hscroll_font0) mov r0, a mov font, @r0 ;get font for this line add a, #(hscroll_end0 - hscroll_font0) mov r0, a ;point to end clr wrap_mode clr vscroll_mode mov r1, #0main_hscroll_redraw_next: movx a, @dptr mov r5, dph mov r6, dpl lcall lookup_char lcall cache_char_only mov dph, r5 mov dpl, r6 inc dpl inc r1 cjne r1, #24, main_hscroll_redraw_cont sjmp main_hscroll_redraw_completemain_hscroll_redraw_cont: mov a, dpl ;check for buffer wrap clr c subb a, @r0 jnz main_hscroll_redraw_next mov dpl, #0 sjmp main_hscroll_redraw_nextmain_hscroll_redraw_complete: mov a, dph anl a, #00000111b mov r7, a mov r5, dph lcall redraw_row mov dph, r5 mov a, r2 ;restore params anl a, #00011111b mov x_pos, a mov y_pos, r4 mov font, r3 mov a, r2 rlc a mov vscroll_mode, c rlc a mov wrap_mode, c mov a, dph anl a, #00000111b add a, #hscroll_pos0 mov r1, a inc @r1 mov a, @r1 clr c subb a, @r0 jnz main_hscroll_redraw_cont1 mov @r1, #0main_hscroll_redraw_cont1: ljmp main_hscroll_redraw_next_row; checks whether the row specified in a is enabled for horizontal; scrolling - result in ccheck_hscroll_en: push acc clr c jnz check_hscroll_en1 mov c, hscroll_en0 sjmp check_hscroll_donecheck_hscroll_en1: dec a jnz check_hscroll_en2 mov c, hscroll_en1 sjmp check_hscroll_donecheck_hscroll_en2: dec a jnz check_hscroll_en3 mov c, hscroll_en2 sjmp check_hscroll_donecheck_hscroll_en3: dec a jnz check_hscroll_en4 mov c, hscroll_en3 sjmp check_hscroll_donecheck_hscroll_en4: dec a jnz check_hscroll_en5 mov c, hscroll_en4 sjmp check_hscroll_donecheck_hscroll_en5: dec a jnz check_hscroll_en6 mov c, hscroll_en5 sjmp check_hscroll_donecheck_hscroll_en6: dec a jnz check_hscroll_en7 mov c, hscroll_en6 sjmp check_hscroll_donecheck_hscroll_en7: dec a jnz check_hscroll_done mov c, hscroll_en7check_hscroll_done: pop acc ret;***********************************************************************;** **;** Handle Control Characters **;** **;***********************************************************************exec_cmd: mov r0, #cmd_buf mov a, @r0 cjne a, #0x5C, exec_ctrl ajmp exec_5c_cmdexec_ctrl: ;ESC Sequenceescape: cjne a, #27, ctrl_char ajmp exec_escctrl_char: jnb ignore_input_mode, ctrl_a mov cmd_len, #0 ret ;CTRL-A: Cursor Homectrl_a: cjne a, #1, ctrl_h lcall display_on lcall move_cursor_home mov cmd_len, #0 ret ;CTRL-H: Backspacectrl_h: cjne a, #8, ctrl_i mov a, #1 lcall move_cursor_left mov cmd_len, #0 ret ;CTRL-I: Tabctrl_i: cjne a, #9, ctrl_j mov a, x_pos anl a, #00000011b cpl a inc a add a, #4 lcall move_cursor_right mov cmd_len, #0 ret ;CTRL-J: Line Feedctrl_j: cjne a, #10, ctrl_k mov a, #1 lcall move_cursor_down mov cmd_len, #0 ret ;CTRL-K: Up one linectrl_k: cjne a, #11, ctrl_l mov a, #1 lcall move_cursor_up mov cmd_len, #0 ret ;CTRL-L: Form Feed (clear display)ctrl_l: cjne a, #12, ctrl_m lcall init_display lcall move_cursor_home mov cmd_len, #0 ret ;CTRL-M: Carriage Returnctrl_m: cjne a, #13, ctrl_u lcall cursor_to_start_of_line mov cmd_len, #0 ret ;CTRL-U: Forwardctrl_u: cjne a, #21, crtl_unknown mov a, #1 lcall move_cursor_right mov cmd_len, #0 retcrtl_unknown: ;just ignore unknown control characters mov cmd_len, #0 ret;***********************************************************************;** **;** Handle Escape Sequences **;** **;*********************************************************************** ;0x1B 0x5B 0x41, move up one line ;0x1B 0x5B 0x42, move down one line ;0x1B 0x5B 0x43, move right one line ;0x1B 0x5B 0x44, move left one line ;0x1B 0x5B 0x48, cursor home ;0x1B 0x5B 0x30 0x3B 0x37 0x6B, begin inverse text ;0x1B 0x5B 0x30 0x6B, begin normal text ;0x1B 0x5B 0x32 0x4A, clear screenexec_esc: mov a, cmd_len add a, #254 jc exec_esc_1 ret ;if len < 2, wait for moreexec_esc_1: mov a, cmd_len add a, #240 jnc exec_esc_2 ;check if len >= 16 mov cmd_len, #0 ;if len > 16, ignore input retexec_esc_2: mov r0, #cmd_buf+1 mov a, @r0 cjne a, #0x5B, exec_esc_esc ajmp exec_esc_5Bexec_esc_esc: cjne a, #0x1B, exec_esc_unknown mov a, #location >> 8 jnz exec_esc_abort dec cmd_len ;ignore the 2nd ESC retexec_esc_abort: ljmp 0 ;return to PAULMON2 on two ESCsexec_esc_unknown: ;just ignore unknown escape sequences mov cmd_len, #0 retexec_esc_5B: ;TODO: this parsing really ought to allow numeric and ';' ;characters and conclude that we have a complete escape ;sequence when we get a alpha character A-Z or a-z. mov a, cmd_len add a, #253 jc exec_esc_5B_2 ret ;if len < 3, wait for moreexec_esc_5B_2: mov r0, #cmd_buf+2 mov a, @r0exec_esc_5B_41: cjne a, #0x41, exec_esc_5B_42 jb ignore_input_mode, exec_esc_unknown mov a, #1 lcall move_cursor_up mov cmd_len, #0 retexec_esc_5B_42: cjne a, #0x42, exec_esc_5B_43 jb ignore_input_mode, exec_esc_unknown mov a, #1 lcall move_cursor_down mov cmd_len, #0 retexec_esc_5B_43: cjne a, #0x43, exec_esc_5B_44 jb ignore_input_mode, exec_esc_unknown mov a, #1 lcall move_cursor_right mov cmd_len, #0 retexec_esc_5B_44: cjne a, #0x44, exec_esc_5B_unknown jb ignore_input_mode, exec_esc_unknown mov a, #1 lcall move_cursor_left mov cmd_len, #0 retexec_esc_5B_unknown: ;just ignore unknown escape sequences mov cmd_len, #0 ret;***********************************************************************;** **;** Handle Custom Display Commands **;** **;***********************************************************************exec_5c_cmd: mov a, cmd_len add a, #254 jc exec_5c_cmd_1 ret ;if len < 2, wait for moreexec_5c_cmd_1: mov a, cmd_len add a, #240 jnc exec_5c_cmd_2 ;check if len >= 16 mov cmd_len, #0 ;if len > 16, ignore input ret ;cmd 0x5C <0x20-0x3F>, display bytes 0 to 31exec_5c_cmd_2: mov r0, #cmd_buf+1 mov a, @r0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -