📄 jw002.asm
字号:
clr c retb2f_nope: clr a setb c ret ;carry set if invalid inputasc2hex: add a, #208 jnc hex_not add a, #246 jc hex_maybe add a, #10 clr c rethex_maybe: add a, #249 jnc hex_not add a, #250 jc hex_not add a, #16 clr c rethex_not:setb c retlcd_pstr: clr a movc a, @a+dptr inc dptr jz lcd_pstr_end push dph push dpl lcall lookup_char lcall cache_char pop dpl pop dph sjmp lcd_pstrlcd_pstr_end: ret;***********************************************************************;** **;** Cursor Movement **;** **;***********************************************************************move_cursor_home: mov x_pos, #0 mov y_pos, #0 retcursor_to_start_of_line: mov x_pos, #0 ret ;move the cursor right by Acc positionsmove_cursor_right: mov r7, a ;keep num positions in r7 add a, x_pos add a, #232 jc mov_rt_2 add a, #24 mov x_pos, a ;easy case, no wrap around retmov_rt_2: ;the x movement puts the cursor off screen jb wrap_mode, mov_rt_3 mov x_pos, #23 ;right edge when wrap mode off retmov_rt_3: mov a, #1 lcall move_cursor_down mov a, #24 clr c subb a, x_pos mov r0, a mov a, r7 clr c subb a, r0 mov x_pos, #0 sjmp move_cursor_right ;move the cursor left by Acc positionsmove_cursor_left: mov r7, a ;keep num positions in r7 mov a, x_pos clr c subb a, r7 jc mov_lf_2 mov x_pos, a ;easy case, no wrap around retmov_lf_2: ;the x movement puts the cursor off screen jb wrap_mode, mov_lf_3 mov x_pos, #0 ;left edge when wrap mode off retmov_lf_3: mov a, #1 lcall move_cursor_up mov a, r7 setb c subb a, x_pos mov x_pos, #23 sjmp move_cursor_left ;move the cursor down by Acc positionsmove_cursor_down: mov r6, a ;keep num positions in r6 add a, y_pos add a, #248 jc mov_dn_2 add a, #8 mov y_pos, a ;easy case, didn't hit the bottom retmov_dn_2: jb vscroll_mode, mov_dn_sch jb wrap_mode, mov_dn_wrap mov y_pos, #7 ;bottom edge if no wrap or vertical scroll retmov_dn_sch: mov a, #7 clr c subb a, y_pos mov r0, a mov a, r6 clr c subb a, r0 mov r6, a mov y_pos, #7 lcall vscroll_normal dec r6 mov a, r6 jnz move_cursor_down retmov_dn_wrap: mov a, #8 clr c subb a, y_pos mov r0, a mov a, r6 clr c subb a, r0 mov y_pos, #0 sjmp move_cursor_down ;move the cursor up by Acc positionsmove_cursor_up: mov r6, a ;keep num positions in r6 mov a, y_pos clr c subb a, r6 jc mov_up_2 mov y_pos, a ;easy case, didn't hit the top retmov_up_2: jb vscroll_mode, mov_up_sch jb wrap_mode, mov_up_wrap mov y_pos, #0 ;top edge if no wrap or scroll retmov_up_sch: mov a, r6 clr c subb a, y_pos mov r6, a mov y_pos, #0 lcall vscroll_reverse dec r6 mov a, r6 jnz move_cursor_up retmov_up_wrap: mov a, r6 setb c subb a, y_pos mov y_pos, #7 sjmp move_cursor_up;**************************************************************************;** **;** LCD Display Controller (KS0108B) Routines **;** **;** Refer to **;** http://www.usa.samsungsemi.com/products/prodspec/graflcd/ks0108b.pdf **;** **;**************************************************************************;; Display is rotated 90 degrees WRT controller - our x is display column Y, our y, display row X;; Characters are formed as an 8x5 cell - Y column position is determined by 5 * x_pos; - X row position is determined using vertical scrolldraw_char: mov a, x_pos add a, #244 ; x < 12 then left side jnc draw_char_left add a, #244 ; 12 <= x < 24 then right side jnc draw_char_right retdraw_char_left: lcall left_busy mov dptr, #left_cmd_wr mov a, x_pos ;find Y column address of character x_pos mov b, #5 mul ab anl a, #00111111b orl a, #0x40 ;set display Y address (display is rotated 90 degress) movx @dptr, a lcall left_busy mov dptr, #left_cmd_wr mov a, vscroll_offset ;find X row address for character y_pos swap a rl a add a, y_pos anl a, #00000111b orl a, #0xB8 ;set display X address (display is rotated 90 degrees) movx @dptr, a ;write 5 vertical slices of character lcall left_busy mov dptr, #left_data_wr mov a, char_buf+0 movx @dptr, a lcall left_busy mov dptr, #left_data_wr mov a, char_buf+1 movx @dptr, a lcall left_busy mov dptr, #left_data_wr mov a, char_buf+2 movx @dptr, a lcall left_busy mov dptr, #left_data_wr mov a, char_buf+3 movx @dptr, a lcall left_busy mov dptr, #left_data_wr mov a, char_buf+4 movx @dptr, a retdraw_char_right: lcall right_busy mov dptr, #right_cmd_wr mov a, x_pos ;find Y column address of character x_pos add a, #244 mov b, #5 mul ab anl a, #00111111b orl a, #0x40 ;set display Y address (display is rotated 90 degress) movx @dptr, a lcall right_busy mov dptr, #right_cmd_wr mov a, vscroll_offset ;find X row address for character y_pos swap a rl a add a, y_pos anl a, #00000111b orl a, #0xB8 ;set display X address (display is rotated 90 degrees) movx @dptr, a ;write 5 vertical slices of character lcall right_busy mov dptr, #right_data_wr mov a, char_buf+0 movx @dptr, a lcall right_busy mov dptr, #right_data_wr mov a, char_buf+1 movx @dptr, a lcall right_busy mov dptr, #right_data_wr mov a, char_buf+2 movx @dptr, a lcall right_busy mov dptr, #right_data_wr mov a, char_buf+3 movx @dptr, a lcall right_busy mov dptr, #right_data_wr mov a, char_buf+4 movx @dptr, a retleft_busy: mov dptr, #left_cmd_rdlbusy2i:movx a, @dptr jb acc.7, lbusy2i retright_busy: mov dptr, #right_cmd_rdrbusy2i:movx a, @dptr jb acc.7, rbusy2i ret;; clear the row specified by a;clear_row: mov dph, #display_cache mov r7, a swap a clr c rlc a rlc a mov dpl, a mov b, a mov a, #0 mov r6, #60 jnc clear_row_next1 inc dphclear_row_next1: movx @dptr, a inc dpl djnz r6, clear_row_next1 mov r6, #60 orl dph, #2 mov dpl, bclear_row_next2: movx @dptr, a inc dpl djnz r6, clear_row_next2 jnb update_mode, clear_row_done acall redraw_rowclear_row_done: retredraw: mov r7, #7 ;row counter start at 7redraw_next_row: ;lcall watchdog ; should not be needed, since T0 ISR does it lcall redraw_row dec r7 cjne r7, #0xff, redraw_next_row ret ;redraw the row r7redraw_row: lcall right_busy mov dptr, #right_cmd_wr mov a, #0x40 ;right start at first column movx @dptr, a lcall left_busy mov dptr, #left_cmd_wr mov a, #0x40 ;left start at first column movx @dptr, a lcall right_busy mov dptr, #right_cmd_wr mov a, r7 ;right move to current row orl a, #0xb8 movx @dptr, a lcall left_busy mov dptr, #left_cmd_wr mov a, r7 ;left move to current row orl a, #0xb8 movx @dptr, a mov redraw_addr, #display_cache mov a, r7 swap a rlc a rlc a anl a, #11000000b mov redraw_addr+1, a jnc redraw_next_column inc redraw_addr ;ripple into MSBredraw_next_column: mov dph, redraw_addr mov dpl, redraw_addr+1 orl dph, #2 ;point to right side cache movx a, @dptr mov b, a lcall right_busy mov a, b mov dptr, #right_data_wr movx @dptr, a mov dph, redraw_addr ;point to left side cache mov dpl, redraw_addr+1 movx a, @dptr inc dptr mov redraw_addr, dph mov redraw_addr+1, dpl mov b, a lcall left_busy mov a, b mov dptr, #left_data_wr movx @dptr, a mov a, redraw_addr+1 anl a, #0x3f ;60 columns per row cjne a, #60, redraw_next_column retvscroll_normal: mov a, vscroll_offset add a, #8 anl a, #0x3F mov vscroll_offset, a lcall update_vscroll_offset mov r0, #7 ;r0 is line # to clear sjmp vscroll_clear_linevscroll_reverse: mov a, vscroll_offset add a, #248 anl a, #0x3F mov vscroll_offset, a lcall update_vscroll_offset mov r0, #0 ;r0 is line # to clearvscroll_clear_line: lcall left_busy mov dptr, #left_cmd_wr mov a, #0x40 movx @dptr, a lcall right_busy mov dptr, #right_cmd_wr mov a, #0x40 movx @dptr, a lcall left_busy mov dptr, #left_cmd_wr mov a, vscroll_offset swap a rl a add a, r0 anl a, #00000111b orl a, #0xB8 movx @dptr, a lcall right_busy mov dptr, #right_cmd_wr mov a, vscroll_offset swap a rl a add a, r0 anl a, #00000111b orl a, #0xB8 movx @dptr, a mov r3, #64 ;r3 counts horizontal positionvscroll_loop: lcall left_busy mov dptr, #left_data_wr clr a movx @dptr, a ;clear left side lcall right_busy mov dptr, #right_data_wr clr a movx @dptr, a ;clear right side djnz r3, vscroll_loop retupdate_vscroll_offset: lcall left_busy mov dptr, #left_cmd_wr mov a, vscroll_offset anl a, #0x3F orl a, #0xC0 movx @dptr, a ;set top of display at y=0 lcall right_busy mov dptr, #right_cmd_wr mov a, vscroll_offset anl a, #0x3F orl a, #0xC0 movx @dptr, a ;set top of display at y=0 retinit_display: mov hscroll_en, #0 mov vscroll_offset, #0 lcall update_vscroll_offset lcall clear_cached_display jb update_mode, init1 ;if update is enabled then update display retinit1: mov r2, #0 ;r2 counts line numberinit2: lcall left_busy mov dptr, #left_cmd_wr mov a, #0x40 movx @dptr, a lcall right_busy mov dptr, #right_cmd_wr mov a, #0x40 movx @dptr, a lcall left_busy mov dptr, #left_cmd_wr mov a, r2 orl a, #0xB8 movx @dptr, a lcall right_busy mov dptr, #right_cmd_wr mov a, r2 orl a, #0xB8 movx @dptr, a mov r3, #64 ;r3 counts horizontal positioninit3: lcall left_busy mov dptr, #left_data_wr clr a movx @dptr, a ;clear left side lcall right_busy mov dptr, #right_data_wr clr a movx @dptr, a ;clear right side djnz r3, init3 inc r2 cjne r2, #8, init2 mov lcd_on_timer, #0display_on: lcall left_busy mov dptr, #left_cmd_wr mov a, #0x3F movx @dptr, a ;turn on display lcall right_busy mov dptr, #right_cmd_wr mov a, #0x3F movx @dptr, a ;turn on display clr turn_lcd_on ret;***********************************************************************;** **;** Pushbuttons **;** **;***********************************************************************timer0_setup: clr ea setb pb_recv_1 setb pb_recv_2 setb pb_recv_3 setb pb_recv_4 clr pb_xmit_1 setb pb_xmit_2 setb pb_xmit_3 mov pb_scan_state, #0 orl tmod, #00000001b anl tmod, #11110001b clr tr0 clr tf0 clr a mov pb_event_head, a mov pb_event_tail, a mov pb_state+0, a mov pb_state+1, a mov pb_state+2, a mov pb_state+3, a mov pb_state+4, a mov pb_state+5, a mov pb_state+6, a mov pb_state+7, a mov pb_state+8, a mov pb_state+9, a mov pb_state+10, a mov pb_state+11, a mov pb_config+0, a mov pb_config+1, a mov pb_config+2, a mov pb_config+3, a mov pb_config+4, a mov pb_config+5, a mov pb_config+6, a mov pb_config+7, a mov pb_config+8, a mov pb_config+9, a mov pb_config+10, a mov pb_config+11, a clr pt0 setb et0 setb ea setb tr0 lcall copy_strings_to_sram rettimer0_isr: push psw push acc push reg0 push reg1 clr tr0 mov th0, #0xF4 ;run this code at approx 300 Hz mov tl0, #0x12 setb tr0 jnb cin_serviced, t0_lcd_on ;clear the watchdog timer, but only if the main program has been ;running "cin" (accepting user input) and of course this timer ;interrupt routine is still working. lcall watchdog clr cin_servicedt0_lcd_on: inc lcd_on_timer mov a, lcd_on_timer cjne a, #12, pb_row_1 mov lcd_on_timer, #0 setb turn_lcd_ont0_hscroll: mov a, hscroll_en jz pb_row_1 inc hscroll_t0_count mov a, hscroll_t0_count clr c subb a, hscroll_speed jnz pb_row_1 mov hscroll_t0_count, #0 setb hscroll_redrawpb_row_1: mov a, pb_scan_state cjne a, #0, pb_row_2 mov c, pb_recv_1 mov r0, #pb_state+10 mov r1, #pb_config+10 lcall pushbutton mov c, pb_recv_2 mov r0, #pb_state+4 mov r1, #pb_config+4 lcall pushbutton mov c, pb_recv_3 mov r0, #pb_state+1 mov r1, #pb_config+1 lcall pushbutton mov c, pb_recv_4 mov r0, #pb_state+0 mov r1, #pb_config+0 lcall pushbutton mov pb_scan_state, #1 setb pb_xmit_1 clr pb_xmit_2 setb pb_xmit_3 pop reg1 pop reg0 pop acc pop psw retipb_row_2: cjne a, #1, pb_row_3 mov c, pb_recv_1 mov r0, #pb_state+6 mov r1, #pb_config+6 lcall pushbutton mov c, pb_recv_2 mov r0, #pb_state+5 mov r1, #pb_config+5 lcall pushbutton mov c, pb_recv_3 mov r0, #pb_state+8 mov r1, #pb_config+8
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -