6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Nov 24, 2024 1:10 am

All times are UTC




Post new topic Reply to topic  [ 50 posts ]  Go to page Previous  1, 2, 3, 4  Next
Author Message
PostPosted: Fri Jul 18, 2014 4:45 am 
Offline

Joined: Sat Jul 28, 2012 11:41 am
Posts: 442
Location: Wiesbaden, Germany
One observation looking at the code:

The 8 µs minimum duration of pb7-hs=1 after a write to the AVR internal shifter may still not be enough, if an interrupt delays the loop after label VOutput1.

But I don't think it is relevant in your case.

I would put an LED on pb7-hs to see, if the AVR stays busy and drive another LED on any 6522 port turned on at the beginning of VOutput and turned off at the end to see wether it gets stuck.

_________________
6502 sources on GitHub: https://github.com/Klaus2m5


Top
 Profile  
Reply with quote  
PostPosted: Fri Jul 18, 2014 5:38 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1748
Location: Sacramento, CA
Rich,

Can you confirm the ATMega88 and 65X22 both get the reset signal to them? If they do, then the fact that the reset switch does not unlock the problem causes some concern as that should everything back to a sane state. We need to find out where in the 6502 loop it's getting stuck and if that is consistent. We also need to monitor the ATMega88 somehow as a reset should cause the splash screen to re-appear at least.

I will play with my prototype this weekend. It is connected to a WDC 65C22 on my SBC-4.

Martin, are you using WDC parts or are they something else?

As for the delay loop in my code, that was left over from testing. The first few lines of code pokes an RTS at the beginning of the delay, nulling it out.

Daryl

_________________
Please visit my website -> https://sbc.rictor.org/


Top
 Profile  
Reply with quote  
PostPosted: Fri Jul 18, 2014 10:51 am 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
8BIT wrote:
Martin, are you using WDC parts or are they something else?


I'm using a Rockwell 65C22P and a WDC 65C02. The CPU is new and the 65C22 was pulled from an old system.


Top
 Profile  
Reply with quote  
PostPosted: Fri Jul 18, 2014 11:48 am 
Offline
User avatar

Joined: Wed Sep 03, 2003 6:53 pm
Posts: 153
Location: Long Island, NY
8BIT wrote:
Rich,

Can you confirm the ATMega88 and 65X22 both get the reset signal to them?
Daryl


Per the schematic, yes. Martin, you can put a continuity tester on the reset line (with power off) and confirm that pin 40 of the 6502 goes to pin 1 of the ATMEGA88 and pin 34 of the VIAs.

Regarding the chip, I'm using WDC versions for all of the chips except the 6551.

_________________
Rich Cini
Build Master and maintainer of the Altair32 Emulation project
http://cini.classiccmp.org
http://altair32.classiccmp.org


Top
 Profile  
Reply with quote  
PostPosted: Sat Jul 19, 2014 6:53 am 
Offline

Joined: Sat Jul 28, 2012 11:41 am
Posts: 442
Location: Wiesbaden, Germany
Martin, I wonder what happens if the reset is out of sync and the Atmega88 is raising busy too late or is loosing serial clocks. Is the 65C02 on 1 MHz? What is the startup delay (fuses) for the Atmega88? If you reset the board when it is working, does it come back working all the time?

You may want to try a weak pullup (about 47k) on the handshake bit to guarantee, that the Atmega88 signals busy early in its reset

Daryl, instead of defining a fixed busy signal, toggeling the handshake bit after receiving a character would remedy many of the current workarounds. The old idle state automatically becomes the new busy state, so the 6502 does not need to wait for it. The Atmega toggles to idle again when the data in SPDR has been saved to the input register instead of waiting for jsr ProcChr or the minimum time of 8 µs.

There is one disadvantage: 1 Byte is needed in RAM, preferably in zeropage.

Proposed code changes not tested! The 6502 Video driver:
Code:
; The modification to toggled handshake requires a reserved byte in RAM
V_idle          = $ee       ; Bit 7 holds the next expected idle state

;----------------------------------------------------------------------
; Output contents of A to the Video Display
;  A is preserved, Flags are changed.
;----------------------------------------------------------------------
VOutput
                pha
                lda  V_idle             ; toggle to new expected idle state
                eor  #$80 
                sta  V_idle
VOutput1               
                lda  Via2PRB            ; test handshake bit (pb7)
                eor  V_idle             ; is old idle state (xored bit7=1)?
                bpl  VOutput1           ; if pb7=busy wait for AVR idle
                pla
                sta  Via2SR             ; send to display via shift register
                rts
 
;----------------------------------------------------------------------
; Call this once to initialize the interface
; it sets up Port B, pin 7 and CB1/CB2 for serial mode
; A is changed and Flags are changed.
;----------------------------------------------------------------------
VInitDisp                                             
                sei                     ; disable interrupts
                lda  Via2DDRB           ; get ddr b
                and  #$7F               ; force bit 7=0
                sta  Via2DDRB           ; set bit 7 to input
                lda  Via2ACR            ; get ACR contents
                and  #$E3               ; mask bits 2,3,4
                ora  #$18               ; set Shift out under control of PHI2 mode
                sta  Via2ACR            ; store to acr
                lda  #$04               ; shift register flag in IER
                sta  Via2IER            ; disable shift register interrupts
                lda  #0                 ; set initial expected idle state
                sta  V_idle
                cli                     ; Enable Interrupts again
                rts                     ; done
The ATMega's video.asm main loop part checking for new data in SPDR:
Code:
main3:
SERIN1:
    in      i, SPSR             ; get shift register status
    sbrs    i, SPIF             ; Wait for reception complete
    rjmp    Main
    st      Y, Curschr          ; restore chr under cursor
    in      inpt, SPDR          ; Read received data
    sbi     pinb,hsp            ; Toggle busy -> idle (SPDR available)
; on the older ATMega8 you need to replace the SBI pinx with the next 4 lines
;    in      i,portb             ; Toggle busy -> idle (SPDR available)
;    ldi     j,(1<<hsp)
;    eor     i,j
;    out     portb,i
    rcall   ProcChr             ; process received data
    rjmp    Main                ; repeat

_________________
6502 sources on GitHub: https://github.com/Klaus2m5


Top
 Profile  
Reply with quote  
PostPosted: Sat Jul 19, 2014 3:00 pm 
Offline
User avatar

Joined: Wed Sep 03, 2003 6:53 pm
Posts: 153
Location: Long Island, NY
I pulled out my board this morning and I'm running a simple loop to keep it busy -- it does multiple passes counting to 32,000, printing each number to the console terminal and video screen.

It's been running for about an hour with no reported issues. I'll see how long it runs or if/when it goes into la-la land.

_________________
Rich Cini
Build Master and maintainer of the Altair32 Emulation project
http://cini.classiccmp.org
http://altair32.classiccmp.org


Top
 Profile  
Reply with quote  
PostPosted: Sat Jul 19, 2014 3:56 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1748
Location: Sacramento, CA
Klaus2m5 wrote:
What is the startup delay (fuses) for the Atmega88? If you reset the board when it is working, does it come back working all the time?

Daryl, instead of defining a fixed busy signal, toggeling the handshake bit after receiving a character would remedy many of the current workarounds. The old idle state automatically becomes the new busy state, so the 6502 does not need to wait for it. The Atmega toggles to idle again when the data in SPDR has been saved to the input register instead of waiting for jsr ProcChr or the minimum time of 8 µs.


Hi Klaus,

Thanks for the recommendations. I just recheck my fuse setting and discovered that thy are set incorrectly. I have the clock source set to use a full-swing crystal vs. external clock. It currently takes 30k clocks + 65ms from power up to come out of reset. The right fuse setting (low byte = $C0 vs. $FF) will provide 20k Clocks + 4.1ms. The major issue is the startup time. Using the corrected setting will get the AVR out of reset faster. It is possible that the SBC OS is getting to the video out routine before the AVR is ready. One easy test is to add a delay loop to the SBC OS before it start generating video outputs.

I will also give your test code a try.

thanks!

Daryl

_________________
Please visit my website -> https://sbc.rictor.org/


Top
 Profile  
Reply with quote  
PostPosted: Sat Jul 19, 2014 4:07 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1748
Location: Sacramento, CA
Martin_H wrote:
Which makes me think the ATMEGA88 firmware is getting wedged and never altering the pin state. I was looking at the schematic and it claims that the ATMEGA88 is reset when the 6502 is, but I've noticed that often the only way to get the system unstuck is to power it off and power it back up again. I don't know if that is significant or not.


Martin,

After reading Klaus' question about the AVR's reset timing, it is possible that the SBC's OS is attempting to write to the video display at about the same time as the AVR is getting ready. If the timing is close, it could explain why the reset does not work. A power cycle will introduce more variables into which system gets ready first.

A simple test would be to add a 1 second delay in the reset code of the SBC. This will ensure the AVR gets ready before the SBC. If that works, we will at least understand the problem better. Can you give that a try?

Klaus also recommended a better handshake protocol which I will test. If that works better, I will provide Rich the updated AVR firmware and SBC routines. This will also fix the AVR fuse settings, helping it start up faster from power-up and reset.

thanks!

Daryl

_________________
Please visit my website -> https://sbc.rictor.org/


Top
 Profile  
Reply with quote  
PostPosted: Sat Jul 19, 2014 4:47 pm 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
RichCini wrote:
Per the schematic, yes. Martin, you can put a continuity tester on the reset line (with power off) and confirm that pin 40 of the 6502 goes to pin 1 of the ATMEGA88 and pin 34 of the VIAs.

I just pulled out the DMM and can confirm there is continuity between all of those pins.

Tonight I'll try two things:

First I'll put a delay loop in the reset processing as suggested to see if that has any effect.

I could swap the two Rockwell 65C22's to see if that alters the behavior in any way. It should be unlikely for two IC's to be faulty in exactly the same way. I've been hesitant to do this because 40 pin IC's are a hassle to get out of their sockets without bending or breaking pins.


Top
 Profile  
Reply with quote  
PostPosted: Sat Jul 19, 2014 7:16 pm 
Offline
User avatar

Joined: Wed Sep 03, 2003 6:53 pm
Posts: 153
Location: Long Island, NY
Guys --

My board has been running in that tight loop since about 10am this morning and it hasn't yet crashed.

The fuse settings are:

; Extd = 0xf9
; High = 0xdf
; Low = 0xff
;
; Compiled using AVR Studio V4.19 with Version 2 assembler

_________________
Rich Cini
Build Master and maintainer of the Altair32 Emulation project
http://cini.classiccmp.org
http://altair32.classiccmp.org


Top
 Profile  
Reply with quote  
PostPosted: Sat Jul 19, 2014 7:17 pm 
Offline

Joined: Sun Jul 28, 2013 12:59 am
Posts: 235
Martin_H wrote:
First I'll put a delay loop in the reset processing as suggested to see if that has any effect.


You might also try putting a delay loop in the AVR reset processing to see if that makes the symptoms worse.


Top
 Profile  
Reply with quote  
PostPosted: Sat Jul 19, 2014 7:47 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1748
Location: Sacramento, CA
RichCini wrote:
Guys --

My board has been running in that tight loop since about 10am this morning and it hasn't yet crashed.

The fuse settings are:

; Extd = 0xf9
; High = 0xdf
; Low = 0xff
;
; Compiled using AVR Studio V4.19 with Version 2 assembler


Rich,

I think it really has to do with the power-up and/or reset and the two MPU's racing to the first video output. If that is the case, then once its past that point, it should run stable, just as your system does. If you really want to confirm this theory, try resetting it repeatedly and see if it ever locks up on you. Could be a timing issue with the WDC 65C22's vs. the Rockwell ones as well.

We will see if adding the reset delay fixes the issue. As far as the fuses goes, it will still work fine with the 0xFF fuse setting, it will just take a little longer to come out of reset.

Daryl

_________________
Please visit my website -> https://sbc.rictor.org/


Top
 Profile  
Reply with quote  
PostPosted: Sat Jul 19, 2014 8:35 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1748
Location: Sacramento, CA
Klaus2m5 wrote:
Daryl, instead of defining a fixed busy signal, toggeling the handshake bit after receiving a character would remedy many of the current workarounds. The old idle state automatically becomes the new busy state, so the 6502 does not need to wait for it. The Atmega toggles to idle again when the data in SPDR has been saved to the input register instead of waiting for jsr ProcChr or the minimum time of 8 µs.

There is one disadvantage: 1 Byte is needed in RAM, preferably in zeropage.

Proposed code changes not tested! The 6502 Video driver:
Code:
; The modification to toggled handshake requires a reserved byte in RAM
V_idle          = $ee       ; Bit 7 holds the next expected idle state

;----------------------------------------------------------------------
; Output contents of A to the Video Display
;  A is preserved, Flags are changed.
;----------------------------------------------------------------------
VOutput
                pha
                lda  V_idle             ; toggle to new expected idle state
                eor  #$80 
                sta  V_idle
VOutput1               
                lda  Via2PRB            ; test handshake bit (pb7)
                eor  V_idle             ; is old idle state (xored bit7=1)?
                bpl  VOutput1           ; if pb7=busy wait for AVR idle
                pla
                sta  Via2SR             ; send to display via shift register
                rts
 
;----------------------------------------------------------------------
; Call this once to initialize the interface
; it sets up Port B, pin 7 and CB1/CB2 for serial mode
; A is changed and Flags are changed.
;----------------------------------------------------------------------
VInitDisp                                             
                sei                     ; disable interrupts
                lda  Via2DDRB           ; get ddr b
                and  #$7F               ; force bit 7=0
                sta  Via2DDRB           ; set bit 7 to input
                lda  Via2ACR            ; get ACR contents
                and  #$E3               ; mask bits 2,3,4
                ora  #$18               ; set Shift out under control of PHI2 mode
                sta  Via2ACR            ; store to acr
                lda  #$04               ; shift register flag in IER
                sta  Via2IER            ; disable shift register interrupts
                lda  #0                 ; set initial expected idle state
                sta  V_idle
                cli                     ; Enable Interrupts again
                rts                     ; done
The ATMega's video.asm main loop part checking for new data in SPDR:
Code:
main3:
SERIN1:
    in      i, SPSR             ; get shift register status
    sbrs    i, SPIF             ; Wait for reception complete
    rjmp    Main
    st      Y, Curschr          ; restore chr under cursor
    in      inpt, SPDR          ; Read received data
    sbi     pinb,hsp            ; Toggle busy -> idle (SPDR available)
; on the older ATMega8 you need to replace the SBI pinx with the next 4 lines
;    in      i,portb             ; Toggle busy -> idle (SPDR available)
;    ldi     j,(1<<hsp)
;    eor     i,j
;    out     portb,i
    rcall   ProcChr             ; process received data
    rjmp    Main                ; repeat


Hi Klaus,

I tested your code and it indeed works. One issue that many cause a problem is the possibility of a misguided write to the VIA SR or to the V_idle byte will get the handshake bit out of sync. If that happens, the video output will lock up. If adding the delay in the reset fixes the problem, I think its best to keep the handshaking the way it is. If not, then we may need to explore this option further.

Thanks again for your contribution!

Daryl

_________________
Please visit my website -> https://sbc.rictor.org/


Top
 Profile  
Reply with quote  
PostPosted: Sat Jul 19, 2014 11:09 pm 
Offline
User avatar

Joined: Wed Sep 03, 2003 6:53 pm
Posts: 153
Location: Long Island, NY
8BIT wrote:
RichCini wrote:
Guys --

My board has been running in that tight loop since about 10am this morning and it hasn't yet crashed.

The fuse settings are:

; Extd = 0xf9
; High = 0xdf
; Low = 0xff
;
; Compiled using AVR Studio V4.19 with Version 2 assembler


Rich,

I think it really has to do with the power-up and/or reset and the two MPU's racing to the first video output. If that is the case, then once its past that point, it should run stable, just as your system does. If you really want to confirm this theory, try resetting it repeatedly and see if it ever locks up on you. Could be a timing issue with the WDC 65C22's vs. the Rockwell ones as well.

We will see if adding the reset delay fixes the issue. As far as the fuses goes, it will still work fine with the 0xFF fuse setting, it will just take a little longer to come out of reset.

Daryl


I went through 25 reset cycles in a row and couldn't get it to crash. I'm using a WDC 65C22 with the diode on the /IRQ line. I have not tried a regular 6522.

Daryl -- if you feel confident with the code, I will merge it into the ROM.

On a separate note, I tried the SD2IEC adapter with a 16mb card with the SBC and it works fine.

_________________
Rich Cini
Build Master and maintainer of the Altair32 Emulation project
http://cini.classiccmp.org
http://altair32.classiccmp.org


Top
 Profile  
Reply with quote  
PostPosted: Sun Jul 20, 2014 12:02 am 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
Here are the results of my two tests:

I added a delay loop in the reset handler and it improved things considerably. Lockups were fewer, and a reset usually fixed things. However, the system could be running stable and still freeze when outputting a character. So improved, but not satisfactory.

I swapped the two Rockwell 65C22's and the lockups seemed to go away. I've been using the system, hitting reset, and powering it off and on. Before I would have seen a lockup within six power cycles. Now I'm still using the ROM version with the reset delay loop, but I'll probably remove that.

So this appears to be a problem with that specific Rockwell 65c22. What's odd about this is I've been able to use the pins for I/O, and the shift register isn't completely broken when this works. It just mysteriously gets out of sync with the ATMEGA88 every once in a while and locks up.

Very odd and sorry for making people scramble if this was a hardware issue. But thanks for all the help.

Update I removed the reset delay loop and the system still seems stable. So it definitely appears to be a problem with that specific 65c22.


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

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 39 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: