About the dropped echo characters: The datasheet has a note saying "The Command and Control Registers should be set up first before transmission begins when writing the TDR/TSR." I suspect what this actually means is that it's invalid to write to the command register while data is transmitting. You are sending the echo char and then immediately writing to the control register. Swapping the order (modifying CTS, then reading from the buffer and echoing) might be enough to fix the bug... But you probably need to poll the status register and wait for TDR to be empty before any writes to control or command.
It sounds like you'll want to process sending and setting flags using a command buffer, with "out of order" execution because you'll still want to clear that CTS flag in a hurry.
Also "back in the day", we used to bit twiddle memory mapped IO and ports by reading from the device's registers (memory address), AND/ORing with a bit mask to clear/set only the intended bits, then write the result back to the address it was read from. Whilst there is nothing wrong with an immediate load then store to set bits, you need to be sure that it is ok to clobber the others. It could be possible that the UART was using the other bits that got zeroed for some other purpose and that's why you don't see some of the output echoed back?
Ben, I noticed the get character routine will write to CTS for _every_ character read from the buffer except when the buffer is mostly full. My hunch is that the UART might not totally like being continually told that it's CTS when it already is CTS. Edit: So you could keep the state in memory and only write it when it changes My first computer was the ZX81 and I envied my friends who had 6502 computers. Your series has brought back so many memories! Thank you so much for your work 13:33
Sounds like a worthy experiment, see if the greatly reduced traffic to that register has any affect. Still it makes no sense to me - the 'perfectly received' character value that is 'pushed/popped and returned' should match exactly the value sent to CHROUT. (@12:17) The effect we see when listing implies that the returned character is always correct, *later in the flow*, and yet the printed value from the same register A source is not. Could it be that CHROUT is producing CRLFs in response to extraneous NUL characters, that the line editor discards? Theory (probably utter nonsense) - overly prodding CTS causes the UART to offer spurious receive data ready signals that CHROUT and the line editor handle very differently.
Good points about what _should_ be happening. I guess that's the thing about bugs - they are unexplainable until you work out how the bug causes the problem. And then in hindsight the logic is so obvious you wonder how on earth you made the mistake in the first place. The highs and lows of being a developer.
Great demonstration of flow control. It's interesting (at least to some of us nerds) that the original naming of signals was waaayyy back when RS232 was between 'Data Terminal Equipment' and 'Data Communication Equipment'. That is to say, between a data terminal and a data modem. So names like 'clear to send' was the modem telling the terminal it could send data, and 'request to send' was the terminal 'asking' the modem if it could send data. It also helps understand which signals were controlled from the DTE and which from the DCE.
My job involves a lot of old standards like RS-232, EIA 530, etc., especially in regards to using them for jobs they weren't quite designed for. I'm an old tech close to retirement, and I've been trying to get the younger techs to be able to visualize how the machines are designed in concepts like DTE/DCE and flow control, but they're having difficulty. Strangely, it doesn't help that things that would be classic DTE/DCE relationships like craft terminals are so fast and reliable that if there is any flow control it's just XON/XOFF, so they never see what the handshaking and timing pins do until the rare odd-duck problem. Then they'll spend months to years never thinking about what they learned and the next problem still baffles them.
This brings back memories. I used RS-232 (and its derivatives) to talk over HF/VHF/UHF radios for years. You'd have a speaker set to the frequency, and watch the RS-232 handshake lines while listening to the tones. Note that the communication path was half-duplex - you could either transmit OR receive, not both at the same time. If you "push to talk"ed, then you weren't going to hear what the other side said! The handshake lines defined the various phases of the communication: DSR: (Data Set Ready - Input) Modem is turned on. Without this, there's no point in even starting to communicate. DTR: (Data Terminal Ready - Output) Computer is turned on. This might literally send power to various parts of the modem and/or transmitter in preparation. RTS: (Request to Send - Output) Tell the modem to first "key" the radio (press to talk), then send the carrier - a preamble and start tones - to signal the far side that it was about to get a transmission. DCD: (Data Carrier Detect - Input) The modem has detected a carrier, so prepare to receive a message - oh, and DON'T start a transmission of your own (raise RTS)! CTS: (Clear to Send - Input) The modem sends this in response to RTS, to state that the preamble has been sent and the transmission can begin. For those that remember dial-up modems, you know the "melody" that is played up front, before the raw static-noise data transfer starts? Well, that melody is the preamble. The modem would respond to RTS by playing the melody down the wire, and when finished would respond with CTS to signal that data transmission could start. Meanwhile, the other end would be doing the same thing - and also raising DCD to signal that the other end has initiated transmission. Given that the modems could speak full-duplex, that meant that the two modems could talk at the same time - but the RTS/DCD/CTS sequence would still be followed. As modems got better, they'd just raise CTS immediately, and internally buffer the data until communications had been established. Finally, the last signal (other than TX and RX for transmit and receive data, and GND for Ground) is RI. This is Ring Indicate, a phone-line signal (not radio!) which pulses to say that the phone is ringing. You'd raise DTR to answer. Cool fact: you know that the original phones had a hammer that struck a bell repeatedly to make the "ring" sound? RI would pulse for each hammer-strike, not just raise to say "phone's ringing!"
Nice post! I was about to comment that my understanding is RTS and CTS are "viewed from the opposite end of the connection" Request to send [to a device] - raised by the host to signal the device that it wants to send data Clear to send [from a device] - raised by the device to signal the host that it is ready for transmission Your explanation covers all the lines and is great for understanding why it is how it is!
Thank you for explaining this. I've configured a lot of network switches which have RS232 interfaces, and I've always wondered why pasting in a large config file all at once caused issues with it being able to read it. It's common wisdom to just paste small sections at a time lol, but I never knew why this happened
@@Antiwindowscatalog I worked on a project where I had to configure 200 switches without ZTP, so it was quicker to just stage the configs, unbox them into a pile and then hammer through them one by one prior to physically installing them in the rack.
Ben , This is what is happening with the RTS when you put 00 TIC it disables the Transmit look at the Rockwell data sheet, This is not a BUG but how the RTS and CTS were designed. To get this to work it is better to use the DTR pin as it acts like a IO pin and the DSR as an Interrupt pin, but you still use RTS/CTS from the computer. FYI I will tell WDC to correct there Data Sheet
I really like your teaching approach of "This is why this technique WON'T work, here's how'd we make it work instead" I personally learn so much more this way, as opposed to just seeing it work the first time
Ben, Im older than the PCs with BASIC in ROM BIOS... Here I was with my Nortons Guide to the IBM PC, trying to work out what your making sound easy... And in my 30 years of Systems integration, there's one thing I value most. When someone can articulate the most complicated ideas so simply, it makes sense to everyone. We can all read the text, those that can relay it on in simple terms, are the ones that understand and master it. Bravo, Ive been watching for years now, always as good as the last ep.
Ha, childhood memories! I still remember those settings for some of the equipment I was playing with at the time. At the time, I didn't care about what they did - mostly because there wasn't an entertaining explanation around. Thank you, Ben!
Love this series, brings back so many memories. Had some thoughts/observations. You're odd behaviour with the hardware flow control may be because you left the CTS input on the UART floating, and it's picking up it's state from the adjacent RTS pin. Since your transmit code is not flow-control aware it just trashes what's already in the transmit register waiting to be sent. Try pulling this pin low to see if that fixes the problem. (or better yet, route the CTS as well) Another potential issue I noticed is with your "fix" for the flow control problem, you are doing a blind write instead of a read-modify-write to PORTA. So if PORTA had pins being used for other purposes as outputs, you would be trashing those states by setting them to 0 when you update your RTS/RFR pin.
I had the same thought, maybe he left CTS floating. However, pause the video at 3:55 or 10:49 and we can clearly see pin 9 (CTS) is tied to ground. I'm surprised he didn't mention this in the video.
@@fqed I feel like y'all have a very difficult experience with npm than I do. There's certainly a lot of bloated crap but none of it is necessary. Of course the web application at work is stuffed to the gills with unnecessary frameworks but that's a whole different story.
@@DanKaschelit’s less npm or even Node JS’s fault. It’s JavaScript’s weak typing and implicit conversion that necessitate dumb packages like ‘isarray’ that get millions of downloads 😂
This is getting to stuff even most professionals haven't had to deal with and wouldn't get right the first time, just like the USB videos. In-depth stuff!
Another great video, thanks Ben! Yeah, UART bugs are definitely nothing new, I recall back in the day the 16550 had a FIFO buffer bug that was fixed on the 16550A
Yep, and that bug was such a PITA. It was one of those "that's all I need you to do correctly and it's the one thing you don't do correctly!" Had that same sort of problem with PIC's output buffers not correctly flagging their status.
He's back! September has been a month full of surprises. A few days ago, a game in my Steam library that I've been playing for about the past 4 years officially came out with their 1.0 release. The game is no longer in Early Access, and that is completely Satisfactory!!! And now, a new Ben Eater video! On top of that my birthday is less than a week away. So, it's been a relatively very good month!
Still no ZIF docket for that poor eprom. That is a spectacularly heavy duty package! : Love the explanations and concepts we all take for granted these days.
It's been decades, but the whole "wtf does RTS even mean?" thing contributed significantly to me choosing to be a software guy instead of a hardware guy. And then your UART problem brought back my serial communication PTSD.
My Spidey senses must be working, because I was thinking last night that I haven't seen a Ben Eater video for a while. I'm going to have to watch the previous video to see what/why you already have the BUFFER_SIZE in your code.
10:06 I know you say you don't need to check if you MacBook is ready to receive but i think you should check that. you may find that is why it isn't echoing properly.
When you were troubleshooting your UART chip, did you ever connect the other Clear to Send signal from the PC's receiver to the UART chip? That pin might be floating low/high due to signal transitions around it, or it might be pulled-up/down (whichever blocks transmission) when put into "flow control mode" and not driven. I have seen chips in the past where if you enable some mode (e.g. flow control) on the receive side, the chip internals will also configure the transmit side in the same mode (i.e. you can't have the receiver with hardware flow control and the transmitter without it).
This was exactly my thought, radio interference from the neighboring pins. That's the only thing that would clearly explain the receive of all characters, but the loss of output. If it's doing this, it could easily lose the buffer output any time the signal is swapping on (between B0 and F0). That could be why you see little "spurts" of output as well.
G'day Ben, I left a message on Patreon regarding my take on this but not sure if you saw it. The short answer is that you are clearing the ECHO mode by clearing bit 4 on the command register. As you are receiving data, you shouldn't need to play with the TIC (bits 2 & 3)... in fact the datasheet asserts (page 11, 2014) that when bit 4 is HIGH (ECHO mode set), bits 2 and 3 MUST be clear. When re-enabling receipt of data, instead of setting the command register to $09, try using $11. This will assert DTR/CTS (bit 0) and REM (bit 4).
Ben, please note that the OTHER reason you needed to route the RTS and CTS signals through the MAX232 chip is because RTS and CTS obey the same RS232 standard that the TX and RX signals do: they're defined to be ±3-25V, which MUST NOT be routed directly to a TTL-level (or other typical level) chip. They need to be converted to the 0-5V (or whatever) voltages that the UART expects. And yes, they perform the inversion while doing so...
Ooh. Would have been fun to watch the cts signal on a scope with a really slow sweep. I recall this junk echo behavior using Kermit on a PC long ago. Like maybe the 80s. Can't remember details. Just as here, the data were always correct.
I also notice your terminal program is titled "USB Serial Controller". USB Serial adapters are notorious for introducing unexpected issues. It could very well be the USB that has a tiny buffer and is overflowing, and trying to say "woah!" to the 6502SBC.
@@misterhat5823 Correct, but I'm saying it probably shouldn't be there. I think his breakout board is labeled wrong, and it expects an input signal which is active-low (not active-high, which is what the inverter would give you)
@@Muny On the wire RS232 signals are the opposite "polarity" of the TTL level signal. The transmitter end inverts and hence the receiving end must also invert. "Polarity" because really a logic 0 from the UART is upwards of +12V or so on the wire and a logic 1 is as low as -12V or so.
Ah do I remember this. Hardware and of course Software flow control if its supported properly. Thats Async Rs232. Then there is Sync Serial and Hdlc and Sdlc . We had to support them all or at least troubleshoot them. I found it fascinating watching a session being setup with the latter Protocols on a HP DLM Data Line Monitor. Working in real comms allways required finding a way around an issue when there was no easy existing method. Eg a Hardware device doing a File Transfer through a Protocol Converter to some other location in Australia that kept failing on some sites and not others. Monitoring the conversation between them proved their equipment did not support any Flow Control at all. The quick and dirty work around was to replace the 2 port serial cards in the receiving device with a 4 port serial card. Why did that work , those cards had a much larger memory buffer that was obviously shared between the 4 ports and I was only using 1 port. Slowing the baud rate right down did not help by the way. Sorry for hi jacking your post.
This style of buffer with high and low-water points tends to cause clumping of data flows when the speeds are mismatched. What happens is that transmitter goes full steam ahead until the high water mark is hit, then the receiver effectively blocks the channel while some software in the transmitting device fills its output buffer, and that clumping can continue backing up the channel to the next higher source, and so on and so forth. Then when the receiver has bought some time it goes full steam processing its buffer until the receive buffer is at the low-water mark, then it turns the flow back on the channel, and the transmitter can empty its transmit buffer at full steam, triggering the emptying of it's source's transmit buffer and so on and so forth, back up the chain. If you imagine this process happening globally then you get circular systems with very non-linear behaviour, so I think the result is that latency on the network goes up. Back in 2015 or so someone noticed this happening on the Internet in the TCP/IP stack and they deduced that the problem was that people were making buffers too big! So there was a campaign to reduce latency by decreasing buffer sizes. This was called "buffer bloat" and apparently it worked, because buffer bloat is no longer an issue, I heard. But whether this results in more dropped packets during congestion I don't know. But dropping packets is just another sort of buffering which filters back up the chain eventually resulting in clumpy Internet behaviour as a whole. So maybe you just get times when the Internet appears to go down and your apps all stop. If so then they pushed the problem right out of their domain into the user's minds! Whether that was a good idea or not, I don't know. Personally I think that using circular FIFOs would be a better solution, as I think it might still allow large buffers but without causing clumping: circular buffers can grow and shrink linearly in proportion to the ratio of the speeds of their upstream/downstream connections. I don't really know enough about statistics to be able to analyze this properly though.
CTS makes plenty of sense, in the exact same way as Tx > Rx and Rx < Tx do. You have to keep the correct perspective in this stuff. This pin is an input that means: "I am clear to send." The same way an Rx pin is an input. UART is all labeled from the perspective of it's own side of the connection. You just have to keep in mind that multiple pins in UART cross over, just like you already have to do with Tx/Rx.
My first thought - as another poster has pointed out - is that you are writing to the command register after calling the CHROUT routine. That you should assert RTS before calling CHROUT. But, your CHROUT routine delays to ensure the tx register is empty (working around the TxEmpty hardware bug), so that shouldn't be it. Try it and see. I've also seen code that only writes to the command register if the command register has changed. Another poster mentioned this. So something like (easy to make into a subroutine): LDA #1:CMP ACIA_CMD:BEQ skip1:STA ACIA_CMD:.skip1 LDA #9:CMP ACIA_CMD:BEQ skip9:STA ACIA_CMD:.skip9 My second thought is - is the other end missing incoming characters? You have enabled RTS/CTS flow control on the laptop terminal program, but you haven't actually connected the laptop's outgoing RTS. So - even though you have stated the laptop is so much faster than the 6502SBC - the laptop could actually be being swamped. It could be saying "woah neddy!" at its end, but because the 6502SBC doesn't know that and keeps sending, the laptop misses characters. The laptop is busy transmitting data it could very well actually not have enough brain power to deal with the received data at the same time. It could be that the terminal program itself is too busy with sending characters to display received input. Which leads onto the next video - flow control from the 6502SBC to the laptop. Which will involve the hardware bug on the 6551's incoming CTS line and having to use the DSR line instead and manually monitoring it via the status register. Oh dear 6551. Such a useful little UART, so many bugs to work around. ;)
About the dropped echo characters:
The datasheet has a note saying "The Command and Control Registers should be set up first before transmission begins when writing
the TDR/TSR."
I suspect what this actually means is that it's invalid to write to the command register while data is transmitting. You are sending the echo char and then immediately writing to the control register.
Swapping the order (modifying CTS, then reading from the buffer and echoing) might be enough to fix the bug... But you probably need to poll the status register and wait for TDR to be empty before any writes to control or command.
It sounds like you'll want to process sending and setting flags using a command buffer, with "out of order" execution because you'll still want to clear that CTS flag in a hurry.
Annoyingly, on that chip TDR is ALWAYS empty.
Those are sentences I didn't know were even possible. Just made me realise I thought I knew computers, but actually, I know so little.
Also "back in the day", we used to bit twiddle memory mapped IO and ports by reading from the device's registers (memory address), AND/ORing with a bit mask to clear/set only the intended bits, then write the result back to the address it was read from.
Whilst there is nothing wrong with an immediate load then store to set bits, you need to be sure that it is ok to clobber the others. It could be possible that the UART was using the other bits that got zeroed for some other purpose and that's why you don't see some of the output echoed back?
Ben, I noticed the get character routine will write to CTS for _every_ character read from the buffer except when the buffer is mostly full. My hunch is that the UART might not totally like being continually told that it's CTS when it already is CTS. Edit: So you could keep the state in memory and only write it when it changes
My first computer was the ZX81 and I envied my friends who had 6502 computers. Your series has brought back so many memories! Thank you so much for your work 13:33
Sounds like a worthy experiment, see if the greatly reduced traffic to that register has any affect.
Still it makes no sense to me - the 'perfectly received' character value that is 'pushed/popped and returned' should match exactly the value sent to CHROUT. (@12:17) The effect we see when listing implies that the returned character is always correct, *later in the flow*, and yet the printed value from the same register A source is not. Could it be that CHROUT is producing CRLFs in response to extraneous NUL characters, that the line editor discards?
Theory (probably utter nonsense) - overly prodding CTS causes the UART to offer spurious receive data ready signals that CHROUT and the line editor handle very differently.
Good points about what _should_ be happening. I guess that's the thing about bugs - they are unexplainable until you work out how the bug causes the problem. And then in hindsight the logic is so obvious you wonder how on earth you made the mistake in the first place. The highs and lows of being a developer.
You don't really need memory - you just need to send that command when the buffer size is exactly at the watermark
It's unlikely to break anything...
Great demonstration of flow control. It's interesting (at least to some of us nerds) that the original naming of signals was waaayyy back when RS232 was between 'Data Terminal Equipment' and 'Data Communication Equipment'. That is to say, between a data terminal and a data modem. So names like 'clear to send' was the modem telling the terminal it could send data, and 'request to send' was the terminal 'asking' the modem if it could send data. It also helps understand which signals were controlled from the DTE and which from the DCE.
I tried NPM, React, etc. for a year at work. Ended up ditching it for HTMX. Couldn't be happier.
My job involves a lot of old standards like RS-232, EIA 530, etc., especially in regards to using them for jobs they weren't quite designed for. I'm an old tech close to retirement, and I've been trying to get the younger techs to be able to visualize how the machines are designed in concepts like DTE/DCE and flow control, but they're having difficulty. Strangely, it doesn't help that things that would be classic DTE/DCE relationships like craft terminals are so fast and reliable that if there is any flow control it's just XON/XOFF, so they never see what the handshaking and timing pins do until the rare odd-duck problem. Then they'll spend months to years never thinking about what they learned and the next problem still baffles them.
This brings back memories. I used RS-232 (and its derivatives) to talk over HF/VHF/UHF radios for years. You'd have a speaker set to the frequency, and watch the RS-232 handshake lines while listening to the tones. Note that the communication path was half-duplex - you could either transmit OR receive, not both at the same time. If you "push to talk"ed, then you weren't going to hear what the other side said! The handshake lines defined the various phases of the communication:
DSR: (Data Set Ready - Input) Modem is turned on. Without this, there's no point in even starting to communicate.
DTR: (Data Terminal Ready - Output) Computer is turned on. This might literally send power to various parts of the modem and/or transmitter in preparation.
RTS: (Request to Send - Output) Tell the modem to first "key" the radio (press to talk), then send the carrier - a preamble and start tones - to signal the far side that it was about to get a transmission.
DCD: (Data Carrier Detect - Input) The modem has detected a carrier, so prepare to receive a message - oh, and DON'T start a transmission of your own (raise RTS)!
CTS: (Clear to Send - Input) The modem sends this in response to RTS, to state that the preamble has been sent and the transmission can begin.
For those that remember dial-up modems, you know the "melody" that is played up front, before the raw static-noise data transfer starts? Well, that melody is the preamble. The modem would respond to RTS by playing the melody down the wire, and when finished would respond with CTS to signal that data transmission could start. Meanwhile, the other end would be doing the same thing - and also raising DCD to signal that the other end has initiated transmission. Given that the modems could speak full-duplex, that meant that the two modems could talk at the same time - but the RTS/DCD/CTS sequence would still be followed. As modems got better, they'd just raise CTS immediately, and internally buffer the data until communications had been established.
Finally, the last signal (other than TX and RX for transmit and receive data, and GND for Ground) is RI. This is Ring Indicate, a phone-line signal (not radio!) which pulses to say that the phone is ringing. You'd raise DTR to answer. Cool fact: you know that the original phones had a hammer that struck a bell repeatedly to make the "ring" sound? RI would pulse for each hammer-strike, not just raise to say "phone's ringing!"
Nice post!
I was about to comment that my understanding is RTS and CTS are "viewed from the opposite end of the connection"
Request to send [to a device] - raised by the host to signal the device that it wants to send data
Clear to send [from a device] - raised by the device to signal the host that it is ready for transmission
Your explanation covers all the lines and is great for understanding why it is how it is!
I'm writing a library for a 5g sim modem, thank God I don't have do all that lol. I still use RTS/CTS but it's to handle asynchronous tasks.
Thank you for explaining this. I've configured a lot of network switches which have RS232 interfaces, and I've always wondered why pasting in a large config file all at once caused issues with it being able to read it. It's common wisdom to just paste small sections at a time lol, but I never knew why this happened
I would hand configure just enough over serial to get Telnet or SSH working first, then switch connections.
@@Antiwindowscatalog I worked on a project where I had to configure 200 switches without ZTP, so it was quicker to just stage the configs, unbox them into a pile and then hammer through them one by one prior to physically installing them in the rack.
Ben , This is what is happening with the RTS when you put 00 TIC it disables the Transmit look at the Rockwell data sheet, This is not a BUG but how the RTS and CTS were designed. To get this to work it is better to use the DTR pin as it acts like a IO pin and the DSR as an Interrupt pin, but you still use RTS/CTS from the computer. FYI I will tell WDC to correct there Data Sheet
I really like your teaching approach of "This is why this technique WON'T work, here's how'd we make it work instead"
I personally learn so much more this way, as opposed to just seeing it work the first time
Agreed! The result of veritsiums PhD was that teaching misconceptions first was more effective than teaching the correct thing only
Ben, Im older than the PCs with BASIC in ROM BIOS... Here I was with my Nortons Guide to the IBM PC, trying to work out what your making sound easy...
And in my 30 years of Systems integration, there's one thing I value most. When someone can articulate the most complicated ideas so simply, it makes sense to everyone. We can all read the text, those that can relay it on in simple terms, are the ones that understand and master it. Bravo, Ive been watching for years now, always as good as the last ep.
You are an excellent communicator! You make it seem simple. It is a joy to watch your videos! I look forward to a new one coming out. Great job!
So glad to see a video drop Ben!! Always a treat!
My heart. I really said "omg, omg another ben eater video." Thanks, ben.
me too!
Wake up! New Ben Eater video just dropped!
thanks babe
it's time boys
So sick of this comment❄️
Like for real, wake up babe bla bla! Okay we get it.
You make this look effortless and I understood it. Thank you for being an awesome communicator!
Ha, childhood memories! I still remember those settings for some of the equipment I was playing with at the time. At the time, I didn't care about what they did - mostly because there wasn't an entertaining explanation around. Thank you, Ben!
Missed your work 🙏🏻
Nice to see something done that I did 40 years ago. Ben rocks.
Love this series, brings back so many memories. Had some thoughts/observations. You're odd behaviour with the hardware flow control may be because you left the CTS input on the UART floating, and it's picking up it's state from the adjacent RTS pin. Since your transmit code is not flow-control aware it just trashes what's already in the transmit register waiting to be sent. Try pulling this pin low to see if that fixes the problem. (or better yet, route the CTS as well) Another potential issue I noticed is with your "fix" for the flow control problem, you are doing a blind write instead of a read-modify-write to PORTA. So if PORTA had pins being used for other purposes as outputs, you would be trashing those states by setting them to 0 when you update your RTS/RFR pin.
I had the same thought, maybe he left CTS floating.
However, pause the video at 3:55 or 10:49 and we can clearly see pin 9 (CTS) is tied to ground. I'm surprised he didn't mention this in the video.
@@prow7 Oh I missed that, thanks for pointing it out.
What a lovely break from 400 gigabytes of NPM packages and desktop apps that use 200 megs of ram. Truly an elegant computer from a more civilized age.
Nothing screams elegance like smelling a wumpus.
I wrote X program in 3 lines of code......and 400 gigabytes of NPM packages.
@@fqed I feel like y'all have a very difficult experience with npm than I do. There's certainly a lot of bloated crap but none of it is necessary.
Of course the web application at work is stuffed to the gills with unnecessary frameworks but that's a whole different story.
Id actually appreciate desktop apps that only use 200MB ram.
Most electron crap uses 1.5GB+
@@DanKaschelit’s less npm or even Node JS’s fault. It’s JavaScript’s weak typing and implicit conversion that necessitate dumb packages like ‘isarray’ that get millions of downloads 😂
This is getting to stuff even most professionals haven't had to deal with and wouldn't get right the first time, just like the USB videos. In-depth stuff!
You're a mad man! I've spent heaps of time playing with modbus; She's a wild old school method but is solid as a rock when setup right.
Great video Ben, enjoy watching retro programming videos
Another great video, thanks Ben! Yeah, UART bugs are definitely nothing new, I recall back in the day the 16550 had a FIFO buffer bug that was fixed on the 16550A
Yep, and that bug was such a PITA. It was one of those "that's all I need you to do correctly and it's the one thing you don't do correctly!" Had that same sort of problem with PIC's output buffers not correctly flagging their status.
Your channel is so useful. I love your videos, especially these about communication. Please never stop making them.
Always a joy to watch your videos.
He's back! September has been a month full of surprises. A few days ago, a game in my Steam library that I've been playing for about the past 4 years officially came out with their 1.0 release. The game is no longer in Early Access, and that is completely Satisfactory!!! And now, a new Ben Eater video! On top of that my birthday is less than a week away. So, it's been a relatively very good month!
Mr. Eater, you are truly my inspiration.
Still no ZIF docket for that poor eprom. That is a spectacularly heavy duty package! :
Love the explanations and concepts we all take for granted these days.
Another great video! Really enjoy watching these. I learn so much. Thank you!
“hello? is this thing on?” 😂
As an assembler programmer, its becoming a lost art. Love the videos
This man is at another level of excellence. Respect.
3:25 -- "Technically wrong" is the best kind of wrong.
Always watching for more Ben! Thank you Ben!
It's been decades, but the whole "wtf does RTS even mean?" thing contributed significantly to me choosing to be a software guy instead of a hardware guy. And then your UART problem brought back my serial communication PTSD.
I feel the same, yet being able to do that sorcery he does must be so nice 🥲
Long time no see! Have a good day!
watching this in the kitchen. friend walks in, goes "are you fr watching lectures on the weekend?". so yeah ben, great job with your content style :D
My Spidey senses must be working, because I was thinking last night that I haven't seen a Ben Eater video for a while. I'm going to have to watch the previous video to see what/why you already have the BUFFER_SIZE in your code.
This bug was discovered by a 6502 forum member and very well documented and discussed. 🙂
Care to share the link, perhaps? I'm intrigued by this - and so are many others, I suppose...
Please share a link.
They can't share a link, TH-cam removes the comment.
@@AngelaTheSephiraNot necessarily. The comment would be flagged for review though meaning Ben would have to clear it.
@@NotBroihon Not since 2020; now a days no link is allowed *unless* it's a TH-cam link.
You got the wumpus!
Excellent video as always! 👍
Pretty nostalgic and that's why I love it..
Never clicked on a video notification so fast.
OMG, Today's Dinner would be awesome! Thanks for uploading.
WHOAAA!! A NEW VIDEO AFTER AGES!
Thank you for video ❤
Thats really cool! I recognise the PORTA and DDRA registers from Atmel microcontroller programming.
Happy Day! New Ben Eater video 🙂
Yes!!! The Return of the King.
My fav channel. Ben is back🔥🔥
Huiiiiiiiiii!
Ben is back again! ❤
He's alive!
Fantastic Let's Play.
Congrats on bagging the wumpus 😂
Oh yeah, we're about to get down to bitsness!
Heyyyy Ben's back! I was missing these videos!
10:06 I know you say you don't need to check if you MacBook is ready to receive but i think you should check that. you may find that is why it isn't echoing properly.
When you were troubleshooting your UART chip, did you ever connect the other Clear to Send signal from the PC's receiver to the UART chip? That pin might be floating low/high due to signal transitions around it, or it might be pulled-up/down (whichever blocks transmission) when put into "flow control mode" and not driven. I have seen chips in the past where if you enable some mode (e.g. flow control) on the receive side, the chip internals will also configure the transmit side in the same mode (i.e. you can't have the receiver with hardware flow control and the transmitter without it).
This was exactly my thought, radio interference from the neighboring pins. That's the only thing that would clearly explain the receive of all characters, but the loss of output. If it's doing this, it could easily lose the buffer output any time the signal is swapping on (between B0 and F0). That could be why you see little "spurts" of output as well.
HES BACK
Ahhhhh, the good ol' XON/XOFF days, god I love serial communications.... there, I said it.
Weekend starts early 🙌, Ben eater at it folks 🎉
Blind like, tea and I'm ready to watch 😊
“No Wumpus was harmed in the making of this video.”
G'day Ben,
I left a message on Patreon regarding my take on this but not sure if you saw it.
The short answer is that you are clearing the ECHO mode by clearing bit 4 on the command register.
As you are receiving data, you shouldn't need to play with the TIC (bits 2 & 3)... in fact the datasheet asserts (page 11, 2014) that when bit 4 is HIGH (ECHO mode set), bits 2 and 3 MUST be clear.
When re-enabling receipt of data, instead of setting the command register to $09, try using $11. This will assert DTR/CTS (bit 0) and REM (bit 4).
FINALLY. THE DROUGHT IS OVER. THE KING HAS RETURNED!!
The king's back 🎉
Ben one of my favorite dudes on YT
Ben, please note that the OTHER reason you needed to route the RTS and CTS signals through the MAX232 chip is because RTS and CTS obey the same RS232 standard that the TX and RX signals do: they're defined to be ±3-25V, which MUST NOT be routed directly to a TTL-level (or other typical level) chip. They need to be converted to the 0-5V (or whatever) voltages that the UART expects. And yes, they perform the inversion while doing so...
Ooh. Would have been fun to watch the cts signal on a scope with a really slow sweep. I recall this junk echo behavior using Kermit on a PC long ago. Like maybe the 80s. Can't remember details. Just as here, the data were always correct.
You are my hero!
nice work king
Welcome back
Vraiment un super projet !
He returneth
I also notice your terminal program is titled "USB Serial Controller". USB Serial adapters are notorious for introducing unexpected issues. It could very well be the USB that has a tiny buffer and is overflowing, and trying to say "woah!" to the 6502SBC.
Haven‘t watched the Video yet, but it‘s gonna be awesome
Welcome back Ben
happy to see you're alive
i really wonder what is this bug on the uart
looooove your videos
3:53 The CTS and RTS signals are considered active-low, as you noted. So I think you probably shouldn't have used the inverter.
It's not an inverter, it's a level translator that happens to invert.
@@misterhat5823 Correct, but I'm saying it probably shouldn't be there. I think his breakout board is labeled wrong, and it expects an input signal which is active-low (not active-high, which is what the inverter would give you)
@@Muny On the wire RS232 signals are the opposite "polarity" of the TTL level signal. The transmitter end inverts and hence the receiving end must also invert.
"Polarity" because really a logic 0 from the UART is upwards of +12V or so on the wire and a logic 1 is as low as -12V or so.
@@Muny No. That's standard operation for those level translators for historical reasons. There's nothing weird here.
Ah do I remember this. Hardware and of course Software flow control if its supported properly. Thats Async Rs232. Then there is Sync Serial and Hdlc and Sdlc . We had to support them all or at least troubleshoot them. I found it fascinating watching a session being setup with the latter Protocols on a HP DLM Data Line Monitor. Working in real comms allways required finding a way around an issue when there was no easy existing method. Eg a Hardware device doing a File Transfer through a Protocol Converter to some other location in Australia that kept failing on some sites and not others. Monitoring the conversation between them proved their equipment did not support any Flow Control at all. The quick and dirty work around was to replace the 2 port serial cards in the receiving device with a 4 port serial card. Why did that work , those cards had a much larger memory buffer that was obviously shared between the 4 ports and I was only using 1 port. Slowing the baud rate right down did not help by the way. Sorry for hi jacking your post.
RS232 is asynchronous whether flow control is used or not. There's a clue in the abbreviation for the chip, whether it's a UART or an ACIA.
Two things were accomplished: setting up better flow control, and catching the Wumpus
This style of buffer with high and low-water points tends to cause clumping of data flows when the speeds are mismatched. What happens is that transmitter goes full steam ahead until the high water mark is hit, then the receiver effectively blocks the channel while some software in the transmitting device fills its output buffer, and that clumping can continue backing up the channel to the next higher source, and so on and so forth. Then when the receiver has bought some time it goes full steam processing its buffer until the receive buffer is at the low-water mark, then it turns the flow back on the channel, and the transmitter can empty its transmit buffer at full steam, triggering the emptying of it's source's transmit buffer and so on and so forth, back up the chain. If you imagine this process happening globally then you get circular systems with very non-linear behaviour, so I think the result is that latency on the network goes up. Back in 2015 or so someone noticed this happening on the Internet in the TCP/IP stack and they deduced that the problem was that people were making buffers too big! So there was a campaign to reduce latency by decreasing buffer sizes. This was called "buffer bloat" and apparently it worked, because buffer bloat is no longer an issue, I heard. But whether this results in more dropped packets during congestion I don't know. But dropping packets is just another sort of buffering which filters back up the chain eventually resulting in clumpy Internet behaviour as a whole. So maybe you just get times when the Internet appears to go down and your apps all stop. If so then they pushed the problem right out of their domain into the user's minds! Whether that was a good idea or not, I don't know. Personally I think that using circular FIFOs would be a better solution, as I think it might still allow large buffers but without causing clumping: circular buffers can grow and shrink linearly in proportion to the ratio of the speeds of their upstream/downstream connections. I don't really know enough about statistics to be able to analyze this properly though.
Good Day Eater 👍
Your wumpus game reminds me of "games" I'd write on my TI calculator around 1991. Took the idea from BBS games like Major Mud or Telearena.
I was thinking text version of minesweeper. The kids are still writing games like this on their current (??) TI calculators.
Sweetheart! Ben Eater put out a new video! It's going on the big screen, no more true crime for you!
Yay another video!
Legend 💪💪💪
CTS makes plenty of sense, in the exact same way as Tx > Rx and Rx < Tx do.
You have to keep the correct perspective in this stuff.
This pin is an input that means: "I am clear to send."
The same way an Rx pin is an input.
UART is all labeled from the perspective of it's own side of the connection.
You just have to keep in mind that multiple pins in UART cross over, just like you already have to do with Tx/Rx.
no way he's back
Appreciating how TI's MAX232 datasheet is dated "February 1989 - Revised February 2024"...that's 35 years.
What do you get in this channel?
Me: autopsy and DNA reports of computers 😂😂😂😂😂
YAY, ANOTHER BEN EATER VIDEO, this is like drugs for nerds (or for me at least)
new vid lets go
I've never been this early before, noice, lemme bring something to snack on first.
Babe wake up, new Ben Eater video just dropped
Ben vid! WAHOO!
finally after so looong
I believe more common terms for "mostly full" and "mostly empty" are high mark and low mark respectively
This is a teaching video. "Mostly full" is easier for the target audience to understand.
this is very helpful. It's probably why his UART didn't work :D
Ben, you need release an ASMR video of just you typing, lol. I could listen to it all day
Hunt the Wumpus! I wish I had all the hours of playing that game back!
Next, load the text-based Star Trek game!
My first thought - as another poster has pointed out - is that you are writing to the command register after calling the CHROUT routine. That you should assert RTS before calling CHROUT. But, your CHROUT routine delays to ensure the tx register is empty (working around the TxEmpty hardware bug), so that shouldn't be it. Try it and see.
I've also seen code that only writes to the command register if the command register has changed. Another poster mentioned this. So something like (easy to make into a subroutine):
LDA #1:CMP ACIA_CMD:BEQ skip1:STA ACIA_CMD:.skip1
LDA #9:CMP ACIA_CMD:BEQ skip9:STA ACIA_CMD:.skip9
My second thought is - is the other end missing incoming characters? You have enabled RTS/CTS flow control on the laptop terminal program, but you haven't actually connected the laptop's outgoing RTS. So - even though you have stated the laptop is so much faster than the 6502SBC - the laptop could actually be being swamped. It could be saying "woah neddy!" at its end, but because the 6502SBC doesn't know that and keeps sending, the laptop misses characters. The laptop is busy transmitting data it could very well actually not have enough brain power to deal with the received data at the same time. It could be that the terminal program itself is too busy with sending characters to display received input.
Which leads onto the next video - flow control from the 6502SBC to the laptop. Which will involve the hardware bug on the 6551's incoming CTS line and having to use the DSR line instead and manually monitoring it via the status register.
Oh dear 6551. Such a useful little UART, so many bugs to work around. ;)