This is really interesting and informative. Aside from the programming knowledge, I really appreciate your clarity and pace. Things like reiterating the prior result before getting a new one helps to make the narrative clear. There are a lot of channels about retro computers, but few about retro computING. It's good to see them actually used as intended and not just being cleaned and re-capped!
Here's the index, and also there's two errors I'm aware of: 16:02 I say "It will never reach pi" but I should have said "It will never reach zero". 13:55 I should have deleted the A=15 from line 10, it's unnecessary Index 0:00 Intro 0:44 Recap of previous optimizations 1:42 Alternative apps for Android 2:18 GOTO with no parameter! 3:12 Blank the screen 4:15 Quick lesson about ANDing bits 6:13 Disable interrupts 7:48 Unrolling loops 10:58 More unrolling! 12:40 Using Pi 15:14 FOR/NEXT loops as an alternative
I can't tell you how many (late night) hours I spent with my C-64 doing exactly these sorts of things - not really creating a useful program, but learning how to get the most out of the computer and it's BASIC. Just an interesting side: I came into computer programming from the electronics side - through the power cord rather than the keyboard. It's typical for an electronics tech (of my age) to think of the '0' (or least significant) bit being the left most bit. Most right-handed techs will breadboard a circuit from left to right; most schematics have a (more or less) left to right / top down orientation; most 7400 and 74LS00 series I.C. counters and multiplexers had a left to right output orientation with the least significant bit being the top left pin. It's been a source of confusion and heated debate between El-techs and programmers since the 50s. Watch an old 50s or 60s sci-fi movie. If there is a computer involved, it will most likely have flashing lights on the front panel controlled by a binary "up counter". In most cases the light on the left as you view the panel, will be flashing the fastest. This is the '0' bit of the counter. No rules have ever been set in the electronics world for this, it's just something that sort of became the standard. Programmers without an electronics background think in a right to left orientation, binary or hex, because it follows the normal convention for printed numbers, with the least significant number on the far right.
Was taking my blood pressure at home and needed to change mental gears and relax for a few minutes before I starting the machine. I thought to myself "I bet there's a Robin video I haven't seen yet, those are relaxing". Sure enough, Robin's mellifluous, honeyed voice did the trick (got a good reading), and I stayed around for the rest of this episode. ;) Interesting stuff!
Great videos! Your explanations are very clear. I love the split screens showing the monitor and keyboard simultaneously-and the comments and clarifications. You could probably keep your hand off-camera while talking. Somehow, as disembodied hand gesturing is unsettling.
Thanks! As for the gesturing, while editing I noticed I was getting a bit closer to the camera than usual this time. I'll attempt to back off some. Completely off-camera sounds boring, but your preference is noted. Someday I'll make everyone happy :)
I've been following these optimization videos, but using my Vic 20. Similar results! The VIC I chip has the same audio click and can produce a tone too.
Great stuff! I've been enjoying these optimization episodes and playing along at home, holding my Android phone in the air to see which apps most accurately match your readings. Spectroid is pretty much spot on to yours.
That's interesting idea... redirecting text RAM to SID area and then using printa$ to generate the sound! I actually thought about it but... couldn't be bothered. So amazed someone actually connected all the necessary dots and implemented it. Hats off to Jason!
I think it'll vary; some optimizations might cause the compiler to fail, like the parameter-less GOTO will likely. Others will work fine. Others might actually be counter-productive. For example, I think some compilers will see a constant like 54296 or 53280 or whatever and turn that into a super-fast 16-bit integer. But if you turned the constant into a variable as an optimization (as we've done here) the compiler will actually turn that into slower variable code. So the best rule is to write your code for the compiler if you're going to use one, by following the tips given in the manual.
It's too bad that the age of computer magazines with type in BASIC programs went away. I actually miss doing that (even though more than once it took me HOURS to type in the thing and then had an error which took me ANOTHER hour to find!). "Compute's Gazette" was my favorite, or possibly "Info 64".
@@8_Bit I was jealous of the European computer magazines which frequently had a disc taped to the front with awesome demos or even full versions of games, etc. Still, some pretty interesting type in programs over the years (including one of the first "turbo tape" clones that made tape access faster than 1541 access. There was even a fairly primitive BASIC compiler in one magazine.
@@8_Bit CG was the one I could always find at the Mike's Mart on my paper route. :D Ahoy! and Transactor died about the time I was seriously getting into C64. Thanks, muchly, for your assistance in boosting my magazine library a number of years ago...
OK, here's a question for you. When you type "first," you don't go "fir-st," do you? Or when you do "second," you don't type "seco-nd," right? And when you type "fourth," it's not "four-th," is it? Right. So why do you think "zeroth" needs a hyphen, as with "zero-th"? Why not just say "zeroth"?
The extra 64K of main memory on the C128 can't be accessed in C64 mode, but the VDC (80 column video chip) RAM can be. However, the video RAM is slow to access since the CPU can't directly access it. The CPU can also be switched into 2 MHz mode from C64 mode, which is the speed up you're thinking of. Unfortunately, 2 MHz mode also kills video output since the VIC-II can't run at 2 MHz. So some programs switch to 2 MHz while in vblank, but run at 1 MHz the rest of the time, speeding up the computer by around 20%.
It has been a very long time since I used a C64, so I apologize if this information is incorrect, but I do remember being able to rename the BASIC commands, as long as you used same length alternatives. Would it be possible to use this technique, with some sort of hack, to make the PEEK and POKE use a single letter (such as 'E' and 'O', respectively), thus speeding up the interpreter?
Peek and poke (and all other commands) already use a single char internally called Token. Abbreviations are useful only inside the editor to help basic recognize commands. Whether you use ? or PRINT from the memory's point of view is the same: they both occupy 1 byte.
It's certainly possible to copy the BASIC ROM to the RAM underneath and then patch it. But all the BASIC commands are already crunched down to a single byte so there's nothing to be gained there. Certainly though, BASIC could be patched to be better optimized, but at that point I think we're better off abandoning BASIC and switching to machine language :)
It can only be done if your program is less than 256 bytes long, because the execution pointer is a 16-bit value. If your program was more than 256 bytes long, it would require two pokes to change it properly. The BASIC interpreter would never get to the second poke because the execution pointer would be pointing to the wrong location after the first poke. I have no idea if a POKE command would be faster than a GOTO. My guess is no, because a poke requires BASIC to interpret two numbers instead of just one.
Interesting idea, but yeah, I doubt it would be faster than the GOTO. I'd be interested to learn if anyone tried it. Might need more than one POKE to actually implement this too, there are probably other variables/counters/indexes in play.
This method only achieves 167 Hz with an non-unrolled loop where the equivalent code at 7:31 achieved 250 Hz. The extra POKE is a lot slower than the GOTO. Line 0 also needs a leading ":" character to keep the BASIC interpreter happy. It pretty much thinks that line 0 is infinitely long. 0 :POKEV,A:POKEV,.:POKEG,L 10 V=54296:A=15:G=122:L=5 20 POKE53265,PEEK(53265)AND255-2^4 30 POKE56334,PEEK(56334)AND254 40 GOTO0
Disabling screen is not fair optimization. This way you could add just one more poke to switch 8502 to 2MHz clock because you are using C128 and achieve 100% boost. But biggest boost would be just adding machine program in DATA and then run it by SYS, common practice in C64/C128 programming :)
I see what you're saying, and that's what I was trying to address at the beginning of the episode when I said that I was aware of many of the suggested optimizations (or maybe more accurately, speed-ups) but didn't use them in the previous episode because I was looking at just using the BASIC language itself. But for this episode, I was throwing everything at the idea of increasing the pitch, but still limiting myself to just C64 features available from BASIC. But yes, POKEing a ML program in and then SYSing it is valid from a certain perspective, and something I plan on covering in the future :)
@@AlexanderKurtz I mean POKE 53296,1 which turns 2MHz clock on even in C64 mode. Turning screen off speeds up only little bit - it is already shown in the video.
You can turn off the VIC screen for a speed boost on all models of the C64 just like you can on the C128. And BASIC programs commonly do all kinds of POKEry magic.
an UNOFFICIAL git with the code from these videos is available on GitHub. the link for the Code used in this one is github.com/duckyvirus/8bitshowandtell/tree/master/8-Bit%20Show%20And%20Tell%20-%20EP15
Do you call the "1" key the "exclamation mark/one" key? If not, the why would you call the "Stop" key the "Run/Stop" key? It only performs one of those functions at a time and you have to Shift to get the alternate function, just like with the "1" key. Or maybe the closer analogy would be the key with the dual functions "CLR" and "Home". If you want to instruct the user to send the cursor to the home position without clearing the screen, do you tell them to press the "Clear/Home" key or the "Home" key? The former is confusing because it's two different functions and you're tempting the user to activate the wrong function.
0:04 Your guitar-tuner app claims to measure "hz". Are those anything like the "Hz" SI unit? 1:13 I'm a little surprised that a GOTO of the current line doesn't perform well, but I verified that it doesn't. BASIC keeps track of the current line number in locations (59,60) and if it also kept a pointer to the start of the current line, then it would be able to execute «GOTO self» efficiently no matter how far from the start of the program the line is, but I guess they didn't consider this to be an important use case. 2:06 You can just call me "Brutikus". "Red" is the extra distinction I added to my RU-vid Premium account (they used to call the service RU-vid Red). 5:25 Using the term "zeroth" is just a bad idea, since in that scheme, the term "first" means "second", which is just double-talk gibberish. 7:43 I guess it's useful that the Kernal has a special routine to check the Stop key ($FFE1) which directly reads the key-matrix hardware instead of relying on values left behind by the keyboard scanning routing ($FF9F) since otherwise, the Stop-Restore trick wouldn't work because disabling the interrupts disables scanning the keyboard. 10:05 What, fast-forwarding doesn't speed things up for YOU?! ru-vid.com/video/%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-pFrMLRQIT_k.html 10:27 BASIC is totally fine with lines up to 255 (or so) characters, though you'd have to POKE them into place. 13:18 Oh look, a little horsie is running across the screen! I remember first learning about programmable characters entering a program called "VIC Downs" from COMPUTE! magazine. www.commodore.ca/gallery/magazines/compute/Compute-033-01.pdf (p.44) 15:28 You don't need to optimize the FOR statement itself since it is only ever executed once and the TO and STEP values are evaluated only then and stored on the stack in binary floating-point format for later reference. This is why I expected it to beat a GOTO. It's also why in Commodore BASIC, you can't influence a FOR loop by changing the TO or STEP variables inside of the loop, unlike in languages like C. The FOR record structure is shown on page 4 of The Complete Commodore Inner Space Anthology. www.classiccmp.org/cini/pdf/Commodore/The%20Complete%20Commodore%20Inner%20Space%20Anthology.pdf 15:57 It's not clear to me why a loop from π to 0 doesn't recognize that it's finished and exit quickly, assuming that BASIC treats the 0 STEP in the same way as a positive STEP. BASIC needs to execute the continuation comparison as ' π with a STEP of 0.
Indeed. I've also always wondered about Kelvin bytes (KB) versus kilobytes (kB). I guess it's an ingenious way to get more storage as the computer heats up.
If the initial value is greater than the terminal value, the BASIC interpreter is most-likely expecting the step to be negative. For example, for i=70 to 65 step -1: print chr$(i);:next:print. Therefore, it's probably checking for the variable being
@@timsmith2525: BASIC seems to handle a STEP of 0 as a special case. FOR I=0 TO 1 STEP 0:NEXT runs forever and so does FOR I=1 TO 0 STEP 0:NEXT. If you use a STEP of -0.1 or +0.1 with either statement above, they both finish. FOR I=0 TO 0 STEP 0:NEXT does exit, so it probably uses the sign of the step to determine which comparisons to use and only tests for direct equality with a STEP of 0.
I understand the academic value. But why would you ever want to optimize basic so much in practice? I'm curious to know if there is a use case I don't see? If you need such speed and performance you would always use Assembly, no?
Isn't that the point though? Just a fun excercise to see what can be done to basic. In practice, why even use a C64 at all, except for academic value/for fun?
The BASIC language is a "B"eginner's programming language and the home computers of the time were sold with BASIC already installed and ready to go. Assembly is by its nature far from a beginner's language. It was far easier to optimize your BASIC code than to learn assembly which required you to purchase additional software and/or books and manuals.
@@sockcutter I agree with the respective goals/objective of assembly vs basic and their intended audience... But I would argue that if you get into a situation where you need to do such wizardry, you are no longer in the realms of a beginner anyway ;). I assume you could always write your specific routine in assembly, and invoke it from a basic program, no? Is there even such a thing as "inline assembly" support?
M S no, run and stop are different functions on a same key, which is labeled ”Run Stop”. Just like ”Clr Home”, it does ”clear” or ”home”, it does not magically clean up your room when pressed.
@barcoboy1: "SHIFT LOCK" is a single function: locking the shift key down, so you would say both, especially to distinguish it from the non-locking SHIFT keys. Similar to the "Page Down" on PC keyboards, it's neither a "Page" key nor a "Down" key; it's "Page Down": it advances one page downward.
The struggle with built-in atrocious BASIC - created by well-known Bill G. BTW - has no sense whatsoever. If you're into BASIC programming simply try Comal. Comal is what you can describe as "BASIC done right". Why waste time on that crappy CBM BASIC V2 - only because "it's ready after power-on"? One can create Comal-80 cartridge and have it "ready after power-on" as well.