Software constantly hitting ISR

Building your first 6502-based project? We'll help you get started here.
LIV2
Posts: 173
Joined: 12 Feb 2014
Location: Sweden

Software constantly hitting ISR

Post 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?
Image
User avatar
GARTHWILSON
Forum Moderator
Posts: 8775
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Software constantly hitting ISR

Post 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:
Quote:

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).
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?
User avatar
floobydust
Posts: 1394
Joined: 05 Mar 2013

Re: Software constantly hitting ISR

Post 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?
User avatar
BitWise
In Memoriam
Posts: 996
Joined: 02 Mar 2004
Location: Berkshire, UK
Contact:

Re: Software constantly hitting ISR

Post by BitWise »

LIV2 wrote:
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?
Image
(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.
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
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Software constantly hitting ISR

Post 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
LIV2
Posts: 173
Joined: 12 Feb 2014
Location: Sweden

Re: Software constantly hitting ISR

Post 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.
User avatar
floobydust
Posts: 1394
Joined: 05 Mar 2013

Re: Software constantly hitting ISR

Post 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 ;-)
LIV2
Posts: 173
Joined: 12 Feb 2014
Location: Sweden

Re: Software constantly hitting ISR

Post 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!
User avatar
floobydust
Posts: 1394
Joined: 05 Mar 2013

Re: Software constantly hitting ISR

Post by floobydust »

LIV2 wrote:
*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.
User avatar
BigDumbDinosaur
Posts: 9428
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Software constantly hitting ISR

Post by BigDumbDinosaur »

LIV2 wrote:
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.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
LIV2
Posts: 173
Joined: 12 Feb 2014
Location: Sweden

Re: Software constantly hitting ISR

Post by LIV2 »

floobydust wrote:
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 :)
BigDumbDinosaur wrote:
LIV2 wrote:
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
Image
User avatar
cbscpe
Posts: 491
Joined: 13 Oct 2013
Location: Switzerland
Contact:

Re: Software constantly hitting ISR

Post by cbscpe »

You should have this
Read-Write.png
Read-Write.png (3.03 KiB) Viewed 3237 times
And connect all /OE from ROM, RAM etc to /RD and connect /WE from ROM, EEPROM etc to /WR
User avatar
BigDumbDinosaur
Posts: 9428
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Software constantly hitting ISR

Post by BigDumbDinosaur »

cbscpe wrote:
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.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
LIV2
Posts: 173
Joined: 12 Feb 2014
Location: Sweden

Re: Software constantly hitting ISR

Post 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.
User avatar
BigDumbDinosaur
Posts: 9428
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Software constantly hitting ISR

Post by BigDumbDinosaur »

LIV2 wrote:
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.
Quote:
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.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
Post Reply