6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Sep 21, 2024 1:13 am

All times are UTC




Post new topic Reply to topic  [ 55 posts ]  Go to page Previous  1, 2, 3, 4  Next
Author Message
PostPosted: Mon Jun 10, 2024 2:56 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8390
Location: Midwestern USA
floobydust wrote:
Some things to think about:

- Never use a JSR routine in your interrupt handler... just don't.

I bring this up in my 65C816 interrupts article:


    The use of subroutines in an interrupt service routine can substantially degrade performance, as each JSR – RTS pair will consume 12 clock cycles, or 14 cycles if using JSL – RTL.  If your interrupt handler includes three calls to the same subroutine and is processing a 100 Hz jiffy interrupt, 3600 clock cycles will be consumed per second just in executing JSR and RTS instructions.  A lot of foreground processing can be completed in 3600 cycles!  Only use subroutines if you have to squeeze every last byte out of the available address space.

Quote:
- The routines you're using... any chance they are altering the X or Y index registers??

When writing an interrupt handler, always ensure ALL of your processor registers are saved on entry and restored on exit...

An interrupt handler should never make any assumptions about what the foreground is doing when an interrupt is serviced.  As Flooby notes, do a complete register save and restore, and even though you may not have any immediate plans to use BRK for anything, sniff the stack to determine if you are responding to an IRQ or a software interrupt and if the latter, provide something to trap it.  A bug in your foreground code could result in the MPU seeing $00 as an opcode.  Without differentiation in the IRQ handler’s front end, the MPU will be responding to a spurious interrupt, with possibly “deadly” consequences.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 10, 2024 4:14 am 
Offline

Joined: Fri Mar 18, 2022 6:33 pm
Posts: 489
To answer Jeff's earlier question, yes, the glitches happen with the WDC part even when the board is clocked at a meager 4MHz. They do *NOT* happen if I pull the WDC part and replace it with a CMD or Rockwell part.

Here are my input buffer routines:
Code:
;   Initialize input buffer
;   Modifies: flags
_INPUT_BUFFER_init:
      stz   r_ptr
      stz   w_ptr
      rts

;   Write character in .A to the input buffer
;   Modifies: flags
_INPUT_BUFFER_write:
      phx

      ldx   w_ptr
      sta   INPUT_BUFFER,x
      inc   w_ptr

      plx
      rts

;   Read next character from input buffer and return it in .A
;   Modifies: .A, flags
_INPUT_BUFFER_read:
      phx
      ldx   r_ptr
      lda   INPUT_BUFFER,x
      inc   r_ptr
      plx
      rts

;   Return the number of unread bytes in the buffer in .A
;   Modifies: .A, flags
_INPUT_BUFFER_sizeof:
      lda   w_ptr
      sec
      sbc   r_ptr
      rts

_________________
"The key is not to let the hardware sense any fear." - Radical Brad


Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 10, 2024 4:32 am 
Offline

Joined: Fri Mar 18, 2022 6:33 pm
Posts: 489
Just to give you an idea what I'm seeing, this is what happens when I just hold down the spacebar in wozmon. The backslash is because wozmon resets its line buffer every 128 characters.
Attachment:
Screenshot from 2024-06-09 23-31-00.png
Screenshot from 2024-06-09 23-31-00.png [ 11.85 KiB | Viewed 466 times ]

_________________
"The key is not to let the hardware sense any fear." - Radical Brad


Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 10, 2024 2:57 pm 
Offline

Joined: Fri Mar 18, 2022 6:33 pm
Posts: 489
floobydust wrote:

- You might need to add some additional decoupling caps as you might be getting more noise from the WDC part.
I wasn't able to do this immediately, but I did circle back to it yesterday evening. I put an extra bypass cap by the ACIA's VCC pin, and just for kicks added an extra (wire wrap) ground return. This didn't totally eliminate the glitches, but it does seem to have caused them to become far less frequent. I'm getting 1 glitch every 2 pages of input or so now, instead of 2 - 4 per page.

I wonder if I could have a bad batch of capacitors. I was running low on the nice blue ones I bought from Mouser to build Blue April, so I quickly snagged these guys: https://www.amazon.com/gp/product/B08B3 ... UTF8&psc=1 that were linked to by someone here a while back. It seems kind of farfetched, but they are common to the two boards I've built that have suffered from these kinds of hard-to-locate glitches.

_________________
"The key is not to let the hardware sense any fear." - Radical Brad


Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 10, 2024 3:14 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 843
Location: Potsdam, DE
Personally I wouldn't trust them as far as I could throw, if they were glued to an anvil.

Manufacturer = mxuteuk?

It is alleged - not by me, but I believe it - that there are huge numbers of random company names being generated by the Chinese tat makers, largely to avoid bad news when people discover what they're peddling is indeed crap. Capacitors like this should be a jelly bean part, but be honest: they're not. These may be wonderful - but I'll continue to get my caps from a known brand and from a reputable outlet - Digikey, Mouser, LCSC and the other big names.

https://www.slashgear.com/1336325/reaso ... and-names/

Neil


Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 10, 2024 3:59 pm 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1382
I always buy new known brand parts. For bypass caps, I've been using the Vishay 0.1uF MLCCs for years. Never a problem with them. Mouser stocks them at reasonable prices for qty of 100:

https://www.mouser.com/ProductDetail/Vi ... pm1Q%3D%3D

Before going much further on diagnosing the intermittent issues, I suggest getting better caps and replace all of them. I'd also be sure to add some decent higher value caps around 68uF as well.

Also, be sure to have decent gauge wires for both ground and +5V lines. Do post a few pics as well.... that thousand word kinda thing ;-)

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


Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 10, 2024 5:12 pm 
Offline

Joined: Fri Mar 18, 2022 6:33 pm
Posts: 489
floobydust wrote:
Before going much further on diagnosing the intermittent issues, I suggest getting better caps and replace all of them. I'd also be sure to add some decent higher value caps around 68uF as well.
What are these for, and where should I put them? Is it one-per-IC on the nose like my regular bypass caps, or should I just stick a few of them on the power rails like I do the bulk smoothing caps?

Quote:
Do post a few pics as well.... that thousand word kinda thing ;-)
There are lots of pics over in the Blue August thread, but I don't mind posting more here! :D

_________________
"The key is not to let the hardware sense any fear." - Radical Brad


Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 10, 2024 5:29 pm 
Offline

Joined: Fri Mar 18, 2022 6:33 pm
Posts: 489
Some pics:
Attachment:
PXL_20240610_171945287.jpg
PXL_20240610_171945287.jpg [ 2.5 MiB | Viewed 445 times ]
Attachment:
PXL_20240610_171935057.jpg
PXL_20240610_171935057.jpg [ 3.16 MiB | Viewed 445 times ]

Attachment:
PXL_20240610_172033783.jpg
PXL_20240610_172033783.jpg [ 2.29 MiB | Viewed 445 times ]

Attachment:
PXL_20240610_172146941.jpg
PXL_20240610_172146941.jpg [ 3.08 MiB | Viewed 445 times ]

Attachment:
PXL_20240610_172127034.jpg
PXL_20240610_172127034.jpg [ 3.11 MiB | Viewed 445 times ]

_________________
"The key is not to let the hardware sense any fear." - Radical Brad


Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 10, 2024 6:57 pm 
Offline

Joined: Fri Mar 18, 2022 6:33 pm
Posts: 489
floobydust wrote:
Before going much further on diagnosing the intermittent issues, I suggest getting better caps and replace all of them.
Did that. Didn't make things worse, but didn't make things better either. :cry:

_________________
"The key is not to let the hardware sense any fear." - Radical Brad


Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 10, 2024 7:09 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8390
Location: Midwestern USA
Paganini wrote:
Here are my input buffer routines:
Code:
 ...snip...

;   Write character in .A to the input buffer
;   Modifies: flags
_INPUT_BUFFER_write:
      phx
      ldx   w_ptr
      sta   INPUT_BUFFER,x
      inc   w_ptr
      plx
      rts

;   Read next character from input buffer and return it in .A
;   Modifies: .A, flags
_INPUT_BUFFER_read:
      phx
      ldx   r_ptr
      lda   INPUT_BUFFER,x
      inc   r_ptr
      plx
      rts

...snip...

I see what is fundamentally the same fault in both of the above routines.  Prior to storing a datum into the receive queue (n.b. Referring to it as a “buffer” is technically incorrect—the structure is a circular queue or FIFO.), you need to determine if there is room.  Otherwise, should your queue write index w_ptr (which is not a pointer, BTW) wrap to the same value as your queue read index r_ptr, you will trash older, but still-valid queue content.

Similarly, when fetching a datum from the queue, you need to ascertain that valid data is available.  Otherwise, you will instead fetch garbage, with undefined results.

The general logic used for queue management is:

Code:
put   == get   Queue is empty
put   != get   Queue not empty
put+1 == get   Queue is full

In the above, put corresponds to your w_ptr variable and get corresponds to your r_ptr variable.  In practical use, only the first and third conditions need to be accounted for in software.  This core logic applies to both foreground and background (interrupt) queue accesses.

Regarding the difference between running with a Rockwell or CMD 6551 and the WDC part, the latter has more aggressive edges and much faster overall timing than the older parts.  You might want to examine your construction to see if fast edges might be causing some trouble.  Keep in mind that this is a problem that is relatively independent of the Ø2 clock rate.

Quote:
floobydust wrote:
Before going much further on diagnosing the intermittent issues, I suggest getting better caps and replace all of them.

Did that. Didn't make things worse, but didn't make things better either. :cry:

Take a very close look at your construction methods, and if necessary, scope VCC and ground at the UART for signs of voltage sag and/or ground bounce.  You may have issues related to construction that are not obvious.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Last edited by BigDumbDinosaur on Sat Jun 15, 2024 7:25 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 10, 2024 9:34 pm 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1382
So, I've been examining the attached pics... some observations (which might be wrong):

- Power and Ground: Are you just using wire-wrap for these? I don't see any actual connections to the bottom of the proto boards for ground or power... and in general, you should solder the bypass caps directly to the ground and Vcc pins of the individual chips. Wire-Wrap is not sufficient for power or ground, as you can easily get some ground loop issues.

- The black electrolytic caps should be fine, nuff said.

- you are joining two boards together to make up your SBC... the cables between them are carrying address bus, data bus, clock lines, etc. Is the power also going thru those same ribbon cables?

Back in the day when I did wire-wrap, I always started by running a heavy ground and Vcc lines to all of the chips and directly wired the bypass caps at the same time. In general 22ga wire was what I used. Also note that the ground and Vcc wires were NOT wrapped, but soldered directly at the very bottom of the wire-wrap socket.

In some cases with larger boards and spaced out parts, you might consider soldering in some horizontal ground and Vcc wires between the chips to "sorta" close up the ground and Vcc nets.

Also, if you have open frame IC sockets, you easily install the bypass caps under the chips and directly solder the ends to the ground and Vcc pins on the chips.

One last thought: if you're only trying to get the W65C51 ACIA working, perhaps remove the VIAs and any other components that are not needed. These add loads to the power lines and may cause some noise with the thin wire-wrap wires "IF" they are being used for ground and Vcc.

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


Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 10, 2024 10:38 pm 
Offline

Joined: Fri Mar 18, 2022 6:33 pm
Posts: 489
BigDumbDinosaur wrote:
Regarding the difference between running with a Rockwell or CMD 6551 and the WDC part, the latter has more aggressive edges and much faster overall timing than the older parts.  You might want to examine your construction to see if fast edges might be causing some trouble.  Keep in mind that this is a problem that is relatively independent of the Ø2 clock rate.
That's exactly right. I'd like to know more about this, in general. I think in a day or so (I'll be traveling all day tomorrow) I'll start a new thread that's not specifically about the ACIA.

Quote:
Take a very close look at your construction methods, and if necessary, scope VCC and ground at the UART for signs of voltage sag and/or ground bounce.  You may have issues related to construction that are not obvious.
Ya think? :P

I have checked power and ground all around; every IC has about 4.98 volts across its power/ground pins. I have looked at power and ground on the scope, and nothing looks to me to be too bad, but I am still relatively new at this. Also, my scope is an old 100MHz analogue scope, so it is hard to see really fast or really slow things. I guess it's possible that there could be stuff there that's just invisible to me.

_________________
"The key is not to let the hardware sense any fear." - Radical Brad


Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 10, 2024 10:46 pm 
Offline

Joined: Fri Mar 18, 2022 6:33 pm
Posts: 489
floobydust wrote:
- Power and Ground: Are you just using wire-wrap for these? I don't see any actual connections to the bottom of the proto boards for ground or power... and in general, you should solder the bypass caps directly to the ground and Vcc pins of the individual chips. Wire-Wrap is not sufficient for power or ground, as you can easily get some ground loop issues.
The proto-board I'm using is laid out like solderable breadboards: https://www.amazon.com/POW3U-PowerBoard ... 286&sr=8-1

I make additional power / ground rails by using short jumper wires to join up the 5-hole rows. Basically there's a grid of "squares" so that each IC has power and ground on all 4 sides.

Quote:
- you are joining two boards together to make up your SBC... the cables between them are carrying address bus, data bus, clock lines, etc. Is the power also going thru those same ribbon cables?
Yes; Each cable is a 20-pin IDC with 10 signals; every other wire is a ground. The middle cable has a VCC wire as well. I have some other headers situated around the perimeter of the boards to make additional VCC/GND connections if needed.

There are a few wire-wrapped ground/vcc connections. Generally, inputs that are held high or low are attached directly to that IC's power or ground pin via wire wrap. There are also places where the larger ICs made a gap in the rungs of the ladder, so to speak, so there are a few wire-wrap ground connections back to the edge connecter where I felt like a shorter ground return path might be needed.

_________________
"The key is not to let the hardware sense any fear." - Radical Brad


Top
 Profile  
Reply with quote  
PostPosted: Tue Jun 11, 2024 5:53 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8390
Location: Midwestern USA
Paganini wrote:
BigDumbDinosaur wrote:
Regarding the difference between running with a Rockwell or CMD 6551 and the WDC part, the latter has more aggressive edges and much faster overall timing than the older parts.  You might want to examine your construction to see if fast edges might be causing some trouble.  Keep in mind that this is a problem that is relatively independent of the Ø2 clock rate.
That's exactly right. I'd like to know more about this, in general. I think in a day or so (I'll be traveling all day tomorrow) I'll start a new thread that's not specifically about the ACIA.

There are already a number of topics about this—starting another one probably is unnecessary.

Quote:
I have checked power and ground all around; every IC has about 4.98 volts across its power/ground pins. I have looked at power and ground on the scope, and nothing looks to me to be too bad, but I am still relatively new at this. Also, my scope is an old 100MHz analogue scope, so it is hard to see really fast or really slow things. I guess it's possible that there could be stuff there that's just invisible to me.

Have you scoped the UART’s VCC and ground pins while the serial interface is active?  Checking while things are quiescent won’t tell you much, in my opinion.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Fri Jun 21, 2024 6:43 pm 
Offline

Joined: Sun Feb 22, 2004 9:01 pm
Posts: 87
I've been doing a bit more investigation about working with the 6551 as used on the BenEater 6502 SBC. This is all considering polled I/O. Does the following make sense?

Transmitting:
With TxRDY (TxEmpty) always being stuck ON, the recommended workaround is to use a software delay long enough for the shift register to move the data out. That seems a waste of CPU cyles to me, and I looked for ways to have some other "poll until ready" method that would allow the CPU to be doing something else between each transmission.

The BenEater also has a 6522 VIA, so my first thought was to program that to provide a centisecond counter - a common interupt task - and have that decrement a counter that the transmitter code could check. However, a 1cs tick at 1MHz is 10,000 cycles - 20 times longer than the 520 ticks that 19,200 at 1MHz needs. Maxing out at 115,200 just needs 87 ticks which you get from only 12 counts of a loop. So, reluctantly, at this point, sticking with a hard transmission delay.

The other thing that BenEater doesn't seem to have addressed yet is handshaking. Before transmissing you should check that the other end isn't saying "woah! I'm busy!". Here we hit another hardware problem.

Normally, CTS is used for this. But on the 6551 if CTS is lowered when a byte is being transmitted the TxData is corrupted. Documentation recommends CTS be tied to ground. However there is another input which can be monitored manually, DSR. So, tie DCD and CTS to ground, and use DSR as the incoming CTS line.

So, this gives me this code for polled data transmission:

Code:
; DCD and CTS tied to ground
; DSR used as incoming CTS
;
TxDELAY: EQU   ((MHZ*10000)/(BAUD/1000)-41)/5+1
; Minimum baud: 1MHz = 9600
;               2MHz = 19200
;               4MHz = 38400
; Modified code can be used for slower speed/faster CPU
TxBYTE:                 ; 6 for JSR
    PHA                 ; 3
    SEC                 ; 2
    LDA  #DELAY         ; 2
TxLOOP:
    SBC  #1             ; 2
    BNE  TxLOOP         ; 3,2   ; Loop to delay
TxWAIT:
    LDA  ACIA_STATUS    ; 4
    ASL  A              ; 2     ; Move DSR to bit 7
    BPL  TxWAIT         ; 3,2   ; Loop until other end says Ok to transmit
    PLA                 ; 4     ; Get byte back
    STA  ACIA_DATA      ; 4     ; Send it
    RTS                 ; 6

Receiving:
With receiving, we are the end saying "woah! I'm busy!" To do this we need to raise RTS or DTR depending on how we rise the output to the outgoing RTS line. Also, we need to ensure that we only lower RTS when we are able to take a byte from the incoming RxData. With polled input that means we must only lower RTS in the read routine itself to prevent something being sent when we are busy in some other code.

Something easy to miss is that even when we have raised RTS there may still be data "on the line" which will get overwritten if we lower RTS and don't get the previous byte of soon enough. So, we should check if there's a byte waiting for use before telling the other end it can start sending.

So, this gives me this code for polled data reception:

Code:
; DTR or RTS used as outgoing RTS
;
RxBYTE:
    LDA  ACIA_STATUS
    AND  #&08           ; Check RxRDY (RxFull)
    BNE  RxREAD         ; Already a byte waiting
    LDA  #&09           ; RTS=0, DTR=0
    STA  ACIA_COMMAND   ; Allow other end to transmit
RxWAIT:
    LDA  ACIA_STATUS
    AND  #&08           ; Check RxRDY (RxFull)
    BEQ  RxWAIT
    LDA  #&00           ; RTS=1, DTR=1
    STA  ACIA_COMMAND   ; Stop other end transmitting
RxREAD:
    LDA  ACIA_DATA
    RTS

All this needs initialisation code along these lines:
Code:
RxTxINIT:
    STA  ACIA_RESET     ; Reset ACIA
    LDA  #&00           ; RTS=1, DTR=1
    STA  ACIA_COMMAND   ; Prevent other end transmitting
    LDA  #&1F           ; Eg: 19,200 with 1.8MHz clock
    STA  ACIA_CONTROL
    RTS


A TxDATA routine to allow a wider range of baud rates and CPU speed.
Code:
TxDELAY: EQU   ((MHZ*10000)/(BAUD/1000)-37)/86+1
; Minimum baud: 1MHz = 600
;               2MHz = 1200
;               4MHz = 2400
TxDATA:                 ; 6 for JSR
    PHA                 ; 3
    TXA                 ; 2
    PHA                 ; 3
    SEC                 ; 2
    LDA  #DELAY         ; 2
TxLOOP1:
    LDX  #16            ; 2
TxLOOP2:
    DEX                 ; 2
    BNE  TxLOOP2        ; 3,2
    SBC  #1             ; 2
    BNE  TxLOOP1        ; 3,2   ; Loop to delay
    PLA                 ; 4     ; Get X back
    TAX                 ; 2
    PLA                 ; 4     ; Get byte back
    STA  ACIA_DATA      ; 4     ; Send it
    RTS                 ; 6

_________________
--
JGH - http://mdfs.net


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

All times are UTC


Who is online

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