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

All times are UTC




Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Sat May 10, 2014 8:03 am 
Offline

Joined: Wed Feb 12, 2014 1:39 am
Posts: 173
Location: Sweden
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:
.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


Top
 Profile  
Reply with quote  
PostPosted: Sat May 10, 2014 8:35 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8534
Location: Southern California
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:
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?


Top
 Profile  
Reply with quote  
PostPosted: Sat May 10, 2014 8:45 am 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1385
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?

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
PostPosted: Sat May 10, 2014 8:51 am 
Offline
User avatar

Joined: Tue Mar 02, 2004 8:55 am
Posts: 996
Location: Berkshire, UK
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:
.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:
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


Top
 Profile  
Reply with quote  
PostPosted: Sat May 10, 2014 3:13 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1948
Location: Sacramento, CA, USA
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


Top
 Profile  
Reply with quote  
PostPosted: Sun May 11, 2014 2:08 pm 
Offline

Joined: Wed Feb 12, 2014 1:39 am
Posts: 173
Location: Sweden
Thanks guys, I've taken your advice and here's what I have

Code:
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.


Top
 Profile  
Reply with quote  
PostPosted: Sun May 11, 2014 4:55 pm 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1385
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 ;-)

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
PostPosted: Tue May 13, 2014 1:45 am 
Offline

Joined: Wed Feb 12, 2014 1:39 am
Posts: 173
Location: Sweden
*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!


Top
 Profile  
Reply with quote  
PostPosted: Tue May 13, 2014 2:50 am 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1385
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.

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
PostPosted: Tue May 13, 2014 5:32 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8466
Location: Midwestern USA
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!


Top
 Profile  
Reply with quote  
PostPosted: Tue May 13, 2014 12:47 pm 
Offline

Joined: Wed Feb 12, 2014 1:39 am
Posts: 173
Location: Sweden
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


Top
 Profile  
Reply with quote  
PostPosted: Tue May 13, 2014 4:03 pm 
Offline
User avatar

Joined: Sun Oct 13, 2013 2:58 pm
Posts: 491
Location: Switzerland
You should have this

Attachment:
Read-Write.png
Read-Write.png [ 3.03 KiB | Viewed 2838 times ]


And connect all /OE from ROM, RAM etc to /RD and connect /WE from ROM, EEPROM etc to /WR


Top
 Profile  
Reply with quote  
PostPosted: Tue May 13, 2014 6:20 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8466
Location: Midwestern USA
cbscpe wrote:
You should have this

Attachment:
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!


Top
 Profile  
Reply with quote  
PostPosted: Wed May 14, 2014 2:24 am 
Offline

Joined: Wed Feb 12, 2014 1:39 am
Posts: 173
Location: Sweden
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.


Top
 Profile  
Reply with quote  
PostPosted: Wed May 14, 2014 5:12 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8466
Location: Midwestern USA
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!


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

All times are UTC


Who is online

Users browsing this forum: No registered users and 10 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:  
cron