MPASM creates a CALL 0x0 ???

Thread Starter

techristian

Joined Aug 27, 2013
53
DISASSEMBLED CODE:
0164 0739 ADDWF 0x39, W 531: addwf Trigger777,0 ;to get proper patch table
0165 0733 ADDWF 0x33, W 532: addwf countUp,0 ;to get proper patch table
0166 00BC MOVWF 0x3C 533: movwf EnvPointer
0167 2109 CALL 0x109 534: Call read
0168 210C CALL 0x10C 535: CALL TinyDelay;NEW
0169 3008 MOVLW 0x8 536: movlw HIGH ATKDecayTable
016A 008A MOVWF PCLATH 537: movwf PCLATH
016B 083C MOVF 0x3C, W 538: MOVF EnvPointer,0
016C 1003 BCF STATUS, 0x0 539: BCF STATUS,0 ;CLEAR CARRY FLAG
540:
016D 2000 CALL 0x0 541: call ATKDecayTable ;GET RegData FROM TABLE
542:
016E 00B0 MOVWF 0x30 543: MOVWF RegData
016F 0086 MOVWF PORTB 544: movwf PORTB
545:
0170 210C CALL 0x10C 546: CALL TinyDelay
0171 2100 CALL 0x100 547: Call inactive
END CODE:

LATER ON MORE CODE:
2397:
2398: org 0x800
2399:
2400:
2401: ATKDecayTable ;EnvTest PARAM CHANGE 24-39 DECIMAL INCLUSIVE
2402:
0800 0782 ADDWF PCL, F 2403: ADDWF PCL ,1
2404: ;00h
0801 3400 RETLW 0x0 2405: RETLW 0x00 ; ENV_FreqLow equ 0xB
0802 3401 RETLW 0x1 2406: RETLW 0x01 ; ENV_FreqHgh equ 0xC
0803 3409 RETLW 0x9 2407: RETLW b'00001001' ;ENV_Shape equ 0xD ;BIT3 CONT BIT2 ATT BIT1 ALT BIT0 HOLD
0804 3401 RETLW 0x1 2408: RETLW 0x01 ;FreqNoise equ 0x6 ;lower 5 BITS
2409:
 
Last edited by a moderator:

Thread Starter

techristian

Joined Aug 27, 2013
53
# At this point, ANY CALL to address $800h will create the "CALL 0x0" code. I think that this is a compiler error and I'm tempted to change a byte using my EPROM BURNER.
#
I expected the assembler to do what I told it to do !Instead it created a endless loop by CALLing 0x0.

# Dan
 

sagor

Joined Mar 10, 2019
1,046
It would be good if you say what processor this is for, chip type. Many 16F series of PICs have a maximum CALL address of 0x7FF. 18F series use 2 words for longer addresses.
Your code suggests this is some chip similar to the 16F series, where the CALL is one 14 bit word, bit pattern:
10 0kkk kkkk kkkk
where "k" is the address (11 bits). Obviously, 0x800 won't fit.
 

Thread Starter

techristian

Joined Aug 27, 2013
53
My original post was deleted. I explained everything there. This is a 16F887. I thought I was supposed to have 16k of memory or close to that! What good is memory IF YOU CAN'T USE IT?

I THOUGHT THAT PCLATH MADE UP FOR THE MISSING BITS.


DAN
 
Last edited:

Papabravo

Joined Feb 24, 2006
22,058
I would change $2000 to $2800
And that would no longer be a CALL opcode. In fact, it would be a GOTO instruction. Look at the instruction decoding table on p. 226 of the datasheet and notice that either a CALL or a GOTO only has room for an 11-bit literal. 0x800 requires 12 bits to represent it and it just won't fit in an 11-bit space. Am I right?

ETA: PCLATH will take care of the missing bits, but you have to explicitly assign a value to it prior to the call. Were you expecting the assembler to be smart enough to add that code for you? Some of them may, but others may not be that clever and they will expect you to do it explicitly.
 
Last edited:

joeyd999

Joined Jun 6, 2011
6,204
Code:
0169 3008 MOVLW 0x8 536: movlw HIGH ATKDecayTable
016A 008A MOVWF PCLATH 537: movwf PCLATH
These are the lines that make the paged call work correctly.

There is no error in the assembled object code.
 

Thread Starter

techristian

Joined Aug 27, 2013
53
And that would no longer be a CALL opcode. In fact, it would be a GOTO instruction. Look at the instruction decoding table on p. 226 of the datasheet and notice that either a CALL or a GOTO only has room for an 11-bit literal. 0x800 requires 12 bits to represent it and it just won't fit in an 11-bit space. Am I right?
You are correct . That would change to a GOTO command.

Dan
 

sagor

Joined Mar 10, 2019
1,046
Bits in PCLATH<4:3> are supposed to indicate which 2k block of ram is to be used when doing a CALL instruction. See section 2.4 of the datasheet. With PCLATH set correctly, a call to 0x800 would be interpreted into a call to 0x000 when translated to the second ram block. (second ram block enabled by PCLATH)
 

Thread Starter

techristian

Joined Aug 27, 2013
53
Nope . am I missing something here?
When the table is placed at 700h NO PROBLEM but if I move it to 800h while ALL OTHER THINGS are REMAINING THE SAME, pic16f887 LOOPS ENDLESSLY !!

Maybe I have a cheap KNOCKOFF pic chip with less memory?
I'll try an official Microchip part next.

movwf EnvPointer
Call read
CALL TinyDelay;NEW
movlw HIGH ATKDecayTable
movwf PCLATH
MOVF EnvPointer,0
BCF STATUS,0 ;CLEAR CARRY FLAG

call ATKDecayTable ;GET RegData FROM TABLE

MOVWF RegData
movwf PORTB
 

joeyd999

Joined Jun 6, 2011
6,204
Nope . am I missing something here?
When the table is placed at 700h NO PROBLEM but if I move it to 800h while ALL OTHER THINGS are REMAINING THE SAME, pic16f887 LOOPS ENDLESSLY !!

Maybe I have a cheap KNOCKOFF pic chip with less memory?
I'll try an official Microchip part next.

movwf EnvPointer
Call read
CALL TinyDelay;NEW
movlw HIGH ATKDecayTable
movwf PCLATH
MOVF EnvPointer,0
BCF STATUS,0 ;CLEAR CARRY FLAG

call ATKDecayTable ;GET RegData FROM TABLE

MOVWF RegData
movwf PORTB
Are you sure it's not a 16F882?

Selection_076.png
 

geekoftheweek

Joined Oct 6, 2013
1,429
I'll admit I don't have experience with this yet, but I'm wondering if you have to change PCLATH before the call wouldn't you have to change it back before the return? It seems to be you would be returning to the wrong address
 

joeyd999

Joined Jun 6, 2011
6,204
I'll admit I don't have experience with this yet, but I'm wondering if you have to change PCLATH before the call wouldn't you have to change it back before the return? It seems to be you would be returning to the wrong address
No, but he would need to change PCLATH prior to the next CALL or GOTO to page 0.

Selection_077.png
 

Thread Starter

techristian

Joined Aug 27, 2013
53
Ok. Here is the other thing I'm only using PCLATH with RETLW call TABLES. In other words am not using it at all with GOTO or Simple CALLS.

I HAVE LOTS OF CALLS.

IF I NEED TO USE PCLATH with every one, the code would get even more unreadable. Nevertheless why would the program work fine up until I use that next page?

I also use some UNDOCUMENTED PNEUMONICS such BC BNC BZ BNZ ...if there are others I'd like to know them!

Dan
 

joeyd999

Joined Jun 6, 2011
6,204
Ok. Here is the other thing I'm only using PCLATH with RETLW call TABLES. In other words am not using it at all with GOTO or Simple CALLS.

I HAVE LOTS OF CALLS.

IF I NEED TO USE PCLATH with every one, the code would get even more unreadable. Nevertheless why would the program work fine up until I use that next page?

I also use some UNDOCUMENTED PNEUMONICS such BC BNC BZ BNZ ...if there are others I'd like to know them!

Dan
One of the drawbacks -- and benefits! -- of coding .asm is that you are in control of everything. You don't need to worry about a compiler interpreting your intentions properly.

But this also means you need to maintain all the registers (like PCLATH) for your code to work properly.

I agree it's a pain to manage PCLATH in PIC16s with more than one page of program space.

It was one of the primary reasons I moved to the 18F series many years ago.
 

joeyd999

Joined Jun 6, 2011
6,204
Thank you joeyd999

Are you saying that i must use PCLATH every single GOTO and CALL now that I have crossed "The Event Horizon"


Thanks again!
Dan
PCLATH must match the destination page of the CALL or GOTO just prior to execution of the instruction.

If you plan your memory map in advance, you can arrange things to make this a bit easier (Example: keep all your subs in a single page, and your main code in another page).

Also, use separate ORGs for each code page. This will force an assembler error when one page of code extends into another, giving you a hint to check your PCLATH settings.

Alternatively, C will do all this automagically for you, at the expense of larger code size and slower execution speed.
 
Top