6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Nov 16, 2024 11:59 pm

All times are UTC




Post new topic Reply to topic  [ 48 posts ]  Go to page 1, 2, 3, 4  Next
Author Message
 Post subject: Orwell - odd 6551 issues
PostPosted: Mon Nov 04, 2013 3:17 am 
Offline

Joined: Mon Apr 16, 2007 6:04 am
Posts: 155
Location: Auckland, New Zealand
Hello, an update and an issue on my project. I have been trying to get load and save working using the 6551 (a Rockwell one) I have on my Orwell machine. I am using it to send serial to my little VDU board. That works great.

To save I simply capture the byte stream in a terminal program (I use PuTTY). That all works great.

For load I enable the receive interrupt on the 6551 then use Garth's circular buffer scheme to store characters each interrupt. A flag enabled when in 'LOAD' mode then makes my main loop inside MS Basic read characters from the buffer instead of the keyboard as is usual. To exit out of load mode and resume keyboard control I look for a control-c key press on the keyboard. In loading mode that's the only key press that does anything.

This all actually works pretty well... most of the time.

My ACIA is sitting at $4800. My VIA (used for keyboard scanning is at $5000). As far as I can tell my chip select logic is all fine (it's based on Garth's from the primer).

I do however get some odd errors. If I keep sending it lots of data eventually the computer locks up. Well, it's still running, I can see interrupts happening if I send more data it's way, but my IO stops. It's like the VIA stops working or the code is stuck in a loop somewhere.

The other thing I found is if I do a POKE 18433, 0 from Basic the same thing happens. It's like the VIA stops responding. 18433 is $4801 which is the ACIA status register and it should do a programmed reset. Poking anything to that address stops it. Poking the other registers is fine. Just something weird about the status register.

Another odd thing is if I disconnect either of the CS lines on the ACIA (and wire them the appropriate way to NOT select the chip) I get the same symptoms. It's like my VIA stops working so the keyboard doesn't work.

It's very odd. Maybe some hardware fault? Some quirk of the breadboard construction? Something really obvious I am missing?

As I say normally the machine works fine. I can boot into Microsoft Basic. Can input from the keyboard, get video output, can input and run Basic programs. I have a buzzer on Pin 7 of the VIA and I can poke to the timer one latch and make silly noises with it fine. It's can't be a fundamental wiring issue as I can get things set up and running OK. There is just something odd with the ACIA and it's status register I think.

Simon

_________________
My 6502 related blog: http://www.asciimation.co.nz/bb/category/6502-computer


Top
 Profile  
Reply with quote  
PostPosted: Mon Nov 04, 2013 3:52 am 
Offline

Joined: Mon Apr 16, 2007 6:04 am
Posts: 155
Location: Auckland, New Zealand
OK, I think I gave myself a hint what is happening. It's not hardware. I think it's getting stuck in my send character routine. The code for that has to check a bit in the status register to make sure the transmitter data register is empty before writing a new character to be sent. I think I am getting stuck in a loop there. It's like the transmit buffer has something in it that never clears. My code is waiting for it to clear to send the next character to the screen. It never clears so effectively my machine is locked up.

Simon

_________________
My 6502 related blog: http://www.asciimation.co.nz/bb/category/6502-computer


Top
 Profile  
Reply with quote  
PostPosted: Mon Nov 04, 2013 4:25 am 
Online
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8541
Location: Southern California
Just groping in the dark for possibilities, since we can't see it:

  • Does your ISR make sure all possible interrupt sources in the ACIA are serviced before exiting? (I mention this in Tip #14 at the bottom of the first page in the "Tip of the Day" column.)
  • Can you tell if a constant IRQ\ low is keeping the computer from doing anything else when it seems to lock up (ie, that as soon as it exits the ISR, it goes right back into it)?
  • Do the lights on the minitester give away any secrets? (This is covered near the end of the RS-232 primer.) (You can get the same info from an oscilloscope on the ACIA pins, but less conveniently.)

_________________
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: Mon Nov 04, 2013 7:38 am 
Offline

Joined: Mon Apr 16, 2007 6:04 am
Posts: 155
Location: Auckland, New Zealand
The only interrupt I have it the ACIA receive interrupt. I specifically check for that bit in the ISR and then handle it.

It's definitely not getting stuck in the ISR. I thought of that too and checked that. I can see on the scope the ISR line is remaining high.

And I think the serial lines are all OK. I was actually running it with no flow control at all. Now I am using RTS/CTS and it behaves the same.

The issue is definitely that the ACIA gets into a bad state then I can't reset it properly. Although I have it now so that when I get a receive error I do a program reset on the ACIA and go out of load mode. That stops the whole machine locking up as I can still transmit from it so my character send routine doesn't get stuck.

What I have noticed is if I read the ACIA data register enough times it seems to eventually clear itself and start working again.

I am currently not using any flow control to make things a bit easier to follow.

The issue only happens when I send a lot of data at once. If I am typing normally in the terminal program the characters all get received fine. It's only if I paste a bunch of lines in there it overflows then I can't get it to reset.

What I have found is once it does break doing a few reads and writes to the ACIA data register seems to clear the error. I can do those from Basic using poke commands.

_________________
My 6502 related blog: http://www.asciimation.co.nz/bb/category/6502-computer


Top
 Profile  
Reply with quote  
PostPosted: Mon Nov 04, 2013 8:36 am 
Offline

Joined: Mon Apr 16, 2007 6:04 am
Posts: 155
Location: Auckland, New Zealand
I found it's a lot more reliable if I don't do a programmed reset on the ACIA and instead just do another read of the data register. That clears the overrun error. Instead of dropping out of load mode I just beep now on errors and continue on. I also turned off the flow control. I just let the buffer overwrite if necessary.

Odd chip to get working right! I did discover the only data sheet that explains things well is the Rockwell one. The MOS one is a bit vague!

Simon

_________________
My 6502 related blog: http://www.asciimation.co.nz/bb/category/6502-computer


Top
 Profile  
Reply with quote  
PostPosted: Mon Nov 04, 2013 9:06 am 
Online
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8541
Location: Southern California
Quote:
I found it's a lot more reliable if I don't do a programmed reset on the ACIA and instead just do another read of the data register. That clears the overrun error. Instead of dropping out of load mode I just beep now on errors and continue on.

Can you tell why you're getting errors? I have used the (non-WDC) 65c51 for 20+ years and have never had any trouble with it, and have transferred--who knows? gigabytes? with it, without errors. I never needed to do any troubleshooting with it either (except the issue with neglecting to put the capacitors in the crystal circuit). It just worked.

Yes, the Rockwell data sheet tells more than other brands.

_________________
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: Mon Nov 04, 2013 9:21 am 
Offline

Joined: Mon Apr 16, 2007 6:04 am
Posts: 155
Location: Auckland, New Zealand
I was getting receive buffer over run errors. The receiver is the only interrupt I have so it should be getting serviced as soon as one arrives. And my code is pretty much like your primer serial receive example with the circular buffer.

I think it's just when I try to paste a lot of data into the terminal window it overwhelms things and I get errors. I am just trying a different terminal program (Teraterm instead of PuTTY) and in that I can specify a delay between characters. So I am still sending/receiving at 19200 but with a 1mS delay between characters being sent and it's working fine. No errors at all now.

Needs more playing with. Late here now though. Bring is going to sleep! Thanks for your help and suggestions. Will investigate more tomorrow.

_________________
My 6502 related blog: http://www.asciimation.co.nz/bb/category/6502-computer


Top
 Profile  
Reply with quote  
PostPosted: Mon Nov 04, 2013 1:51 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
Haven't been following this closely, but off the top of my head here's a question. If putting a delay between transmitted characters helps, that suggests maybe the circular receive buffer is overflowing for some reason. What happens if you increase the size of that buffer? Is it easy to try such an experiment?

As a "solution," it's just a band-aid. But you may gain some insight that lets you solve the real problem. (You could try reducing the buffer size, too, just to see what happens.) I'd suggest the change be drastic : factor-of-four, maybe, just so any change in behavior is unmistakable...

cheers,
Jeff

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
PostPosted: Mon Nov 04, 2013 4:50 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8493
Location: Midwestern USA
Dr Jefyll wrote:
Haven't been following this closely, but off the top of my head here's a question. If putting a delay between transmitted characters helps, that suggests maybe the circular receive buffer is overflowing for some reason. What happens if you increase the size of that buffer? Is it easy to try such an experiment?

As a "solution," it's just a band-aid. But you may gain some insight that lets you solve the real problem. (You could try reducing the buffer size, too, just to see what happens.) I'd suggest the change be drastic : factor-of-four, maybe, just so any change in behavior is unmistakable...

cheers,
Jeff

It's possible that CTS/RTS handshaking isn't working as it should. If it was, CTS should be deasserted when the receive buffer is close to full and no overrun should ever occur. It's been my (very lengthy) experience with TIA-232 that many implementations have errors in how they handle the handshaking situation. The 6551 makes it more difficult due to its brain-dead design.

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


Top
 Profile  
Reply with quote  
PostPosted: Mon Nov 04, 2013 6:47 pm 
Offline

Joined: Mon Apr 16, 2007 6:04 am
Posts: 155
Location: Auckland, New Zealand
Currently I have the circular buffer but with no handshaking at all. So when the buffer is full it just starts overwriting itself. So I might see errors in the received stream from dropped characters perhaps but not overrun errors which seem to be when you haven't read the data buffer on the ACIA before the next arrives.

Could I be causing myself problems having interrupt driven receive but poll driven transmit?

_________________
My 6502 related blog: http://www.asciimation.co.nz/bb/category/6502-computer


Top
 Profile  
Reply with quote  
PostPosted: Mon Nov 04, 2013 7:48 pm 
Online
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8541
Location: Southern California
Quote:
And my code is pretty much like your primer serial receive example with the circular buffer.

"Pretty much"? So there are slight differences? What are they? Is it just the bit rate, and additions for setting up the transmit? I just realized you're using the NMOS 6551, which I have never used, so I was looking for an ap. note I have somewhere on things to watch out for, but I can't find it at the moment. There were a couple of small differences. I have only used the CMOS one. What do you have in the command and control registers? The unused hardware handshake input lines aren't just left floating, are they?

Dr. Jefyll's idea of trying something not apparently related does sometimes expose another problem, or at least get you thinking on the right track. In my debugging tips, I also mention commenting thoroughly as if to explain it in detail to someone else, because there have been times that I did that on code that seemed to be working, and in the process, I found bugs that had not shown up yet.

_________________
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: Mon Nov 04, 2013 8:41 pm 
Offline

Joined: Mon Apr 16, 2007 6:04 am
Posts: 155
Location: Auckland, New Zealand
Agree about the commenting. It definitely helps. I do comment thoroughly. And to be honest when posting my issues here I don't really expect people to solve them for me. Just explaining them helps a lot then you guys point out any really boneheaded mistakes and give me lots of other things I should think of.

It takes me a long time to debug because 1. I am still learning as I go and 2. I only change one thing at a time. I've learned changing too many things at once can really mess you up!

But here's the latest. I probably didn't make it clear but I am using interrupt driven receive but doing polled transmit. The transmit just waits until the transmit data register is empty in a loop then it puts in the byte to transmit.

It's doing this whenever the machine wants to output to the screen (via my serial driven display board).

The receive is working off interrupts. I only enable that when I am loading. The Basic code though is echoing whatever is received to the screen as it's being received.

I think what was happening was the two were clashing. To test this I now don't send anything to the screen when receiving serial data in load mode. Instead I enabled the local echo on the ACIA.

This is now working well. I get almost no errors now. Although if I send it a lot of data really fast something else stops working and my keyboard scanning breaks!

So what I think I need to do is change the transmit to be interrupt driven too so the serial is properly interrupt driven full duplex. This is how the ISR looks now.
Code:
 
; =============================================================================
; ISR
; =============================================================================

ISR:
    SEI                        ; Disable interrupts.
    BIT     acia1_s         ; Check the status register (loads bit 7 into N and bit 6 into V).
    BMI     ACIA_Interrupt  ; Result negative (bit 7 set) so service ACIA.       
   
    CLI                        ; Re-enable interrupts.
    RTI


; =============================================================================
; ACIA Interrupt.
; =============================================================================

ACIA_Interrupt:
   
    PHA                          ; Store A.   
    TXA                          ; Store X.
    PHA   
       
    LDA     acia1_s                  ; Get the contents of the ACIA's status register. Reading it clears the interrupt.                               
    STA     IO                         ; Display on the LEDs.
    AND     #%00000111           ; Check for error conditions (lower 3 bits of status).
    BNE     ACIA_Interrupt_Error ; If there was any error go report it.

    LDX     acia1_wr_ptr         ; Start with A containing the byte to put in the buffer.
    LDA     acia1_d                 ; Get the data from the ACIA.
    STA     acia1_rx_buffer, X   ; Get the pointer value and store the data where it says
    INC     acia1_wr_ptr          ; then increment the pointer for the next write.

  ;  JSR     ACIA_Buffer_Diff       ; Now see how full the buffer is.
  ;  CMP     #$F0                       ; If it has less than 240 bytes unread
  ;  BCC     ACIA_Interrupt_Done  ; just exit the ISR here.
 
    JMP     ACIA_Interrupt_Done 

ACIA_Interrupt_Error:       
    JSR     Beep   
    LDA     acia1_d              ; Get the data from the ACIA to clear the error. 
   
ACIA_Interrupt_Done: 
    PLA                             ; Retrieve X.
    TAX
    PLA                             ; Retrieve A.
   
    RTI


Simon

_________________
My 6502 related blog: http://www.asciimation.co.nz/bb/category/6502-computer


Top
 Profile  
Reply with quote  
PostPosted: Mon Nov 04, 2013 9:06 pm 
Online
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8541
Location: Southern California
Code:
ISR:
    SEI                      ; Disable interrupts.
    BIT     acia1_s          ; Check the status register (loads bit 7 into N and bit 6 into V).
    BMI     ACIA_Interrupt   ; Result negative (bit 7 set) so service ACIA.       
   
    CLI                      ; Re-enable interrupts.
    RTI

I'll get to the rest later, but this immediately stuck out. The interrupt sequence already sets the interrupt-disable bit, so SEI is not necessary. The part that can really get you in trouble though is your CLI before RTI in the case that it was not the ACIA that interrupted. If the line is still being pulled down, the ISR will be re-entered before the RTI, and again it was something other than the ACIA, so it goes another level, another level, etc., overruns the stack, and is stuck in this ISR loop. The RTI pulls the previous status off the stack and restores it, which includes the interrupt-disable bit, so the CLI is not necessary.

_________________
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: Mon Nov 04, 2013 9:29 pm 
Offline

Joined: Mon Apr 16, 2007 6:04 am
Posts: 155
Location: Auckland, New Zealand
Ah. I did know about the SEI and had removed it previously. Sometimes I really mess up and revert to a previous version of the code. That version had it back in there. That's that only change one things at a time thing.

The only interrupt I have enabled is the ACIA receive one at the moment. I was going to enable and disable individual interrupts eventually but was cheating here and enabling/disabling them all.

I see what you mean though. I fixed that. I can still break things by really throwing lots of data at it so I have something else going on.

_________________
My 6502 related blog: http://www.asciimation.co.nz/bb/category/6502-computer


Top
 Profile  
Reply with quote  
PostPosted: Mon Nov 04, 2013 9:59 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8493
Location: Midwestern USA
Simon wrote:
Ah. I did know about the SEI and had removed it previously. Sometimes I really mess up and revert to a previous version of the code. That version had it back in there. That's that only change one things at a time thing.

The only interrupt I have enabled is the ACIA receive one at the moment. I was going to enable and disable individual interrupts eventually but was cheating here and enabling/disabling them all.

I see what you mean though. I fixed that. I can still break things by really throwing lots of data at it so I have something else going on.

There's no harm in leaving the RxD IRQ enabled at all times. The UART won't interrupt you if there's no datum in the receive buffer.

Also, BITting the status registers might not be a sound programming technique. A BIT instruction counts as read of the status register and hence clears some status bits. You may be inadvertently tossing away information that could be important.

_________________
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  [ 48 posts ]  Go to page 1, 2, 3, 4  Next

All times are UTC


Who is online

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