Hi guys, Firstly, don't scream.. I HAVE read the datasheets!. My table reading subroutine is based on the final example in AN556 "Implementing a Table Read" and can be used across page boundaries and be located anywhere in memory... BUT!... will not work if the table itself is longer than 256 bytes. This is because the table element offset is passed in w (8 bits) and then used in the calculation for the program counter. Trying to access elements that start beyond an offset of 256 bytes won't work. I could make a new separate table, but would prefer to keep it all together. Based on the app note from Microchip, I can't see a simple way to do this with one table. This particular example (example 5 in AN556) is already complicated, and would be a mess if I try to make it cater for such things. Has anyone posted a lookup table reader that can access defined elements in a table longer than 256 bytes?. Weird thing is that AN556 does not specifically warn of this. Maybe I'm doing something wrong... Hopefully one of you can help. My application is listed in part below. Firstly, the top of the table looks like this. I have the modem strings arranged with the string length first, then the string. This is the best way for this particular application. ;********************************************************** ;* Data tables ;********************************************************** command movwf PCL ;Update PCL with computed value table_base ;Table start reference off_hook dt 0x07,"AATDT;",0x0d hang_up dt 0x05,"AATH",0x0d modem_reset dt 0x05,"AATZ",0x0d dummy_dial dt 0x17,"AATM2S07=48DT,xxxxxxxx",0x0d ; You can call up one of these modem strings by simply doing this... movlw modem_reset-table_base ;Calculate table offset for reset string call send_command ; And the big daddy of a table reader/modem string sender... ;********************************************************* ;* Send modem command string - called with table offset in w ;********************************************************* send_command movwf table_offset ;Save table offset movlw LOW table_base ;Get low 8 bits of table address addwf table_offset,f ;8-bit add to get abs location of string, could overflow... movlw HIGH table_base ;Get high 5 bits of table address btfsc STATUS,C ;Did that last add cross page boundary? addlw 1 ;Yes, roll over into next page movwf PCLATH ;Preload high address movf table_offset,w ;Update calculated offset get_length call command ;Get first byte (string length) movwf msg_length ;Save message length send_next movlw 1 ;Increment table offset... carefully addwf table_offset,f movlw HIGH table_base btfsc STATUS,C ;Crossed page boundary when incremented? addlw 1 ;Roll over into next page movwf PCLATH ;Preload high address movf table_offset,w ;Update offset call command ;Jump to table with offset in w... loop_com btfss PIR1,TXIF ;Check if txreg empty goto loop_com ;Loop until free ; wait_CTS ;Hardware flow control. CTS is normally LOW btfsc PORTB,CTS ;Are we clear to send? goto wait_CTS ;If CTS = HIGH, modem is busy ; gie_tx bcf INTCON,GIE ;Disable interrupts, dammit! btfsc INTCON,GIE goto gie_tx movwf TXREG ;Send byte to modem bsf INTCON,GIE ;Re-enable interrupts decfsz msg_length,f ;Decrement length, if not zero goto send_next ;Keep going... return