'**************************************************************************** 'T69B_LIB.BAS Graphic library of subroutines for use with a Toshiba T6963C 'graphic LCD controller connected to a Microchip(TM) PIC 16F877 microcontroller 'Version 1.0 'Written in MELabs PicBasicPro(TM) Ver 2.47 'GLUTIL.EXE Ver 1.1 is an Windows based interface that is used with T69_demo.BAS '============================================================================ ' 'The Graphic Library contains and initializes all the variables used. ' '================== NOT FOR COMMERICIAL USE ================================= ' ' Author: Ranjit Diol, COMPSys Date: April, 2007 ' (c) Copyright COMPSys, April 2007 ' ' DISCLAIMER: This file is being released as non-commericial ' software. It is being provided "AS IS", neither the author, ' nor COMPSys shall be held liable for any damages caused ' by its use. ' ' This product is issued as a single license and can not ' be distributed to others without the explicit consent of ' COMPSys. ' ' SINGLE USER LICENSE: This application may be used in its entirety or ' in parts within some other non-commercial application(s) as long ' as the those applications are used solely by the licensee. ' ' ' Contact: rsdiol@compsys1.com for more information '=============================================================================== '************************ ' LCD Module constants * '************************ ' 'Register set commands: CURSOR_PTR_SET con $21 'Cursor Pointer Set OFFSET_REG_SET con $22 'Offset Register Set ADDR_PTR_SET con $24 'Address Pointer Set 'Control Word Set commands: TEXT_HOME_SET con $40 'Text Home Address Set TEXT_AREA_SET con $41 'Text Area Set GRAPH_HOME_SET con $42 'Graphics Home address Set GRAPH_AREA_SET con $43 'Graphics Area Set 'Mode Set commands (OR with CG rom commands): OR_MODE con $80 'OR mode XOR_MODE con $81 'XOR mode AND_MODE con $83 'AND mode TEXT_ATTR_MODE con $84 'Text Attribute mode INT_CG_MODE con $80 'Internal CG ROM mode EXT_CG_MODE con $88 'External CG ROM mode 'Display Mode commands (OR together required bits): DISPLAY_OFF con $90 'display off BLINK_ON con $91 CURSOR_ON con $92 TEXT_ON con $94 GRAPHIC_ON con $98 TEXT_AND_GRAPH_ON con $9C 'Cursor Pattern Select CURSOR_1LINE con $A0 CURSOR_2LINE con $A1 CURSOR_3LINE con $A2 CURSOR_4LINE con $A3 CURSOR_5LINE con $A4 CURSOR_6LINE con $A5 CURSOR_7LINE con $A6 CURSOR_8LINE con $A7 'Data Auto Read/Write DATA_AUTO_WR con $B0 DATA_AUTO_RD con $B1 AUTO_DATA_RESET con $B2 'Data Read/Write DATA_WR_INC con $C0 'Data write and increment addr DATA_RD_INC con $C1 'Data read and increment addr DATA_WR_DEC con $C2 'Data write and decrement addr DATA_RD_DEC con $C3 'Data read and decrement addr DATA_WR con $C4 'Data write - no addr change DATA_RD con $C5 'Data read - no addr change 'Screen Peek SCREEN_PEEK con $E0 'Screen Copy SCREEN_COPY con $E8 'Bit Set/Reset (OR with bit number 0-7) BIT_RESET con $F0 BIT_SET con $F8 '************************ ' STATUS bits * '************************ STA0 con 0 'command excution status STA1 con 1 'data read/write status STA2 con 2 'auto data read status STA3 con 3 'auto data write status STA5 con 5 'controller status STA6 con 6 'peek/copy error flag STA7 con 7 'blink? or blank? status ASCII_OFFSET con $20 'ASCII offset for conversion GL_PAUSE con 2 GL_ROW con 32 GL_COL con 64 GL_XMAX con 239 GL_XMIN con 0 GL_YMAX con 63 GL_YMIN con 0 GL_LINES con 8 'Serial I/O definitions out_pin var PORTC.6 'Serial OUT pin in_pin var PORTC.7 'Serial IN pin ser_baud con 32 '16448 = 19200 Baud INVERTED, 32 = NON INV in_dat var BYTE 'In coming byte data in_ser var BYTE[15] 'In coming data buffer in_lsb var BYTE 'In coming lsb of word in_msb var BYTE 'In coming msb of word gl_chr var BYTE 'Character byte eep_addr var WORD 'External eeprom address b_inp1 var BYTE b_inp2 var BYTE b_inp3 var BYTE 'Variables used ' *** MODIFY AS REQUIRED FOR OTHER PINS AND PORTS ***** ' 'Variables used ' *** MODIFY AS REQUIRED FOR OTHER PINS AND PORTS ***** ' glcd_tris var TRISB 'Data bus direction glcd_dat var PORTB 'LCD 8 bit data bus glcd_wr var PORTC.2 'Write control bit glcd_rd var PORTC.5 'Read control bit glcd_ce var PORTC.0 'Chip enable control bit glcd_cd var PORTC.1 'Command and Data toggle bit glcd_rst var PORTA.0 'Reset control bit glcd_bsy var PORTB.7 'In case there is a need, not really used glcd_sta0 var PORTB.0 'Status Bit 0 glcd_sta1 var PORTB.1 'Status Bit 1 glcd_sta2 var PORTB.2 'Status Bit 2 glcd_sta3 var PORTB.3 'Status Bit 3 'I2C EEprom scl VAR PORTC.3 'I2C SCL for ext eeprom sda VAR PORTC.4 'I2C SDA for ext eeprom ctl CON $A0 'EEprom control code 'Set appropriate port/bit dir TRISB = 0 TRISC = 0 TRISA.0 = 0 'General use variables used glcd_msb var BYTE 'Data 1 variable glcd_lsb var BYTE 'Data 2 variable glcd_cmd var BYTE 'Command variable gl_tmp var BYTE 'Temp var gl_old var BYTE 'Previous byte var gl_x var WORD '16 bit var for address loop gl_y var WORD '16 bit var for address loop gl_i var BYTE gl_j var BYTE gl_k var BYTE gl_l var BYTE gl_m var BYTE num_1 var BYTE num_2 var BYTE gl_stp var BYTE 'Step var in FOR..NEXT gl_ad1 var BYTE 'Addr var gl_ad2 var BYTE 'Addr var graph_home var WORD 'LCD graphic start addr graph_area var WORD 'LCD graphic bytes per line text_home var WORD 'LCD text start addr text_area var WORD 'LCD text chars per line gl_xpos var BYTE gl_ypos var BYTE gl_addr var WORD lcd_cmd var BYTE rs_flag var BYTE 'Reset pixel flag gl_byte var BYTE 'Graphic byte gl_char var BYTE 'Text byte g_char var BYTE ptr_flag var BYTE 'Addr ptr flag gl_oldaddr var WORD 'Var to keep track of address gl_oldx var BYTE 'Variables to keep track gl_oldy var BYTE 'of x and y values glcd_fs var BYTE 'LCD font size glcd_fs = 0 '0=8x8 character space, 1=6x8 g_count var WORD gl_flag var BYTE ee_addr1 var WORD ee_addr2 var WORD ee_addr var WORD unset_flag var BYTE 'Initialize variables gl_tmp = 0 gl_i = 0 gl_stp = 1 rs_flag = 0 ptr_flag = DATA_WR gl_flag = 0 unset_flag = 0 'Circle constants and variables gl_pi con 2 'PI as an integer glc_x var BYTE 'Calculation var glc_y var BYTE 'Calculation var glc_s var WORD 'Slope glc_cx var BYTE 'Center x glc_cy var BYTE 'Center y glc_r var BYTE 'Radius g_num var WORD 'Line variables gl_x1 var BYTE gl_x2 var BYTE gl_y1 var BYTE gl_y2 var BYTE gl_inc1 var WORD gl_inc2 var WORD 'Chart Variables s_xstart var BYTE s_xend var BYTE s_ystart var BYTE s_yend var BYTE s_tick var BYTE 'FS offsets font_size var BYTE font_byte var BYTE 'Terminal variables in_array var BYTE[32] 'In coming array in_ctl var BYTE[8] 'In coming control array buff_count var BYTE 'General counter gl_delay var BYTE 'Delay variable gl_idx var BYTE 'General use gl_idy var BYTE 'General use 'Initialize variables gl_tmp = 0 gl_i = 0 rs_flag = 0 ptr_flag = DATA_WR 'Initial settings of port and bits glcd_dat = 0 'Clear LCD DATA PORT glcd_wr = 1 'Write high glcd_rd = 1 'Read high glcd_ce = 1 'Chip enable high (active low) glcd_cd = 1 'Command high glcd_rst = 1 'RESET always high (low will reset the LCD controller) pause 500 'Let things stabilize 'Initialize LCD VRAM area variables glcd_fs = 0 graph_home = $1000 'Decimal 4096 text_home = $0000 if glcd_fs = 0 then font_size = 8 font_byte = 7 graph_area = $0020 '32 bytes per line text_area = $0020 '32 8x8 chars per line else font_size = 6 font_byte = 5 graph_area = $0028 '40 bytes per line text_area = $0028 '40 6x8 chars per line endif glcd_rst = 0 ' Reset after power-on pause 100 glcd_rst = 1 '*** jump past the routines below *** goto continue_to_main '*********** PBP Subroutines used in this program ******* send_2: gosub busy_chk glcd_dat = glcd_lsb glcd_cd = 0 glcd_rd = 1 glcd_ce = 0 glcd_wr = 0 'pauseus GL_PAUSE glcd_wr = 1 glcd_ce = 1 send_1: gosub busy_chk glcd_dat = glcd_msb glcd_cd = 0 glcd_rd = 1 glcd_ce = 0 glcd_wr = 0 'pauseus GL_PAUSE glcd_wr = 1 glcd_ce = 1 send_cmd: gosub busy_chk glcd_dat = glcd_cmd glcd_rd = 1 glcd_ce = 0 glcd_wr = 0 'pauseus GL_PAUSE glcd_wr = 1 glcd_ce = 1 return busy_chk: glcd_ce = 1 glcd_tris= %11111111 glcd_cd = 1 glcd_wr = 1 glcd_ce = 0 glcd_rd = 0 'pauseus GL_PAUSE if (glcd_sta0 <> 1) AND (glcd_sta1 <> 1) then busy_chk glcd_rd = 1 glcd_ce = 1 glcd_tris = %00000000 return read1: gosub busy_chk 'On return Ce =1. rd = 1, wr = 1, CD = 1 glcd_tris = %11111111 glcd_cd = 0 glcd_rd = 0 glcd_ce = 0 pauseus GL_PAUSE gl_chr = glcd_dat glcd_ce = 1 glcd_rd = 1 glcd_tris = %00000000 return read_lcd: 'Assumes gl_x and gl_y and ptr_flag are given. Returns gl_chr gosub gl_gaddr 'glcd_cmd = ptr_flag 'gosub send_cmd gosub read1 return gl_resetdot: rs_flag = 1 gl_setdot: 'Set a pixel given gl_x,gl_y gl_addr = graph_home + (gl_y * GL_ROW) + (gl_x/font_size) gl_oldaddr = gl_addr gl_oldx = gl_x gl_oldy = gl_y glcd_msb = gl_addr.BYTE1 glcd_lsb = gl_addr.BYTE0 glcd_cmd = ADDR_PTR_SET gosub send_2 'Check for reset flag if rs_flag = 0 then glcd_cmd = ($f8 | (font_byte - (gl_x//font_size))) else glcd_cmd = ($f0 | (font_byte - (gl_x//font_size))) endif gosub send_cmd rs_flag = 0 'Reset flag return 'Set address given x,y coordinates gl_gaddr: gl_addr = graph_home + (gl_y * GL_ROW) + (gl_x/font_size) gl_oldaddr = gl_addr glcd_msb = gl_addr.BYTE1 glcd_lsb = gl_addr.BYTE0 glcd_cmd = ADDR_PTR_SET gosub send_2 return set8: gl_x = glc_x+glc_cx : gl_y=glc_y+glc_cy '1 gosub gl_setdot gl_x = glc_cx-glc_x : gl_y=glc_y+glc_cy '2 gosub gl_setdot gl_x = glc_cx+glc_x : gl_y=glc_cy-glc_y '3 gosub gl_setdot gl_x = glc_cx-glc_x : gl_y=glc_cy-glc_y '4 gosub gl_setdot gl_x = glc_y+glc_cx : gl_y=glc_x+glc_cy '5 gosub gl_setdot gl_x = glc_cx-glc_y : gl_y=glc_cy+glc_x '6 gosub gl_setdot gl_x = glc_cx+glc_y : gl_y=glc_cy-glc_x '7 gosub gl_setdot gl_x = glc_cx-glc_y : gl_y=glc_cy-glc_x '8 gosub gl_setdot return reset8: gl_x = glc_x+glc_cx : gl_y=glc_y+glc_cy '1 gosub gl_resetdot gl_x = glc_cx-glc_x : gl_y=glc_y+glc_cy '2 gosub gl_resetdot gl_x = glc_cx+glc_x : gl_y=glc_cy-glc_y '3 gosub gl_resetdot gl_x = glc_cx-glc_x : gl_y=glc_cy-glc_y '4 gosub gl_resetdot gl_x = glc_y+glc_cx : gl_y=glc_x+glc_cy '5 gosub gl_resetdot gl_x = glc_cx-glc_y : gl_y=glc_cy+glc_x '6 gosub gl_resetdot gl_x = glc_cx+glc_y : gl_y=glc_cy-glc_x '7 gosub gl_resetdot gl_x = glc_cx-glc_y : gl_y=glc_cy-glc_x '8 gosub gl_resetdot return 'Initialize and clear display gl_init: 'Initialization 'See data sheets for more info for the commands and parameters ' Set Graphic Home Addr glcd_msb = graph_home.BYTE1 glcd_lsb = graph_home.BYTE0 glcd_cmd = GRAPH_HOME_SET gosub send_2 ' Set Graphic Area glcd_msb = graph_area.BYTE1 glcd_lsb = graph_area.BYTE0 glcd_cmd = GRAPH_AREA_SET gosub send_2 ' Set Text Home Addr glcd_msb = text_home.BYTE1 glcd_lsb = text_home.BYTE0 glcd_cmd = TEXT_HOME_SET gosub send_2 ' Set Text Area glcd_msb = text_area.BYTE1 glcd_lsb = text_area.BYTE0 glcd_cmd = TEXT_AREA_SET gosub send_2 ' Set OR mode glcd_cmd = OR_MODE gosub send_cmd grf_clr: ' Set Addr Ptr glcd_msb = $00 glcd_lsb = $00 glcd_cmd = ADDR_PTR_SET gosub send_2 ' Set Graphic mode on glcd_cmd = GRAPHIC_ON gosub send_cmd for gl_i = 1 to 240 ' Clear Graphic Screen for gl_j = 1 to 64 glcd_msb = $00 'Clear byte glcd_cmd = DATA_WR_INC 'Command gosub send_1 'Send glcd_msb followed by glcd_cmd next next 'Do it 240x64 times ' Set Graphic mode on glcd_cmd = TEXT_AND_GRAPH_ON gosub send_cmd return 'End of Init routine '*** gl_circle d = diameter r = radius x,y are point locations *** '***** Given Center = glc_cx,glc_cy and Radius = glc_r ********** gl_circ: glc_x = 0 glc_y = glc_r glc_s = gl_pi-2*glc_r while (glc_x <= glc_y) if unset_flag = 0 then gosub set8 else gosub reset8 endif if (glc_s.15 =1) then glc_s = glc_s + (4*glc_x + 6) else glc_s = glc_s + (4*(glc_x-glc_y) + 10) glc_y = glc_y - 1 endif glc_x = glc_x + 1 wend return '*** 4 sided Star *** '***** Given Center = gl_cx,gl_cy and Radius = gl_r ********** gl_star4: glc_x = 0 glc_y = glc_r glc_s = gl_pi-2*glc_r while (glc_x <= glc_y) if unset_flag = 0 then gosub set8 else gosub reset8 endif glc_s = glc_s + (4*(glc_x-glc_y) + 10) glc_y = glc_y - 3 glc_x = glc_x + 1 wend return 'Line subroutines gl_line: gosub chk_xy 'Make sure x1,x2,y1,y2 values are correct gl_l = gl_x2 - gl_x1 gl_m = gl_y2 - gl_y1 if gl_m > gl_l then gl_line2 'If Y delta > X delta 'Assumes X delta > Y delta glc_s = ((gl_m<<2)-gl_l) gl_y = gl_y1 gl_inc1 = gl_m << 2 gl_inc2 = 2*(gl_m - gl_l) for gl_x = gl_x1 to gl_x2 if glc_s.15 = 1 then glc_s = glc_s + gl_inc1 else glc_s = glc_s + gl_inc2 gl_y = gl_y+1 endif if unset_flag = 0 then gosub gl_setdot else gosub gl_resetdot endif next return gl_line2: 'Assumes Y delta > X delta glc_s = ((gl_l<<2) - gl_m) gl_x = gl_x1 gl_inc1 = gl_l<<2 gl_inc2 = 2*(gl_l - gl_m) for gl_y = gl_y1 to gl_y2 if glc_s.15 = 1 then glc_s = glc_s + gl_inc1 else glc_s = glc_s + gl_inc2 gl_x = gl_x+1 endif if unset_flag = 0 then gosub gl_setdot else gosub gl_resetdot endif next return 'This routine checks if x1 > x2 and if y1 > y2 if so it swaps them chk_xy: if gl_x1 > gl_x2 then swap gl_x1,gl_x2 endif if gl_y1 > gl_y2 then swap gl_y1,gl_y2 endif return gl_txt_pos: gl_addr = (text_home + (gl_y/8 * GL_ROW) + gl_x/font_size) glcd_msb = gl_addr.BYTE1 glcd_lsb = gl_addr.BYTE0 glcd_cmd = ADDR_PTR_SET gosub send_2 return put_char: 'Assumes g_char,gl_x,gl_y and ptr_flag gosub txt_home gosub send_2 gosub txt_on gl_char = g_char - ASCII_OFFSET put_it: gosub gl_txt_pos 'Set text addr given gl_x,gl_y glcd_msb = gl_char glcd_cmd = ptr_flag gosub send_1 gosub grf_txt_on return 'Place a digit as ascii on the LCD put_5dig: 'Assumes g_num,gl_x,gl_y and ptr_flag g_char = g_num DIG 4 gosub lookup_dig gl_x = gl_x + 8 put_4dig: g_char = g_num DIG 3 gosub lookup_dig gl_x = gl_x + 8 put_3dig: g_char = g_num DIG 2 gosub lookup_dig gl_x = gl_x + 8 put_2dig: g_char = g_num DIG 1 gosub lookup_dig gl_x = gl_x + 8 put_1dig: g_char = g_num DIG 0 gosub lookup_dig return lookup_dig: lookup g_char,["0123456789"],gl_tmp gl_char = gl_tmp - $20 gosub put_it return put_byte: 'Assumes gl_x,gl_y and gl_byte and ptr_flag gosub txt_home gosub txt_on 'Graphic and Text mode gosub gl_gaddr 'Set address glcd_msb = gl_byte glcd_cmd = ptr_flag gosub send_1 gosub grf_txt_on return grf_on: gosub send_2 glcd_cmd = GRAPHIC_ON gosub send_cmd return txt_on: gosub txt_home glcd_cmd = TEXT_ON gosub send_cmd return grf_txt_on: gosub txt_home glcd_cmd = TEXT_AND_GRAPH_ON gosub send_cmd return '***** Convert incoming ascii to hex byte Routine ***** gl_find: Lookdown in_ser[gl_i],["0123456789abcdef"],in_dat return grf_home: ' Set Addr Ptr to graphic home glcd_msb = graph_home.BYTE1 glcd_lsb = graph_home.BYTE0 glcd_cmd = GRAPH_HOME_SET gosub send_2 return txt_home: ' Set Text Home Addr glcd_msb = text_home.BYTE1 glcd_lsb = text_home.BYTE0 glcd_cmd = TEXT_HOME_SET gosub send_2 ' Set Text Area 'glcd_msb = text_area.BYTE1 'glcd_lsb = text_area.BYTE0 'glcd_cmd = TEXT_AREA_SET 'gosub send_2 ' Set OR mode 'glcd_cmd = OR_MODE 'gosub send_cmd return 'Scale subroutines which draws an XY scale with tick marks 'Assumes values assigned to s_xtart, s_xend, s_ystart, s_yend, and s_tick 'and also that the addr ptr is set before drawing each axis 'Uses variables gl_x,gl_y and the gl_setdot subroutine gl_yaxis: 'Draw vertical Y axis 'Set addr ptr gl_x = s_xstart for gl_y = s_ystart to s_yend if unset_flag = 0 then gosub gl_setdot else gosub gl_resetdot endif next 'Add the tick marks to the Y axis gl_x = s_xstart+1 for gl_y = s_ystart to s_yend step s_tick if unset_flag = 0 then gosub gl_setdot else gosub gl_resetdot endif next return gl_xaxis: 'Draw horizontal X axis gl_y = s_yend for gl_x = s_xstart to s_xend if unset_flag = 0 then gosub gl_setdot else gosub gl_resetdot endif next 'Draw X axis tick marks gl_y = s_yend - 1 for gl_x = s_xstart to s_xend step s_tick if unset_flag = 0 then gosub gl_setdot else gosub gl_resetdot endif next return 'end of scale routines 'Bar subroutine given width, height and x,y locatation gl_bar: gosub chk_xy for gl_i= gl_x1 to gl_x2 step s_tick for gl_j= gl_y1 to gl_y2 step s_tick gl_x = gl_i gl_y = gl_j if unset_flag = 0 then gosub gl_setdot else gosub gl_resetdot endif next gl_j next gl_i return 'Rectangle subroutine given gl_x1,gl_x2,gl_y1, gl_y2 gl_rect: gosub chk_xy for gl_i= gl_x1 to gl_x2 step s_tick gl_x = gl_i gl_y = gl_y1 if unset_flag = 0 then gosub gl_setdot else gosub gl_resetdot endif gl_y = gl_y2 if unset_flag = 0 then gosub gl_setdot else gosub gl_resetdot endif next gl_i for gl_i= gl_y1 to gl_y2 step s_tick gl_y = gl_i gl_x = gl_x1 if unset_flag = 0 then gosub gl_setdot else gosub gl_resetdot endif gl_x = gl_x2 if unset_flag = 0 then gosub gl_setdot else gosub gl_resetdot endif next gl_i return '*** gl_gl_square45 turned 45 degrees *** '***** Given Center = gl_cx,gl_cy and Radius = gl_r ********** gl_square45: glc_x = 0 glc_y = glc_r glc_s = gl_pi-2*glc_r while (glc_x <= glc_y) if unset_flag = 0 then gosub set8 else gosub reset8 endif glc_s = glc_s + (4*(glc_x-glc_y) + 10) glc_y = glc_y - 1 glc_x = glc_x + 1 wend return '*** gl_square *** '***** Given Center = gl_cx,gl_cy and Radius = gl_r ********** gl_square: glc_x = 0 glc_y = glc_r glc_s = gl_pi-2*glc_r while (glc_x <= glc_y) if unset_flag = 0 then gosub set8 else gosub reset8 endif glc_s = glc_s + (4*glc_x + 6) glc_x = glc_x + 1 wend return '**** Following Code is used primarily for use with glt6963c.bas ******** '**** However, they can be adapted for use in other applications ******** 'Subroutines to get serial data send_one: serout2 out_pin,ser_baud,[HEX2 gl_chr] 'Send gl_chr out to I/O return get_one: serin2 in_pin,ser_baud,[wait("]"),STR in_ser\2] for gl_i = 0 to 1 'Convert to hex nibbles gosub gl_find in_ser[gl_i]=in_dat next gl_i 'Now convert to hex bytes b_inp1 = ((in_ser[0]<<4) | (in_ser[1])) return get_two: serin2 in_pin,ser_baud,[wait("]"),STR in_ser\4] for gl_i = 0 to 3 'Convert to hex nibbles gosub gl_find in_ser[gl_i]=in_dat next gl_i 'Now convert to hex bytes b_inp1 = ((in_ser[0]<<4) | (in_ser[1])) b_inp2 = ((in_ser[2]<<4) | (in_ser[3])) return get_three: serin2 in_pin,ser_baud,[wait("]"),STR in_ser\6] 'circle = ]c]40201e for gl_i = 0 to 5 'Convert to hex nibbles gosub gl_find in_ser[gl_i]=in_dat next gl_i 'Now convert to hex bytes b_inp1 = ((in_ser[0]<<4) | (in_ser[1])) b_inp2 = ((in_ser[2]<<4) | (in_ser[3])) b_inp3 = ((in_ser[4]<<4) | (in_ser[5])) return get_tick: serin2 in_pin,ser_baud,[wait ("]"),in_dat] 'Wait for ] and the load in_dat s_tick = in_dat - $30 'Strip ASCII value gl_chr = in_dat 'Load gl_chr with the char return get_four: serin2 in_pin,ser_baud,[wait("]"),STR in_ser\8] for gl_i = 0 to 7 'Convert to hex nibbles gosub gl_find in_ser[gl_i]=in_dat next gl_i 'Now convert to hex bytes gl_x1 = ((in_ser[0]<<4) | (in_ser[1])) gl_x2 = ((in_ser[2]<<4) | (in_ser[3])) gl_y1 = ((in_ser[4]<<4) | (in_ser[5])) gl_y2 = ((in_ser[6]<<4) | (in_ser[7])) return 'NOTE: These subroutines used by glt6963c.bas only c_assign: glc_cx = b_inp1 'Assign them glc_cy = b_inp2 glc_r = b_inp3 return xy_assign: gl_x = b_inp1 gl_y = b_inp2 return '********** End of PBP subroutines ********************* '======================================================== '************End of all subroutines ********************* '******************************************************** '************* Jump to INIT section ********************* '******************************************************** 'Entry point to the main program which can call the above subroutines as needed continue_to_main: