Hello Ryan, Below is the LCD code which will overcome the PCLATH problems that you have been experiencing when processing long text strings. It is a "prototype version" which Andy Warren helped me with, but the code will assemble and work perfectly. You can easily modify the code by replacing the "long winded" movlw message_1, call write_string instructions with something like: movlw .1 ;Initially start by displaying message number one movwf msg_cntr disp_loop ;Loop to display messages 1 to 5 movf msg_cntr,w ;Point to the desired display message in th e list call write_string ;Display the message call long_delay ;Call the long delay subroutine movlw CLR_DISP ;Clear the disply ready for next message call send_lcd_cmd call long_delay ;Call the long delay two times incf msg_cntr,f ;Increment the message counter by on e movf msg_cntr,w ;Get the current message number in the W r eg xorlw .5 ;Test to see if messages 1 to 5 have been displayed btfss status,z ;Have all messages 1 to 5 been displayed ? goto disp_loop1 ;No, thus display the next message in the sequence ;Yes, thus continue with the pro gram ;Your main program continues from here on....... Below is the code that displays the messages the "long winded way" for illustration purposes. Good luck Ryan, I hope that this helps you. Let me know how you get on, best wishes and take care: Lee Hewitt (Manchester ENGLAND) ------------------------------------------------------------------------------ ------------------------------------------ TITLE "Set-up of PCLATH for multi-length text strings" SUBTITLE "Page boundary crossing problems resolved - thank goodne ss !!" ;File Name: pcl_ok.asm LIST P=16c84, R=HEX include "p16c84.inc" include "a:\defs\lcd_defs.h" ERRORLEVEL -302 ;Supress incorrect bank selection message __config _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC ;LCD Message Equates message_1 equ 0x00 message_2 equ 0x01 message_3 equ 0x02 message_4 equ 0x03 message_5 equ 0x04 message_6 equ 0x05 message_7 equ 0x06 message_8 equ 0x07 message_9 equ 0x08 message_10 equ 0x09 message_11 equ 0x0A message_12 equ 0x0B message_13 equ 0x0C message_14 equ 0x0D ;LCD File Marker Equates EOMSG equ 0x04 EOLN equ 0x0D ;Other Equates RAM_BASE equ 0xC0 RAM_TOP equ 0x2F ;Defines #define ZERO STATUS,Z #define CARRY STATUS,C #define RPAGE STATUS,5 #define E_LINE PORTB,4 #define RS_LINE PORTB,5 #define RBPU 0X01,7 ;Bank switching defines #define PAGE_1 bsf STATUS,RP0 #define PAGE_0 bcf STATUS,RP0 ;Macro definitions pulse_e macro bsf E_LINE call short_delay bcf E_LINE endm ;variables cblock 0x0C ;Start of code block at address 0x0C msg_ptr char_ptr dly_cnt_1 dly_cnt_2 dly_cnt_3 temp temp1 endc ;----------------------------------------------------------------------------- ; reset vector ;----------------------------------------------------------------------------- org 00h goto reset ;----------------------------------------------------------------------------- ; program entry point ;----------------------------------------------------------------------------- reset bcf STATUS,RP1 ;Always maintain this bit clear for PIC16Cxx movlw 0x00 ;Initial set-up of I/O ports movwf PORTA ;Set-up of registers in Bank 1 PAGE_1 ;Select bank 1 movlw 0x00 movwf TRISA ;Port A - all pins unused, output 0 movwf TRISB ;Port B - all pins outputs (LCD Module) PAGE_0 ;Select bank 0 clrf INTCON ;**** Dissable ALL interupts **** movlw b'10000000' ;Disable weak pull-ups on Port B option ;Set-up LCD Module and display the initial Power Up message start call init_lcd ;Initialise LCD module call long_delay ;Wait for LCD to reliably initialise call long_delay ;Wait for LCD to reliably initialise movlw message_1 ;Display: "ROBOT:" message call write_string ;Call subroutine to write text string to LCD call long_delay call long_delay call long_delay call long_delay movlw CLR_DISP ;Clear the disply ready for next message call send_lcd_cmd call long_delay call long_delay movlw message_2 ;Display: "ROBOT:" message call write_string ;Call subroutine to write text srting to LCD call long_delay call long_delay call long_delay call long_delay movlw CLR_DISP ;Clear the disply ready for next message call send_lcd_cmd call long_delay call long_delay movlw message_3 call write_string ;Call subroutine to write text string to LCD call long_delay call long_delay call long_delay call long_delay movlw CLR_DISP ;Clear the disply ready for next message call send_lcd_cmd call long_delay call long_delay movlw message_4 call write_string ;Call subroutine to write text string to LCD call long_delay call long_delay call long_delay call long_delay movlw CLR_DISP ;Clear the disply ready for next message call send_lcd_cmd call long_delay call long_delay movlw message_5 call write_string ;Call subroutine to write text string to LCD call long_delay call long_delay call long_delay call long_delay movlw CLR_DISP ;Clear the disply ready for next message call send_lcd_cmd call long_delay call long_delay movlw message_6 call write_string ;Call subroutine to write text string to LCD call long_delay call long_delay call long_delay call long_delay movlw CLR_DISP ;Clear the disply ready for next message call send_lcd_cmd call long_delay call long_delay movlw message_7 call write_string ;Call subroutine to write text string to LCD call long_delay call long_delay call long_delay call long_delay movlw CLR_DISP ;Clear the disply ready for next message call send_lcd_cmd call long_delay call long_delay movlw message_8 call write_string ;Call subroutine to write text string to LCD call long_delay call long_delay call long_delay call long_delay movlw CLR_DISP ;Clear the disply ready for next message call send_lcd_cmd call long_delay call long_delay movlw message_9 call write_string ;Call subroutine to write text string to LCD call long_delay call long_delay call long_delay call long_delay movlw CLR_DISP ;Clear the disply ready for next message call send_lcd_cmd call long_delay call long_delay movlw message_10 call write_string ;Call subroutine to write text string to LCD call long_delay call long_delay call long_delay call long_delay movlw CLR_DISP ;Clear the disply ready for next message call send_lcd_cmd call long_delay call long_delay movlw message_11 call write_string ;Call subroutine to write text string to LCD call long_delay call long_delay call long_delay call long_delay movlw CLR_DISP ;Clear the disply ready for next message call send_lcd_cmd call long_delay call long_delay movlw message_12 call write_string ;Call subroutine to write text string to LCD call long_delay call long_delay call long_delay call long_delay movlw CLR_DISP ;Clear the disply ready for next message call send_lcd_cmd call long_delay call long_delay movlw message_13 call write_string ;Call subroutine to write text string to LCD call long_delay call long_delay call long_delay call long_delay movlw CLR_DISP ;Clear the disply ready for next message call send_lcd_cmd call long_delay call long_delay goto start ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ write_string clrf char_ptr ;Clear character pointer to zero movwf msg_ptr ;Load message pointer with message number ws1: movlw high (JUMP_TABLE) movwf PCLATH clrc ;Clear carry 'flag in status register' rlf msg_ptr,w ;Multiply by two to prevent pointing to goto addlw low (JUMP_TABLE) ;Computed GOTO < msg_ptr == string pointer > btfsc STATUS,C incf PCLATH,f movwf PCL JUMP_TABLE: call string0 ;Get next character in the string goto ws2 ;Upon return call ws2 to step through characters call string1 goto ws2 call string2 goto ws2 call string3 goto ws2 call string4 goto ws2 call string5 goto ws2 call string6 goto ws2 call string7 goto ws2 call string8 goto ws2 call string9 goto ws2 call string10 goto ws2 call string11 goto ws2 call string12 ws2: movwf temp1 ;store char returned from table in temp1 xorlw EOMSG ;test for end of message marker (0x04) btfsc ZERO ;Zero set iff EOM is detected return ;End Of Message marker detected, thus return movf temp1,w xorlw EOLN ;Test for EOL marker btfsc ZERO goto new_line_1 movf temp1,w call send_lcd_char tst incf char_ptr,f goto ws1 new_line_1 movlw NW_LINE ;send new line command to display call send_lcd_cmd call short_delay goto tst ;Text string look-up tables string0 bcf PCLATH,0 movlw high (TABLE_0) ;Load HIGH byte movwf PCLATH movlw low (TABLE_0) ;Load LOW byte addwf char_ptr,w btfsc STATUS,C incf PCLATH,f movwf PCL TABLE_0 dt "Robot Number:",EOLN," One ",EOMSG string1 bcf PCLATH,0 movlw high (TABLE_1) ;Load HIGH byte movwf PCLATH movlw low (TABLE_1) ;Load LOW byte addwf char_ptr,w btfsc STATUS,C incf PCLATH,f movwf PCL TABLE_1 dt "Robot Number:",EOLN," Two ",EOMSG string2 bcf PCLATH,0 movlw high (TABLE_2) ;Load HIGH byte movwf PCLATH movlw low (TABLE_2) ;Load LOW byte addwf char_ptr,w btfsc STATUS,C incf PCLATH,f movwf PCL TABLE_2 dt "Robot Number:",EOLN," Three ",EOMSG string3 bcf PCLATH,0 movlw high (TABLE_3) ;Load HIGH byte movwf PCLATH movlw low (TABLE_3) ;Load LOW byte addwf char_ptr,w btfsc STATUS,C INCF PCLATH,f movwf PCL TABLE_3 dt "Move:",EOLN," Forward ",EOMSG string4 bcf PCLATH,0 movlw high (TABLE_4) ;Load HIGH byte movwf PCLATH movlw low (TABLE_4) ;Load LOW byte addwf char_ptr,w btfsc STATUS,C INCF PCLATH,f movwf PCL TABLE_4 dt "Move:",EOLN," Backwards ",EOMSG string5 bcf PCLATH,0 movlw high (TABLE_5) ;Load HIGH byte movwf PCLATH movlw low (TABLE_5) ;Load LOW byte addwf char_ptr,w btfsc STATUS,C INCF PCLATH,f movwf PCL TABLE_5 dt "Move:",EOLN," Right ",EOMSG string6 bcf PCLATH,0 movlw high (TABLE_6) ;Load HIGH byte movwf PCLATH movlw low (TABLE_6) ;Load LOW byte addwf char_ptr,w btfsc STATUS,C INCF PCLATH,f movwf PCL TABLE_6 dt "Move:",EOLN," Left ",EOMSG string7 bcf PCLATH,0 movlw high (TABLE_7) ;Load HIGH byte movwf PCLATH movlw low (TABLE_7) ;Load LOW byte addwf char_ptr,w btfsc STATUS,C INCF PCLATH,f movwf PCL TABLE_7 dt "BODY:",EOLN," Head ",EOMSG string8 bcf PCLATH,0 movlw high (TABLE_8) ;Load HIGH byte movwf PCLATH movlw low (TABLE_8) ;Load LOW byte addwf char_ptr,w btfsc STATUS,C INCF PCLATH,f movwf PCL TABLE_8 dt "BODY:",EOLN," Hands ",EOMSG string9 bcf PCLATH,0 movlw high (TABLE_9) ;Load HIGH byte movwf PCLATH movlw low (TABLE_9) ;Load LOW byte addwf char_ptr,w btfsc STATUS,C INCF PCLATH,f movwf PCL TABLE_9 dt "BODY:",EOLN," Legs ",EOMSG string10 bcf PCLATH,0 movlw high (TABLE_10) ;Load HIGH byte movwf PCLATH movlw low (TABLE_10) ;Load LOW byte addwf char_ptr,w btfsc STATUS,C INCF PCLATH,f movwf PCL TABLE_10 dt "SPEED:",EOLN," Slow ",EOMSG string11 bcf PCLATH,0 movlw high (TABLE_11) ;Load HIGH byte movwf PCLATH movlw low (TABLE_11) ;Load LOW byte addwf char_ptr,w btfsc STATUS,C INCF PCLATH,f movwf PCL TABLE_11 dt "SPEED:",EOLN," Medium ",EOMSG string12 bcf PCLATH,0 movlw high (TABLE_12) ;Load HIGH byte movwf PCLATH movlw low (TABLE_12) ;Load LOW byte addwf char_ptr,w btfsc STATUS,C INCF PCLATH,f movwf PCL TABLE_12 dt "SPEED:",EOLN," Fast ",EOMSG ; ********* LCD Drive Subroutines ********* init_lcd movlw MODE_8 ;MUST BE INCLUDED call send_lcd_cmd ;MUST BE INCLUDED movlw 0x32 ;MUST BE INCLUDED call send_lcd_cmd ;MUST BE INCLUDED movlw MODE_4 ;function mode set-up call send_lcd_cmd ;4-bit mode, 2 lines, 5x7 dot format movlw INC_NSFT ;entry mode set-up* call send_lcd_cmd ;cursor incriment on write* movlw DISP_ON_FLASH call send_lcd_cmd movlw CLR_DISP call send_lcd_cmd ;clear diaply, cursor home call long_delay return send_lcd_cmd movwf temp swapf temp,w andlw 0X0F bcf RS_LINE bcf E_LINE movwf PORTB call short_delay pulse_e ;call macro call short_delay movf temp,w andlw 0F movwf PORTB call short_delay pulse_e ;call macro call short_delay return send_lcd_char movwf temp swapf temp,w andlw 0X0F bsf RS_LINE bcf E_LINE iorlw 0X20 movwf PORTB call short_delay pulse_e ;call macro call short_delay movf temp,w andlw 0F iorlw 0X20 movwf PORTB call short_delay pulse_e ;call macro call short_delay return ;Delay routines short_delay movlw 0X08 movwf dly_cnt_1 dly_loop_1 decfsz dly_cnt_1,f goto dly_loop_1 return med_delay movlw 0X80 movwf dly_cnt_2 dly_loop_2 call short_delay decfsz dly_cnt_2,f goto dly_loop_2 return long_delay movlw 0X40 movwf dly_cnt_3 dly_loop_3 call med_delay decfsz dly_cnt_3,f goto dly_loop_3 return end ;End of source code listing ;END OF TEST PROGRAM ------------------------------------------------------------------------------ ---------------------------- Below is the lcd_defs.h file which contains the various LCD control commands: TITLE "Header File: "lcd_defs.h" ; This Header File Contains All The Necessary LCD Module Control Command ; DEFINITIONS Refered To In The Main Program Listing nolist ;TEMP equ 0x035 ;temporary register ;CHAR equ 0x036 ;temporary register, Holds value to send to LCD module. ; ; Control Commands For The Hitachi LM032L LCD Module ;FUNC_... - Function Set and Display Resolution, ( 4 bit, 2 lines, 5 x 7 dots) MODE_8 equ 0x033 MODE_4 equ 0x028 ; CURS_RHT equ 0x093 DD_RAM_ADDR equ 0x080 ;Least Significant 7-bit are for address DD_RAM_UL equ 0x080 ;Upper Left coner of the Display ; ; ; CLR_DISP equ 0x001 ;CLEAR display and HOME cursor command HOME_DISP equ 0x002 ;HOME cursor command - (restores shifted display ) NW_LINE equ 0x0C0 ;NEW LINE command ;ENTRY_... - Sets Entry Mode, S = Display Shift ON, INC / DEC Cursor Move Dir DEC_NSFT equ 0x004 ; DEC_SFT equ 0x005 ; INC_NSFT equ 0x006 ; INC_SFT equ 0x007 ; ;DISP_... - Display ON / OFF Control, CSR = Cursor ON, FLASH = Flash char pos DISP_OFF equ 0x008 ;Display OFF DISP_ON equ 0x00C ;Display ON DISP_ON_CSR_ON equ 0x00E ;Display ON, Cursor ON DISP_ON_FLASH equ 0x00F ;Display ON, Cursor ON, FLASH cursor ;SFT_... - Cursor & Display Shift, DISP = Display, CSR = Cursor, LFT = Left, RHT = Right SFT_CSR_LFT equ 0x010 SFT_CSR_RHT equ 0x014 SFT_DISP_LFT equ 0x018 SFT_DISP_RHT equ 0x01C list =================================================== Lee Hewitt Manchester ENGLAND Home E-Mail: LHewitt104@aol.com University E-Mail: L.Hewitt@eee.salford.ac.uk ===================================================