Fixing a hardware bug in software (65C51 UART)

Поділитися
Вставка
  • Опубліковано 5 тра 2023
  • More 6502: eater.net/6502
    Support these videos on Patreon: / beneater or eater.net/support for other ways to support.
    ------------------
    Social media:
    Website: www.eater.net
    Twitter: / ben_eater
    Patreon: / beneater
    Reddit: / beneater
    Special thanks to these supporters for making this video possible:
    Adrien Friggeri, Aleksey Smolenchuk, Alex, Amit Bueno, An Dương, Anthony Weems, anula, Ben, Ben Cochran, Ben Williams, Bill Cooksey, Bill Watkins, Binh Tran, Богдан Федоров, Bradley Stach, Brian Haug, Burt Humburg, Carl Fooks, Carsten Schwender, Chai, Chris Anders, Chris Lajoie, Chris Sachs, criis, Cristi Cobzarenco, Daniel Jeppsson, Daniel Pink, Daniel Tang, Daniel Zimmer, Dave Walter, David Clark, David Cox, David Dawkins, David House, David Klassen, David Sastre Medina, David Turner, Dean Bevan, Dean Winger, Deep Kalra, Dennis Henderson, Dennis Schubert, Dilip Gowda, Dirk Sperling, Dmitry Guyvoronsky, Dušan Dželebdžić, Dustin Campbell, Dylan Speiser, Dzevad Trumic, Emilio Mendoza, Eric Dynowski, Erik Broeders, Erik Granlund, Ethan Sifferman, Eugene Bulkin, Evan Serrano, Evan Thayer, Eveli László, EvinSaysMarxWasRight!, Florian Bürgi, fxshlein, George Miroshnykov, ghostdunk, GusGold, Hailey, Hovis Biddle, Ingo Eble, Ivan Esparza, Jacob Ford, James Beldock, James Capuder, Jared Dziedzic, Jason Bowen, Jason DeStefano, Jason Grim, Jason Thorpe, JavaXP, Jaxon Ketterman, jemmons, Jeremy Cole, Jesse Miller, Jim Kelly, Jim Knowler, Joe Beda, Joe Pregracke, Joe Rork, Joel, Joey Murphy, John Hamberger jn., John Henning, John Meade, Jon Dugan, Jonn Miller, Joseph Portaro, Jurģis Brigmanis, Justin Graziani, Kai Wells, Kefen, Ken Paul, Kennard Smith, Kenneth Christensen, Kyle Kellogg, Lambda GPU Workstations, László Bácsi, Lithou, Lord Dorogoth, Lukasz Pacholik, Marcos Fujisawa, Marcus Classon, Mariano Uvalle, Mark Day, Martin Noble, Mats Fredriksson, Matthew Clifford, melvin2001, Michael Koreshkov, MICHAEL SLASS, Michael Tedder, Michael Timbrook, Michael Weitman, Miguel Ríos, mikebad, Mikel Lindsaar, Miles Macchiaroli, Muqeet Mujahid, NacOJerk, Nate Welch, Nicholas Counts, Nicholas Moresco, Nick Chapman, Oli Homer, Olivier HUBER, Ori Shamir, Örn Arnarson, Paul Heller, Paul Pluzhnikov, Pete Dietl, Phil Dennis, Philip Hofstetter, ProgrammerDor, Ralph Irons, Randal Masutani, Randy True, raoulvp, real_huitz, ReJ aka Renaldas Zioma, Ric King, Rick Hennigan, Rob Bruno, Robert Diaz, Robert Keown, Robey Pointer, Roland Munsil, Sagnik Bhattacharya, Sam Sturgis, Scott Gorlick, Scott Holmes, Sean Bright, Sean Patrick O’Brien, Sergey Kruk, Shane Mulcahy, SonOfSofaman, Spencer Ruport, Stefan Nesinger, Stephen Kovalcik, Stephen Riley, Steve Jones, TheWebMachine, Thomas Eriksen, Tim Oriol, Tim Walkowski, Tim Wheeler, Tom, Tom Smith, Tyler Latham, Usseod, Vincent Bernat, Warren Miller, Wim Coekaerts, Yee Lam Wan

КОМЕНТАРІ • 421

  • @RobertMilesAI
    @RobertMilesAI Рік тому +126

    This kind of thing is so useful, to show how sometimes there are bugs that aren't your fault and aren't documented. Important for newcomers to know that this kind of thing happens

    • @bill3143
      @bill3143 Рік тому +1

      Unexpected Robert Miles sighting! Love your work

    • @MichaelOfRohan
      @MichaelOfRohan Рік тому +2

      Ive wondered how many exploits were implimented on purpose for a manufacturer backdoor.

    • @milky3ay566
      @milky3ay566 Рік тому +1

      Trap for young players. I recently found a bug in the Toshiba chip LED driver.

    • @AirmanCS
      @AirmanCS 2 місяці тому

      Took me years to accept that sometimes I just need to debug the software/hardware im using instead of blaming myself

  • @der.Schtefan
    @der.Schtefan Рік тому +409

    In general, with microcontrollers, if you don't use interrupts, don't wait at the end of I/O for it to complete, wait at the start of the i/o for the previous operation to complete. That gives you time to fetch the next data item without losing precious time.
    Of course, with that hardware bug, it's pointless.

    • @dkosmari
      @dkosmari Рік тому +20

      But does the bug affect the interrupt bit too? I think that's what Ben planned, but he always shows a simpler implementation first. The whole point of using a dedicated chip for serial I/O was so the CPU was free to do something else, and that doesn't happen right now (with or without the hardware bug.) So it's safe to assume the interrupt-based implementation will come at a later video.

    • @threeMetreJim
      @threeMetreJim Рік тому +5

      @@dkosmari Might get away with it if only ever using half duplex and you can enable the interrupt for rx and tx separately. You might also be able to determine if it's an rx or tx interrupt as long as both flags were never going to get set simultaneously, but that is getting a bit dodgy (interrupt source is always serial, if not an rx interrupt must be a tx one).

    • @dkosmari
      @dkosmari Рік тому +10

      @@threeMetreJim According to another comment, the interrupt bit is also buggy for transmissions. At this point, it might just be better sticking a USB controller in there instead.

    • @luisjalabert8366
      @luisjalabert8366 Рік тому +4

      I really don't understand why he wouldn't use interrupts. It's infinitely better than polling. And more interesting too.

    • @threeMetreJim
      @threeMetreJim Рік тому +4

      @@dkosmari Were there any 8-bit home computers that actually used this chip? From what I remember, they all seemed to have a custom implementation for serial comms. Maybe this is why.

  • @Klaevin
    @Klaevin Рік тому +21

    "what's the difference between science and messing around?"
    "writing it down"

  • @falconeagle3655
    @falconeagle3655 Рік тому +532

    Your channel should be mandatory in all computer engineering curriculum. Hardware and Software design together is something every cs engineer should know about.

    • @MichaelOfRohan
      @MichaelOfRohan Рік тому +16

      Computer engineering*

    • @whtiequillBj
      @whtiequillBj Рік тому +28

      I half agree with this sentiment because I, as a student, feel like the professor should understand and teach the material. Not offload their work that I'm paying for onto a UA-cam channel that can be found for free.

    • @bkucenski
      @bkucenski Рік тому +10

      My computer science program included designing a four bit alu starting with logic gates. This stuff is taught at least at some colleges.

    • @falconeagle3655
      @falconeagle3655 Рік тому +5

      @@bkucenski was it implementation as well. I think design part is done in all CS programs in the computer architecture course. But the real life hardware software integration is not done anywhere as far as i understand. You learn that from job. Or do simple microprocessor programming in micro c.

    • @xavierdemers-bouchard2747
      @xavierdemers-bouchard2747 Рік тому +7

      Man, I knew nothing of electronics and Ben's video series last year got me so intrigued, entertained and just overall curious. I did a deep dive, scouring the web for info and now I am retrofitting 555s everywhere I can, thinking that if Ben can make a computer based on those, he'd be proud to know he's inspired me into using archaic tech to build my own things. It's sooooo so fun to play with and to learn how to use to that level.

  • @dkosmari
    @dkosmari Рік тому +222

    They literally turned the "it's a bug" into a "it's a feature" simply because it would not be cost effective to fix the bug.
    I imagine you planned to make a video dedicated to "how to write I/O routines." And you ended up teaching a far more valuable lesson to engineers: hardware bugs are way too common, and you can't just switch suppliers when you gotta finish the product within 6 months.

    • @jc33353
      @jc33353 Рік тому +30

      This is a very well-known bug. He definitely knew about it before making the video. But yes, a valuable lesson.

    • @d0nnyr0n
      @d0nnyr0n Рік тому +11

      @@pikadroo I don't think you are.

    • @iXenox
      @iXenox Рік тому +3

      Imagine if they renamed it to "Chip ready", now that is how you turn it into a feature!

    • @ericg7044
      @ericg7044 Рік тому +2

      @@pikadroo Who said that?

    • @c31979839
      @c31979839 Рік тому +3

      @@pikadroo it is because of your comments attacking the creator of this video series?

  • @wbfaulk
    @wbfaulk Рік тому +50

    I feel like it would make more sense to wait for "transmit buffer empty" before you send a character, not after. The whole point of a UART is that you don't have to spend CPU time to deal with I/O, but now you're using CPU time to wait on the UART to deal with the I/O.
    Edit: Aaaand, of course that's where the bug is.

    • @genderender
      @genderender Рік тому +5

      Its funny how ben's video seem leading and like they're gonna run into an issue, when that was planned all along to teach a lesson

  • @taldmd
    @taldmd Рік тому +64

    23:24 that reset button is asking for a hardware or software debouncing implementation, could be interesting to compare both approaches to deal with it.

    • @PhoenixClank
      @PhoenixClank Рік тому +21

      Oddly enough I remember Eater talking about debouncing before. That must have been for the 8-bit breadboard computer then.

    • @silaspoulson9935
      @silaspoulson9935 Рік тому +17

      @@PhoenixClank yep - whilst building the clock module due to needing to debounce the single step button

    • @snitkofb
      @snitkofb Рік тому +16

      Hard to debounce a reset in software…

    • @pv2b
      @pv2b Рік тому +28

      @@snitkofb It's actually super easy. Just add a 100 ms delay loop at the very start of your program. That way, while the reset line is "bouncing" it will just be stuck resetting the initial startup delay.

    • @YateyTileEditor
      @YateyTileEditor Рік тому +6

      I'd go with a hardware approach just in case there anything else that needs to be cleanly reset. The 65C51 has a hardware reset pin that could be tied to the same reset line as the 65C02.
      I like the DS1813 EconoReset IC because it will hold it's reset pin low until the system voltage has stabalised. And it can also debounce and hold it's reset low via a push button. The MAX6816 switch debouncer could also be used but it doesn't cater for system power on (and is bizarrely expensive).

  • @alanangelfire1217
    @alanangelfire1217 Рік тому +78

    Awesome videos Ben, I've been following the series from the beginning!
    Just a minor point in your code style that I've noticed : when using buffered transmission where you write to a transmit register as you have done, it is preferable to check buffer full *before writing a new character to it. That way you can't accidentally corrupt an ongoing transmission, and you don't have to wait for the transmit to finish before returning from the sub, so more code can be executed while the character is being transmitted. This theory works for polled or interrupt driven routines.
    Doesn't help with this hardware bug of course!

    • @dkosmari
      @dkosmari Рік тому +11

      He probably planned incremental improvements to the code, to eventually get to that, and the hardware flaw changed his plans. When he gets to integrate the serial interrupts that shouldn't be needed anyway, the handler will always just send or receive one single byte, and not do anything until the next interrupt.

    • @johnm2012
      @johnm2012 Рік тому +14

      @@dkosmari Ben didn't just stumble across the bug while preparing this video. He knew all about it well in advance and designed the lesson around it. He's a brilliant teacher and he did his homework.

  • @dhpbear2
    @dhpbear2 Рік тому +24

    Having not watched the whole video yet, I remember way back in 1984 when I was working with this chip. I vaguely remember a certain register had to be read THREE TIMES on initialization to fix a hardware bug.

  • @DeeBash
    @DeeBash Рік тому +12

    Good to see your video again

  • @tildessmoo
    @tildessmoo Рік тому +7

    "You know, you could really end up banging your head against the wall." Meaning you banged your head against the wall for us.

  • @metamud8686
    @metamud8686 Рік тому +11

    The fixed delay subroutine now locks you in to using 19200 baud. At other speeds, a different loop (or rather, value of reg. x) is needed.

  • @brianh9105
    @brianh9105 Рік тому +2

    Wow - this really brought back memories from the mid 80's... One of my first assignments in my career was using a similar Intel UART, 8251 if I recall, which had a very similar bug in one version of the chip. I was given a development board to update code for a government project. My code worked well in the lab and we shipped the EPROM with my code to the customer. Weeks later, I was told that the upgrade failed. The boss was very angry "Didn't you test this before sending it to our customer?" Fortunately another engineer I worked with was familiar with the problem and realized that I developed code on a system with a newer UART, while the customer's system had the older buggy UART. I felt horrible. How could I have known that the customer had different hardware? Fortunately it was a simple fix - and a valuable lesson learned.

  • @EricaCalman
    @EricaCalman Рік тому +14

    ah yes, the infamous mantra "we'll just fix it in software"

    • @dkosmari
      @dkosmari Рік тому +7

      And "it's not a bug, it's a feature."

  • @joseamadorsilva7395
    @joseamadorsilva7395 Рік тому +4

    Seriously love your videos. I tinkered as a youth with chips and very old systems (early x86 and younger).. this takes me back and at the same time opens my eyes at what I was deduced from my experiences (no manuals, minimal equipment and no teachers).
    I wish these vids were available as a kid.

  • @2Sor2Fig
    @2Sor2Fig Рік тому +3

    19:33 - I appreciate anyone willing to update their documentation. Thank-you so much for doing all this. As a self-taught programmer, it's been absolutely fascinating learning about the inner workings of a computer. You present it all very well. Much love from Zimbabwe.

    • @donovan6320
      @donovan6320 11 місяців тому

      Yeah they updated it to say it's broken.

  • @essamgouda1609
    @essamgouda1609 Рік тому +3

    Mans making assembly looking like python.
    You are on another level Ben 👏🏾👏🏾

  • @ColaEuphoria
    @ColaEuphoria Рік тому +21

    You have no idea how much I love UART and RS232. It's dirt simple. It's not locked down like USB. It's been around forever, and it JUST WORKS for what it's designed to do. You don't see many consumer applications use it much but we use it every day at work and it's VERY appreciable.

    • @linelinelinelinep440
      @linelinelinelinep440 Рік тому +3

      yea 232 and 485 own industry
      all the simple comms you need over 2-3 wires

    • @jeffspaulding9834
      @jeffspaulding9834 Рік тому

      I absolutely hate RS232. Not because it's bad, per se (it's actually really well suited for is purpose), but because it's used incorrectly.
      RS232 was never intended to be used for anything but connecting telephony equipment (like a modem) to terminals (like a computer). It specifies voltages outside the range of TTL chips, but many RS232 products on the market only work with 5v. It doesn't take ground loops into consideration because that was never an issue for its intended use. Most of the signals are ignored in modern applications.
      To make things worse, figuring out exactly which settings are being used a particular device is using can be frustrating. Baud rate, byte size, parity, and stop bits have to match on both sides or you get garbage. That's not an issue when you're using it for what it was designed for (just flip the DIP switches on the modem to the settings you want and use the same settings on your computer/terminal/whatever), but when the device you're talking to is on the other side of the plant and is inside a metal box halfway up the side of a hot tank it's not horribly helpful.
      The only reason RS232 has reached the popularity that it has is that a) every computer had a port for that back in the day and b) no popular alternatives emerged. In the early industrial automation world where no two manufacturers used the same protocol, RS232 was the one thing they could agree on.
      RS422 and RS485 suffer from some of the same shortcomings, but at least they're general purpose busses. The biggest problem with those is underspecification - every manufacturer has a different pinout for RS485 ports.
      It's the twenty-first century. Why don't we have a well-specified serial bus with automatic negotiation? The mind boggles.

  • @GilgaFrank
    @GilgaFrank Рік тому +5

    Thanks, Ben. Another terrific instalment in an excellent series. There's nothing else like this on the internet!

  • @mikehibbett3301
    @mikehibbett3301 20 днів тому

    Even though I've been writing embedded software for 45 years, I still love watching you write software on the 6502 like I did in 1979.

  • @Haagimus
    @Haagimus Рік тому +18

    You know it's gonna be a good Saturday when Ben releases a new video!

    • @mashrien
      @mashrien Рік тому +3

      Sadly he disappeared for like the whole pandemic, right when we all needed him the most ; ;

    • @jasedxyz
      @jasedxyz Рік тому +4

      ​@@mashrien at least he's back, releasing his good content once again

  • @TonyHammitt
    @TonyHammitt Рік тому +10

    Glad you posted this or everyone with the UART kit would be tearing their hair out. Very informative video, thanks

  • @chrisl2656
    @chrisl2656 Рік тому +36

    If not for the hardware bug, ‘send_char’ would be better as wait-and-then-send rather than send-and-then-wait as it would make it more likely that the cpu was doing useful work while the data was sending, rather than guaranteeing that the cpu was wasting cycles every time the data was sending.

    • @ottobass9193
      @ottobass9193 Рік тому +1

      Yeah... very annoying bug

    • @frankfix247
      @frankfix247 5 місяців тому

      They clearly know about the bug, so why don't they make a rev.2 with a bit option for backwards-compability or something?!

  • @narayanbandodker5482
    @narayanbandodker5482 Рік тому +8

    Next video you can make a bootloader to load binary from serial so that you don't have to keep flashing the EEPROM

  • @tim1724
    @tim1724 Рік тому

    I had been wondering if you were going to talk about the bug. I'm pleased to see you did!

  • @zrodger2296
    @zrodger2296 Рік тому

    At some point I'm going to have to rewatch this whole series! Nicely done.

  • @LordThanathos
    @LordThanathos Рік тому

    This is pure gold. New favorite UA-cam channel.

  • @colinstu
    @colinstu Рік тому +4

    TIL that WDC on those chips is for Western Design Center, not Western Digital Corporation. I always thought the HDD company dabbled in some chips and supporting cards.

    • @eDoc2020
      @eDoc2020 Рік тому +1

      Western Digital _did_ make chips and cards, just not these ones.

  • @AbelShields
    @AbelShields Рік тому +9

    12:28 if you wait for the tx data to be empty *before* you send the data, it'll never have to wait unless it needs to (this solution waits for every character whether you're transmitting another straight after or not).
    EDIT: guess it doesn't matter lmao

    • @kaitlyn__L
      @kaitlyn__L Рік тому

      I'd hope that's what he'd have done next if the bug hadn't existed lol

  • @jasonwilliams8730
    @jasonwilliams8730 Рік тому

    I love this channel! Thanks Ben:)

  • @blackpanda3771
    @blackpanda3771 Рік тому +1

    i just love your videos will buy my own kit with a friend soon

  • @melanierhianna
    @melanierhianna Рік тому +11

    If you set the 65C51 up to output the clock on the RxC pin (Pin 5) you can pass that in to the VIA and pulse count and use the interrupt to trigger when enough clock ticks have passed on passing out the data. So you can still use interrupts just not a 65C51 one.

    • @jal01126
      @jal01126 Рік тому +1

      This is exactly what I did and it works!

    • @AshtonSnapp
      @AshtonSnapp 11 місяців тому

      That’s actually a really good idea, I think I may use this.

    • @johnm2012
      @johnm2012 5 місяців тому

      How fast can the 6522 count? Can it keep up with the fastest baud rate? One approach that would definitely work is to use a second 65C51 to monitor the outgoing Tx signal by feeding it into its Rx input, using its Rx interrupt to signal that the main ACIA had finished transmitting.

  • @solcloud
    @solcloud Рік тому

    Awesome video, thank you!

  • @carloscorrea260
    @carloscorrea260 Рік тому

    This content is exactly what I was looking for, I just do not want to become a software developer that learn framework X or y, I am really curious about how what computer Science is and this channel is amazing, keep going and thank you

  • @michaelhaardt5988
    @michaelhaardt5988 Рік тому +3

    That workaround fails if hardware handshaking via CTS is used, which this chip can do in hardware, whereas the 8250/8251/16450 did not support until the 16550 was introduced. The 6551 was a great chip if it would have been less quirky, like each vendor having different requirements for the crystal with the oscillator not starting reliably if you did not follow closely.

  • @byronwatkins2565
    @byronwatkins2565 Рік тому +11

    This bug offers a perfect opportunity to introduce a timer and interrupt routine... You could even read status immediately after sending a byte to choose whether to use the timer or the status bit (maybe a pointer to the correct code and an indirect jump).
    At 12:50, to me it is more reasonable to pha and wait for transmit buffer empty before pla, sending the byte, and going on while the ACIA transmits the bits. If the calling code needs the sent byte, they can pha before the call and pla after the call.

    • @Majromax
      @Majromax Рік тому +3

      > If the calling code needs the sent byte, they can pha before the call and pla after the call.
      This gets into the interesting matter of calling conventions and binary interfaces. Your statement is perfectly reasonable, that the caller of a send_serial_byte(char a) routine probably doesn't need to re-use the parameter after the call. However, if you have some subroutines use caller-saved registers and other subroutines use callee-saved registers, the programmer will forever need to keep that distinction in mind.
      Sticking to one convention or the other saves programmer effort, even if it loses a few cycles here and there.

  • @BenBE1987
    @BenBE1987 Рік тому +3

    @23:10 you should have put the delay before the status register loop to avoid additional delays on chips that work properly.

  • @timthompson468
    @timthompson468 Рік тому

    Excellent video. I was going to ask if you sold kits. I’m glad you mentioned it. I’ve never used the 6502, so this might be fun to follow along. Reminds me of the old Heathkit days.

  • @electronic7979
    @electronic7979 Рік тому +1

    Helpful video

  • @Chrls5
    @Chrls5 Рік тому +2

    This is colossal work to be programming your own computer! it's really inspiring! beautiful work !

  • @TrueFarnz
    @TrueFarnz Рік тому +6

    A very minor thing; in your code, you use the pair LDA $reg ; AND #$const just to set the zero flag. This is the sort of thing the BIT instruction is designed for - and as a nice side effect, it leaves A undamaged.

  • @Gamemaster0225
    @Gamemaster0225 Рік тому +2

    Me not understanding a word of what is being said but just wanting background noise to not feel lonely

  • @user28bR3kY
    @user28bR3kY Рік тому

    Love your videos

  • @Karreth
    @Karreth Рік тому +4

    In the initial implementation of send_char (which assumed there was no hardware fault), I think it would have been better to do the status check at the beginning rather than at the end. That way you wouldn't have to wait for characters to be sent unless you were trying to send characters too quickly.

  • @no_bamboozle
    @no_bamboozle Рік тому +2

    Debounce that button!!
    Great video as always, Ben.

  • @garagelab_lucas_gongora
    @garagelab_lucas_gongora Рік тому

    Exelente amigo!!! Gracias😊

  • @ruevs
    @ruevs Рік тому +2

    12:10 the "send_char" routine should first do the "tx_wait" and then send the character. With a working chip (without the hardware bug) this will in principle reduce busy waiting (polling) the transmit data register empty bit, because the transmitting will happen in parallel with other code running.
    Edit: naturally at least four more earlier comments pointing out the same thing are present.

  • @johnscarfone
    @johnscarfone Рік тому +18

    It might be more efficient to check the tx buffer status before transmitting rather than after since any work done between transmits will reduce busy waiting.

    • @dkosmari
      @dkosmari Рік тому +7

      He might have planned that out, but since that tx status bit doesn't work at all, it's useless to optimize it. Regardless, the serial routines are still blocking, and he put a dedicated serial chip precisely to avoid blocking the CPU while doing I/O. To be actually more efficient, he will have to handle interrupts (if the interrupt bits are bug-free.)

    • @someguy4915
      @someguy4915 Рік тому +6

      @@dkosmari From the datasheet: '. The Transmitter Interrupt should never be enabled because the Transmitter Shift Register (TSR) is written when the TDR is written.' Basically you cannot do interrupt based transmitting with the W65C51 due to this bug, nor can you do polling based transmitting...
      The next most logical step (as Ben Eater has already covered this partially in earlier videos) would be to use the timer in the W65C22 to handle UART transmission timing using interrupts so that the UART transmit routine becomes non-blocking.

    • @dkosmari
      @dkosmari Рік тому +2

      @@someguy4915 So the chip is pretty much useless? Surely this chip would not work on any board that expects a functioning one?

    • @someguy4915
      @someguy4915 Рік тому +9

      @@dkosmari It is severely flawed with this bug, unless you're only receiving data...
      Alternatives are the older R6551 chips for instance but those can be tricky to find depending on where you live etc. and are usually limited to 1-2Mhz.
      But even without the bug, the 6551 ACIA's are fairly limited anyway as they have no FIFO buffers, meaning you have to send data one Byte at a time. More 'advanced' UARTs have FIFO buffers, allowing you to throw 16 Bytes or more to the UART and have the UART just send all of them in order, as soon as the first Byte is sent you can throw in the next one in case you're sending more than 16 Bytes.
      But for most cases, 16 Bytes/characters is more than enough.
      Those UARTs also have 16 Byte FIFO buffers for the receiving data, meaning you won't easily miss data even if the CPU is very busy.
      But yeah, if you stick the W65C51 onto a board with firmware that uses the transmit bit/interrupts it will either corrupt transmitted data or hang the CPU in infinite interrupts unfortunately.

    • @brucemcfarling6594
      @brucemcfarling6594 Рік тому +2

      @@dkosmari Note that a primary objective was to avoid having the serial write block the read. If one of the VIA timers are free, it can be used to time the delay. The system initialization routine could start the timer so it will be expired on the first call, and the transmit routine first checks if there is a read byte, and if so stores it in a buffer location, then checks if the timer has expired, if not busy loops until it has, then writes the transmit byte, then starts the timer and returns.

  • @thedanyesful
    @thedanyesful Рік тому

    Great video. A little long for my taste since I mainly wanted to see the part near the end where you explain the workaround.
    Maybe switch 'debouncing' could be the topic for your next video! :P

  • @rafalklepinski7372
    @rafalklepinski7372 Рік тому

    Excellent video as usual thank you. Still hoping for a SerDes series to jailbreak PCIe to connect to breadboard 😁

  • @georgegonzalez2476
    @georgegonzalez2476 Рік тому +1

    Speaking of serial chip bugs, there is another prominent one. You remember PC serial cards with the 16550A serial chip? The 16550 was a revolutionary serial port- it had and has a 16 byte buffer so you don’t lose bytes if the CPU falls behind a bit. For example at 9600 baud the CPU has to grab a byte every 1000 microseconds or so, other wise a byte gets dropped. But a 16 byte buffer gives the CPU some breathing room. It also lowers the number of interrupts needed so less time is wasted handling interrupts. Except that the original 16550 had a bug! The 16 byte buffer didn’t work. It wasn’t until the A or maybe AF suffix version that the serial buffer worked.

    • @bulldogcraft
      @bulldogcraft 6 місяців тому

      I think it was only the 16550AFN that didn't have any bugs. The 8250, 16450 and early 16550's all had problems of some sort. I was a technician in the early 90's and used to swap the chips all the time since the 16450, 16550AF and 16550AFN were all interchangeable. That was back in the day when a lot of factories and companies were still using computers as terminals over rs232.

  • @taucix
    @taucix Рік тому

    Danke für Deine Videos 😀😀😀😀😀

  • @brickcrafting
    @brickcrafting Рік тому

    Can`t wait how you amaze me next time, but I cant wait to find out!
    You are very inspiring to me.
    Great work, like always

  • @dacomputernerd4096
    @dacomputernerd4096 Рік тому +25

    This seems like a cool video.
    Still think a video on the I2C protocol would be cool too

    • @JTCF
      @JTCF Рік тому +2

      Absolutely, such an amazing protocol for low-level peripherals.

    • @alanangelfire1217
      @alanangelfire1217 Рік тому +4

      CAN would be an excellent choice too, the built-in priority arbitration in the ID header to prevent message collisions on a shared bus is pretty cool to see in action.

    • @mariorobben794
      @mariorobben794 Рік тому

      SPI and I2S too 🙂

    • @andlabs
      @andlabs Рік тому +2

      @@mariorobben794 He made one on SPI already

    • @kestaskuliukas5296
      @kestaskuliukas5296 Рік тому +3

      @@alanangelfire1217 Bleh I had to grapple with CAN in a recent project and I found the reflections / terminating resistors / checking impedence a real pain, had to get the oscilliscope out to find out the right frequency and troubleshoot reflections, CAN ground which isn't regular ground, it has optional heartbeats and different modes of operating.. bleah.. Of course now I have more understanding it wouldn't have been so bad, but the experience didn't make me a fan

  • @KirstyTube
    @KirstyTube Рік тому

    Way above my level of comprehension but still great viewing!

  • @Richardincancale
    @Richardincancale Рік тому

    Wow! That Tx bug! That probably explains why a data transmission test I made around 1984 wouldn’t work! What a relief to finally know it wasn’t me being dumb!

  • @mrblc882
    @mrblc882 Рік тому +5

    My approach would be:
    1.) Before send, wait for bit 4 to be 1
    2.) After send, check if bit 4 is zero
    3.) If zero, return from subroutine
    4.) If one, go to wait loop
    Why? With chip without bug, I'm not wasting time waiting. If I need to send another character, before previous one is sent, only then I need to wait. If bit 4 is one, that is clear sign that chip is bugged (with assumption that check is faster than sending byte) and fallback is activated.

    • @pv2b
      @pv2b Рік тому +2

      It's a clever approach, but unfortunately now you've instead created a more subtle performance bug, where your processor's performance will be greatly different while transmitting serial data depending on what UART chip you happen to have.

    • @mrblc882
      @mrblc882 Рік тому +1

      @@pv2b that is issue only if application is timming critical (which should be avoided by using timers), otherwise it's maximizing performance depending on available HW. Of course, timmer could be used instead of loop delay, but since timmers are also limited resources, it often can be better used.

    • @tetsujin_144
      @tetsujin_144 Рік тому

      I think my approach would be to avoid using defective ICs. I mean it sounds like kind of a flippant reply but I actually went through the different options, patch the code, patch the hardware, etc. - just selecting for ICs that actually work properly seems like the option that makes the most sense.
      The thing about writing additional code to patch around the defective IC (and detect whether the IC is defective and switch behavior accordingly) is that it wastes code space. On a CPU with a 16-bit address space, that space is precious...

    • @mrblc882
      @mrblc882 Рік тому

      @@tetsujin_144 that approach is already covered in video and it has some bad news for you - only defective ICs are produced. You can hunt for old stock and used IC's but that is expensive sport with limited stocks...

  • @adamdoyle5785
    @adamdoyle5785 8 місяців тому +1

    In case anyone else tries using one of the older S6551 chips, you'll also want to make sure you ground pin 9 which is the CTS (clear to send) pin.

    • @frankfix247
      @frankfix247 5 місяців тому

      This also goes for the unused input pins for channel 2 of the MAX232. Leaving them floating could interfere with channel 1 according to the datasheet.

    • @frankfix247
      @frankfix247 5 місяців тому

      This also goes for the unused input pins for channel 2 of the MAX232. Leaving them floating could interfere with channel 1 according to the datasheet.

  • @genabatalski8239
    @genabatalski8239 Рік тому

    Thanks

  • @phasemod
    @phasemod Рік тому +4

    Hate this bug. I did bang my head against the wall for hours on this years ago and I am still salty. Blocking the CPU to send a block of data makes me sad. Using up a whole timer interrupt also makes me sad. And this chip is not cheap! >:[

  • @Ragnarok540
    @Ragnarok540 Рік тому +2

    Would be interesting to see what needs to be done to make the code work well with both versions of the chip. Anyway, very interesting stuff!

  • @zaqqumkitchen
    @zaqqumkitchen Рік тому

    Beautiful work as always! Is there a practicable way to demonstrate or infer the bug directly without the updated data sheet?

  • @robvandeschepop8595
    @robvandeschepop8595 Рік тому

    Ah, 6502 assembly code!
    This brings me back to the early 80's when I bought my Acorn Atom with its built in assembler/disassembler.
    .

  • @muzaffaryusupov6435
    @muzaffaryusupov6435 Рік тому +1

    Thank you! Will there be a video about sound chips like YM?

  • @RSCuber
    @RSCuber Рік тому

    I built a 6502 system in 2017 and remember this very bug being the bane of my existence, before I checked the WDC datasheet (or maybe it was some forum or something). All the documentation I had about the chip was from other older manufacturers who didn't have that issue.

  • @toddp9541
    @toddp9541 Рік тому

    I have one of those older 6551 chips, be interesting to recreate 👍

  • @intbar
    @intbar Рік тому +4

    yuh new video

  • @phils_arcade
    @phils_arcade Рік тому +1

    Very good to not bang heads off walls.
    Think you need a debounce circuit on that button :)

  • @eformance
    @eformance Рік тому +1

    You could work around the hardware bug with an external integrator circuit too. Charge an RC delay with the transmit line and when the charge dissipates, the line is clear. Couple that to the data line with some logic gates and you could replicate the correct behavior without looping.

  • @clytle374
    @clytle374 Рік тому

    Good video, I keep meaning to get back into some digital stuff. For some reason my electronics hobby keeps migrating back to tube gear. Wonder if assembly is like riding or falling off a bike. Enjoyed it

  • @Jethro.Maloku-le.Rey.Kalsitran

    you virtually sawed off the legs of my chair when you counted how many clock cycles costed each code line in the last loop delay 😂👍

  • @JerryEricsson
    @JerryEricsson Рік тому

    Thanks, man this brings back memory. The old RUN magazine, I think it was, published free shareware or free software that you could enter using the machine language monitor in C=64, if you did not have. a copy of the monitor, you could enter that in basic that they published as well. I spent many an hour with the love of my life sitting next to me calling out the hex numbers as I typed them into the monitor and if all went well, I would have a new game to save to a floppy drive so I could. load it instead of having to enter it every time I wanted it. Eventually I tired of this and ordered the magazine with the floppy included so all I had to do was insert the disk and have fun. One of the games they had was my favorite, well I should say my wife's favorite. You see she was a math genius and love games where she could best me, especially on computers because I was a computer wiz and her math skills trumped most of the computer's back then. God I miss her, I lost her to cancer 3 years ago after 51 years and 4 days of pure love and joy.

  • @tonycook3460
    @tonycook3460 Рік тому

    Ben seems to have added back 5 or 6 videos on connecting a keyboard. If you have not been watching from the get-go you would miss it. I presume they were left out later as it is not part of the end-product. Thanks for adding it back Ben. Any chance of getting a Kicad schematic for what I guess is the final product from a hardware point of view?

  • @edsilver
    @edsilver Рік тому +2

    Wonder if some sort of resistor capacitor circuit, along with a comparator across the tx lines could be used to check whether a byte was sending, rather than the delay. I imagine you're setting up interrupts soon so the computer doesn't have to sit checking for data as before.

  • @4623620
    @4623620 4 місяці тому

    After seeing this (23:25) I call the guy "Bouncing Ben" from now on 🤣❗

  • @WaldoHazeleger
    @WaldoHazeleger Рік тому

    Hopefully you will also extend this excellent series with a sound and video chip (like Yamaha YM2149F and TMS9918A).

  • @cbmeeks
    @cbmeeks Рік тому

    Great video. You have the guys over at the 6502 forum to thank for finding that hardware bug. :-)

  • @theosib
    @theosib Рік тому +5

    I'm going to guess that the reason the designers missed this bug is that they expected all TX and RX to be handled by ISRs.

    • @someguy4915
      @someguy4915 Рік тому +15

      Interrupt driven transmission is not possible either due to this bug, the W65C51 bases its interrupt on bit 4 of the status register (the bit that is stuck at '1') meaning enabling transmit interrupts on the W65C51 would just create an infinite loop of interrupts.
      Likely the only reason the designers missed this bug is because they didn't test it and just assumed that this fairly simple feature of the design would be fine.

    • @brucemcfarling6594
      @brucemcfarling6594 Рік тому

      Or the customer was already using a transmit buffer and timing the transmission with a VIA.

    • @sparkybrit
      @sparkybrit Рік тому +1

      WDC claim their design passed their test suite in their emulator before they sent it to the fab

  • @monad_tcp
    @monad_tcp Рік тому +1

    23:02 remember when you could count clock cycles ! because it wasn't a pipelines out-of-order CPU

  • @ELYESSS
    @ELYESSS Рік тому +7

    When transmitting, why not wait for the buffer to be empty before writing instead of after, that way you don't waste time waiting if you're not transmitting something else right away.

    • @tetsujin_144
      @tetsujin_144 Рік тому +1

      I had the same thought - though since the "wait for the buffer to be empty" feature of the serial IC is defective, that strategy doesn't work. To do something with that CPU time other than just marking the passage of time, you'd need a timer or some other means of determining if the UART had enough time to send the data.

    • @ELYESSS
      @ELYESSS Рік тому

      ​@@tetsujin_144 he did implement a wait loop, still after writing though.

  • @JosuaKrause
    @JosuaKrause Рік тому +1

    in the send_char function I would wait for the status update *before* sending the data. this way you can continue doing other work without having to wait for the confirmation but if you try to send another byte it will wait until it is ready. right now, you're eagerly waiting for the status update when you could do something else during that wait time

  • @kreuner11
    @kreuner11 Рік тому

    Nice, new video

  • @dru6809
    @dru6809 Рік тому +2

    Hi Ben, that was fun. I do recommend switching out that uart though. The 65xx support chips line was notorious for bugs.
    You would serve your followers better by switching to an 8250 or one of its derivatives. This design is still used today as the UART for many SOCs.
    Alternatively, the more powerful (but complex) Zilog 8530 is good. It was used in early Macintosh and Apple IIgs computers.

  • @c128stuff
    @c128stuff Місяць тому

    Thanks, very nice video.
    It so happens I'm busy writing an OS for the C128, and also want to support the 6551 (for turbo232, swiftlink), and this info is very helpfull for that.
    I wonder if this means the transmit interupt is not working either? Do you happen to know? I only have access to an original (1980s era) 6551, so can't test this.
    Looks like it is not difficult to detect if a specific 6551 has this bug or not by sending a byte and seeing if the transmit buffer empty bit changes to 0 inmediately after having written the byte to the data register.

  • @PebblesChan
    @PebblesChan Рік тому +1

    What an epic fail! I wonder what process was used to transfer the original working design to its CMOS variant?

  • @BillySugger1965
    @BillySugger1965 Рік тому

    Simple polled comms is a great start, but interrupt driven, buffered, serial comms is so freakin’ powerful it has to be worth the effort! Every one of my microcontroller projects starts with buffered comms and a command interpreter.

    • @renakunisaki
      @renakunisaki Рік тому

      Unfortunately the interrupt logic is also broken on this chip. Thankfully it's only the transmit part, so a delay isn't too big of a deal as a workaround, and interrupts can still be used for receiving.

  • @NoobHuman
    @NoobHuman Рік тому

    wow new video!

  • @aaronspangler5320
    @aaronspangler5320 Рік тому +1

    Hey Ben, It is my understanding that both W65C51N and W65C51S are sold by WDC but have subtle differences. Notice that your datasheets have different part numbers. BTW, thanks you for your awesome videos!

    • @TheGrejp
      @TheGrejp Рік тому +1

      I believe W65C51S isn't actually available for sale, at least not widely - only some engineering samples exist. The S version also doesn't appear to have the bug, so the first datasheet Ben showed is actually correct for that part. And it confuses me how WDC managed to fix the bug but more than 15 years later they still only produce the version with the bug.

    • @YateyTileEditor
      @YateyTileEditor Рік тому +1

      ​@@TheGrejp They've only ever done one production run for the W65C51N. The chips available now were all produced a bit more than a decade ago.
      It's a really slow seller (watch how the stock numbers on Mouser change compared to, say, the W65C02S)

  • @aaronr.9644
    @aaronr.9644 Рік тому +1

    20:10 The way I understand that 2021 datasheet, that bit will be 0 during transmission but you will see it set to 1 once the reg is empty. So instead of the delay, I think you could also poll waiting for that bit to transition to high.

    • @renakunisaki
      @renakunisaki Рік тому +3

      That's how it's supposed to work, but not how it actually works.

    • @HenryLoenwind
      @HenryLoenwind Рік тому

      The issue is that the bit is 1 when it is ready to transmit and "not 0" when it is transmitting. It only is 0 when it isn't transmitting and isn't ready to transmit. This may happen if the hardware handshake lines are used, and the receiver signals it's not ready to receive, but I wouldn't bet on that either.

  • @tarekalabbar2426
    @tarekalabbar2426 Рік тому

    Hi Ben, I'm from the UK and tried to make an order on your website, but it says that the order can’t be shipped to my address. Is there a way to order the 8-bit computer kit to the UK? I love you videos and have been thoroughly enjoying them!

  • @logiclrd
    @logiclrd Рік тому

    This isn't actually _fixing_ the hardware bug, it's working around it. :-)

  • @KeesAlderliesten
    @KeesAlderliesten Рік тому +3

    12:33 can't you check the buffer emtpy flag before sending the new byte? Wait for it to clear, send the byte and carry on doing other stuff. you might be able to send more bytes per second (with a chip without the bug, that is...)

  • @MikesTropicalTech
    @MikesTropicalTech Рік тому +1

    I'm disappointed you didn't break out a laser and tiny soldering iron! ^:)

    • @renakunisaki
      @renakunisaki Рік тому +1

      "Fixing a hardware bug in software by programming a robot to physically repair the chip"

  • @GameBacardi
    @GameBacardi Рік тому

    Cool!

  • @BytebroUK
    @BytebroUK Рік тому

    That's interesting. I was dicking with that stuff in, what, 80s and I think I would always have used RST/CTS as a clean handshake.

  • @davethedaemon9024
    @davethedaemon9024 Рік тому +2

    I have an old 6551 (date code 7933). All register bits and interrupts work as expected. (Looks like some old 6551's are still available at Jameco on clearance. It's not a WDC chip and I don't think it has the bug.) The problems with this old chip: it is not a "C" version and needs a quiet and steady 5V, and doesn't work much faster than 2Mhz - it requires wait states at higher CPU clocks. (I programmed an ATF22V10C to handle CPU clock stretching.) Things stopped working when I upped the processor clock to 8Mhz and switched to the WDC 65C51. The same exact code didn't work on the "new" 65C51 and it drove me NUTS before I realized it was their hardware bug. I eventually designed discreet hardware to divide the serial clock output and provide the interrupt at the correct time. Writing on one address started the counter, reading another address confirmed it was the interrupting device, and another stopped the counter and reset the interrupt. By the time I was done, I didn't have room for more '51s and didn't relish the idea of making another board with so many discreet chips (two 74HC373's, 74HC245, 74HC192, 74HC193, 74HC154, 74HC74, etc). My next attempt was simpler and used a timer on a 65C22 to do the interrupt timing. Everything worked fine until I zapped something a while ago and shelved the project in frustration. Maybe I'll rebuild and try again - more carefully this time. My goal is one serial port for debugging, one for a PuTTY terminal, and at least one for talking to an Arduino and/or Raspberry PI. And since another commenter mentioned I2C, I managed to score two PCF8584P's (20 pin dip version). They need wait states too (down to 1Mhz IIRC), but otherwise worked fine (until I zapped things.) As of today, Mouser has an SOIC version in stock - "PCF8584T/2,512". I believe there's a faster/better chip out there, but I don't recall the part number. Thanks for the vids by the way. You got me interested in microprocessor hardware again after 40 years of just programming.

    • @Rx7man
      @Rx7man Рік тому

      I don't think it works with the 6502, but newer chips like the in Arduino you could set a timer to raise an interrupt flag to send the next byte, at which point of course you might as well implement your own buffer as well

  • @shaunclarke94
    @shaunclarke94 Рік тому +5

    Is there a reason you used hex values to initialise the ACIA instead of binary values as we have in the past?
    Just seems an extra step to have to convert to/from binary as you read the data sheet and need to revise/make changes etc.

  • @MonochromeWench
    @MonochromeWench Рік тому

    Seems like the delay loop only really needs to be used when just sending a string and not when echoing the input back. If doing the delay always I'd be concerned that you might wait too long between reads of the receive register

  • @sjair6526
    @sjair6526 3 місяці тому +2

    I was pretty excited to get this hooked up. I found that when I ran this program, text printed to the LCD fine however the computer did not send back the proper character to the serial program. It would print the message fine and the character that I pressed showed up properly on the LCD. I am using the print_char routine from the keyboard interface program. TWO.....HOURS....LATER I realized that this routine destroys the top four bits of the A register before returning from the sub routine. I guess you can put the send_char routine before the print_char routine. You can also do a pha right after the pla on line 13 of the print_char routine. Im interested if anyone has a more efficient way to do this. Seems kind of redundant to pla and pha right after each other.

    • @boris---
      @boris--- 2 місяці тому

      Thank you :D Saved me from bad weekend

  • @mikepennington8088
    @mikepennington8088 Рік тому +1

    If it is documented, a bug becomes a feature.