6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Nov 24, 2024 10:13 pm

All times are UTC




Post new topic Reply to topic  [ 69 posts ]  Go to page 1, 2, 3, 4, 5  Next
Author Message
PostPosted: Mon Jul 20, 2020 6:38 pm 
Offline

Joined: Tue Oct 08, 2013 5:40 am
Posts: 72
Location: /home/sci4me
Hey everyone. So, I recently moved my 65c02 computer from a breadboard to a PCB. As far as I can tell, all the hardware is working as intended. However, there is a strange problem with interrupts. The RTI instruction jumps to the wrong place! I've printed this on the serial port: Expected address was $109F, Actual address was $A0A0. The heck?

First I thought I just had a stack issue. But after a lot of auditing (and even printing the stack pointer to serial...) I concluded that this was not the issue.

Then I thought maybe there's a problem with RAM. I wrote a test program that just writes to every address from $0100 to $01FF and reads the written byte back, and checks that they're identical. This problem never found any memory errors...

At this point I'm totally at a loss. I have started to try to build a little debugging jig (poor-man's logic analyzer basically) but haven't gotten that working with the entire computer yet (but it works with only the CPU lol).

I have attached the schematic. If anyone has any ideas, please do reach out! :)


Attachments:
schematic.pdf [829.58 KiB]
Downloaded 87 times
Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 20, 2020 6:57 pm 
Offline

Joined: Thu Mar 03, 2011 5:56 pm
Posts: 284
I think the accepted wisdom here is that /WE should be qualified by phi2, but /CS should not be. The way you do it, you squeeze the entire RAM operation into one half of a processor cycle.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 20, 2020 6:59 pm 
Offline

Joined: Tue Oct 08, 2013 5:40 am
Posts: 72
Location: /home/sci4me
rwiker wrote:
I think the accepted wisdom here is that /WE should be qualified by phi2, but /CS should not be. The way you do it, you squeeze the entire RAM operation into one half of a processor cycle.


That's the other thing I've had in the back of my mind; shouldn't /WE be driven from /RWB?

EDIT: Scratch what I just said; was thinking of /WE for some reason. I'd think that it should be driven the same way as /WE but without the phi2 part?

EDIT2: Actually I don't know what I'm talking about right now lol; my brain just got twisted.
So, /WE should be qualified by phi2 but not /CS? Wouldn't that lead to both the CPU and the RAM trying to drive the bus simultaneously?

EDIT3: Is it wrong to be using PHI2O ("PHI2C") rather than PHI2? i.e. I'm using the output from the CPU rather than from the clock directly.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 20, 2020 7:34 pm 
Offline

Joined: Thu Mar 03, 2011 5:56 pm
Posts: 284
sci4me wrote:
rwiker wrote:
I think the accepted wisdom here is that /WE should be qualified by phi2, but /CS should not be. The way you do it, you squeeze the entire RAM operation into one half of a processor cycle.


That's the other thing I've had in the back of my mind; shouldn't /WE be driven from /RWB?

EDIT: Scratch what I just said; was thinking of /WE for some reason. I'd think that it should be driven the same way as /WE but without the phi2 part?

EDIT2: Actually I don't know what I'm talking about right now lol; my brain just got twisted.
So, /WE should be qualified by phi2 but not /CS? Wouldn't that lead to both the CPU and the RAM trying to drive the bus simultaneously?

EDIT3: Is it wrong to be using PHI2O ("PHI2C") rather than PHI2? i.e. I'm using the output from the CPU rather than from the clock directly.


I just checked against the "6502 Primer", and it looks like I may be wrong about what should be qualified by phi2; see http://wilsonminesco.com/6502primer/addr_decoding.html


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 20, 2020 7:59 pm 
Offline

Joined: Tue Oct 08, 2013 5:40 am
Posts: 72
Location: /home/sci4me
rwiker wrote:
sci4me wrote:
rwiker wrote:
I think the accepted wisdom here is that /WE should be qualified by phi2, but /CS should not be. The way you do it, you squeeze the entire RAM operation into one half of a processor cycle.


That's the other thing I've had in the back of my mind; shouldn't /WE be driven from /RWB?

EDIT: Scratch what I just said; was thinking of /WE for some reason. I'd think that it should be driven the same way as /WE but without the phi2 part?

EDIT2: Actually I don't know what I'm talking about right now lol; my brain just got twisted.
So, /WE should be qualified by phi2 but not /CS? Wouldn't that lead to both the CPU and the RAM trying to drive the bus simultaneously?

EDIT3: Is it wrong to be using PHI2O ("PHI2C") rather than PHI2? i.e. I'm using the output from the CPU rather than from the clock directly.


I just checked against the "6502 Primer", and it looks like I may be wrong about what should be qualified by phi2; see http://wilsonminesco.com/6502primer/addr_decoding.html


So if I read that right, /CS should be qualified by phi2 right?

Also, I just tried using the phi2 input rather than the phi2 output as the input to the decode logic, but it didn't seem to change anything other than that the actual address changed from $A0A0 to $10A0. Strange...


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 20, 2020 8:32 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8546
Location: Southern California
There's more than one way it can be done. You just have to make sure you don't write to RAM before the address is valid and stable, otherwise you may write to unintended addresses, even if by the end of the cycle the intended address also gets written to. This is because the address is not guaranteed to be valid and stable before the R/W line goes down. You can either just not select the RAM until phase 2 rises (which will be plenty of time after the address is valid and stable), or, if it's really slow RAM and you need the extra setup time, you can select it directly from the address decoding but keep its WR\ input false (ie, high) until phase 2 rises. SRAM is available in much faster speeds than anything else you'll probably put on the bus anyway though, so you probably don't need the extra time afforded by the second method.

The 6502 does not drive the bus during the phase-2-low period; so you don't have to be concerned with bus contention. Even when the 6502 does a store, the data are only guaranteed to become valid some time (tMDS) after phase 2 rises; so if the RAM is putting out data until phase 2 rises, driving its WR\ input low should end that before the '02 starts driving the data bus. As for hold time after the end of the write, bus capacitance will hold the data for a surprisingly long time when nothing is driving the bus—not just nanoseconds, not just microseconds, but even milliseconds, according to my experiments. (Actually, I tripped across that fact accidentally, and although I observed the milliseconds part, I did not go further to see just how long I could take it.)

I tried looking at your .pdf schematic, and all I get is eight totally blank pages.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 20, 2020 8:50 pm 
Offline

Joined: Tue Oct 08, 2013 5:40 am
Posts: 72
Location: /home/sci4me
GARTHWILSON wrote:
There's more than one way it can be done. You just have to make sure you don't write to RAM before the address is valid and stable. You can either just not select the RAM until phase 2 rises, or, if it's really slow RAM and you need the extra setup time, you can select it directly from the address decoding but keep its WR\ input false (ie, high) until phase 2 rises. SRAM is available in much faster speeds than anything else you'll probably put on the bus anyway though, so you probably don't need the extra time afforded by the second method.

The 6502 does not drive the bus during the phase-2-low period; so you don't have to be concerned with bus contention. Even when the 6502 does a store, the data are only guaranteed to become valid some time (tMDS) after phase 2 rises; so if the RAM is putting out data until phase 2 rises, driving its WR\ input low should end that before the '02 starts driving the data bus. As for hold time after the end of the write, bus capacitance will hold the data for a surprisingly long time when nothing is driving the bus—not just nanoseconds, not just microseconds, but even milliseconds, according to my experiments. (Actually, I tripped across that fact accidentally, and although I observed the milliseconds part, I did not go further to see just how long I could take it.)

I tried looking at your .pdf schematic, and all I get is eight totally bank pages.


Huh, that's really weird. I'll post pictures of the relevant parts. Also, I am using a 1 MHz crystal oscillator for my clock and the RAM is a CY7C199-35PC. I had this all working on the breadboard so it's confusing me that the PCB version is having this issue now. The fact that interrupts are the only thing having any problem like this suggests to me that it may not actually be that I've made a mistake in the hardware, but I find it hard to believe that at the same time, because I don't see how it could be a software mistake, given that I've been using incredibly simple programs just for testing this specific issue.


Attachments:
2020-07-20_16-44.png
2020-07-20_16-44.png [ 12 KiB | Viewed 1419 times ]
2020-07-20_16-42.png
2020-07-20_16-42.png [ 5 KiB | Viewed 1419 times ]
Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 20, 2020 9:00 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8546
Location: Southern California
I don't offhand see anything wrong with that. You've got a lot of gate delays there, but if you're running at 1MHz, it should be fine. I did edit my last post above to clarify something, but it probably won't affect your circuit. What's in your interrupt code?

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 20, 2020 9:11 pm 
Offline

Joined: Tue Oct 08, 2013 5:40 am
Posts: 72
Location: /home/sci4me
GARTHWILSON wrote:
I don't offhand see anything wrong with that. You've got a lot of gate delays there, but if you're running at 1MHz, it should be fine. I did edit my last post above to clarify something, but it probably won't affect your circuit. What's in your interrupt code?


So, I've done a number of different tests. The simplest way I can think to demonstrate this issue is simply to have the ISR immediately return (`rti`). Then, just use `brk`. So, what I did was to set an LED before the `brk` and set another one after it. And that program ends up just setting the first LED but not the second.

I've also done various tests like printing to to serial via an ACIA, but, given that that simple example is enough to demonstrate the issue, I don't know how relevant this is.

Note that this issue happens both with software and with hardware interrupts. If I recall correctly it also happens on non-maskable interrupts.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 20, 2020 9:41 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
I'd suggest doing something visible in the ISR too. That'll tell you that you arrived.

Do you already know that you can JSR and RTS? The memory activity will be similar.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 20, 2020 10:55 pm 
Offline

Joined: Tue Oct 08, 2013 5:40 am
Posts: 72
Location: /home/sci4me
BigEd wrote:
I'd suggest doing something visible in the ISR too. That'll tell you that you arrived.

Do you already know that you can JSR and RTS? The memory activity will be similar.


Ah, I should've been more specific. I actually did also have an LED turn on in the ISR. (Technically I used the 7-segment LEDs built into my computer but, neither here nor there.)

And yes, I have JSR and RTS working.

Also, I actually tried, at the end of the interrupt, just re-enabling interrupts and `jmp`ing back to the correct address (since I happened to know the address for that test...) and that works just fine, unsurprisingly. Furthermore, I have confirmed that the issue appears to be that the wrong address is being written to the stack when the interrupt occurs (by printing the address used by `rti` to the serial port.)


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 20, 2020 11:08 pm 
Offline

Joined: Tue Oct 02, 2018 4:22 am
Posts: 48
By any chance does anything in your ISR write to the stack?

Do you have an NMI triggering during a regular interrupt?

Shotgunning ideas based on mistakes I made on my machine.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 20, 2020 11:09 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8546
Location: Southern California
What do you find if you look a few bytes above and below that return address? Is the correct address in there somewhere? (which would indicate you have something in the ISR that's getting the stack out of balance)

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Tue Jul 21, 2020 12:53 am 
Offline

Joined: Tue Oct 08, 2013 5:40 am
Posts: 72
Location: /home/sci4me
thedrip wrote:
By any chance does anything in your ISR write to the stack?

Do you have an NMI triggering during a regular interrupt?

Shotgunning ideas based on mistakes I made on my machine.


Technically I do have things that write to the stack in the ISR, but I do know that the pushes are matched with pops correctly.
I'm doubtful that I have an NMI triggering... I haven't explicitly checked for this, but, I have the NMI pin tied high with a pull-up resistor.

GARTHWILSON wrote:
What do you find if you look a few bytes above and below that return address? Is the correct address in there somewhere? (which would indicate you have something in the ISR that's getting the stack out of balance)


Just did a quick test of this, here's what I got:
Code:
01FA: 0A
01FB: E3
01FC: 11
01FD: 31
01FE: A0
01FF: 10
0200: 05
0201: FA
0202: 00
0203: 00


I have kept this testing code as simple as possible; probably under a hundred lines total (most of that is just a few utility procedures for the 7-segment LEDs and the ACIA). I'm pretty convinced that I don't have any silly stack mistake like pushing without popping, etc.; if I do, it's fake news; I've literally even printed out the stack pointer at various points to make sure it was popped appropriately, after calling these 'utility procedures'. Not that it's impossible that I've got a bug in the code somewhere, but I have good reason to doubt it.

This issue is going to be the death of me :lol:

EDIT: Strange; I added some more prints for some more stack values, descending from $01FA. That 31 changed to 71. Assuming that's the flags, uh, well, that's weird...


Top
 Profile  
Reply with quote  
PostPosted: Tue Jul 21, 2020 1:53 am 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
Hmmm. Earlier you said the RTI instruction jumps to the wrong place. Just for fun, what happens if you use RTI to jump somewhere specific -- $1234, for example -- by doing this (below)? Maybe the success or failure of this will reveal a clue, or raise a new question. :|
Code:
lda #12
pha
lda #34
pha
php
rti

-- Jeff

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 69 posts ]  Go to page 1, 2, 3, 4, 5  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: