> org 0x80 > > movlw LOW Table ;get low 8 bits of address > addwf offset,F ;do an 8-bit add operation (1) > movlw HIGH Table ;get high 5 bits of address > btfsc status,c ;page crossed? > addlw 1 ;yes then increment high address > movwf PCLATH ;load high address in latch > movf offset,w ;load computed offset in w reg > call Table > > > org 0x9FD > > Table: > movwf PCL,F ;load computed offset in PCL (2) > retlw 'A' ;return the ASCII char A > retlw 'B' ;return the ASCII char B > retlw 'C' ;return the ASCII char C > > I'd expect a second label right before the first retlw instruction > that would be used in the offset calculation in the addwf marked (1). > > A second thought... > Would it not be better to move the address calculation > *inside* the subroutine, so you don't have to dublicate > the offset calculation everytime the table is called ? This is yet more proof that while Microchip may have smart people designing silicon, they hire bargain basement bozos to do software (Doesn't anyone with a functional brain ever check over this stuff?). You are right, this code doesn't work for an offset of 0. That could be forgiven if this limitation were clearly documented (perhaps it is in the full app note?). Note also that all the table entries must be in the same block of 256 addresses because the same PCLATH value is used to jump to all of them. This restriction is not noted. Incredibly, the fixed starting address of 9FDh explicitly puts the "C" entry in the next 256 word block!! Duh!! Are you sure this code didn't appear in a section titled "Don't let this happen to you"? I also agree that it makes sense to put the address calculations into the subroutine. A subroutine is required for a RETLW table, and the instructions have to be written at least once somewhere, so why not put them where they can be re-used? Here is how I would do it: ; Subroutine TABLE_LOOKUP ; ; Returns the table value in W, given the 0-N table entry number ; in REG0. No check is made for out of range table entry numbers, ; which cause all manner of destruction. ; ; *** THIS CODE HAS NOT BEEN ASSEMBLED, LET ALONE TESTED *** ; glbent table_lookup, noregs movlw high table ;get table start address high byte movwf pclath ;init entry address high byte movlw low table ;get table start address low byte addwf reg0, w ;make entry address low byte skip_nc ;no carry into high byte ? incf pclath ;propagate the carry movwf pcl ;jump to the selected table entry table retlw "A" ;table entry 0 ... Note that this places no restriction whatsoever on the placement of TABLE. TABLE could be in a external module, and can cross 256 block and page boundaries. For extra credit, compute the table length at assembly time and return 0 for out of range values at run time. (Hint: I've got an example of something similar in the HOS_CMD.ASPIC module in the HOS project at http://www.embedinc.com/pic). ***************************************************************** Embed Inc, embedded system specialists in Littleton Massachusetts (978) 742-9014, http://www.embedinc.com -- http://www.piclist.com hint: PICList Posts must start with ONE topic: [PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads