OT: table CALL does not work

Program:

LIST p=P16F648A #include P16F648A.inc ; Was P16F628A __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_OFF & _HS_OSC & _LVP_OFF & _MCLRE_OFF & _BOREN_OFF __IDLOCS 0x0001

; VARIABLES ptrlo EQU 0x20 ; table pointer ptrhi EQU 0x21 COUNT1 EQU 0x22 ; delay counter COUNT2 EQU 0x23 COUNT3 EQU 0x24 sSTATUS EQU 0x25 sW EQU 0x26 ; ORG 0x0000 GOTO start GOTO start GOTO start GOTO start ORG 0x0010 start: ;** setup I/O ; All pins have 10K in series with an LED to GND except OSC pins (and GND)

CLRF 6 ; Set all Port B pins to logic 0 BSF 3,5 ; Bank 1 command comes next STATUS RP0 set CLRF 6 ; sel all Port B pins as outputs BCF 3,5 ; Bank 0 command comes next STATUS RP0 clear

CLRF ptrlo CLRF ptrhi

CLRW MOVWF 6 ; Port B to zero CALL DELAY ; "freeze" LEDs

MOVLW 0xFF MOVWF 6 ; Port B ones CALL DELAY ; "freeze" LEDs setup: MOVLW Low(tab1) ADDWF ptrlo,W ; add pointer to W MOVLW High(tab1) BTFSC STATUS,C INCF PCLATH,F ; W=1 CALL tab1 ;;*REMoving this, one sees 0x00 0xFF 0x01 repeating ; RETurns here ;; otherwise, LEDs show 0x00 0xFF repeating MOVWF 6 ; Port B from W CALL DELAY ; "freeze" LEDs GOTO start

repeat: ;;*This part disabled for now.. INCF ptrlo ; next loc ; BTFSC STATUS,C ; INCF ptrhi MOVF ptrlo,W ; CALL tab1 ;;*REMoving this, one sees W counting ;; otherwise, LEDs show 0x00 0xFF 0x00 0xFF 0x00 etc MOVWF 6 ; Port B from W CALL DELAY ; "freeze" LEDs GOTO repeat

; ---------------------------------------------- DELAY MOVWF sW ; MOVF STATUS,W ; MOVWF sSTATUS CLRF COUNT1 CLRF COUNT2 MOVLW d'43' ; fudge for about 4 Sec delay MOVWF COUNT3 LUPINR DECFSZ COUNT1 GOTO LUPINR DECFSZ COUNT2 GOTO LUPINR DECFSZ COUNT3 GOTO LUPINR DEXIT:; MOVF sSTATUS,W ; MOVWF STATUS MOVF sW,W RETURN ; ---------------------------------------------- sine ORG 0x0100 tab1: ;; RETLW 0x01 ; [0] t=0.7500 r=0.0000 ADDWF PCL,F RETLW 0x15 ; [1] t=0.7539 r=0.0240 RETLW 0x14 ; [2] t=0.7578 r=0.0964 RETLW 0x13 ; [3] t=0.7617 r=0.2173 RETLW 0x12 ; [4] t=0.7656 r=0.3865 RETLW 0x02 ; [5] t=0.7695 r=0.6040

WHAT in all heck is happening??

Reply to
Robert Baer
Loading thread data ...
[snip code]

Have you used the simulator and single step to see what's happening (or not)?

It's quite difficult enough to follow such convoluted and poorly documented code, and you insist on using register address numbers rather than the mnemonics, which is more obfuscation. Table calls DO work, but it seems you are adding extra code for some reason and then question why it doesn't work.

Sorry, can't help.

Paul

Reply to
P E Schoen

Here, W contains High(tab1), PCLATH contains zero.

If you can ensure that the table doesn't cross a page boundary, it suffices to use:

MOVLW High(tab1) MOVWF PCLATH MOVF ptrlo,W CALL tab1

In the most general case, you have to allow for the fact that tab1 might not even be on the same 2k super-page as the target RETLW instruction, meaning that PCLATH needs different values for the CALL and the computed goto, which basically means that the calculation needs to be moved into the table routine. E.g.

MOVLW High(tab1) ; far call to tab1 MOVWF PCLATH CALL tab1

...

tab1: MOVLW High(tab1_data) ADDWF ptrhi,W MOVWF PCLATH

MOVLW Low(tab1_data) ADDWF ptrlo,W BTFSC STATUS,C INCF PCLATH,F

MOVWF PCL,F

tab1_data: RETLW ...

Reply to
Nobody

The "extra code" is the setup for 8-bit display using the LEDs (at least the RB0-RB7) and a "freeze" delay to allow visual confirmation of what might be happening. Somewhere i saw that the "simulator" and single-stepping would not work for the PIC16F48A (and i do have the so-called debug header, which is a modified (and more expensive) version. Cannot use it as there is no space on the project board for that monster (in process of making a whole new board).

Reply to
Robert Baer

  • Yes, that is the way i see it also.
  • I have noted that, and it looks nice for a presumed look-up "anywhere". BUT.. The "gotcha" is nothing is pushed on the stack, so WTH does the program go after the RETURN/RETLW? And can one rely on the unknown/undefined stack contents/

My goal is to have a number of 1K look-up tables entry at 0x0100 sections.

Reply to
Robert Baer

For heavens sake! *Single step* the failing code in a PIC *emulator* and watch exactly what happens at the critical point. Get the basic version I posted working first and then modify it to use pages!!!!

Crash and burn with obfuscated code is no way to run a circus.

You could probably get away with a toy hobby board that just supplied power to the device and a LED to flash PICAXE or whatever. You have already wasted several multiples of the tools cost in your time.

--
Regards, 
Martin Brown
Reply to
Martin Brown

The Microchip software simulator works very well for simple stuff like this and it's included free in the MPLAB IDE. The MPLABX simulator is a bit trickier to use but still works very well. You can set up watches for variables, and inspect and modify the contents of RAM, and single step or run to cursor or use breakpoints. There is a stopwatch which is useful for timing loops (but you must be sure to set the clock frequency properly). You can even use external register injection files to simulate ADC inputs, and manual stimulus to simulate pushbuttons.

A hardware emulator or debugger is rarely needed.

Paul

Reply to
P E Schoen

Try..... ;D

; ---------------------------------------------- sine ORG 0x0050 tab1: ;; RETLW 0x01 ; [0] t=0.7500 r=0.0000 ADDWF PCL;,F RETLW 0x15 ; [1] t=0.7539 r=0.0240 RETLW 0x14 ; [2] t=0.7578 r=0.0964 RETLW 0x13 ; [3] t=0.7617 r=0.2173 RETLW 0x12 ; [4] t=0.7656 r=0.3865 RETLW 0x02 ; [5] t=0.7695 r=0.6040

This is why MOVWF PCL is perfered.

Cheers

Reply to
Martin Riddle

oops, use this

; ---------------------------------------------- sine ORG 0x0050 tab1: ADDWF PCL,F RETLW 0x15 ; [1] t=0.7539 r=0.0240 RETLW 0x14 ; [2] t=0.7578 r=0.0964 RETLW 0x13 ; [3] t=0.7617 r=0.2173 RETLW 0x12 ; [4] t=0.7656 r=0.3865 RETLW 0x02 ; [5] t=0.7695 r=0.6040

Cheers

Reply to
Martin Riddle

Thanks; will try that.

Reply to
Robert Baer

But that is what i have,and it does not work; acts as a "system reset".

Reply to
Robert Baer

I don't know about PIC, but these days avr-gcc is so well optimized that using straight assembly to write anything that's not speed-critical even on small AVR microcontrollers just seems pathological.

Reply to
bitrex

"CALL tab1" pushes the address of the following instruction onto the stack. "RETLW" pops it. The computed goto ("MOVWF PCL,F") between the two doesn't touch the stack.

Reply to
Nobody

With ORG 0x0050 ????

Cheers

Reply to
Martin Riddle

Correct; but that is the way supposedly working program samples are presented.

Reply to
Robert Baer

Last time I was playing with PICs it was a DOS based emulator but quite capable although newer ships were not supported. But jump tables for function value lookup definitely worked fine I used them extensively.

--
Regards, 
Martin Brown
Reply to
Martin Brown

For very small chunks of code it can be quicker than linking an HLL.

The last thing I wanted to do was very low power so the code was speed critical only in the sense that the faster it executed the slower the system clock and longer the battery life ~3y on 2xAA.

It also did some tricky jitter based frequency generation (awful phase noise but quite good averaged over the longer term).

--
Regards, 
Martin Brown
Reply to
Martin Brown

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.