Page 1 of 3
Freezing 6502
Posted: Thu Jan 25, 2007 8:02 pm
by kernal34
It appears my breadboard 6502 computer is freezing. It will only execute the first few lines of code on my 2864 ROM chip, and then appears to freeze. I know it's working that far, as the first few lines of code turn on some LED's attached to a 6522, but after that it does nothing.
Is there anyway that I can tell if the processor is actually frozen by putting a scope on it or something... I'm at a loss to find a reason for it.
Thanks
Posted: Thu Jan 25, 2007 8:47 pm
by GARTHWILSON
I know it's working that far, as the first few lines of code turn on some LED's attached to a 6522
LEDs are not very reliable for troubleshooting because their turning on can be the result of a crash or other undesired behavior, so you still might not be able to be sure of anything. A beep works better because the pitch, beep lengths, pauses, etc are determined by software and tell what part of the program you're in. Don't use a beeper with a built-in oscillator though.
Is there anyway that I can tell if the processor is actually frozen by putting a scope on it or something... I'm at a loss to find a reason for it.
Try the tips numbers 35 through 37 at
viewtopic.php?t=342&start=35 . Tip #41 at
viewtopic.php?t=342&postdays=0&postorder=asc&start=53 might help too.
You might want to give the NOP generator at
http://6502.org/mini-projects/nop-gen/nop-gen.htm a try.
Posted: Thu Jan 25, 2007 9:06 pm
by kernal34
LEDs are not very reliable for troubleshooting because their turning on can be the result of a crash or other undesired behavior
Even when they are connected to a 6522? Isn't that something you might expect an I/O chip to do? What is it about an LED that would cause a CPU to crash?
Thanks
Posted: Thu Jan 25, 2007 9:24 pm
by kernal34
Could I prevent the LED's being an issue if I used an 74LS138 hexinverter as a buffer between the 6522 and the LED's?
Posted: Thu Jan 25, 2007 9:25 pm
by kernal34
Woops... I meant an 74LS04....

Posted: Thu Jan 25, 2007 9:43 pm
by GARTHWILSON
If you want to add to your post, you can click on "Edit" in the top-right corner. Then you won't end up with three short posts in a row. I frequently use the "Edit" since I often find mistakes or omissions after I post.
The source of potential trouble with the LEDs does not come from the 6522, but rather from the fact that various problems in your program or even hardware design might turn an LED on or off without telling you something is wrong. That's not to say LEDs are useless as a troubleshooting tool, but you might want to at least use a software routine to make them go off an on at a rate or in a sequence that guarantees you that it's happening under software control instead of being a possible random effect of the whole thing being out of control.
Current-production 65c22's can drive more current that a 74LS04. I would put a few hundred ohms in series with the LED to control the current so you don't damage either the LED or the VIA. I think the old NMOS VIAs had the equivalent of an LSTTL driver at their outputs. I have Rockwell ones here that can sink over 110mA.
Tell us more about the problem if you can so we'll have more to go on.
Posted: Thu Jan 25, 2007 10:24 pm
by kernal34
Well, I have a 6502 CPU with a 2864 EEPROM chip, and a 6522 VIA memory mapped with a 74LS138. I have 16 LED's connected to the 16 I/O pins from ports A and B on the VIA.
The initial code turns on Every Second LED by sending a $AA to the ouput ports of the VIA.
The LED's then look like this.....
10101010 10101010
This worked no problem... I then modified the code to flash the LED's alternating between the on and off by sending $AA to the output ports followed by a $55.
here is the code
Code: Select all
; Program NCS ROM2 $0000 to $1FFF 01/24/2007
; Flashes alternating LED's connected to 6522 Port 'A' & 'B'
.ORG $0000
Out_B = $8000 ;Output Port B 6522
Out_A = $8001 ;Output Port A 6522
DDR_B = $8002 ;Data Direction Register Port B 6522
DDR_A = $8003 ;Data Direction Register Port A 6522
LDA #$FF ;Set Data Direction to Output for both ports
STA DDR_A
STA DDR_B
main LDA #$AA ;Turn Every Second Bit on for both Ports 10101010
STA Out_A
STA Out_B
JSR delay ;Wait 1/10 second
LDA #$55 ;Turn Alternate bits on for both Ports 01010101
STA Out_A
STA Out_B
JSR delay ;Wait 1/10 second
JMP main ;repeat
delay LDA #$00
LDX #$C4 ;2 cycles $C4x$FF=49980 Cycles apprx 1/10 second
loopB LDY #$FF
loopA DEY
BNE loopA
DEX
BNE loopB
RTS
.END
When I run this code... only the $AA gets sent to the ports, and it seems to crash before the $55 gets there, as the LED's only showed the following.
10101010 10101010
To test this, I switched the $AA for the $55, and switched the $55 for the $AA and when I run it I get
01010101 01010101 on the LED's, so I know it's getting that far.
The code seems to work fine in the simulator, so I don't think it's the code, all though I'm not simulating the 6522, so maybe the problem is there.
Any thoughts?
Posted: Thu Jan 25, 2007 10:50 pm
by faybs
You may have a problem with your stack. Two questions, sorry if they seem dumb but it's usually best to start with the simple stuff
1. Do you have RAM wired at the $0100-$01ff address range? if you've messed up the address decoder, it's possible that your stack wouldn't have any memory to live on, and so the RTS at the end of 'delay' will cause your code to jump to some random address. If there's no memory at that address, then who knows what crazy opcodes the CPU is seeing...
2. What was your stack pointer set to when your code started? if you have the reset vector just set to 0 to jump to your code on reset, then the stack pointer will have an unpredictable value, which again could cause the RTS to go off the deep end.
Posted: Thu Jan 25, 2007 10:55 pm
by GARTHWILSON
Reading between the lines, I hear you saying you have EEPROM in low memory, and no RAM. Zero page does not normally have code in it since the benefits it affords with quicker addressing and more addressing modes are enjoyed in system variables and not code. The hardware stack resides in page 1 and you don't have any RAM there, meaning that the processor has no way to find its way back to the main routine after the subroutine has run. Hence, the crash.
Edit: I see faybs posted while I was writing, saying the same thing for his #1. I don't think #2 however should make any difference if you reserve the whole page 1 for stack. Wherever the pointer starts, it should work, even if it wraps around. The automatic wrap-around makes it like a circle, and any part of the circle is as good as any other part to start on. I've never tried going without the usual LDX #FF, TXS at the beginning though. My current workbench computer keeps a few system variables in the area of $100 to $120, so I have to keep the stack from overwriting those.
Posted: Thu Jan 25, 2007 11:02 pm
by kernal34
Well... that's probably it then.... cause I don't have any RAM at all!! I guess as soon as you do any branching, the stack need memory. I feel kinda stupid now!
Posted: Thu Jan 25, 2007 11:16 pm
by faybs
It's more the JSR/RTS that got you... regular branching doesn't use the stack. As you have your system right now, PLA, PLX, PLY, PLP and RTS are not going to work. On the plus side, you can (ab)use the S register as an extra regular register thanks to TXS and TSX.
Posted: Thu Jan 25, 2007 11:21 pm
by faybs
I don't think #2 however should make any difference if you reserve the whole page 1 for stack. Wherever the pointer starts, it should work, even if it wraps around. The automatic wrap-around makes it like a circle, and any part of the circle is as good as any other part to start on.
Interesting... for some reason I have always thought that if the stack pointer was set to 0 (so the next push of a byte would to write to $0100) and you did a jsr, something would go horribly wrong on the rts because the low byte of the return address would go to $0100 and the high byte to $01ff. Was that a quirk of the 6510 or my fevered teenage imagination?
Posted: Fri Jan 26, 2007 12:25 am
by GARTHWILSON
Interesting... for some reason I have always thought that if the stack pointer was set to 0 (so the next push of a byte would to write to $0100) and you did a jsr, something would go horribly wrong on the rts because the low byte of the return address would go to $0100 and the high byte to $01ff. Was that a quirk of the 6510 or my fevered teenage imagination?
That could have been a bug of the NMOS ones, but I think I would remember reading about it. I quit using NMOS soon after I got into this game. The high byte will always be 01 on the 6502, and the low byte will cross the 00-FF boundary in both directions the same as any other boundary like EF-F0. High byte could get written to 100, low to 1FF, and then upon return, they get taken off in reverse order. You'd be out of luck if you did a JMP (ind) using 1FF, but I can't think of any reason to do that on a stacked value. That's what RTS is for. In fact RTS has uses beyond just returning from a subroutine.
PLA, PLX, PLY, PLP and RTS are not going to work.
Better add RTI to that list.
Posted: Fri Jan 26, 2007 12:46 am
by faybs
Better add RTI to that list.
Doh!
Posted: Fri Jan 26, 2007 3:05 am
by kernal34
Well, I put a 2K RAM chip starting at $00, and it didn't seem to make any difference, although abviously I need RAM, but I must have other problems as well.
I am in the process of checking over my whole setup, and I have a question.
When keeping the RDY pin high, should I be using a 3K pullup, or can I tie directly to +5V. Also, what about IRQ and NMI?
Thanks