Page 1 of 2
Software constantly hitting ISR
Posted: Sat May 10, 2014 8:03 am
by LIV2
Hi,
Does the 6502 jump to the Interrupt vector if it encounters things like stack overflows etc?
I've got some simple code just to write to the ACIA but instead of running in a loop, most of the time it just loops in the ISR.
Randomly resetting a bunch of times eventually gets it working, but I have no idea why.
Here's my code that I've managed to bodge together from other examples:
Code: Select all
.PSC02
.SEGMENT "ROMCODE"
ACIA = $D110
ACIA_CTRL = ACIA+3
ACIA_CMD = ACIA+2
ACIA_SR = ACIA+1
ACIA_DAT = ACIA
RESET: CLD ;Clear decimal arithmetic mode.
CLI
LDA #$1E ;* Init ACIA to 9600 Baud.
STA ACIA_CTRL
LDA #$0B ;* No Parity.
STA ACIA_CMD
LDX #$FF
LOOP:
LDA #$4D
STA ACIA_DAT ;*Send it.
WAIT: LDA ACIA_SR ;*Load status register for ACIA
AND #$10 ;*Mask bit 4.
BEQ WAIT ;*ACIA not done yet, wait.
JSR DELAY_6551
JMP LOOP ;*Done, over and out...
DELAY_6551: PHY ;Save Y Reg
PHX ;Save X Reg
DELAY_LOOP: LDY #10 ;Get delay value (clock rate in MHz 2 clock cycles)
;
MINIDLY: LDX #$68 ;Seed X reg
DELAY_1: DEX ;Decrement low index
BNE DELAY_1 ;Loop back until done
DEY ;Decrease by one
BNE MINIDLY ;Loop until done
PLX ;Restore X Reg
PLY ;Restore Y Reg
DELAY_DONE: RTS ;Delay done, return
ISR:
LDA #$21
STA ACIA_DAT ;*Send it.
WAIT2: LDA ACIA_SR ;*Load status register for ACIA
AND #$10 ;*Mask bit 4.
BEQ WAIT2 ;*ACIA not done yet, wait.
PLA ;*Restore A
JSR DELAY_6551
RTI
I'm also wondering if it could be a bad CPU, the markings are screen printed rather than laser cut like the ACIA and VIA I have, does this look legit to you guys?

Re: Software constantly hitting ISR
Posted: Sat May 10, 2014 8:35 am
by GARTHWILSON
I'll look at it more in a minute, but since you posted recently maybe you'll see this soon enough to save some grief if I punch it out. The first thing that pops out is this:
Code: Select all
RESET: CLD ;Clear decimal arithmetic mode.
CLI
If it's a hardware reset, it shouldn't be any problem, because it should leave no interrupt source set up to produce interrupts (if the reset line goes to the I/O ICs too); but otherwise, you could get into trouble immediately because CLI is CLear the Interrupt
disable bit, not clear interrupt
enable. To answer your question though, no, overflowing the stack does not cause an interrupt; but in normal usage you will only use a small percentage of the page-1 hardware stack space. I suspect if the processor were bad, it wouldn't work at all. BTW, the CMOS 6502 (which you have) already clears the decimal flag on reset, so it's not necessary to put CLD at the beginning of the reset routine or an ISR.
Edit: In ISR, you have a PLA with no matching PHA (or PH-anything).
Re: Software constantly hitting ISR
Posted: Sat May 10, 2014 8:45 am
by floobydust
Hi Liv2,
Seems you grabbed my delay routine which gets around the defective W65C51 chips which were recently made available. I'm guessing you have one of the newer chips which has the XMIT bit stuck in the status register. Note that my timing seed value for the X reg ($68) creates a delay for 19.2K baud rate (524 clock cycles). As you're running at 9.6K baud rate, you should double the X reg seed value ($D0). Also note that looping on the XMIT bit (assuming a defective 65C51 chip) is of no value and you can delete that part of the code. The Y reg value is set for the CPU clock rate in MHz. You show a value of 10 decimal. What clock speed are you running the CPU at? With the values shown ($68 for X reg and 10 for Y reg) a 5MHz clock would be the max that would work with the bad chip.
As for the CPU stack overflow question, short answer is no.... it doesn't know if you overflow the stack, it would just circle back around and get corrupted.. Also, your startup routine seems to load the Xreg with $FF but doesn't xfer to the stack pointer with a TXS, so unless your code segment is incomplete, your stack pointer is not actually set. As you're not enabling any interrupts on the 65C51, it won't create an interrupt, so is there another hardware device that is generating interrupts?
Re: Software constantly hitting ISR
Posted: Sat May 10, 2014 8:51 am
by BitWise
Hi,
Does the 6502 jump to the Interrupt vector if it encounters things like stack overflows etc?
I've got some simple code just to write to the ACIA but instead of running in a loop, most of the time it just loops in the ISR.
Randomly resetting a bunch of times eventually gets it working, but I have no idea why.
Here's my code that I've managed to bodge together from other examples:
Code: Select all
.PSC02
.SEGMENT "ROMCODE"
ACIA = $D110
ACIA_CTRL = ACIA+3
ACIA_CMD = ACIA+2
ACIA_SR = ACIA+1
ACIA_DAT = ACIA
RESET: CLD ;Clear decimal arithmetic mode.
CLI
LDA #$1E ;* Init ACIA to 9600 Baud.
STA ACIA_CTRL
LDA #$0B ;* No Parity.
STA ACIA_CMD
LDX #$FF
LOOP:
LDA #$4D
STA ACIA_DAT ;*Send it.
WAIT: LDA ACIA_SR ;*Load status register for ACIA
AND #$10 ;*Mask bit 4.
BEQ WAIT ;*ACIA not done yet, wait.
JSR DELAY_6551
JMP LOOP ;*Done, over and out...
DELAY_6551: PHY ;Save Y Reg
PHX ;Save X Reg
DELAY_LOOP: LDY #10 ;Get delay value (clock rate in MHz 2 clock cycles)
;
MINIDLY: LDX #$68 ;Seed X reg
DELAY_1: DEX ;Decrement low index
BNE DELAY_1 ;Loop back until done
DEY ;Decrease by one
BNE MINIDLY ;Loop until done
PLX ;Restore X Reg
PLY ;Restore Y Reg
DELAY_DONE: RTS ;Delay done, return
ISR:
LDA #$21
STA ACIA_DAT ;*Send it.
WAIT2: LDA ACIA_SR ;*Load status register for ACIA
AND #$10 ;*Mask bit 4.
BEQ WAIT2 ;*ACIA not done yet, wait.
PLA ;*Restore A
JSR DELAY_6551
RTI
I'm also wondering if it could be a bad CPU, the markings are screen printed rather than laser cut like the ACIA and VIA I have, does this look legit to you guys?

(1) Stack overflows and underflows do not cause interrupts on the 6502. The stack pointer just wraps around and starts accessing the other end of page one.
(2) Once a UART generates an interrupts you must either clear the condition that caused it by reading the received character, putting a new character in the transmit buffer OR you must disable the interrupt. If you don't then after you execute the RTI the interrupt will be immediately re-invoked.
I have been playing with a 3-chip 6502 system and have an emulated 6551 with interrupt driven I/O. The section of my interrupt handler that deals with the ACIA looks like this
Code: Select all
00FF11 AD01FE : LDA ACIA_STAT ; ACIA is the source?
00FF14 103A : IF MI
00FF16 48 : PHA
00FF17 2910 : AND #$10 ; TX Buffer empty?
00FF19 F01C : IF NE
00FF1B AE4002 : LDX TXHEAD ; Any data to send?
00FF1E EC4102 : CPX TXTAIL
00FF21 F00F : IF NE
00FF23 BD4202 : LDA TXBUFF,X ; Yes, extract and send it
00FF26 8D00FE : STA ACIA_DATA
00FF29 205EFF : JSR BumpTx
00FF2C 8E4002 : STX TXHEAD
00FF2F 4C37FF : ELSE
00FF32 A901 : LDA #$01 ; No, disable TX interrupt
00FF34 8D02FE : STA ACIA_CMND
ENDIF
ENDIF
00FF37 68 : PLA
00FF38 2908 : AND #$08 ; RX Buffer full?
00FF3A F014 : IF NE
00FF3C AD00FE : LDA ACIA_DATA
00FF3F AE0102 : LDX RXTAIL
00FF42 9D0202 : STA RXBUFF,X
00FF45 2056FF : JSR BumpRx
00FF48 EC0002 : CPX RXHEAD
00FF4B F003 : IF NE
00FF4D 8E0102 : STX RXTAIL
ENDIF
ENDIF
ENDIF
00FF50 68 : PLA
00FF51 AA : TAX
00FF52 AD0001 : LDA IRQ_TEMP
00FF55 40 : RTI
BumpRx:
00FF56 E8 : INX
00FF57 E03E : CPX #RXSIZE
00FF59 D002 : IF EQ
00FF5B A200 : LDX #0
ENDIF
00FF5D 60 : RTS
BumpTx:
00FF5E E8 : INX
00FF5F E03E : CPX #TXSIZE
00FF61 D002 : IF EQ
00FF63 A200 : LDX #0
ENDIF
00FF65 60 : RTS
The bit patterns for the command register might need a small tweak on a real device by the overall logic is correct.
Re: Software constantly hitting ISR
Posted: Sat May 10, 2014 3:13 pm
by barrym95838
I'm not an ISR expert, but Garth's point about an unbalanced PLA jumped out at me immediately too. Also, there may be a good reason for you to do this, but to me it seems rather wasteful of resources to put a wait loop inside an ISR ... it just rubs me the wrong way, since an ISR is supposed to trigger, get things done as quickly as possible, and get back to the main program.
Mike
Re: Software constantly hitting ISR
Posted: Sun May 11, 2014 2:08 pm
by LIV2
Thanks guys, I've taken your advice and here's what I have
Code: Select all
ACIA = $D110
ACIA_CTRL = ACIA+3
ACIA_CMD = ACIA+2
ACIA_SR = ACIA+1
ACIA_DAT = ACIA
RESET: SEI
LDA #$1E ;* Init ACIA to 9600 Baud.
STA ACIA_CTRL
LDA #$0B ;* No Parity.
STA ACIA_CMD
LDX #$FF
LOOP:
LDA #$4D
JSR PUTC
JMP LOOP ;*Done, over and out...
PUTC:
STA ACIA_DAT ;*Send it.
JSR DELAY_6551
RTS
DELAY_6551: PHY ;Save Y Reg
PHX ;Save X Reg
DELAY_LOOP: LDY #$10 ;Get delay value (clock rate in MHz 2 clock cycles)
;
MINIDLY: LDX #$D0 ;Seed X reg
DELAY_1: DEX ;Decrement low index
BNE DELAY_1 ;Loop back until done
DEY ;Decrease by one
BNE MINIDLY ;Loop until done
PLX ;Restore X Reg
PLY ;Restore Y Reg
RTS ;Delay done, return
ISR: ; Check if this was triggered by an IRQ or a BRK source http://www.6502.org/tutorials/65c02opcodes.html
PHX
TSX
PHA
INX
INX
LDA $100,X
AND #$10
BNE BREAK
BEQ IRQ
IRQ:
LDA #$21
JSR PUTC
PLA
PLX
RTI
BREAK:
LDA #$43
JSR PUTC
PLA
PLX
RTI
NMI:
PHA
LDA #$3F
JSR PUTC
PLA
RTI
It's still hit and miss, and now I'm getting a weird thing where on some resets it's running at 11520 Baud somehow even though I'm using a 1.8432mhz Oscillator to the XTLI input on the ACIA, reading around I found that setting bit 4 in the control register to 0 can cause this source:
http://en.wikipedia.org/wiki/MOS_Technology_6551
This makes me think the main issue I've got is some kind of hardware issue,
here's the schematic for my CPU/RAM/ROM board and
the schematic for my board with the ACIA on it
There's probably a bunch of stuff I'm doing wrong, I believe I'm not supposed to use the PHI2 output from the CPU but to supply that to the rest of the system from the oscillator instead?
Maybe there's too much delay in the address decoding logic too?
I must be doing something horribly wrong here, Running with a 1Mhz system clock or even down as low as a couple hundred Khz using an arduino to generate the clock pulses doesn't make any difference to the reliability.
Re: Software constantly hitting ISR
Posted: Sun May 11, 2014 4:55 pm
by floobydust
Hi Liv2,
A few things become obvious:
1- You're not qualifying read and write signals to the RAM/ROM chips.... that requires simple logic between the PH2 clock and the R/W signals from the CPU to generate the RD and WR lines. See Garth's site for details.
2- You're not enabling any interrupt capability on the 6551, so having both an IRQ and NMI service routine (both attempting to send data to the 6551) makes no sense as neither routine will ever be invoked.
3- You're still not setting the stack pointer.... put a TXS after the LDX $FF in the startup code.
4- Still no clue on which 6551 chip you're using. If you have an older chip, chances are it might be fully functional, in which case there's no need for any delay routine, i.e., you can poll the xmit bit in the status register. If you have the latest WD 65C51 chip, then it has the xmit bit bug and you need the delay routine. Look at laser engraved codes on the chip... let us know.
5- 6522... are you initializing it? Suggest yanking it for diagnostic purposes... one less thing to get in the way.
Would also recommend looking at Daryl Rictor's site and study his schematic for the SBC 2.5 board... it's about as classic as it gets and much simpler. Look at his I/O decoding and wiring up of the 6551 interface signals (RTS, CTS, RxD, TxD, etc.) to ensure you have it done right. Hope this helps.
PS - sorry to be a bit terse..... it's just the day, don't forget to call Mom

Re: Software constantly hitting ISR
Posted: Tue May 13, 2014 1:45 am
by LIV2
*smacks own forehead* that probably explains a lot... if I'm not qualifying the R/W I'm probably filling my ram with junk!
The ISRs are useless so I'll remove them now, and add the TXS so that I'm actually setting the pointer
The 6551 I'm using is the W65C51N6TPG-14 which I ordered from Jameco
And I haven't been initialising the 6522, so I'll pull it out until I get the rest of the system stable.
I’ll re-do the ram selects, R/W signalling on the weekend to work the same as SBC. fingers crossed.
Thanks for the help!
Re: Software constantly hitting ISR
Posted: Tue May 13, 2014 2:50 am
by floobydust
*smacks own forehead* that probably explains a lot... if I'm not qualifying the R/W I'm probably filling my ram with junk!
The ISRs are useless so I'll remove them now, and add the TXS so that I'm actually setting the pointer
The 6551 I'm using is the W65C51N6TPG-14 which I ordered from Jameco
And I haven't been initialising the 6522, so I'll pull it out until I get the rest of the system stable.
I’ll re-do the ram selects, R/W signalling on the weekend to work the same as SBC. fingers crossed.
Thanks for the help!
Well, that's just the WDC part number, what you need to look at is the LOT number which is below the P/N:
W65C51N6TPG-14
A6A749.1
1016G015
The above (and I also bought two from Jameco) are the ones which have the defect. In my experience I've yet to see any code written for the 6551 (including from WDC themselves) which doesn't use the xmit bit in the status register for transmitting data. In short, that means no existing code will work with these chips. That's why I added the simple delay routine, you just waste the right amount of time to allow the 6551 to finish transmitting before exiting the routine. It's just a band-aid and not an elegant one at that.
As for the hardware glitch, well, it happens. When starting from scratch, you can get into a catch-22, i.e., you're not certain whether your hardware is the problem or the software (both of which are new and untested/verified). To ease things a bit (which I did for my first set of boards) I used some (known good) existing code (with the I/O addresses changed for my design) to allow me to verify my hardware worked, then started on writing my own code for it. I still have a version of the old source code which has the delay routine and works with the bad chips. More than happy to send it along if you'd like to try it. It takes one unknown out of the equation.
Re: Software constantly hitting ISR
Posted: Tue May 13, 2014 5:32 am
by BigDumbDinosaur
I’ll re-do the ram selects, R/W signalling on the weekend to work the same as SBC. fingers crossed.
I may be misinterpreting the above, but you don't want to quality the chip selects with Ø2. Only qualify RWB. Chip selects should become valid as soon as your glue logic can make them valid. This is especially important with 65xx I/O silicon, which must have chip selects and RWB valid before the rise of Ø2.
Re: Software constantly hitting ISR
Posted: Tue May 13, 2014 12:47 pm
by LIV2
Well, that's just the WDC part number, what you need to look at is the LOT number which is below the P/N:
W65C51N6TPG-14
A6A749.1
1016G015
*snip*
As for the hardware glitch, well, it happens. When starting from scratch, you can get into a catch-22, i.e., you're not certain whether your hardware is the problem or the software (both of which are new and untested/verified). To ease things a bit (which I did for my first set of boards) I used some (known good) existing code (with the I/O addresses changed for my design) to allow me to verify my hardware worked, then started on writing my own code for it. I still have a version of the old source code which has the delay routine and works with the bad chips. More than happy to send it along if you'd like to try it. It takes one unknown out of the equation.
I've had a look and the lot number is exactly the same on mine
If you could send me that code that'd be great, the whole time I've been assuming it's been a software issue because while I've done a bunch of programming before this is the first time I've touched assembly.
I'll find out on the weekend when I change things around I guess
I’ll re-do the ram selects, R/W signalling on the weekend to work the same as SBC. fingers crossed.
I may be misinterpreting the above, but you don't want to quality the chip selects with Ø2. Only qualify RWB. Chip selects should become valid as soon as your glue logic can make them valid. This is especially important with 65xx I/O silicon, which must have chip selects and RWB valid before the rise of Ø2.
Sorry you're right, I'm terrible at explaining my thoughts etc, this is what I've got and applies to the OE input of the ROM and OE + RW for the RAM

Re: Software constantly hitting ISR
Posted: Tue May 13, 2014 4:03 pm
by cbscpe
You should have this

- Read-Write.png (3.03 KiB) Viewed 3241 times
And connect all /OE from ROM, RAM etc to /RD and connect /WE from ROM, EEPROM etc to /WR
Re: Software constantly hitting ISR
Posted: Tue May 13, 2014 6:20 pm
by BigDumbDinosaur
You should have this
Read-Write.png
And connect all /OE from ROM, RAM etc to /RD and connect /WE from ROM, EEPROM etc to /WR
That's essentially how I have POC wired up. cbscpe's circuit doesn't simultaneously assert /OE and /WE during write cycles, a combination that may be undefined in some hardware.
Note the use of 74AC logic in the illustration. Beware of excessive cumulative propagation delay, which can easily build up with 74HC or 74LS logic. 74HC ("high speed" CMOS) logic, despite the name, is on average no faster than 74LS.
Re: Software constantly hitting ISR
Posted: Wed May 14, 2014 2:24 am
by LIV2
Ahh ok, I've changed my design to match that now, and I've ordered some 74AC logic IC's
I can't seem to get the '85 or '688 comparators in anything faster than HC though, I presume that won't be a problem at 1-5Mhz?
I also realised that I've got VPB tied low on my current design which probably isn't helping things... I'll remove that/replace it with a jumper selection in case I ever want to use a 6502 made by a different vendor.
Re: Software constantly hitting ISR
Posted: Wed May 14, 2014 5:12 am
by BigDumbDinosaur
Ahh ok, I've changed my design to match that now, and I've ordered some 74AC logic IC's
I can't seem to get the '85 or '688 comparators in anything faster than HC though, I presume that won't be a problem at 1-5Mhz?
Almost anything will work at 1 MHz. You'll need to do a timing analysis to determine just how fast the circuit will run.
I also realised that I've got VPB tied low on my current design which probably isn't helping things... I'll remove that/replace it with a jumper selection in case I ever want to use a 6502 made by a different vendor.
VPB (vector pull) is an output and should
*never* be connected to ground. VPB is continuously driven high except during cycles 6 and 7 of an interrupt response sequence, at which time it is driven low. Needless to say, grounding VPB could be a death sentence for the MPU.