
There is no way on the 16 series PICs to read a byte directly from program
memory. The way a table is achieved is by the use of a computed goto and a
return with literal in w instruction.
For very simple tables where a byte maps to another byte, the code would be as follows:
movlw a ;index for table call lookup ;get table value . . do something with the byte. lookup addwf pc,f ;add the offset in w to ;the program counter retlw b ;return from the call with b in w retlw c retlw dIn MPASM, there is a shorthand for great long lists of retlw's. It is DT, define table.
DT b,c,d
char *string0 = "zeroeth";
char *string1 = "first";
char *string2 = "second";
char *string_ptrs[3] = {string0,string1,string2};
The table of CALLs is analogous to the array of pointers, while the table of strings is
analogous to the string declarations.
;*******************************************************************
;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.
;
; Memory used
; buffer2, buffer3
; Calls
; LCD_WRITE_DATA
; Inputs
; W = String Number
;
write_string
CLRF buffer2 ;Used as an index into the string table
MOVWF buffer3 ;Save a copy of which string we're to write
ws1: CLRC
RLF buffer3, W ;Get the saved copy and multiply it by two
ADDWF PCL, F ;Computed GOTO
CALL string0 ;Get next character in the string
GOTO ws2
CALL string1
GOTO ws2
CALL string2
GOTO ws2
CALL string3
GOTO ws2
CALL string4
ws2: ANDLW 0xff ;"Return" point for computed goto's.
BTFSC STATUS, Z ;If the returned byte is zero, end reached
RETURN
CALL LCD_WRITE_DATA ;Write a single character
INCF buffer2, F ;Point to the next character in the string
GOTO ws1
string0 MOVF buffer2, W ;Get the string index
ADDWF PCL, F ;and add it to the PC to get the next character
dt "SENSOR",0 ;Note the zero termination.
string1 MOVF buffer2, W
ADDWF PCL, F
dt "SMALL",0
string2 MOVF buffer2, W
ADDWF PCL, F
dt "MEDIUM",0
string3 MOVF buffer2, W
ADDWF PCL, F
dt "LARGE",0
string4 MOVF buffer2, W
ADDWF PCL, F
dt "0123456789ABCDEF",0
day_table movwf temp ;day number 0-6
clrc
rlf temp,f ;multiply by 2
rlf temp,w ;multiply by 2
;this takes us to the correct day
addwf counter,w ;add char offset within day string 0-3
addwf pc,f
dt "Sun "
dt "Mon "
dt "Tue "
dt "Wed "
dt "Thu "
dt "Fri "
dt "Sat "
dt "Sun "
Write_day clrf counter
another movlw 5 ;write "Fri " as an example.
call day_table
call write_to_LCD ;character is now in w. print it.
incf counter,f
movlw 4
subwf counter,w
btfss status,z
goto another_char
.
.
end
