C64 Turbo Assembler 34-Year-Old Bug Found & Fixed

แชร์
ฝัง
  • เผยแพร่เมื่อ 29 ม.ค. 2025

ความคิดเห็น • 288

  • @flurng
    @flurng 5 ปีที่แล้ว +16

    How 8 people dislike this video? Did they not know from the title what they'd be seeing? Personally, I think it is AWESOME that 34 years later, someone STILL cares enough about this language to create a patch! Well done, Sir!

    • @davidnewbaum6346
      @davidnewbaum6346 2 ปีที่แล้ว +1

      Luckily dislikes are not shown any more.

  • @mechaform
    @mechaform ปีที่แล้ว +1

    Wonderful. Running out of space in my head for all this arcane lore.

  • @der.Schtefan
    @der.Schtefan ปีที่แล้ว +3

    Highly specific patches like these often run faster by JMP instead of JSR, because you always know where you RET and thus can write JMP instead of RET, saving few cycles, and some bytes of stack space. This also allows you to use the stack in the patch.

    • @psionl0
      @psionl0 ปีที่แล้ว +1

      I was about to make the same comment. I checked and a JMP takes 3 clock cycles so 2 JMP instructions takes 6 clock cycles. A JSR instruction takes 6 clock cycles, RTS takes 6 clock cycles and NOP takes 2 clock cycles for a total of 14 clock cycles.

    • @ludeksmetana8696
      @ludeksmetana8696 11 หลายเดือนก่อน +1

      So, you will save 8 cycles for 1 convert dec to integer. I don't think if it's very necessary in this situation...

    • @psionl0
      @psionl0 11 หลายเดือนก่อน +1

      @@ludeksmetana8696 More to the point, why code the patch as a JSR in the first place? There is no advantage to this whatsoever.

  • @El_Grincho
    @El_Grincho 5 ปีที่แล้ว +52

    Wonder if Wolfram Römhild will watch this video?

  • @darthnihiluz5305
    @darthnihiluz5305 5 ปีที่แล้ว +50

    Let's track down the original programmer, and open a defect.

    • @AlanCanon2222
      @AlanCanon2222 4 ปีที่แล้ว +2

      I'm down. Shall we use full Agile? I have a shit ton of Post-It notes I'm not using.

    • @madyogi6164
      @madyogi6164 4 ปีที่แล้ว +1

      Neah. Lets reverse engineer so all JMP-s will fit in and make it git clonable...

    • @charles-y2z6c
      @charles-y2z6c 4 ปีที่แล้ว +6

      The original programmer was Jim Butterfield. I learned original 6502 assembler from him. He passed away a few years ago.

  • @jbevren
    @jbevren 5 ปีที่แล้ว +13

    David here- No problem on the controller! I'm happy I was able to find it. :) I don't remember if it ever worked, but if you're unsure you can check with a cellphone selfie cam to see if it's blasting any infrared :)

    • @jack002tuber
      @jack002tuber 5 ปีที่แล้ว

      That's a good tip to know if any IR remote is working. Just cell camera it and you'll see it.

  • @christopheoberrauch784
    @christopheoberrauch784 5 ปีที่แล้ว +4

    Another fantastic video. You can't imagine how much I learned by imitating your solutions on my setup. The demonstrated concept for patching and saving Turbo Macro Pro was/is an eye opener. Thank you!

  • @ralphm786
    @ralphm786 5 ปีที่แล้ว +4

    For me, this has been your most instructive video to date, and the one I've enjoyed most! Sincerely, thank you, Robin.

  • @daviddupoise6443
    @daviddupoise6443 5 ปีที่แล้ว +9

    The minute I saw it was near 128 * 10 I intuitively suspected it was a hex related carry somewhere. Oh takes me back.
    Nice find and fix.
    Well done.

  • @chainedlupine
    @chainedlupine 5 ปีที่แล้ว +27

    I've been writing too much Apple ][ assembler. I spotted the bug the second you mentioned the

  • @TrickysFlyingBurrito
    @TrickysFlyingBurrito 5 ปีที่แล้ว +8

    New subscriber here, got to say these videos are a must watch for me as soon as they appear. Your clear and succinct presentation style and enthusiasm for the material is inspiring.

    • @azzajohnson2123
      @azzajohnson2123 5 ปีที่แล้ว

      TrickysFlyingBurrito how awesome is the subject matter too? This is why I love TH-cam. A lot of this knowledge used to die and no one would have even known.

  • @WarrenGarabrandt
    @WarrenGarabrandt 5 ปีที่แล้ว +4

    I've trying to learn 6502 assembly, so seeing videos like this is tremendously helpful. It is nice to be able to see different ways of accomplishing tasks, and having them explained line by line like you did here is very much appreciated. I hadn't thought about how I might insert an instruction in byte code, and this is a relatively easy way to get the job done. Thanks for showing this!

    • @WarrenGarabrandt
      @WarrenGarabrandt 5 ปีที่แล้ว +1

      It would have been nice to see how you tracked down that particular section where the functionality you were looking for was located. I assume you didn't have to follow the entire program opcode by opcode until you got to something that looked right. Just glancing at a block of opcodes, I'm not good enough to be able to figure out what it actually does, much less jump into the middle and figure out which byte begins an opcode to disassemble correctly.

    • @8_Bit
      @8_Bit  5 ปีที่แล้ว +5

      I did have to trace and hack through the code for about an hour before I found this routine. I was considering trying to show that part too, but it just wasn't flowing well for video so I made the executive decision to just jump into this particular routine. Hopefully in future videos I'll get into that aspect too. Thanks for watching!

    • @csbruce
      @csbruce 5 ปีที่แล้ว

      @@8_Bit: I would have started by locating all of the for ASL «zeropage» instructions (though that wouldn't have worked here). Then, ROL «zeropage».

    • @WarrenGarabrandt
      @WarrenGarabrandt 5 ปีที่แล้ว

      @@csbruce since instructions are variable length, how would you know you were decoding correctly? The same byte for asl could just as easy be a parameter for another operator. If the assembler skipped a byte in memory to align to a page for a subroutine, you couldn't really know even if you started decoding from the program start address. And breaking in at any arbitrary point could mean you start decoding at an operand, or an address used for temp storage.

    • @csbruce
      @csbruce 5 ปีที่แล้ว +1

      @@WarrenGarabrandt: You would have to check each occurrence of these instructions, starting about 16 bytes before, looking for code that multiplies a 16-bit number by 10. If you start disassembling from a random point, you'll find that the disassembly realigns with the real code within a few instructions, owing to the fact that more than half of the instruction bytes are unregistered instructions that are disassembled as one "???" byte.

  • @WarrenMarshallBiz
    @WarrenMarshallBiz 5 ปีที่แล้ว +2

    This was one of your best, thanks! I loved the process of finding a spot in memory and patching in some custom code. Beautiful and SO retro ...

  • @JohnGotts
    @JohnGotts 5 ปีที่แล้ว +7

    Good work. It's always fun to fix 20+ year old bugs.

  • @AnnatarTheMaia
    @AnnatarTheMaia 5 ปีที่แล้ว +62

    Here is a patch without the NOP:
    AB2F 18 CLC
    AB30 20 10 C8 JSR $C810
    AB33 AD B0 A4 LDA $A4B0
    ...
    ...
    ...
    C810 65 39 ADC $39
    C812 85 39 STA $39
    C814 60 RTS

    • @hugovangalen
      @hugovangalen 5 ปีที่แล้ว +14

      Another way, that would also save a few ticks as nothing needs to be pushed and pulled from the stack, would be by doing a JMP to the patch, and then JMP back to the next correct instruction in the original code. :) (Although that is bad for legibility because the garbled instruction would still be visible when disassembling the code from address AB2F, but I have seen similar readability issues with hacks involving the BIT operation.)

    • @strongholds12
      @strongholds12 5 ปีที่แล้ว +6

      UNIX admin another fix would be
      Yfufydjd
      Ifififigi
      Ufifjgig
      Heufivob
      Ugggii
      Jfifedjcuvo
      Sytwydiio

    • @kingsgard3000
      @kingsgard3000 5 ปีที่แล้ว +7

      You’ve just saved 1 precious byte! Respect!
      Edit: Apparently my comment sounded sarcastic to some of you but I meant it literally. I see it as a work of art and in my daily work, even 1 bit can make a huge difference.

    • @AnnatarTheMaia
      @AnnatarTheMaia 5 ปีที่แล้ว +9

      @@kingsgard3000 that's what coding in assembler is all about. In this particular case, a deliberate intent on my part was to slot two instructions in the space of four bytes, thus preserving the rest of the instruction and data stream and since this is a hot code path (executed a lot), not wasting a cycle on a slow processor powering a machine with little memory is important. I like to call it "minimally invasive surgery".

    • @YourTVUnplugged
      @YourTVUnplugged 5 ปีที่แล้ว +5

      @@AnnatarTheMaia Yep because NOP and CLC are both one byte! So might as well have that byte be a meaningful operation rather than a no operation. Still it's good in general to know you can nop to properly patch code like this. It's a good micro optimization for sure though... Let's use it along with what Hugo said though I think he's right to use a JMP rather than JSR as one further micro optimization to not needlessly push to the stack and pop from it to return (RTS)! It also would be the way around not being able to use the stack in your patch code location and you would be able to. JMP is still 3 bytes as with JSR so we can still use your CLC instead of nop optimization and Hugo's JMP instead of JSR optimization for the perfected patch of this little bug in the assembler! :D
      * = $AB2F
      AB2F CLC 18
      AB30 JMP $C810 4C 10 C8
      AB33 LDA $A4B0 AD B0 A4
      * = $C810
      C810 ADC *$39 65 39
      C812 STA *$39 85 39
      C814 JMP $AB33 4C 33 AB
      The needed CLC and JMP to the patch location, the patch containing the instructions we overwrote, then a JMP back to the same place RTS would've returned to.
      :)

  • @10MARC
    @10MARC 5 ปีที่แล้ว +9

    Wow. What great detective work!

  • @vedranmaricevic6760
    @vedranmaricevic6760 5 ปีที่แล้ว +9

    Makes me feel younger. Thank you kind sir

  • @midqualitygaming3498
    @midqualitygaming3498 5 ปีที่แล้ว +20

    Ah yes, I remember playing with my cracked turbo ass when I was a young lad.

    • @MrQuijibo
      @MrQuijibo 5 ปีที่แล้ว +4

      Cracked turbo ass 🤣

  • @VintageGearFreak
    @VintageGearFreak 5 ปีที่แล้ว +10

    Great video, love these debugging sessions

  • @revelationnow
    @revelationnow 5 ปีที่แล้ว +1

    @19:56, I'd argue you can mess with the stack, but you just need to put it back in the right order before you are done :). This is a wicked demo and patch. I wonder how many programs leverage this bug or programs failed because of. Really great work!

  • @markgoldspink5109
    @markgoldspink5109 5 ปีที่แล้ว +83

    The Windows patch for this would be 2 gig.

    • @vasili1207
      @vasili1207 5 ปีที่แล้ว +10

      Nah they just bring out a new version of windows .... with different bugs ... but we fixed that one 😑

    • @Atlas_Redux
      @Atlas_Redux 5 ปีที่แล้ว +5

      Windows patch system is fine. It's way worse with Steam, Nvidia, basically any driver provider and not to mention GAMES where the bloody developer themselves can't inject code and have to update the ENTIRE DATABASE for a simple fix or addition. Changing the look of a small icon? That's a 80GB download.

    • @Atlas_Redux
      @Atlas_Redux 5 ปีที่แล้ว +2

      @@vasili1207 The point of Windows 10 is exactly to prevent giving out new Windows versions so often. There hasn't been a new Windows version in 4 1/2 years and they're hoping to at LEAST double that time.

    • @IamRasheed
      @IamRasheed 5 ปีที่แล้ว +1

      AtlasRedux b

    • @AlanCanon2222
      @AlanCanon2222 4 ปีที่แล้ว

      Best. Comment. Evah.

  • @sheldonkerr
    @sheldonkerr 5 ปีที่แล้ว +37

    I'm watching screens of assembly which I have no idea what's doing gone and hoping like hell he solves this bug like I'm watching some Netflix drama series. What the hell is wrong with me? When does the next video drop?

    • @csbruce
      @csbruce 5 ปีที่แล้ว +3

      Our hero vanquishes another foe!

  • @baardbi
    @baardbi 5 ปีที่แล้ว +6

    Always great to see a C64 assembly video from 8-Bit Show And Tell. I would love it if you made a few videos where you explain how to handle sprites (movement, collisions etc.), joystick input and music in 6502 assembly. I haven't given up on my dream of making a C64 game :)

    • @WarrenGarabrandt
      @WarrenGarabrandt 5 ปีที่แล้ว +1

      You might want to look into the 8-bit-guy's CommanderX16 that's he's creating using all off the shelf parts (except the system board I guess), so repairs and upgrades are possible without using old obsolete parts. He will be selling early versions of it before too long I think, and there's an emulator you can run and develop software for it. Also, Ben Eater just started a series where he takes a W65C02 CPU (variant of the C64's CPU), and shows how to build a system around it and make it work. 2019 is turning out to be a great year!

    • @baardbi
      @baardbi 5 ปีที่แล้ว

      @@WarrenGarabrandt Thanks for the tip. I'm a subscriber of the 8-Bit Guy, so I am aware of the Commander X16. I am also looking forward to the C64, which will be coming out in december. My point was that I would love som tutorial videos from 8-Bit Show And Tell on how to make C64 games in 6502 assembly. That would be awesome :)

    • @8_Bit
      @8_Bit  5 ปีที่แล้ว +3

      Hi, I actually did do a couple videos about those subjects just a few ago: here th-cam.com/video/mOMc6kLkUrg/w-d-xo.html and here th-cam.com/video/EZAcD8aXVm4/w-d-xo.html and will be doing another joystick + sprite video soon. And there's a lot more to explore in the game area which hopefully I'll be getting to later this year.

    • @csbruce
      @csbruce 5 ปีที่แล้ว

      @@WarrenGarabrandt: Robin interviewed The 8-Bit Guy about the Commander X16 in the previous episode: th-cam.com/video/712jLsOnoZg/w-d-xo.html

  • @TheRetrospective
    @TheRetrospective 5 ปีที่แล้ว +3

    That was an intense bug-hunt, well done, sir! 👏🏻

  • @phil2768
    @phil2768 2 ปีที่แล้ว

    Brilliant video - keep doing what you have been here - it's really useful. There seems like SO much to learn to get to your level of understanding of this which is why I keep watching your videos to try to familiarise myself more and more - I've yet to write any significant assembler code, I find it so alien.

  • @thepun3721
    @thepun3721 5 ปีที่แล้ว

    the information here goes way beyond just solving a bug, freakin nice work man!!!

  • @AlanCanon2222
    @AlanCanon2222 4 ปีที่แล้ว

    That was kick ass. Followed the whole thing. 6510 assembler is the only assembler I ever learned.

  • @jack002tuber
    @jack002tuber 5 ปีที่แล้ว +1

    You said you are going to disassemble an assembler. I got a little chill. So you mention location $AB1E, I realize you set for RAM in the area, but when it is ROM that is Kernal and a neat routine that will print a string in memory to the screen until it hits a null. Handy one to use. Great video. Excellent.

    • @8_Bit
      @8_Bit  5 ปีที่แล้ว +2

      Yes, that's a funny coincidence that the code was at $AB1E. At one point when I was disassembling this before I recorded the video, I had to make sure I was actually in the TMP code and not accidentally looking at the BASIC ROMs, as I saw some familiar addresses.

  • @MindFlareRetro
    @MindFlareRetro 5 ปีที่แล้ว

    Excellent work, yet again, Robin. I have great respect and sprinkle of envy for this type of knowledge that I never could grasp very deeply. Thanks for sharing your expertise.

  • @LeeOades
    @LeeOades 5 ปีที่แล้ว +3

    I never did learn assembly but loved this. Fascinating stuff.

  • @jdrukman
    @jdrukman 5 ปีที่แล้ว

    I used to do 6502 for work back in the80s. This really took me back. Nice job!

  • @RetroRelixRestorer
    @RetroRelixRestorer 5 ปีที่แล้ว +1

    ...and you've answered why I had problems with JSR's too re PHP/POP - I never realised 👍

    • @YourTVUnplugged
      @YourTVUnplugged 5 ปีที่แล้ว

      Yea you know a way around that issue right? Use JMP instead of JSR (JMP to patch and JMP back to next instruction after overwritten ones):
      * = $AB2F
      AB2F CLC 18
      AB30 JMP $C810 4C 10 C8
      AB33 LDA $A4B0 AD B0 A4
      * = $C810
      C810 ADC *$39 65 39
      C812 STA *$39 85 39
      C814 JMP $AB33 4C 33 AB
      xD Try that next time Mark!

    • @RetroRelixRestorer
      @RetroRelixRestorer 5 ปีที่แล้ว +2

      I wrote and read from the zero page, which from memory was actually faster by one cycle..!

  • @ret4kind
    @ret4kind 4 ปีที่แล้ว +2

    7:36 bitwise addition in your head is pretty damn impressive. That's the difference between college-trained programmers and Full Sail University-trained programmers.

  • @lostindesolation2810
    @lostindesolation2810 5 ปีที่แล้ว +1

    Neat!
    I used a similar approach with a small routine at the end a while back while fixing a annoying bug in Funkpaint related to the timing discrepancy in the different revisions of the cia. But after some reading and testing I could remove my routine by instead changing a value for setting up the timer irq. I'm quite new to asm on the c64 so the path to success is sometimes less obvious.
    Thanks for a great video!

  • @chaoslab
    @chaoslab 5 ปีที่แล้ว +5

    Awesome 8-Bit Styles.

  • @Psychlist1972
    @Psychlist1972 5 ปีที่แล้ว +7

    Is this the same "The Fatman" who did the music for 7th Guest?

    • @8_Bit
      @8_Bit  5 ปีที่แล้ว +2

      This is a different guy! I've never met the 7th Guest musician, but a friend of mine knows him well, so that's nifty.

  • @jeremiahlyleseditor437
    @jeremiahlyleseditor437 5 ปีที่แล้ว

    Great Job.
    It's incredible this was not done decades ago.
    Wonderful

  • @BdR76
    @BdR76 4 ปีที่แล้ว +1

    22:30 "he did figure out ways of working around it" ok but what's the work around? Can't you just type hex values like *STA $04F8* or something?

  • @MrRobbyvent
    @MrRobbyvent 5 ปีที่แล้ว +4

    Sooo typical this happens when programmers used techniques to steal every byte and tick of clock in their LM routines back then ! Very instructive.

  • @rorkirbabtista9429
    @rorkirbabtista9429 5 ปีที่แล้ว +3

    You're a true hero of our time.

  • @SyphistPrime
    @SyphistPrime 4 ปีที่แล้ว

    That's some good detective work. It's interesting to see bugs like this go undocumented for so long. I guess someone just had to wait 34 years for that patch lol.

  • @FluffyAnvil
    @FluffyAnvil 5 ปีที่แล้ว

    Imagine videos like these been available 30 years ago. Awesome video.

    • @tarekdemiati9991
      @tarekdemiati9991 3 ปีที่แล้ว

      30 years ago it was a black art for most mere mortals ;-)

  • @Wenlocktvdx
    @Wenlocktvdx 5 ปีที่แล้ว +1

    Brings back asm memories on Tandy Color Computer with Edtasm+, the equivalent of CLC is AND CC, and the the value to clear Carry bit, SEC is the same but using the value to set the bit.

  • @azzajohnson2123
    @azzajohnson2123 5 ปีที่แล้ว +2

    “Unless you know what your doing” = if you are more of a god than me. Fixing 30+ year old bugs in assembly.

  • @manicsorceress2181
    @manicsorceress2181 5 ปีที่แล้ว

    I don't really understand what you are doing but I love watching your videos. It's the same as with the EEVblog. Looks like I have a weakness for things that are too high for me.

  • @quantumac
    @quantumac 5 ปีที่แล้ว

    I remember writing this kind of assembly code back in the day, only with the Apple ][+ and the 6502. I'm so very glad I don't have to do assembler anymore, especially with those old 8-bit processors. Debugging was often a long and painful affair.

  • @demoscenes
    @demoscenes 5 ปีที่แล้ว +1

    Totally awesome dude! Love the way you explain, step by step. Making it understandable. How did you capture the signal from the C-64? It looks so sharp and crisp :) Thanks for the inspiration.

    • @8_Bit
      @8_Bit  5 ปีที่แล้ว +1

      Thanks. I'm using the HDML Cloner Box Evolve for all my capture. I'm pretty happy with it!

  • @stevejones4275
    @stevejones4275 5 ปีที่แล้ว

    It's all very good and it reminds of the programming I used to do 35 years ago. Good work....

  • @ciesinsk
    @ciesinsk 3 ปีที่แล้ว

    Proving that the patch is safe by using the TMP. I had to smile there.
    Man, this is awesome. I had to watch the video twice to understand switching out the ROMs. I now get it: TMP (as you said) lives partly in the area where the BASIC ROM normally exists.
    But here is my question: How does TMP get there? Can you tell the loading process not only the start address where to load a program, but also the bank switching? Or is there some sophisticated bootstrapping when TMP is started for the first time?

  • @jmp01a24
    @jmp01a24 ปีที่แล้ว

    Did you fix the block byte display crash? It was a famous glitch that happened in Turbo Assembler (possibly if used with a cartridge inserted as some don't like certain memory peeked).

  • @ryanbrooks1671
    @ryanbrooks1671 5 ปีที่แล้ว +2

    Is there a way to program TMP onto a cart? I assume the snapshot button is NMI\?

    • @AnnatarTheMaia
      @AnnatarTheMaia 5 ปีที่แล้ว

      In theory, it should be doable if you have the "EasyFlash" cartridge. I've been meaning to do exactly that for several years now. First though, you'd have to convert the code to a .CRT image.

    • @8_Bit
      @8_Bit  5 ปีที่แล้ว +1

      In the previous video I interview my friend Adrian Gonzalez about the Super Snapshot clone he's making, and he intends to have TMP included on the big flash ROM on the cartridge. I'm really looking forward to him completing that project! You can watch it here: th-cam.com/video/712jLsOnoZg/w-d-xo.html
      Freezer cartridges actually don't use NMI, they use the "GAME" aka "Ultimax" line to take over the computer.

    • @Curt_Sampson
      @Curt_Sampson 5 ปีที่แล้ว

      @@8_Bit Asserting /GAME line just banks out all internal ROM and puts the cart ROMHI and ROMLO at $E000 and $8000 respectively, right? So you still need a way to get control of the computer once you've done that, since the program counter might be anywhere and the CPU could happily continue executing from, say, $2345 or wherever it might have been in RAM.
      The obvious way to get control is by generating an NMI, and that's what the FC III does if you look at the reverse-engineered schematics linked from hackaday.com/2017/05/20/building-a-replica-final-cartridge-iii/ (Of course, you still need to make sure that the NMI vectors to you, which you can be sure of if you asserted /GAME before NMI so that your ROM is providing the vector at $FFFA.

  • @75slaine
    @75slaine 5 ปีที่แล้ว

    Fascinating as always Robin, thanks.

  • @hugovangalen
    @hugovangalen 5 ปีที่แล้ว +3

    Amazing and funny that it was undiscovered for so long!
    BTW that Turbo Assembler is totally unrelated to the Borland product that I used on the PC?

    • @AnnatarTheMaia
      @AnnatarTheMaia 5 ปีที่แล้ว +3

      Completely unrelated to Borland's "Turbo Assembler" ("TASM"). Not only is Turbo Assembler on the C=64 the best assembler to use on that hardware, but it came way before Borland's version. Turbo assembler by Wolfram Roemhild was published by Omikron in Germany in 1985; Borland didn't publish "TASM" until 1989.

  • @VidNudistKid
    @VidNudistKid 4 ปีที่แล้ว

    You can save a couple clock cycles by using a JMP instead of JSR, because it doesn't save the return address on the stack, then instead of RTS use another JMP to the point in the original code right after the NOP you put in. The second JMP isn't faster than a RTS because it's reading the return address from code instead of the stack, but then by skipping the NOP you save another couple of clock cycles. In addition to the speed gain, your patch is now free to manipulate the stack. On the other hand, with this method you can't use the same patch to replace different parts of original code, and the patch is two bytes longer than in your approach (JMP vs RTS).

  • @winfr34k
    @winfr34k 5 ปีที่แล้ว +1

    Very informative - you even slipped in the bit about ,8,1 :-P
    Recently I stumbled upon the VSP bug that plagues my C64c when running the Wonderland 13 demo - It would be really cool if you could make a video about that on this channel as I found the reason of why it happens very surprising when researching it :-)

    • @8_Bit
      @8_Bit  5 ปีที่แล้ว +2

      It's on my list of things to do, but might be a while :) Probably first I'd need to do an episode on how to create a "stable raster"...

    • @AnnatarTheMaia
      @AnnatarTheMaia 5 ปีที่แล้ว

      @@8_Bit and also how to do music replay using the CIA timers, as they are not supposed to be affected by PAL or NTSC...

  • @johneygd
    @johneygd 5 ปีที่แล้ว +3

    Wow, just imagine if that bug became wide spredded back in the 80’s.

  • @nullplan01
    @nullplan01 4 ปีที่แล้ว

    What you can also do is shift the input twice (so you get x4), add the original value (x5), then shift once more (x10). Comes out to the same in effort, but you might save a temporary register. Or stack slot, in case of the 6502.

  • @pierrenagonio
    @pierrenagonio 5 ปีที่แล้ว +2

    Amazing. BTW I had The Pirates game on the cassette, recordet in normal mode. Had to wait... IDK how long? 30 minutes to load. And another amount of time to load another part of the game. Funny things I was so exited waiting. Old days.

  • @haremari
    @haremari 5 ปีที่แล้ว +3

    Three bytes can be saved in the beginning if the sequence SEC; SBC #$30; BCC $AB4B at $AB08 is substituted simply by EOR #$30, which should do the same thing. The BCC is unnecessary anyway, since the case "less than #$30" is already covered by the BCS at $AB0F. Plenty of room to put your patch in.

    • @YourTVUnplugged
      @YourTVUnplugged 5 ปีที่แล้ว

      Henning thanks! You're absolutely right! The BCC $AB4B was where it was actually cleaning exiting but replacing those 3 instructions with an exclusive or works perfectly it takes the next BCS branch immediately after without a hitch! Ive assembled and and tested the follow code which replaces those three instructions with the EOR #$30, shifts the following 23 bytes of the code upwards, and finally inserts the CLC and two nops exactly where needed. Relative addressing branches needed to be fixed as well though, so it's a bit rough and hackish but it doesn't require a hook simply editing the code in place with the saved bytes allowed for an in-place-patch! (See Stuart MoChannachie's post below for a more refined version which I employed your method and his shorter code for an optimal in-place-patch that saves 12 bytes instead of just 3) Here it is though: ->
      ;Shorten code with an EOR instead of 3 instructions and shift code upwards inserting CLC where it's needed a two NOPs! Special Thanks: Henning Jensen!
      patchaddr1 = $ab08
      patchaddr2 = $ab2c
      shiftupto = $ab0a
      shiftupfrom = $ab0d
      *= $1000
      1000 a2 00 ldx #$00
      shiftupwards
      1002 bd 0d ab lda shiftupfrom,x
      1005 9d 0a ab sta shiftupto,x
      1008 e8 inx
      1009 e0 23 cpx #$23
      100b d0 f5 bne shiftupwards
      100d a2 00 ldx #$00
      100f 4c 1f 10 jmp fixbranches
      skipstas
      1012 e8 inx
      1013 e8 inx
      1014 4c 1f 10 jmp fixbranches
      fixbranch
      1017 bd 0a ab lda shiftupto,x
      101a 69 02 adc #$02
      101c 9d 0a ab sta shiftupto,x
      fixbranches
      101f bd 0a ab lda shiftupto,x
      1022 e8 inx
      1023 c9 b0 cmp #$b0 ;BCS
      1025 f0 f0 beq fixbranch
      1027 c9 8d cmp #$8d ;STA anti-clobber
      1029 f0 e7 beq skipstas
      102b e0 23 cpx #$23
      102d d0 f0 bne fixbranches
      102f a2 03 ldx #$03
      1031 ca patch dex
      1032 bd 45 10 lda patchcode,x
      1035 9d 2c ab sta patchaddr2,x
      1038 e0 00 cpx #$00
      103a d0 f5 bne patch
      103c ee 20 d0 finished inc $d020
      103f ee 21 d0 inc $d021
      1042 4c 3c 10 jmp finished
      patchcode
      1045 18 clc
      1046 ea nop
      1047 ea nop
      *= patchaddr1
      ab08 49 30 eor #$30
      :D

  • @stumbling
    @stumbling 5 ปีที่แล้ว +13

    I "solved" an old "bug": I was not old enough at the time to have a C64 but I was playing around with an emulator and some digital copies of Compute! magazine to get some of the feel of the time. There was a proofreading program to help with typing in the other listings, it would give you a simple checksum of the line you typed in (literally just all the ASCII values of the characters on the line added together) so you can check that against the one in the magazine. The writers lamented that this proofreader would not help with transposition errors as transposed characters would still add up to the same value checksum; why oh why did no one think of inverting the bits of the checksum after each character? This gives transposition error detection! I wish I had been around in 1984 to write in with this suggestion.

    • @8_Bit
      @8_Bit  5 ปีที่แล้ว +3

      I remember reading about the problem with transposition errors too. I think a later revision of the checksum program did include a better algorithm that handled transpositions, but I'm not sure how it was implemented. Good memories, thanks for the comment.

    • @vcolinc
      @vcolinc 5 ปีที่แล้ว +1

      Interesting. Can you walk through an example please to show how the arithmetic works?

    • @longlostwraith5106
      @longlostwraith5106 5 ปีที่แล้ว +1

      Simple, elegant and clever solution. Nice.

    • @WarrenGarabrandt
      @WarrenGarabrandt 5 ปีที่แล้ว

      Ben Eater has a great couple of videos talking about how to do checksums of various complexity and what kind of errors each can detect and correct.

    • @AlanCanon2222
      @AlanCanon2222 4 ปีที่แล้ว

      I remember that checksum program!

  • @jensdroessler3575
    @jensdroessler3575 5 ปีที่แล้ว +1

    Hi! I enjoy watching your videos even though I did never code in assembler myself. I won't pretend I know too much about it now, but why do you use JSR to jump to the the patch and RTS to get back instead of simple JMPs in and back? Wouldn't that circumvent the possible problem with the stack if the PHS would have went inside the patch?

    • @8_Bit
      @8_Bit  5 ปีที่แล้ว +2

      RTS only takes one byte, while JMP $xxxx takes 3 bytes, but yes, that solves the stack problem. It's funny how even in a tiny patch like this there are multiple solutions, and not always a clear best way to do it.

    • @jensdroessler3575
      @jensdroessler3575 5 ปีที่แล้ว +1

      8-Bit Show And Tell Oh yes, I see. Thanks for the response!

  • @UberRuthlessOld
    @UberRuthlessOld 4 ปีที่แล้ว

    can you provide fixed d64 but for ide64 version?

  • @0xGEEK
    @0xGEEK 3 ปีที่แล้ว

    I'm was just been playing around with the fixed version of the Turbo Macro Pro and noticed that the counter for labels doesn't decrease when you remove a label you no longer need. As soon as you reach the maximum number of labels, there's nothing you can do to reduce the count, and you end up stuck. Is this a bug also? Or just a way to force you to program more efficiently?

    • @8_Bit
      @8_Bit  3 ปีที่แล้ว

      I've heard about that problem but never encountered it myself. It certainly sounds like a bug, or at least a bad limitation. I believe the workaround is to write your source out as a sequential file (back arrow W), cold-start TMP (back arrow C) then load the sequential file (aka "enter" back arrow E). It'll rebuild the label table and you should have free space again.

    • @0xGEEK
      @0xGEEK 3 ปีที่แล้ว

      @@8_Bit A heartfelt thanks for your answer! Thanks man, you rock! Keep up the good work! Greetz from germany!

  • @AgeofReason
    @AgeofReason 5 ปีที่แล้ว +1

    So you were able to write the patch to the chip?

    • @cfsmart
      @cfsmart 4 ปีที่แล้ว

      No, It is bug. Turbo Assembler released since 1983 and until found and fixed and patched at 34 years later. Not in the chips in Commodore 64.

  • @jeffstack4217
    @jeffstack4217 ปีที่แล้ว

    14:59 So, 0.3% constitutes as 'rare' huh? Someone should've told that to World government 3yrs ago!! lol
    Great Stuff as usual Robin!

  • @shieladixon
    @shieladixon 5 ปีที่แล้ว

    This is awesome Robin, I love the way you make things sound so simple and logical. When you are going through the disassembly, it looks like there's a PHA and shortly after a branch (to the 'illegal quantity' warning). I'm always nervous about using the stack for the reason you mention later. And a branch right after pushing something to the stack seems perilous! Is there a corresponding pull to clean things up during the illegal quantity handling routine?

    • @8_Bit
      @8_Bit  5 ปีที่แล้ว

      Yes, that's definitely bad practice, and I had missed that while making this video. Another commenter just pointed this problem out yesterday. I looked into it a bit now, and there doesn't seem to be any cleanup for it, but it seems that possibly that branch isn't ever taken; one of the later checks for an illegal quantity always occurs first, as far as I can tell. I don't think I'll put more time into this, but it'd be lovely if anyone else wants to dig into it and reports back :) Thanks for your comment and support, Shiela!

    • @lunstee
      @lunstee 5 ปีที่แล้ว

      Those two branches are superfluous. They check that 2x and 2x+n don't overflow, but we would have already overflowed generating 8x and branched then.

    • @Curt_Sampson
      @Curt_Sampson 5 ปีที่แล้ว

      @@lunstee Which two branches? The ones at $AB37, $AB3C and $AB41 all seem necessary to me because even if we didn't overflow when calculating 8x, either of the _additional_ 2x and n that add in after that might still cause it to overflow if it was close to overflowing after the 8x.

    • @lunstee
      @lunstee 5 ปีที่แล้ว

      @@Curt_Sampson The two branches shieladixon referred to, at $AB37 and $AB3C that are after PHPs that haven't been PLPd yet, which would look like potential stack problems.
      The 2x is of the initial value given to the 8x loop, not the result of the 8x. If 8x didn't overflow, x is under 32, so doubling that won't overflow, being under 64. Adding up to 9 to that also won't overflow, being under 73.

  • @TheHighlander71
    @TheHighlander71 5 ปีที่แล้ว

    I really enjoy your videos and I hope things won't become too commercial.

    • @8_Bit
      @8_Bit  5 ปีที่แล้ว +1

      Thanks. I doubt I'm in much danger of selling out by making videos about patching 34-year-old bugs! :)

    • @TheHighlander71
      @TheHighlander71 5 ปีที่แล้ว

      Good point!

  • @thegreathead
    @thegreathead 5 ปีที่แล้ว

    I really like the clear explanation.

  • @MikeNoce
    @MikeNoce 5 ปีที่แล้ว

    Keep it up and maybe you can do this full time! I will donate soon if you keep it up!

  • @xTerminatorAndy
    @xTerminatorAndy 5 ปีที่แล้ว

    09:53 is there PHP in your assembler language?

    • @8_Bit
      @8_Bit  5 ปีที่แล้ว

      Yes, PHP and PLP to push and pull the processor status.

    • @xTerminatorAndy
      @xTerminatorAndy 5 ปีที่แล้ว

      @@8_Bit thank you

  • @BobBeatski71
    @BobBeatski71 5 ปีที่แล้ว +1

    There is something very satisfying about watching 6502/6510 coding.

  • @fuzzybad
    @fuzzybad 5 ปีที่แล้ว +1

    Now this is podracing! Good stuff.

  • @yrath5034
    @yrath5034 5 ปีที่แล้ว +1

    I really enjoyed this. You have picked up a new subscriber.
    I've never owned a C64 but I think I'll try to find one now, which exact model is this?
    Would it be possible to list here (or preferably in the video description) each and every component (software and hardware) that you use?
    Looks like a good setup that I'd like to copy.

    • @8_Bit
      @8_Bit  5 ปีที่แล้ว +3

      Thanks for subscribing! This is a Commodore 64C which is functionally the same as the original Commodore 64, but just has a redesigned case and keyboard that's a bit more pleasant to type on. The original style C64 was sold from approximately 1982 - 1986, and then this 64C from then on. I'm using a Super Snapshot v5 cartridge for its freezing and machine language monitor. I'm also using a uIEC SD card reader from Retro Innovations, but there's also the SD2IEC from The Future Was 8-Bit that's similar.

    • @AlanCanon2222
      @AlanCanon2222 4 ปีที่แล้ว

      Find VICE, the free C64 emulator. It's really good.

  • @mikebell2112
    @mikebell2112 4 ปีที่แล้ว

    Since it's a patch only used once and the code is already assembled, might as well use direct JMPs to the patch and back to avoid messing with the stack.

    • @8_Bit
      @8_Bit  4 ปีที่แล้ว

      I usually use JSR because the RTS uses two less bytes than a return JMP, but yes, this can be a good choice also.

  • @zetaconvex1987
    @zetaconvex1987 5 ปีที่แล้ว

    I guess it's a case of Turbo-Ass by name, and Turbo-Ass by nature.

  • @Ryges
    @Ryges 5 ปีที่แล้ว

    It’s been quite some time since I’ve done 6502 assembler, but can’t you just do an ADD $39 instead of ADC?

    • @8_Bit
      @8_Bit  5 ปีที่แล้ว +5

      6502 only has ADC. A plain ADD would have saved many cycles and bugs over the years!

    • @Ryges
      @Ryges 5 ปีที่แล้ว

      8-Bit Show And Tell you’re right. My bad. I was so sure that there was both an add and adc instruction. Then again, it’s been a while ☺️

    • @8_Bit
      @8_Bit  5 ปีที่แล้ว

      It's easy to get mixed up, because other processors do have both!

    • @Ryges
      @Ryges 5 ปีที่แล้ว +1

      8-Bit Show And Tell yes. The Z80 has both ADD and ADC instructions which might be the source of my confusion since I’ve been reading about Z80 assembler some weeks ago.

  • @Roman_Comrad
    @Roman_Comrad 5 ปีที่แล้ว +2

    Thanks man

  • @svensubunitnillson1568
    @svensubunitnillson1568 5 ปีที่แล้ว +1

    no bug bounty?

    • @AnnatarTheMaia
      @AnnatarTheMaia 5 ปีที่แล้ว

      You get the fix upstreamed in the new version of Turbo Macro Pro by Style and get to use a higher quality assembler, what more do you want?

  • @jasondaigle9852
    @jasondaigle9852 5 ปีที่แล้ว

    :) Thanks ! love how you explain! you do MIPS?

    • @8_Bit
      @8_Bit  5 ปีที่แล้ว

      I've never tried MIPS. I've done some x86, Z80, a little 68000 and ARM, but mostly 6502 :)

    • @AnnatarTheMaia
      @AnnatarTheMaia 5 ปีที่แล้ว

      I'm no stranger to RISC assembler (UltraSPARC), but coding on MIPS is hard. The superscalar design and the six stage pipeline make it a challenge. The entire job is complicated by the fact that the mnemonics are poorly designed and unintuitive; it becomes painfully obvious that this was a processor designed from the ground up for two things: high performance and compiler-generated code. While the former is impressive, the latter is regrettable. (My primary workstation was powered by MIPS R10000 64-bit CPU for quite a while. I loved that thing.)

  • @TheAndjelika
    @TheAndjelika 4 ปีที่แล้ว

    As you said, no one was using decimal numbers in that time, so that is why this bug was irrelevant. In 80ties, my brain was totally working in HEX, and it was long ago. I guess when you use the same assembler now, and you can't force yourself to thing hex, that is the moment to actually see that bug. There are plenty of coding tools, monitor(s), assemblers from that era which can't work decimal at all. (:

  • @napomania
    @napomania 5 ปีที่แล้ว

    ciao Robin, what do you think of the Commander X16 ( the 8BitGuy's dreams computer) ? you think you will try to do something with that when it will be released?

    • @8_Bit
      @8_Bit  5 ปีที่แล้ว +1

      The X16 is interesting, and I will probably try porting one of my old games (such as Minima Reloaded, a mini-RPG) to it once the design is stable enough. I actually helped 8 Bit Guy out with some early KERNAL code on it, such as the keyboard routine, but I think that's been replaced by PageTable's work, and that's fine, that guy's a genius :)

    • @csbruce
      @csbruce 5 ปีที่แล้ว

      To generate much interest, the machine really needs to be C64-compatible, like the MEGA65. Commodore learned this lesson with the Plus/4.

    • @napomania
      @napomania 5 ปีที่แล้ว

      @@csbruce there is no SID. But there is some slots inside that could make some thing about a future compatibility with C64.Who knows?

    • @AnnatarTheMaia
      @AnnatarTheMaia 5 ปีที่แล้ว

      @@csbruce I wish they had... That was my first computer. Commodore was resistant to learning from its mistakes.

  • @HannoBehrens
    @HannoBehrens 3 ปีที่แล้ว

    You can patch this by using the BASIC routine and throw out the whole convertion crap in Turbo Ass. That leaves you a lot of space where you can put features in.
    $BCF3 ASCFLOAT to get ascii to float
    $BC1B ROUND it and
    $BC9B FLOATINT to convert it to an integer
    That's just three jsr with a bit of fluff, scatch the whole mess with converting it by hand and you have even space left.
    Throw out the whole crappy conversion of Turbo-Ass, guess how we did it back then? We killed the crap and if I remember correctly, we even managed to use the rest of codespace for something I don't remember anymore.

  • @azzajohnson2123
    @azzajohnson2123 5 ปีที่แล้ว +3

    I always like people calling me smart, I know I’m smart but I really appreciate when I’m told by someone I respect that I am indeed smart. It makes me feel amazing. You sir are Fucken smart! Enjoy the respect and kudos you deserve you intellectual intelligent human! Keep the content coming. Something you have taught me is how social this sort of learning is. You had a friend surface after 17 years. That’s amazing and a true friend.

  • @publicojornas1787
    @publicojornas1787 5 ปีที่แล้ว

    A video of full of grandfather of the ancient code.

  • @tycoinreno
    @tycoinreno 5 ปีที่แล้ว +1

    While I was watching, the moment you mentioned using a rotate instruction for multiplication instead of a shift instruction, I was sure that was the bug. Turns out it wasn't, of course. But now that has me curious: why on earth would someone use a rotate instead of a shift for multiplying by powers of 2? I would think that using a rotate to multiply is plainly and obviously incorrect. What am I missing?

    • @8_Bit
      @8_Bit  5 ปีที่แล้ว +1

      Yeah, I forgot to mention those two ROLs in a row were bad form. Really it should have been an ASL, and then a ROL. The 2nd ROL is necessary to move the (possible) carry from the low byte to the high byte.

    • @AnnatarTheMaia
      @AnnatarTheMaia 5 ปีที่แล้ว

      @@8_Bit, why not fix that while you're at it too? Put the code on Github and keep it under version control... Or even maybe try to upstream your fixes to Style, there's a good chance they'd take them in.

    • @skilletpan5674
      @skilletpan5674 5 ปีที่แล้ว

      I doubt that Turbo macro pro is opensource software. It's abandonware sure but bourland etc could still say it's worth something (delphi etc).

    • @AnnatarTheMaia
      @AnnatarTheMaia 5 ปีที่แล้ว +1

      @@skilletpan5674 it was published by a German company called Omikron and came out four years before Borland released "TASM". This Turbo Assembler is the real McCoy. It has nothing to do with Borland.

    • @8_Bit
      @8_Bit  5 ปีที่แล้ว

      Turbo Macro Pro has been "re-sourced" and the guys at Style have that source code they've been using for their modifications. We can probably get Elwix to release a new version with this fix and any others discovered.

  • @richardhead8264
    @richardhead8264 5 ปีที่แล้ว +8

    This is not a bug.
    It's a work-around for that thing they did that one time. ☝🤓

  • @garethevans9789
    @garethevans9789 5 ปีที่แล้ว

    What about the security issues associated with unprotected memory, given the recent security flaws associated with caching on modern CPUs? 😉

  • @chromosundrift
    @chromosundrift 5 ปีที่แล้ว +2

    Wow nice one. Are you going to release this fix as a new version? Does anyone have source so you can make a less patchy fix?

    • @8_Bit
      @8_Bit  5 ปีที่แล้ว +1

      There's a .d64 of the fixes linked in the description if you want to check them out. I believe Elwix/Style has the source code to Turbo Macro Pro and hopefully he'll include the fix in a future update. I just saw Elwix at the Vintage Computer Festival Midwest a few weekends ago, actually!

    • @AnnatarTheMaia
      @AnnatarTheMaia 5 ปีที่แล้ว

      @@8_Bit I don't think anyone except maybe Wolfram himself has the source code. I believe what Elwix and the boys did was they resourced Turbo Assembler, reverse-engineered it and put their own labels in.

  • @spudd86
    @spudd86 2 ปีที่แล้ว

    It seems to me that there's no reason your patch couldn't just use a normal jump for both entering and exiting the patch rather than the jump to subroutine/return, it's not like any other part of the program is going to call your patch.

  • @phononify
    @phononify 5 ปีที่แล้ว

    Dear mate, I am totally new to C64 turbo assmebler pro ... used kickassembler before but wanted to check, if i could potentially code natively on the C64because I wanted to hand over the C64 to my son. I stumbled over the following problem: I used the following line to add a petscii char
    data block in one of my kickassembler tests (what works fine):
    text:
    .encoding "screencode_upper"
    .import text "humanrights.txt"
    Now I wanted just to add the same text code block in Turbo Assembler Pro (c64 native prg) and tried the .include command.
    For some reason, I get in this case an assembler crash, that I cannot understand.
    I converted the humanrights.file in my d64 image to PRG, SEQ ... but in all cases the same problem.
    What would be the recommended way to achieve my goal. Thanks a lot, dear mate ... and sorry if i should bother you with my stupid question.
    cheers.

  • @MichaelPohoreski
    @MichaelPohoreski 5 ปีที่แล้ว +1

    Apple ][ fan here. Excellent debugging skills! Using the disassembler to fix the assembler is just meta epic. =P

  • @csbruce
    @csbruce 5 ปีที่แล้ว +1

    0:58 At this point in the video, I'd guess that the problem is in the part of the decimal-number parser that multiplies the already-parsed digits by 10 before adding the next digit. The "127" prefix is the highest 7-bit number. After the multiply is finished, the Carry must not be cleared before adding in the new digit. [Well, I was close.]
    1:18 What about other numbers with a "127" prefix, like "1270" or "12700"?
    4:34 What language is the assembler written in? I wrote an assembler that's written in itself.
    5:00 $AB11, $AB19: it seems odd that they don't have all of their working variables mapped to zero page. At this point in the video, « $AB1E ROL $39 » looks guilty - they should use an ASL so they don't need to rely on the Carry flag always being clear at this point. It does seem that it's always clear, though, barring later branches into the middle of this.
    6:10 BCS is branch if "greater-than or equal to".
    8:58 They do seem to know that the ASL instruction exists! Though, technically, Carry will always be clear at this point since any overflows will be dispatched. Really, though, the designers of the 6502 should have given us just an ROL instruction with no ASL and used the extra "microcode" space to give us the much more useful ADD instruction.
    9:35 They should avoid diddling the stack so much and should do only one operation at a time. They create the awkward need to transmit forward two separate Carry-flag values since they're operating on the low byte twice in a row. No, wait, he's actually doing three separate operations on the low byte before propagating to the high byte. This is madness! In fact, they branch to the error routine at $AAFD with various junk bytes on the stack. The error handler will have to reset the stack.
    10:14 At $AB36, the wrong Carry value from adding the new digit is being brought into the ROL. It should be the Carry value generated by the ASL at $AB28. *ALL* of the Carry values are being propagated to the wrong places. You need to be completely certain that all of the Carries are completely interchangeable before writing code like this!
    19:58 You can mess with the stack in your patch if you JMP to the patch and then JMP back to the next original instruction. This will even be slightly faster in itself and avoid executing the NOP. Since there will only ever be one caller to your patch, it doesn't need to be a subroutine.
    22:18 I wouldn't trust that convoluted code without brute-force testing it with every possible 16-bit input number.

  • @Curt_Sampson
    @Curt_Sampson 5 ปีที่แล้ว

    (After I wrote this I discovered that @Henning Jensen has already posted an even better idea that saves more space. Not to mention others. Ah well. Perhaps some will find this comment useful for fuller explanation of the idea of re-using carries set/cleared earlier.)
    It was worth demonstrating that patching technique so people know what to do when they need more space than is available, but in this particular case you can do the patch inline because there's a byte to be saved earlier in the code.
    The check that the digit is in range '0'-'9' starting with the SEC at $AB08 can be reduced in size by one byte by removing the SEC instruction. Make it the following:
    ; Hand-assembled; I hope I got it right!
    cmp #'9+1 ; AB08 C9 3A
    bcs $AB4B ; AB0A B0 3D
    sbc #'0+1 ; AB0C E9 31
    bcc notdigit ; AB0E B0 39
    sta $A4AF ; ...
    Here instead of starting with the subtraction, comparing to 0, then comparing to $0A, we instead start by comparing with PETSCII ('9' + 1); if it's greater than or equal to that we know it's above our range. Since we've now just passed through a BCS without branching, we know that the carry is clear. Instead of setting it for our subtraction, we leave it clear, which will subtract an an "extra" 1, and compensate for that by giving an argument to SBC of one more than we want to subtract, so PETSCII ('0' + 1) instead of just '0'. The rest continues on as it did before, but since we eliminated the need for the SEC in this section of code, we've saved a byte. The following code is all shifted one byte earlier in memory until we get to $AB2E where we use this now free byte for the SEC, continuing on with the original code from $AB2F onward.
    You need to make sure that nothing's depending on exact instruction locations in that $AB08 - $AB2E range, but given the nature of this code, it's unlikely anything is.
    Also, as @Brutikus Red mentioned, there's two more code bytes that could be removed by using a zero page location instead of $A4B0 for temporary storage of the original running total MSB. Unless they're actually using that somewhere else for something and relying on a copy being there, but I can't see offhand how that would make sense.

  • @8bittimes
    @8bittimes 5 ปีที่แล้ว

    Hm that routine looks complicated. Wouldn't it be easier if there was a shorter routine in place?

    • @8_Bit
      @8_Bit  5 ปีที่แล้ว +1

      Are you saying it would be easier to fix the bug by rewriting the routine? :) That seems like a lot more work to me, but, a number of commenters in this video actually did rewrite it, and I've submitted it all to the guys at Style. Hopefully they'll include it in a future update.

    • @8bittimes
      @8bittimes 5 ปีที่แล้ว

      @@8_Bit I recently wrote one that looked simpler and shorter github.com/fachat/GeckOS-V2/blob/master/apps/common.a65

  • @Twigleaf
    @Twigleaf 5 ปีที่แล้ว

    Only thing Commodore Puter good for, was disk drive doubling as a furnace during Winter. Put disk machine under blanket, and feet warm cozy.

  • @AnnatarTheMaia
    @AnnatarTheMaia 5 ปีที่แล้ว

    The best solution would be to track down Wolfram Roemhild and / or Omikron and ask him / them if we could have the source code. You could make an episode about just the effort to do that.

    • @8_Bit
      @8_Bit  5 ปีที่แล้ว +1

      Even better is the "re-sourced" code that the guys at Style have, that they make the Turbo Macro Pro builds from. It's got many other bug fixes that have been made since Wolfram last worked on it.

  • @paparansen
    @paparansen 5 ปีที่แล้ว

    this is awesome... kudos

  • @cheater00
    @cheater00 5 ปีที่แล้ว

    wonderful - thanks a lot!

  • @FeedingDragon
    @FeedingDragon 2 ปีที่แล้ว

    Just out of curiousity, couldn't you have put the CLC just before the JSR instead of putting a NOP after it?
    $AB2F CLC
    $AB30 JSR $C810
    $C810 ADC $39
    $C812 STA $39
    $C814 RTS

  • @AstAMoore
    @AstAMoore 5 ปีที่แล้ว

    It’s curious that the 6502 doesn’t do a simple ADD, only ADC. On a Z80, fixing this bug would be trivial-ADD A,(HL) and ADC A,(HL) are both one-byte-long instructions.

    • @8_Bit
      @8_Bit  5 ปีที่แล้ว +4

      Yes, and the bug probably wouldn't even have been made in the first place with a ADD opcode. 6502 coders are always trying to optimize away unnecessary CLC instructions, but sometimes it generate bugs like this.

    • @AnnatarTheMaia
      @AnnatarTheMaia 5 ปีที่แล้ว

      @@8_Bit well there is a hardware solution to that, the Motorola MC68000 family of processors. Obsoletes the Zilog Z80, MOS 6502, MOS 6510, MOS 8580 and intel, Cyrix and AMD 80x86 family of proessors, all in one fell swoop. Elegant, as only the MC68000 family can be.

    • @Curt_Sampson
      @Curt_Sampson 5 ปีที่แล้ว

      @@AnnatarTheMaia The 6502 is very elegant for what it is and what its aims were. Keep in mind that the 68000 has somewhere between 12 and 20 times as many transistors as the 6502 and so would be two orders of magnitude more expensive. MOS managed to produce a _very_ nice architecture for its transistor budget, with clear advantages over the 8080 and 6800 in several areas. (Even as a Motorola fan myself, I can see this.) And if you were an engineer or hacker in 1976, you would probably have really appreciated being able to get a powerful (for the time) microprocessor for $25 instead of $175.

    • @AnnatarTheMaia
      @AnnatarTheMaia 5 ปีที่แล้ว

      @@Curt_Sampson I know all of this, yet I love MC68000 more. It was easier and nicer to program (bear in mind, I first learned assembler on MOS 6510).