Serial fun with the 6551
Serial fun with the 6551
I'm having a problem with the WDC65C51. It won't transmit until it receives something. At startup it is supposed to transmit a header message and then wait for input. What it actually does is nothing until I press a key, then it transmits the header. Then I press another key and the first key shows up on the screen. It always lags a character behind.
Setup:
I am using an FT232RL FTDI USB to TTL Serial Converter to connect to the PC running TeraTerm on Win7. USB are the only serial ports I have. Just to try and get this working I am not using flow control or interrupts. I have attached my software. I did find the post by floobydust, thank you very much, and I added the delay to the putch subroutine.
I have tested the FTDI by bridging the Tx & Rx lines and typing, no problem, characters appear as I type them. So that kind of tells me that TeraTerm and the FTDI are working properly. That leaves the software, I've tried different methods including having the putch and getch as inline code. nothing worked until this afternoon when I accidentally hit the keyboard and the header appeared. I have trimmed the sw down to the bare essentials and still cannot see any obvious, at least to me, errors.
Can someone please look over the code, maybe a fresh pair of eyes can see the mistake?
Setup:
I am using an FT232RL FTDI USB to TTL Serial Converter to connect to the PC running TeraTerm on Win7. USB are the only serial ports I have. Just to try and get this working I am not using flow control or interrupts. I have attached my software. I did find the post by floobydust, thank you very much, and I added the delay to the putch subroutine.
I have tested the FTDI by bridging the Tx & Rx lines and typing, no problem, characters appear as I type them. So that kind of tells me that TeraTerm and the FTDI are working properly. That leaves the software, I've tried different methods including having the putch and getch as inline code. nothing worked until this afternoon when I accidentally hit the keyboard and the header appeared. I have trimmed the sw down to the bare essentials and still cannot see any obvious, at least to me, errors.
Can someone please look over the code, maybe a fresh pair of eyes can see the mistake?
- Attachments
-
- test_03f_acia.txt
- (14.18 KiB) Downloaded 242 times
All my stuff
-
JenniferDigital
- Posts: 92
- Joined: 25 May 2015
Re: Serial fun with the 6551
I've just had a quick glance at your code and noticed you're checking the TXE bit.
Don't check that the TX buffer is empty at all with the WDC version of the 6551. The hardware has a bug in it that means the bit is stuck. Just add a delay to ensure that the char is transmitted fully before reloading. Also I tied DSRB and DCDB to ground. Not sure if I needed to but it works.
Just a qualifier though. I'm still new to this part myself but got it working in the end. Since I'm running my homebrew computer at just 2MHz at the moment I've gone and used a Rockwell version but I can imagine using the WDC version should I push the clock rate up beyond 2MHz.
Don't check that the TX buffer is empty at all with the WDC version of the 6551. The hardware has a bug in it that means the bit is stuck. Just add a delay to ensure that the char is transmitted fully before reloading. Also I tied DSRB and DCDB to ground. Not sure if I needed to but it works.
Just a qualifier though. I'm still new to this part myself but got it working in the end. Since I'm running my homebrew computer at just 2MHz at the moment I've gone and used a Rockwell version but I can imagine using the WDC version should I push the clock rate up beyond 2MHz.
Re: Serial fun with the 6551
DigitalDunc wrote:
I've just had a quick glance at your code and noticed you're checking the TXE bit.
Don't check that the TX buffer is empty at all with the WDC version of the 6551. The hardware has a bug in it that means the bit is stuck. Just add a delay to ensure that the char is transmitted fully before reloading.
Don't check that the TX buffer is empty at all with the WDC version of the 6551. The hardware has a bug in it that means the bit is stuck. Just add a delay to ensure that the char is transmitted fully before reloading.
DigitalDunc wrote:
Also I tied DSRB and DCDB to ground. Not sure if I needed to but it works.
Done that, as well as CTSB tied to gnd for now.
All my stuff
Re: Serial fun with the 6551
Well slap me with a kipper!! I took out the TXE bit test and the dam thing works now. Shoulda followed my instinct in the first place, and thanks DigitalDunc for that extra nudge in that direction.
Now a second, related, question. I want to do hardware handshaking, RTS/CTS. But the pinout for the FTDI converter(link in first post) is DTR, RxD, TxD, Vcc, CTS and GND.
Do I connect DTR to DSR(ACIA) & DCD(ACIA) and CTS to RTS(ACIA)?
Or should I tie it's DTR to GND and bring down RTS from the pcb and tie that to CTS(ACIA) and CTS to RTS(ACIA)?
Now a second, related, question. I want to do hardware handshaking, RTS/CTS. But the pinout for the FTDI converter(link in first post) is DTR, RxD, TxD, Vcc, CTS and GND.
Do I connect DTR to DSR(ACIA) & DCD(ACIA) and CTS to RTS(ACIA)?
Or should I tie it's DTR to GND and bring down RTS from the pcb and tie that to CTS(ACIA) and CTS to RTS(ACIA)?
All my stuff
- floobydust
- Posts: 1394
- Joined: 05 Mar 2013
Re: Serial fun with the 6551
Use a standard 5-wire null modem configuration:
1- Tie RXD from the FTDI to TXD on the 65C51
2- Tie TXD from the FTDI to RXD on the 65C51
3- Tie CTS from the FTDI to RTS on the 65C51
4- Tie RTS from the FTDI to CTS on the 65C51
5- Tie DCD, DTR, DSR together on the FTDI
6- Tie DCD, DTR, DSR together on the 65C51
7- Ensure the FTDI ground line is tied to system ground (same as the 65C51)
This is how I use the FTDI DB9-TTL Uart/USB interface with the 65C51.
Check the LOT Code # on the W65C51 and see if it matches the one in my post to confirm the problem chip... and also note that WDC updated the W65C51 datasheet recently that shows this problem in the errata, albeit they got it backwards.
1- Tie RXD from the FTDI to TXD on the 65C51
2- Tie TXD from the FTDI to RXD on the 65C51
3- Tie CTS from the FTDI to RTS on the 65C51
4- Tie RTS from the FTDI to CTS on the 65C51
5- Tie DCD, DTR, DSR together on the FTDI
6- Tie DCD, DTR, DSR together on the 65C51
7- Ensure the FTDI ground line is tied to system ground (same as the 65C51)
This is how I use the FTDI DB9-TTL Uart/USB interface with the 65C51.
Check the LOT Code # on the W65C51 and see if it matches the one in my post to confirm the problem chip... and also note that WDC updated the W65C51 datasheet recently that shows this problem in the errata, albeit they got it backwards.
Regards, KM
https://github.com/floobydust
https://github.com/floobydust
Re: Serial fun with the 6551
1, 2 and 7 already done, 3, 4 and 6 will do, 5 - got only DTR & DCD but that should be alright... yes?
The numbers I can make out on the chip are:
WDC65C51N6
A6A749.1
1016G015
I have the Oct 24th, 2014 datasheet, in the errata it says:
Would it not be better to use the transmit interrupt, then the processor could get on with something else instead of the delay having to be tuned to both processor speed and baud rate?
The numbers I can make out on the chip are:
WDC65C51N6
A6A749.1
1016G015
I have the Oct 24th, 2014 datasheet, in the errata it says:
Quote:
Transmitter Data Register Empty
The W65C51N will not properly set Bit 4 of the Status Register to indicate the Transmitter Data Register is empty. Determining when to send the next byte would need to be done by using the transmit interrupt or having a software delay loop based on the baud rate used.
The W65C51N will not properly set Bit 4 of the Status Register to indicate the Transmitter Data Register is empty. Determining when to send the next byte would need to be done by using the transmit interrupt or having a software delay loop based on the baud rate used.
All my stuff
- GARTHWILSON
- Forum Moderator
- Posts: 8775
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: Serial fun with the 6551
With a very quick look, the only thing that jumps out that's actually wrong is:
and the same thing with "and ACIA_TXE." You need the "#" in there, otherwise you get an address and a ZP addressing mode, instead of a literal to AND the byte with.
Other things are just simplifications and streamlining. For example, the reset vector can be made to just point to MAIN instead of a place labeled RST_VEC that just has jmp MAIN, and the interrupt vectors could both go to the same RTI. Also:
can be replaced with STZ ACIA_STAT. The processor comes out of reset with D clear and I set anyway, so there's no need to CLD and SEI to start. You're initially loading X and A with 0 which is unnecessary because you then immediately proceed to load something else in, without using the 0.
can be replaced with JMP WAIT_6551. Actually, you can go further than that, because since WAIT_6551 is next, you can also skip the JMP instruction and just include a comment that WAIT_6551 must remain next. Going even further, you're always done with A when you get there, so you can use A for a loop index in the wait routine and not push and pull Y.
Using my structure macros, I would write,
which results in slightly fewer bytes of assembler output.
If you want to use an interrupt to tell you when it's ok to feed another byte to the transmit register, you can use a VIA timer (T1 or T2), and then the processor can do something useful while waiting.
Code: Select all
lda ACIA_STAT ; Get Status
and ACIA_RXF ; Rx full bit
Other things are just simplifications and streamlining. For example, the reset vector can be made to just point to MAIN instead of a place labeled RST_VEC that just has jmp MAIN, and the interrupt vectors could both go to the same RTI. Also:
Code: Select all
lda $00
sta ACIA_STAT ; Reset the ACIA
Code: Select all
jsr WAIT_6551 ; required Delay
rts
Using my structure macros, I would write,
Code: Select all
MAIN: LDX #$FF
TXS
JSR INIZ_ACIA
CLI
MSG: LDX #0
BEGIN
LDA MSG_HDR,X
WHILE_NOT_ZERO
JSR PUTCH
INX
REPEAT
BEGIN
JSR GETCH
CMP #$0D
IF_EQ
JSR PUTCH
LDA #$0A
END_IF
JSR PUTCH
AGAIN
MSG_HDR: .BYTE "TLC-MBC Monitor v0.1 - 27/06/15", $0D, $0A, $00
;-------------
GETCH: BEGIN ; Read one char from ACIA.
UNTIL_BIT ACIA_STAT, 3, IS_SET ; (You could also name the bit, but it should
; return the bit number, not its value.)
LDA ACIA_DATA
RTS
;-------------
PUTCH: PHA
BEGIN
UNTIL_BIT ACIA_STAT, 4, IS_SET
PLA
STA ACIA_DATA ; WAIT_6551 must be next.
;-------------
WAIT_6551:
PHX
FOR_A $10, DOWN_TO, 0
FOR_X $6B, DOWN_TO, 0
NEXT_X
NEXT_A
PLX
RTS
;-------------
If you want to use an interrupt to tell you when it's ok to feed another byte to the transmit register, you can use a VIA timer (T1 or T2), and then the processor can do something useful while waiting.
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?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
- floobydust
- Posts: 1394
- Joined: 05 Mar 2013
Re: Serial fun with the 6551
Like I said, WDC shows the Xmit bug in the latest datasheet, albeit they have it backwards, despite me diagnosing the problem completely and sharing my findings with them and the forum here. As a result, you can not use the Xmit bit flag for anything as it's stuck active. There are only two choices; use a delay routine when sending a character to allow the 65C51 to complete sending a character before sending another, or use a 65C22 timer to provide the interrupt and apply it towards the 65C51 driver routine (which is a kludge but more efficient).
Note that you do indeed have the defective WDC 65C51 chip, sorry (I have about 15 of them in DIP and PLCC). Note that Receive IRQ routines will work fine, just the Transmit is the problem and will not work with ANY existing 6551/65C51 coding due to the nature of the defect.
Note that you do indeed have the defective WDC 65C51 chip, sorry (I have about 15 of them in DIP and PLCC). Note that Receive IRQ routines will work fine, just the Transmit is the problem and will not work with ANY existing 6551/65C51 coding due to the nature of the defect.
Regards, KM
https://github.com/floobydust
https://github.com/floobydust
- BigDumbDinosaur
- Posts: 9428
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: Serial fun with the 6551
floobydust wrote:
There are only two choices; use a delay routine when sending a character to allow the 65C51 to complete sending a character before sending another, or use a 65C22 timer to provide the interrupt and apply it towards the 65C51 driver routine (which is a kludge but more efficient).
x86? We ain't got no x86. We don't NEED no stinking x86!
Re: Serial fun with the 6551
@GARTHWILSON
Good catch with the #. I caught it too last nite when I got it to work
I'm still in 6502 land as far as opcodes are concerned, I have yet to read up on the STZ and others available. Haven't used MC since about '84 so I'm a little rusty, plus I have been looking for a decent assembler, I'm using TASM for now. I miss Brevity, but once this is a usable computer I want to update and get Brevity working on it.
The current code is very un-optomised as it is testing code only, it is nowhere near to being done.
@ floobydust
Thanks for the advice, as you can see I'm using the delay for now.
@ BigDumbDinosaur
Four choices actually
I have a Synertek 6551 from way back when, needs testing to see if it's still good to go. Can't remember why now, but in the past I never used 65xx peripheral chips with the 6502, I used the 8255 to get three ports from the space of 2, and I used the 6850 when and if I needed serial stuff. The only reason I have a 65c51 and 65c22 now is that when I got the 65c02 I thought I may as well try the CMOS versions see if I like 'em or not. So far the 65c22 is okay, but the 65c51 is leaving a bad taste in my mouth, so I may well revert to the 6850 as I still have a couple of them, I might even try a Z80-SIO for kicks.
Good catch with the #. I caught it too last nite when I got it to work
Code: Select all
0171 84B1 GETCH ; Read one char from ACIA
0172 84B1 A9 08 lda #ACIA_RXF
0173 84B3 GETCH_LOOP
0174 84B3 2C 01 81 bit ACIA_STAT ; Test Status
0175 84B6 F0 FB beq GETCH_LOOP ; not yet
0176 84B8 AD 00 81 lda ACIA_DATA ; read char
0177 84BB 60 rts
0178 84BC
0179 84BC
0180 84BC PUTCH ; Write one char to ACIA
0181 84BC 8D 00 81 sta ACIA_DATA ; and write it
0182 84BF 20 C4 84 jsr WAIT_6551 ; required Delay
0183 84C2 60 rts
The current code is very un-optomised as it is testing code only, it is nowhere near to being done.
@ floobydust
Thanks for the advice, as you can see I'm using the delay for now.
@ BigDumbDinosaur
Four choices actually
All my stuff
- GARTHWILSON
- Forum Moderator
- Posts: 8775
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: Serial fun with the 6551
lenzjo wrote:
plus I have been looking for a decent assembler, I'm using TASM for now. I miss Brevity, but once this is a usable computer I want to update and get Brevity working on it.
Quote:
Four choices actually
I have a Synertek 6551 from way back when, needs testing to see if it's still good to go. Can't remember why now, but in the past I never used 65xx peripheral chips with the 6502, I used the 8255 to get three ports from the space of 2, and I used the 6850 when and if I needed serial stuff. The only reason I have a 65c51 and 65c22 now is that when I got the 65c02 I thought I may as well try the CMOS versions see if I like 'em or not. So far the 65c22 is okay, but the 65c51 is leaving a bad taste in my mouth, so I may well revert to the 6850 as I still have a couple of them, I might even try a Z80-SIO for kicks.
There are plenty of other options though. The MAX3100 is a 14-pin UART that interfaces to the processor through SPI. If you already have SPI planned, this would be a nice way to go. I've tried it and like it so I will probably use that one in the future. It has 8-byte transmit and receive buffers and takes less board space than the 6551. Part of its design is specifically to also be IrDA-capable (for infrared communications). The MAX3110E is the same thing with line drivers and receivers built in (saving even more board space), and it doesn't need any support parts like the popular MAX232 line driver/receiver IC does.
The only bug in the 65c22 VIA is one that will affect very few users. I have lots of circuits for interfacing things through the VIA on the circuit potpourri page of the 6502 primer.
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?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Re: Serial fun with the 6551
Thanks for that list of assemblers, I missed it when I went thru your guide, I shall have a look at it this evening.
I haven't exactly got SPI "planned" but it and I2C have been on my mind thanks to my playing around with the Arduino. As it stands I have a working 6522 and 6551 for the "mother board". The 6551 is there just to get the system up and running, I don't like being tethered to one computer just so I can use another. My immediate plans are to add a hex keypad, already built (20-key at the moment but may grow) and display, 6 "digit" (got some TIL305s and DL57s). SPI and/or I2C would certainly save some pins.
Yeah... the MAX3100 is a very tempting option, which in turn is twisting my arm towards SPI even more.
I haven't exactly got SPI "planned" but it and I2C have been on my mind thanks to my playing around with the Arduino. As it stands I have a working 6522 and 6551 for the "mother board". The 6551 is there just to get the system up and running, I don't like being tethered to one computer just so I can use another. My immediate plans are to add a hex keypad, already built (20-key at the moment but may grow) and display, 6 "digit" (got some TIL305s and DL57s). SPI and/or I2C would certainly save some pins.
Yeah... the MAX3100 is a very tempting option, which in turn is twisting my arm towards SPI even more.
All my stuff
- BigDumbDinosaur
- Posts: 9428
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: Serial fun with the 6551
GARTHWILSON wrote:
The 6850 does not have an onboard baud-rate generator, and I see that as a major deficiency.
x86? We ain't got no x86. We don't NEED no stinking x86!