Mega88 program counter: 0x1000 bit set?

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm developing a program on the Mega88 (the target is a Mega88PA, but the breadboard uses an old Mega88 20PI chip), and it seems to run perfectly well. I put in some trace code that stores the program counter link from the stack in RAM and noticed something odd: the program counter always seems to have the 0x1000 bit set, i.e. it seems to be executing addresses 0x1000-0x1FFF rather than 0x0000-0x0FFF.

I think I've eliminated anything I could be doing wrong (by saving the link right at the start of execution), and I even tried forcing that bit low by masking it out and putting it back on the stack, but it seems to be stuck there.

Is this a known feature, and is there anything I should look out for where it could cause problems (e.g. when I set a link on the stack directly to an address in the $0000-$0FFF range)?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How are you recording/observing the PC register?

The fact is that PC generally only has as many bits as required to address all of the flash. So 13bits to address 8K. (in fact an 8K processor has just 4K words so probably 12 bits).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
How are you recording/observing the PC register?

I call a subroutine which pops 2 bytes off the stack into registers, pushes them back, then stores the value in the registers somewhere else in RAM where I can look at it.

Quote:
The fact is that PC generally only has as many bits as required to address all of the flash. So 13bits to address 8K. (in fact an 8K processor has just 4K words so probably 12 bits).

It's a word address, so 12 bits. The word addresses should be in the range 0x0000-0x0FFF, but the link on the stack is clearly 0x1000-0x1FFF.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm skeptical, but it certainly could be happening. But if you want us to dig further, post some code. Preferably a complete test program.

There isn't much specific in the datasheet about PC. I see the note about the width on the various family models.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
I'm skeptical, but it certainly could be happening. But if you want us to dig further, post some code. Preferably a complete test program.

There isn't much specific in the datasheet about PC. I see the note about the width on the various family models.


Simply run a program that makes some subroutine calls then stops on a breakpoint, then look at the links on the stack in RAM.

I'm not actually using breakpoints or JTAG, but I have a background thread running which constantly outputs the contents of memory to the serial port so that I can monitor memory in real time.

Edit: If you don't have an easy way to look at RAM, call a subroutine that pops its own link, writes it to EEPROM, then halts. Then use an ISP programmer to read out the EEPROM contents.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

timbierman wrote:
Simply run a program that makes some subroutine calls then stops on a breakpoint, then look at the links on the stack in RAM...
timbierman, you are here asking us for help/advice. The proper thing to do would be for you to make it easier for us to help you by posting the test code, between code tags, here. :)

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

larryvc wrote:
timbierman wrote:
Simply run a program that makes some subroutine calls then stops on a breakpoint, then look at the links on the stack in RAM...
timbierman, you are here asking us for help/advice. The proper thing to do would be for you to make it easier for us to help you by posting the test code, between code tags, here. :)

Well, it was a question about the hardware rather than about a specific coding problem, but here's some code anyway:

EECR:   EQU     0x1F
EEDR:   EQU     0x40
EEARL:  EQU     0x41
EEARH:  EQU     0x42
EEMPE:  EQU     2
EEPE:   EQU     1
        ORG     0
        RCALL   SUB
SUB:    POP     ZH
        LDI     XL,0
        STS     EEARH,XL
        STS     EEARL,XL
        STS     EEDR,ZH
        SBI     EECR,EEMPE
        SBI     EECR,EEPE
HALT:   RJMP    HALT

Run this, then use an ISP programmer to read out the EEPROM. Location 0 in EEPROM will contain the top byte of the subroutine link, which should be 0x00, but will actually be 0x10 (on the Mega88 20PI anyway; I'm not sure yet about the new Mega88PA chips).

Edit: I just tried it with a Mega88PA and the problem has gone away (EEPROM byte 0 reads 0x00). Looks like it was an oddity of the old Mega88, and it doesn't seem to affect the way the program works (except giving me wrong addresses for my debug points, which I can fix by masking with 0x0FFF).