On Mon, 4 Sep 2000, Werner Soekoe wrote: > Hi > > This question has probably been asked before. I am using a PIC16F84. The > first 256 bytes are reserved for code, and the 768 bytes from 0x100 onward > are filled with RETLW instructions (dt "Messages..."). Which is the best > method of retrieving the values stored in the "table", if I provide a 16 bit > counter (two bytes, IndexHi, IndexLo) for the index into the table, starting > at zero and ending at 767? > > I have tried to store the IndexHi + 1 (the high byte of offset 0x100 where > the table starts) value to the PCLATH, and then using CALL IndexLo, but the > code screws up and jumps to a posisiton within the first 256 bytes. After I posted the string look-up routine the other day, I was thinking more about what Olin had posted and how it gets around the problem you describe. Here's a version that can be located anywhere in RAM and contain arbitrarily sized strings - the constraint being the size of the PIC's program memory. It doesn't take a 16-bit pointer like what you request, but it does derive a 16-bit pointer from a `string number'. You may be able to adapt this portion to your code. This is only partially tested. (also, watch out for the comments that wrap around). ;******************************************************************* ;write_string ; ; The purpose of this routine is to display a string on the LCD module. ;On entry, W contains the string number to be displayed. The current cursor ;location is the destination of the output. ; This routine can be located anywhere in the code space and may be ;larger than 256 bytes. ; ; psuedo code: : ; char *string0 = "foo"; ; char *string1 = "bar"; ; ; char *strings[] = { string0, string1}; ; char num_strings = sizeof(strings)/sizeof(char *); ; ; void write_string(char string_num) ; { ; char *str; ; ; str = strings[string_num % num_strings]; ; ; for( ; *str; str++) ; LCD_WRITE_DATA(*str); ; ; } ; ; Memory used ; buffer2, buffer3 ; Calls ; LCD_WRITE_DATA ; Inputs ; W = String Number ; write_string andlw WS_TABLE_MASK ;Make sure the string is in range movwf buffer3 ;Used as an index into the string table addwf buffer3,w ;to get the string offset ; addlw LOW(ws_table) ;First, get a pointer to the string movwf buffer3 ; ; movlw HIGH(ws_table) ; skpnc ; movlw HIGH(ws_table)+1 ; movwf PCLATH movf buffer3,w call ws2 ;First call is to get string offset in table movwf buffer2 incf PCLATH,f incfsz buffer3,w decf PCLATH,f call ws2 ;get the high word (of the offset) movwf PCLATH ; ws1: ;Now loop through the string movf buffer2,w call ws2 andlw 0xff skpnz ;If the returned byte is zero, return ; we've reached the end call LCD_WRITE_DATA incf PCLATH,f ;Point to the next character in the string incfsz buffer2,f decf PCLATH,f goto ws1 ws2 movwf PCL #define WS_TABLE_MASK 1 ; This should equal 2^number of strings ; The first part of the table contains pointers to the start of the ; strings. Note that each string has a two word pointer for the low ; and high bytes. ws_table: retlw LOW(string0) retlw HIGH(string0) retlw LOW(string1) retlw HIGH(string1) string0: dt "GPSIM WROTE THIS",0 string1: dt "A STRING ON ROW 2",0 Scott -- http://www.piclist.com hint: PICList Posts must start with ONE topic: "[PIC]:" PIC only "[EE]:" engineering "[OT]:" off topic "[AD]:" ad's