takao21203
- Joined Apr 28, 2012
- 3,702
I must say that I actually hate all this.You are missing the point. They have the same offset if the offset is only 8 bits. You need to maintain and calculate a 16 bit table address and maintain PCLATH as well. Here's something I whipped up for you to give you the idea. It assembles and works in MPSIM. The main point is that you calculate a FULL ROM address and jam it onto the program counter (which hopefully points to a retlw!) You should take steps to see that your calculated address is valid etc etc...
Rich (BB code):;************************** TABLE 16 EXAMPLE ************************** ; Untested but you get the idea - not exactly optimized either.. INCLUDE "p16F648a.inc" cblock (20h) TablAddrL: 1 ; declare 2 byte table address TablAddrH: 1 savePCLATH:1 ; saves PCLATH during table ops TargetBuf: .32 ; somewhere to put it endc ORG 0 ;--------------------------- ; typical code flow. Could automate this setup with a macro.. ;... movlw TargetBuf ; Set target buffer movwf FSR ; FSR-> where data goes bcf STATUS,IRP movlw low (Text30) ; set ROM address of data to get movwf TablAddrL movlw high (Text30) movwf TablAddrH call GetData_FSR ; gets string from ROM to *FSR ;* goto 0 ;------------------------------------------- ; GetData_FSR Copies RETLW xx ROM data from ; TablAddrH:L to *IRP:FSR GetData_FSR: movf PCLATH,W ; save PCLATH of current page movwf savePCLATH call _GetLoop ; fetches data from TablPtr until \0 movf savePCLATH,W ; restore PCLATH movwf PCLATH return ;---------------------------------------------- ; Gets data from ROM at *TablAddrH:L ->*FSR until ; data is 00h. Doesn't store 00h _GetLoop: call lookup16_W ; fetch one byte via RETLW xx iorlw 0 ; set flags on W (look for \0 to terminate string) skpnz return ; done on data==Z movwf INDF ; else, got one byte, save it at *FSR incf FSR,F ; FSR++ incf TablAddrL,F ; bump 'table' pointer to next RETLW xx skpnz incf TablAddrH,F goto _GetLoop ;------------------------------------------------- ; Jams TablAddrH:L onto PCLATH:PCL to force a jump lookup16_W: movf TablAddrH,W ; forced goto to TablAddrH:L movwf PCLATH movf TablAddrL,W ; returns through RETLW xx movwf PCL ORG 600h ; your table, page 1 (could be anywhere) TableStart: Text1 dt "This is text 1",0 Text2 dt "This is text 2",0 ;.. .blah blah ; Table runs past 600h into page 700h.. but ORG is not needed ; blah blah ORG 700h Text30 dt "Text 30 is in 7xx",0 END
This does not mean your particular effort of work, or project.
This does not mean the actual forum contribution.
All this is appreciate and might be very reasonable to do.
I am saying, it is not appreciate for me, and I strongly don't like it.
I have done complex LCD menu in assembler. At first multilevel tables inside program FLASH, later on, computing indexing tables, storing the data into EEPROM, reading it back (with a different routine), and even removing it from program FLASH. It is stretching over many pages.
Why would you want to code 16bit FLASH table access using a lenghty construct as above?
When you can use this:
Rich (BB code):
char* get_font_ptr(char* font)
{unsigned int addr;
addr=*(font+1);addr<<=8;addr|=*(font);
return(((const char*)(addr)));
}
This is all completely the free choice of the OP.
I am just saying I have coded stuff like this (in assembler), and I believe to have good reasons not to use it anymore.
Not that it could not be done. The resulting code is not useful since it makes heavy use of banking, so it would have to be changed for each PIC. That is almost unthinkable!