6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Nov 22, 2024 1:12 am

All times are UTC




Post new topic Reply to topic  [ 69 posts ]  Go to page Previous  1, 2, 3, 4, 5  Next
Author Message
PostPosted: Tue Jul 21, 2020 2:00 am 
Offline

Joined: Tue Oct 08, 2013 5:40 am
Posts: 72
Location: /home/sci4me
Dr Jefyll wrote:
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


Good idea! To be fair, I think I sort of mis-spoke earlier. That was before I had really inspected the stack values very much. It does appear that the RTI itself isn't the problem, it's that the stack has the wrong values in it.

I just wrote this real quick:
Code:
.macro rti_jmp addr
   lda #>addr
   pha
   lda #<addr
   pha
   php
   rti
.endmacro


And used that in my main loop, instead of `bra`. It works just fine.
So there's one thing ruled out at least.

EDIT: Do interrupts affect the memory timing? i.e. are the write cycles in an interrupt the same as any other write cycle? I'm just thinking, it really seems like the wrong values are being written to RAM by the CPU somehow. Not that I think that the CPU itself is getting the wrong answer, but maybe there's some weird timing/electrical issue that only occurs when the CPU is writing to the stack during an interrupt. *shrugs*

EDIT 2: I just wrote this as a test:
Code:
   ldx #0
:   txa
   sta $0100,x
   lda $0100,x
   jsr acia_put_hex_byte
   lda #10
   jsr acia_putc
   inx
   bne :-


However, surprisingly, this did not work; I had to use the Y register rather than the index to get it to behave as expected:

Code:
   ldy #0
:   tya
   sta $0100,y
   lda $0100,y
   jsr acia_put_hex_byte
   lda #10
   jsr acia_putc
   iny
   bne :-


Am I just being dumb or is this some kind of bug? I will note that the `acia_put_hex_byte` procedure uses the X register to implement a lookup table for converting hex digits to ASCII characters, but it pushes and pops it to and from the stack. (Also, `acia_putc` uses X for a short delay loop.) The fact that this loop fails when using X only when X is pushed and pops tells me that the problem is that any(?) data written to the stack gets corrupted occasionally. Although, it's strange that this issue would _always_ happen on interrupts...

EDIT 3: Everything I said in EDIT 2 was fake news; I thought I was pushing and popping X but I actually wasn't! Oh well. Fixed that anyway. And, what I was testing for gave the correct results: writing and reading back every stack location works fine.


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

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
sci4me wrote:
Oh well. Fixed that anyway. And, what I was testing for gave the correct results: writing and reading back every stack location works fine.
OK, good.

What's next to debug? Best if you can drill down to something SIMPLE that should work but doesn't. Then post the details, including the code.

BTW, does your ISR make use of that priority encoder IC? Maybe (just as a test) you could simplify the ISR so it ignores the encoder.

_________________
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  
PostPosted: Tue Jul 21, 2020 3:25 am 
Offline

Joined: Tue Oct 08, 2013 5:40 am
Posts: 72
Location: /home/sci4me
Dr Jefyll wrote:
sci4me wrote:
Oh well. Fixed that anyway. And, what I was testing for gave the correct results: writing and reading back every stack location works fine.
OK, good.

What's next to debug? Best if you can drill down to something SIMPLE that should work but doesn't. Then post the details, including the code.

BTW, does your ISR make use of that priority encoder IC? Maybe (just as a test) you could simplify the ISR so it ignores the encoder.


Well, this is the simplest ISR I can use that demonstrates this problem:
Code:
.proc isr
    rti
.endproc


Obviously I'm not printing anything at that point but I'm pretty confident the failure mode is the same; the stack containing the wrong return address. This with a brk will fail in this way.

I haven't been using the priority encoder in this test code. I do have it inserted into the computer right now, but I have (well, just did) tried removing it and just tying the IRQ line high. And even that fails on `brk`! It's wild. But it does seem to suggest to me that the problem is that when the CPU writes to the stack on an interrupt, there's some corruption going on.

Here's most of the current code: https://pastebin.com/B9ME8Bmt (I can post the rest if anyone's interested).
Also, here's what I'm using to load the code via serial: https://github.com/sci4me/xboot (just an XMODEM downloader).

EDIT: The stack pointer is definitely correct; it's $FC every time in the ISR, which makes since since it's $FF in my main loop.


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

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10985
Location: England
> EDIT: Do interrupts affect the memory timing? i.e. are the write cycles in an interrupt the same as any other write cycle? I'm just thinking, it really seems like the wrong values are being written to RAM by the CPU somehow. Not that I think that the CPU itself is getting the wrong answer, but maybe there's some weird timing/electrical issue that only occurs when the CPU is writing to the stack during an interrupt. *shrugs*

It is true that interrupts are the only time the 6502 will do three cycles of back-to-back writes. I would have guessed that if you had a circuit or timing issue then the two back-to-back writes of a JSR would also show it - but maybe not.


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

Joined: Tue Mar 02, 2004 8:55 am
Posts: 996
Location: Berkshire, UK
Can you post your interrupt code?

_________________
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs


Top
 Profile  
Reply with quote  
PostPosted: Tue Jul 21, 2020 11:03 am 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
Looking at the circuit diagrams up-thread, I would note that the canonical method of generating /CS, /OE and /WE signals is:

1: /CS for each device should depend only on address lines, /VP, and (for the '816) VDA and VPA. It should not be qualified by Phi2; thus two gates should be removed from the RAM /CS chain.

2: /OE and /WE should be generated as ~(R/W & Phi2) and ~(~(R/W) & Phi2) respectively. They will then produce a pulse on one or the other line on every cycle, during a time interval when the address and /CS signals will all be stable.

At 1MHz the speed of memory devices is not likely to be an issue. Ensuring that relative timing requirements are met, however, is still just as important. If /WE is active at any instant when the address or data lines are not stable, then you can expect incorrect data to be written to the wrong places.


Top
 Profile  
Reply with quote  
PostPosted: Tue Jul 21, 2020 1:06 pm 
Offline

Joined: Tue Oct 08, 2013 5:40 am
Posts: 72
Location: /home/sci4me
BigEd wrote:
> EDIT: Do interrupts affect the memory timing? i.e. are the write cycles in an interrupt the same as any other write cycle? I'm just thinking, it really seems like the wrong values are being written to RAM by the CPU somehow. Not that I think that the CPU itself is getting the wrong answer, but maybe there's some weird timing/electrical issue that only occurs when the CPU is writing to the stack during an interrupt. *shrugs*

It is true that interrupts are the only time the 6502 will do three cycles of back-to-back writes. I would have guessed that if you had a circuit or timing issue then the two back-to-back writes of a JSR would also show it - but maybe not.


That's what I was thinking; it seems strange that, if this is an issue with the way I'm driving my RAM chip, it wouldn't show up in places other than interrupts. Not to mention that when I had this _exact same circuit_ with the _exact same chip_ (except I switched from 'LS to 'HC...) on a breadboard, it worked just fine.

BitWise wrote:
Can you post your interrupt code?


I have gone through many iterations of the code, trying to debug this. This is the example I posted earlier: https://pastebin.com/B9ME8Bmt It includes the ISR which prints out a handful of the values on the stack, to the serial port. If there's something else you're looking for I can sure post that was well.

Chromatix wrote:
Looking at the circuit diagrams up-thread, I would note that the canonical method of generating /CS, /OE and /WE signals is:

1: /CS for each device should depend only on address lines, /VP, and (for the '816) VDA and VPA. It should not be qualified by Phi2; thus two gates should be removed from the RAM /CS chain.

2: /OE and /WE should be generated as ~(R/W & Phi2) and ~(~(R/W) & Phi2) respectively. They will then produce a pulse on one or the other line on every cycle, during a time interval when the address and /CS signals will all be stable.

At 1MHz the speed of memory devices is not likely to be an issue. Ensuring that relative timing requirements are met, however, is still just as important. If /WE is active at any instant when the address or data lines are not stable, then you can expect incorrect data to be written to the wrong places.


That's what I had been thinking, but if that were the cause of this problem, wouldn't this interrupt issue have existed on the breadboard version of the computer? I may be mistaken but, I _think_ /WE _and_ /CS shouldn't ever be active when the addr/data isn't stable. /WE may be active before /CS is but that should be fine? Either way, I'm going to try and change the circuit to this after work and see if that changes anything. Maybe I'll get lucky.


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

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
sci4me wrote:
Not to mention that when I had this _exact same circuit_ with the _exact same chip_ (except I switched from 'LS to 'HC...) on a breadboard, it worked just fine.
Which chip got switched from LS to HC? Just curious.

FWIW, at this point I suspect there's a wiring error, and you're not dealing with the exact same circuit. Some very strange symptoms are possible... especially when a connection is absent, resulting in a CMOS input that floats.

-- 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  
PostPosted: Tue Jul 21, 2020 1:22 pm 
Offline

Joined: Tue Oct 08, 2013 5:40 am
Posts: 72
Location: /home/sci4me
Dr Jefyll wrote:
sci4me wrote:
Not to mention that when I had this _exact same circuit_ with the _exact same chip_ (except I switched from 'LS to 'HC...) on a breadboard, it worked just fine.
Which chip got switched from LS to HC? Just curious.

FWIW, at this point I suspect there's a wiring error, and you're not dealing with the exact same circuit. Some very strange symptoms are possible... especially when a connection is absent, resulting in a CMOS input that floats.

-- Jeff


All of the 74-series chips got switched to HC.

And yeah, I definitely have to agree. It has to be some sort of wiring error, but I don't see it showing up in the schematic, which is interesting. I will say, I did forget to tie the unused inputs of the NAND gates and the NOT gates high/low... but I'm not sure that would cause an issue this consistent and specific. Needless to say, I have updated that in the schematic.

Will post back tonight on what happens when I change the /CS, /OE, and /WE signals to the RAM.


Top
 Profile  
Reply with quote  
PostPosted: Tue Jul 21, 2020 2:22 pm 
Offline
User avatar

Joined: Tue Mar 02, 2004 8:55 am
Posts: 996
Location: Berkshire, UK
What triggers the ISR?

You don't seem to be saving the A/X/Y of the interrupted code.
It doesn't seem to do anything to resolve the reason for the interrupt.

_________________
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs


Top
 Profile  
Reply with quote  
PostPosted: Tue Jul 21, 2020 2:52 pm 
Offline

Joined: Tue Oct 08, 2013 5:40 am
Posts: 72
Location: /home/sci4me
BitWise wrote:
What triggers the ISR?

You don't seem to be saving the A/X/Y of the interrupted code.
It doesn't seem to do anything to resolve the reason for the interrupt.


The interrupt is triggered by the `brk` instruction.

I'm not saving A/X/Y in that code just because I didn't care about their values being preserved. Normally I'd just push A/X/Y and pop at the end of the ISR. But since this testing code doesn't really need their values to be preserved, I eliminated the push/pops just to eliminate any potential points of failure. (This code is _only_ for testing/debugging this specific issue.) Not that I think pushing/popping A/X/Y was causing a problem but, you know. I wanted the code to reproduce the issue to be as minimal as possible. I will say though, when I do save and restore A/X/Y, it doesn't seem to change anything.

As for resolving the interrupt source, normally I would read the value from the priority encoder, stored in that D flip-flop and use that to index a jump table, but since this example isn't using any hardware interrupts, only `brk`, it shouldn't matter.
In other code that I have that actually does use this jump-table technique, the resolution works; it jumps to the right handler for the device that caused the interrupt, but the same issue occurs; the return address in the stack appears to be corrupted.


Thank you to everyone for helping so far! I really appreciate it. I just hope we can figure this out :lol:


Top
 Profile  
Reply with quote  
PostPosted: Tue Jul 21, 2020 4:09 pm 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
One significant difference between 74LS and 74HC is that the former will tend to have disconnected inputs float towards the positive rail, while the latter will float randomly between the rails with a lot of influence from nearby changing signals (they're bounded by the rails only because of ESD protection diodes). It's a consequence of 74LS having a relatively low-impedance input structure compared to 74HC. CMOS logic inputs really don't like being left floating, and it is conceivable that this could affect other gates within the same IC; it will certainly increase power consumption, possibly by a lot.


Top
 Profile  
Reply with quote  
PostPosted: Tue Jul 21, 2020 4:15 pm 
Offline

Joined: Tue Oct 08, 2013 5:40 am
Posts: 72
Location: /home/sci4me
Chromatix wrote:
One significant difference between 74LS and 74HC is that the former will tend to have disconnected inputs float towards the positive rail, while the latter will float randomly between the rails with a lot of influence from nearby changing signals (they're bounded by the rails only because of ESD protection diodes). It's a consequence of 74LS having a relatively low-impedance input structure compared to 74HC. CMOS logic inputs really don't like being left floating, and it is conceivable that this could affect other gates within the same IC; it will certainly increase power consumption, possibly by a lot.


I will go ahead and tie the unused inputs low (or, high? Which should I choose? Does it matter?) when I get to work on it later today. It definitely was one of the things I missed before getting the board made.


Top
 Profile  
Reply with quote  
PostPosted: Tue Jul 21, 2020 4:25 pm 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
For 74HC, it doesn't matter which way you tie them, just so long as they're at one of the rails. For 74LS it's a little more efficient to tie them high.


Top
 Profile  
Reply with quote  
PostPosted: Wed Jul 22, 2020 2:46 am 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
sci4me wrote:
BitWise wrote:
What triggers the ISR?

You don't seem to be saving the A/X/Y of the interrupted code.
It doesn't seem to do anything to resolve the reason for the interrupt.


The interrupt is triggered by the `brk` instruction.


The address pushed by the BRK instruction onto the stack is one greater than the location following the instruction.

Could that be the problem?


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 69 posts ]  Go to page Previous  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: