Check out Darren's video about how he made this Groo art for us: th-cam.com/video/b15rw48czAU/w-d-xo.html And here's an excellent diagram by MagerValp illustrating the effect of VIC-II registers $DD00 and $D018 on what is displayed: 8bitshowandtell.com/downloads/BitmapAddress.png Here's the .d64 file containing the art and code from this episode: 8bitshowandtell.com/downloads/grootube.d64 Or plain text to copy and paste in case TH-cam is munging the links: 8bitshowandtell.com/downloads/grootube.d64 Also, check the video description for more links.
Jeez the speed of the info you’re throwing at idiots like me who thought the 64 was cool at playing games on 35 years ago. I struggle, but owning 5 of these things, I just can’t get past how friggn incredible this thing still is. I’m grappling with 3 Gideon boards and MIDI and trying to find out what SID can REALLY do. And you throw VIC2 at me. These numbers drive me nuts because I know them. But nobody has ever told me why I have to SMASH the RESTORE key, or why the SID was “an organically grown silicon chip”. My head is exploding with this sort of stuff. I can’t even explain why you type in 350800 the thing craps itself.
Something I recently found out - after 40 years! - is that when the C64 is in character mode, each individual character can either be interpreted as high res (mono color) or multicolor (unless I misunderstood what I read). I had always thought that the whole display had to be one or the other* but it appears the VIC-II designers were even more clever than I already thought they were! This opens up even more possibilities for what can be accomplished. * Minus the usual tricks that utilize interrupts to change modes in one or more places on the screen of course.
Note, just to clarify on why you use OR: if you simply poked 32 into 53265, you would enable hires mode, but you would also turn off all the other bits which could effect other settings. You OR the current value in that location so that you only turn that particular bit on without effecting the other bits in that same location.
Another nice vid, really helpful. I just wish I had found it a couple of weeks ago when I was trying to load 1000 bytes of screen data with machine language. Bloody brilliant though, glad I found these.
It's so relaxing to see some clear 6502 assembly code solving well-defined problems before heading into work (got a morning meeting, presenting research to stake holders, defending approaches, etc.). A little 8-bit recreational thinking sets the world right before taking on the complexities of the day. Thanks!
@@kaulbachskave It is 6502 assembly because there is no difference whatsoever (unlike, for example, 65C02 assembly, which is highly compatible but different). The ways in which the 6510 is different from the 6502 is that: 1) it replaces unused pins and some pins the C64 doesn't need with an 8-bit I/O port, which is accessed by the same old set of instructions at addresses 0 and 1; 2) the bus lines are all tri-stated (with a selectable high-impedance state); and 3) the pins are rearranged, so the 6510 is not pin-compatible with the 6502 at all. So while most of their silicon is the same, there are significant differences between the 6510 and 6502. Their assembly/machine languages are absolutely 100% identical, however, including the original NMOS undocumented instructions and the manner in which memory is accessed during instruction decoding and execution (different from the 65C02, once again, but identical to each other). It would make no sense to say 6510 assembly because that implies there are differences, which there aren't.
I bought my Ben Eater 6502 breadboard computer kit and stripped all those wires myself, used a VIA chip, added my own interface buttons, learned assembly, was responsible for every damn physical wire to deal with all address and data lines. Don't get me wrong, I enjoy getting into the trenches of it to gain deep appreciation on how 8-bit architecture was put up. But man, seeing how convoluted it is to just display a color image on a screen, you absolutely respect how graphical user interfaces and dev environments went in the right direction to dumb this all down, away from this C64 paradigm which has you massaging pixel and color data into specific ram locations that you have to dig out of manuals. The entry barrier for budding game programmers is just insane.
I used to have Doodle and Micro Illustrator back in the day. Micro Illustrator got the most use. Great program! I had no mouse so I used to draw on graph paper then zoom in on Micro Illustrator and copy the drawing square by square into the computer. It actually worked out really well.
Wonderful video!! The trick I used to use as a kid to copy large amounts of memory in assembly was to actually write self-modifying code. I would copy 256 bytes in a nice tight loop using the X reg and then INC the high bytes of the source and destination and use the Y register to keep running that loop Y times. If the total amount number of bytes to copy was not a multiple of 256 then I would either have this loop stop short (e.g. at 768 bytes when copying 1000) and then do an extra little loop afterward to handle the last 232 bytes. The second way would be to just go ahead and copy more then you need (e.g. 1024 bytes when you only want 1000, or 8192 when you only want 8000). Of course this can only work if the extra bytes after the destination won't harm anything.
Or zero-page indirect X instructions. I think I used that a lot. Using 4 bytes, you can accomplish any memory move. Still have to increment high bytes after each 256-byte copy but at least it isn't self-modifying code. The code sets the initial values in zero page at the beginning of each copy. This is better when you need to perform the action more than once, like in my routine to display an Ultima-style tile on the screen.
Well, you've got me going. Installed Vice, set it up, downloaded TMP and TAss, studying the 6502/6509/6510, learning about all registers of the C64. I'm pretty stunned what the C64 could/can actually do with so little memory (also understanding its limitations). Must say though that I'm not really comfortable with machine language yet; meaning understanding it towards its full fletched complex context; when to apply what exactly efficiently, etc. However, step by step... Thank you for all this work :) Also looking into the C128 and CBM II 500 (with the VIC II, 40 column)... The latter is a super challenge but it can do so much more than ever seen I think.
This is pretty cool. I made a program for the CoCo 3 back in the day for my own game development that took 16 color 320x200 BMP files that had sprites of 8x8 within it and converted them to ML Binary Sprite data that loaded directly into memory for use by your program. Made making sprites for games so much easier.
Great video thank you - I am curious how you get the C64 video to display as a picture in picture on your video? (what hardware or software do you use for that?)
I still remember some the old commands from the day like poke 53280 ,1 i think that makes the outer boarder change color and 53281 was the inner color , Typing sys 64738 caused the system to restart but typing sys 64718 caused it to crash. No idea how i remember this its been years since ive been on a c64.
As a beginner in assembly, I am really impressed by this. The clever methods shown for loading and shifting data surely have many applications. The linked page with graphics file formats is splendid, now I understand the files produced by my favorite graphics program, Blazing Paddles.
Thanks for "opening secret's of C64 assembly language" and basic code examples. Basic to asm examples - really help me to forward understand bit more of C64 assembly language.
0:23 Love me some Groo 8:50 I think Programming the Commodore 64 does an okay job at explaining this, but even it isn't super clear. Hard to explain for sure. 11:45 I've been bitten by this inverted VIC location thing more than once. After the 3rd time you'd think I'd learn... 24:50 Awww, it's not ugly. It's fast ;-)
Thank u for the easy and clear teaching!. Thinking about getting again a C64 and making art on that awesome machine..i had many C64's in my life and i started in 1983 or 1984 with the first one.
There's a Usaki Yojimbo game, Samurai Warrior, on C64, based on the Stan Sakai comic books. I would have loved a Groo game. The connection here is, not only both being sword wielding warriors, Sakai also did the lettering for the Groo comics, while Sergio Aragones (Groo's creator) did the art and Mark Evanier did most of the writing (early on, it was Sergio himself, but Mark later took over the writing duties).
Used to wonder how the newer planar frame buffers of 1985 would ever be as fast as the character sets & sprites of the old days. We just overpowered the slower frame buffer with higher clockspeed, the same way interpreted languages replaced compiled languages.
The simple answer is that they never were as fast. One thing that annoyed me about my beloved Amiga was how slow a simple directory listing was compared to an old DOS machine using a dumb text display. Any way you sliced it, the planar display required 8 bytes of lookup and 8 bytes of writing per character, instead of just directly writing the character code to the screen. And the Amiga simply wasn't 16 times faster than an old DOS machine. It just wasn't.
@5:50 - 6:00 Correct me if I am wrong, but I think each 1541 block actually contains 256 data bytes, and the two bytes needed to point to the next block (track and sector) is somehow tucked away in there without using 2 bytes of the actual data block. I read this in the Transactor many years ago. I think. : ) ...later: Pretty sure I'm remembering something wrong :P
Yeah, there's 256 bytes per block but in a file (like a PRG or SEQ) the next track/sector does take up the first two bytes leaving 254 bytes of "payload" or whatever we want to call it. If you save a 256 byte file it needs two blocks because it won't quite fit in one. And actually for a PRG, the first block loses another 2 bytes because they're used for a "load address" for the program. If you skip the file system and save data directly to the disk, keeping track of the track/sectors yourself, then you get the full 256 bytes. I think Ultima IV did this for its maps, for example.
@@8_Bit True on all counts, including how _Ultima IV_ (and other games in this series) handles its maps. For that matter, even relative files, which have "side sectors" that contain the track and sector number of each data sector in the file, have data sectors that start with the next track and sector numbers (which are redundant) and hold 254 bytes of data each.
That would work if the load address in the colour data PRG file was set to $D800, where the data needs to load to. But the program file's load address was set to $8000 in this case, so that's why it required the extra sets. It'd be possible to change the load address of the program file with a utility (I showed that in the LOAD"*",8,1 vs. LOAD"*",8 episode recently) but knowing how to do this relocating load is also useful so I thought I'd show that in one of the example programs. Thanks for the question!
@@8_Bit I remember that you could set the load address from the episode you've mentioned, that's why I asked. Make sense to show how to relocate loaded file. All this turns into "aha!" moments for me. To think I used ready-made Koala loader back then, stupid me, I want to invent time machine and go back to smack myself. My only excuse is that all the books were in German, the language I could only introduce myself and order a salad.
I really love the video and look forward to exploring this! I have a question - I am trying to load a bitmap I've exported as a prg file and run it alongside some audio code I have in basic, only there is no code executed once the bitmap is loaded, would you be able to advise how I could do such a thing?
The thing about not being able to loop 1000 times because the 6502 is an 8-bit processor isn't entirely true-the Z80 was just as 8-bit, but you could pair its registers to make 16-bit ones and do loops of 1000 directly. Not that you'd ever do that just to copy memory from one place to another, because it also had the LDIR (Load, Increment and Repeat) instruction to do that for you!
True, I wasn't being as precise as I could have been; I should have said "because the 6502 only has 8-bit index registers" or something along those lines. I actually don't consider the Z80 and 8080 to be pure 8-bit CPUs because of the 16-bit abilities they have; like the 65816 in the SNES or Apple IIgs, I consider them to be 8/16-bit hybrids with an 8-bit data bus and some 16-bit register operations. I disagree with deciding the "bitness" of a CPU only on data bus width as it doesn't describe its abilities well enough. The Z80 has 16-bit index registers (IX and IY) and pairs of 8-bit registers that can do 16-bit operations and that should be part of its classification.
@@8_Bit That would make the 6502 the only 8-bit CPU, AFAIK (8080, Z80, 8085 and 6809 all had 16-bit registers)-were there any others? I tend to go with max 64K address space, myself, which I realise also excludes the TMS9900...
@@d2factotum I think the 8008 and F8 are "pure" 8-bit processors too. The 6800 only has 8-bit accumulators (can't be paired) but does have a 16-bit index register. I should take some time to study some of these other processors in more detail to see if I can really come up with a categorization scheme that works.
@@8_Bit I think the 8008 had a virtual 16-bit register M which was made by combining its H and L registers together-in fact, that might have been the only way to access memory on that chip. because I don't think it had instructions which included memory addresses.
@@8_Bit No single number can really classify a CPU. This includes clock speed, because whether it is 16 bit or not, no Z80 is going to out-process a 6502 running at the same clock speed.
This is interesting, not because I understand the code (I don't, even the explanation is somewhat magic to my mind) but because I finally understand a little more :) The whole OR 32 for example is just mind boggling for me hahah ::) Still, interesting :)
Bit-wise OR means that if either of the corresponding bits in the two values is set, it will also be set in the result. 32 is the value of bit 5, so it is made sure that this bit is set in the result. Other bits set in the first value will also be set in the result and thus not affected. Simply poking 32 would set bit 5, but erase all other bits. :-)
In retrospect, the aspect of C64 design that most annoyes me is color RAM. It has to be static RAM. It adds four data pins onto the VIC-II chip for ... eh ... limited benefit. It's just kinda weird. It made some since with how the previous VIC chip worked, but the VIC-II chip internally stores the character/color data anyway ... It really should have been eliminated in favor of using normal RAM, and having two badlines per character row instead of just one badline. The previous scanline loads color data just after displaying a character. The next scanline loads character data just before displaying a character. Yes, this steals more cycles from the CPU, but the machine is less expensive and more flexible. Color RAM can now be located anywhere (well, within a 16K bank). You get to freely choose both background and foreground color in text mode. Multi-color bitmap mode allows you to freely choose the four colors instead of just three (this allows some nice 80x50 "chunky" pixel graphics). It's possible to achieve some VERY nice looking "interlace" effects switching colors every 1/60 sec. Double buffering is more workable, which can be particularly helpful with scrolling. I mean ... of course any of us could rattle off an endless wishlist of what we wish the VIC-II could have done. But for me, adding badlines for color instead of the weird color RAM is the top wish. If I went back in time and could get myself hired into Commodore, I'd try and make that change in the VIC-II design, arguing for it on the grounds of saving production costs.
Apparently this is more-or-less how the TED in the Plus/4 and C-16 work? Losing another ~1000 cycles per frame to badlines would be a fairly high cost, but I agree with all the advantages and probably the advantage of movable colour RAM would outweigh the cycles cost. Even more than movable colour RAM, my top VIC-II wish list item would be a 10-bit screen memory offset register to allow whole-screen scrolling without shifting data (VSP without any tricks!).
@@8_Bit Yeah, although I'd argue that it would be better if the current character pointer were exposed as a register. That way, you simply shove the desired address for the first (or next) line via CPU. This gives you extra flexibility for independently scrolling regions. Hmm... going with this idea, it would be easiest and most elegant to interleave color and character memory. The combined color/character memory takes up 2000 bytes. The two consecutive badlines simply read in 40 bytes of color and then 40 bytes of character. With this flexibility, you could even have a tile/color map wider than 40 characters and scroll within it. The CPU has to add to the character pointer once every 8 scanlines to do this, but it could easily be worth it in many situations.
I've heard that Commodore had hoarded 2114 chips (maybe for their calculators after TI put the squeeze on them) that they might as well have used for something. Supposedly that's why each VIC-20 had 10 of them and, just speculating here, they stuck one in every C64, too. 🤔 And they should have advertised, quite honestly, that the C64 has 64.5K of RAM. 😉
@@8_Bit I've never owned one of the TED computers and haven't played with them much in emulation, either (at least yet), but it kind of looks as though they might do graphics DMA in the same manner that Atari 8-bit computers do. This is probably why the Plus/4 and C16 run at 1.79 MHz (NTSC). So there is a cost, of course, and it's the same (1000 cycles per frame), but it has a larger shared budget or pool of cycles for the CPU to start with, while another 1000 cycle per frame hit on the slower 1.023 MHz CPU of the C64, though fairly small, may be frowned upon by some. By the way, when displaying the most commonly used graphics modes, the Atari 8-bit is effectively only about 17% faster than the C64, and the TED computers, given their additional graphics DMA cycles, must be slower than that, but they're still faster than the C64, at least by a little. Maybe Commodore just didn't want the C64 to fall any further behind the Atari 8-bit and even the Apple II series (and the VIC-20!) in effective CPU speed.🤔
4:12 You could use the method on line 30 for the LOAD on line 20. 4:30 You could also use the registers and the Kernal calls SETNAM & SETLFS to set the filename, et al., though it'd be less convenient than using the BASIC subroutine that does this. 19:24 You could just load the Koala data into memory anywhere you wish. 23:47 Does the logical file number even matter for a LOAD operation?
I found this extremely interesting and informative! -𝓣𝒉𝒂𝒏𝒌 𝓨𝒐𝒖❣︎ ⦅❓⦆ Correct me if I’m wrong but there’s no penalty for adding additional labels to your ASM code (ignoring the unassembled file size); Label reference get completely removed and/or replaced by the assembler? Are there rules or limitations to how and when label can be used? I appreciate that assemblers numerous and can vary, but I’m just asking in respect to the Commodore64/8510 and its popular assemblers.
That's right, all labels are replaced in the object code with the calculated addresses or offsets; the resulting binary file is the same size whether you used no labels at all or many labels. Labels need to be defined in the left-most column in most assemblers, and then can be referred to in the operand field pretty much without restriction as a substitute for a literal.
@@8_Bit - Just as a silly example, can you use labels as numeric constants like i've done below? Would the offsets work as written? Can you perhaps recommend a comprehensive reference document on turbo assembler? _ADD_LABLES_: scrdata = 32576 coldata = 33576 scrram = 23552 colram = 55296 _OFFS_LABLES_: os1 = -1 os2 = 249 os3 = 499 os4 = 749 ldx #250 loop lda scrdata+os1,x sta scrram+os1,x lda scrdata+os2,x sta scrram+os2,x lda scrdata+os3,x sta scrram+os3,x lda scrdata+os4,x sta scrram+os4,x lda coldata+os1,x sta colram+os1,x lda coldata+os2,x sta colram+os2,x lda coldata+os3,x sta colram+os3,x lda coldata+os4,x sta colram+os4,x dex bne loop
PS: Please don't take this as some kind of "suggestion"; I appreciate that you wrote your code to be exemplary to the topic of discussion. I'm just getting into assembly and am curious about the syntax structures.
@@SudaNIm103 Yes, that should work as written except the "label labels" like _OFFS_LABLES_: probably wouldn't work; PETSCII doesn't have a proper underscore character, though it does have a graphic character that looks like one. You could give it a try. But as they don't serve any functional purpose here anyway, best to just turn them into comments such as ; offset labels. For documentation, this is the official site: turbo.style64.org/docs/table-of-contents and there is also some documentation "hidden" in the official distribution .zip file: style64.org/release/turbo-macro-pro-sep06-style The documentation could use some updating, but mostly everything is there if you hunt a bit.
When a C64 game loads it usually also displays a loader screen while loading. How does that work when even loading a simple image like this takes quite some time?
Showing a loader screen does add extra load time to many games; it's fairly common when games are cracked that they'll remove the title screen or make it optional to increase the load speed. However, the display can be sped up by 1) using a fast loader which many commercial games had built-in, 2) using all machine language instead of BASIC as shown in my last example and 3) compressing the bitmap with a light-weight scheme so the load time is shorter but it's not too CPU-intensive to uncompress, like the various "RLE" (run-length encoding) schemes.
at 5:56 I thought each block held 253 bytes, not 254. Aren't the first _two_ bytes of each block used to either link to the next used block, or to signify the last valid byte in a partially used block?
Something that still confuses me -- what's the difference in the Koala paint file between "screen RAM" and "bitmap"? You'd think those would mean the same thing. Isn't it just dot data + colour data?
Koala files have two 1000 byte areas for colour RAM. One goes in colour RAM like normal, the one called "screen RAM" goes in the usual screen RAM area, but the VIC-II interprets it as colour data also. Then bitmaps are 8000 bytes of the graphic data. This is what allows each 8x8 pixel cell to have 3 unique colours: 2 are defined by "screen" plus the usual one in regular "colour RAM".
I think it makes the loading process more interesting and illustrative to see the colour data after the bitmap is loaded, but yes, the order could be reversed and it would look more tidy. A more professional-looking program might blank the screen while the data is being loaded in and then present it all at once, completely loaded. Or display a "loading..." message while loading the graphics elsewhere in memory, and then quickly switch to display them at once. But I think the order I chose gives a bit more insight into what's going on behind the scenes.
Oh, come on. Everyone knows groos (grues) are a monster in the Zork text adventure game that will eat your character if you wander around in the dark without a light source! 😝 This looks more like the sort of adventurer that would wander around without a light source. 😏
Yeah, that's my fault. I put it at the end so it's easy to skip to the next video.
3 ปีที่แล้ว +1
i am born in 75 and just so managed not to laugh out loud, when you referred to 320x200 as 'high resolution bit map'.... but then again, been there done it. try to explain that to kids growing up with smartphones.
That's the official name of the graphics mode in the C64 Programmer's Reference Guide, even if it hasn't aged well :) Did you know the original iPhone had a 320x480 screen? Not so far from the C64!
I'm just curious, it's been ages since I did any real programming on the C64. At about 10:00 you talk about line 20. Is it more efficient to make the program do the math than to provide the value to be poked? Or is that line written like that for clarity? I assume the latter.
Yes, all these programs are written for clarity over efficiency. That's especially true in the 3rd program, lines 70 and 80 would execute much faster if those constants (like 23552 and 32576) were replaced with variables, as BASIC is very slow at parsing constants.
i clicked on d64 download link and nothing happened. then went to site 8bitshowandtell.com but no download section. i would love to check this d64 image out. thanks.
@@8_Bit , that did it. thanks. Love your channel. I started with a Timex Sinclair 1000 from Walgreens. still have. went to vic 20 then c-64. Still have. Now in my mid 60's and still play and enjoy my first computers. Keep up the great content.
But those graphics commands in more bloated BASIC dialects (boxes, circles, etc.) don't accomplish much. For great graphics, you have to do it the hard way anyway, so I think it was a good decision to have a sleek BASIC in ROM that saves memory space.
@@NuntiusLegis It's a fair point. At what point do you stop supporting graphics in BASIC? With the slow processors and limited memory of the 80s, having a bare-bones BASIC did save some memory and processor cycles. I just feel that since the purpose of BASIC was to provide a simple, easy to learn programming language, a few very simple graphics commands for the C64 would have gone a long way.
@@andymanaus1077 BASIC was designed to be more intuitive than other languages indeed, but not simpler. There are variants of BASIC in any complexity (also highly structured and object-orientated). But in the ROM of an 8-bit-computer, it better be sleek. You also have a point, a command for fast plotting of graphs would have been neat I think. Besides graphics, commands for shifting chunks of memory faster than with PEEK / POKE is what I miss most in BASIC. On the C64, the great graphics characters provide better graphics than circles and boxes already. Combined with some sprites, the result can be quite nice.
One of the annoying things about the C64 is how little its BASIC will do for you. With all of those cool graphics and sound features, you wouldn't know it looking through its language reference. You had to do everything, I mean EVERYTHING with POKEs and PEEKs, which was obtuse and, because it had no built-in routines for doing that stuff, made an already slow language even slower.
Those sound and graphics commands bloating other BASICS don't accomplish much; for interesting sound, you still have to tweak the SID registers, and for interesting hires graphics, you still have to do it the hard way. A good compromise for graphics in BASIC ist PETSCII + Sprites (which can be done with the sleek C64-ROM-BASIC and looks better than simple circles or boxes from the graphics-commands in "better" BASICs).
@@NuntiusLegis They would be more accessible to new users though. I mean, C64 BASIC does SO LITTLE. Why not give access to PETSCII drawing commands? Why not offer even a simple pixel plot command? Even simple SID interface commands would be better than the absolute nothing BASIC 2.0 gives you. Because of BASIC's sparseness, the number 53281 will be fixed in my brain probably until I die.
@@rodneylives Even new users learn to handle chip registers right from the start in the C64 manual. This provides a better understanding of the computer and makes it easier to learn machine language. On other computers with "comfortable" BASIC, the learning curve towards assembler is much steeper. And the sleek C64-BASIC saves address space that can be better used for code and data, which is an important advantage with the limitation of 64 K which must also be used for the interpreter, the KERNAL, "extended zero page", stack, I/O, etc. With mixed BASIC / machine programs that use data for different screens, sprites, sound, it is easy to reach the limit, so I'm glad the BASIC is sleek and not bloated. And what would be "PETSCII drawing commands"? - You just type it in. :-)
And despite it's sparseness, C64-BASIC has powerful features that some other BASICs (for instance the ROM-BASIC in the Apple II) don't have, like floating point arithmetic and bit-wise operators.
@@NuntiusLegis The Apple II had multiple BASICs though, and one of them did have floating point. Plus, the cost of the C64 having floating point was it did ALL MATH in floating point, even math between integers, held in integer variables, at a huge performance cost! And while I enjoy bit fiddling as much as anyone, it's presence in a BASIC is not what I'd call a superstar feature, so long as we have logical operators.
Commodore basic was just too hard for me as a kid to be honest I could never understand bit maps graphics all I ever wanted to do was draw a perfect circle, where my brother school had bbc micro model B, he took me once there and showed me how easy on it to draw in high res etc.. what a let down original basic was.. and no improvement from commodore at all still shipping c64 with old basic years later no wonder they went bust.. thats my rant.
Commodore did put a more feature-rich BASIC which included bitmap commands with circles in all their later models: Commodore 16, Plus/4, Commodore 128. They weren't able to put it in the C64 after the fact because it would affect compatibility with existing software too much. But just on your last point, the Commodore 64 was Commodore's biggest money maker they ever had and had nothing to do with them going bust at the end. If anything, their computers with CIRCLE commands contributed more to their downfall than those without ;)
Check out Darren's video about how he made this Groo art for us: th-cam.com/video/b15rw48czAU/w-d-xo.html
And here's an excellent diagram by MagerValp illustrating the effect of VIC-II registers $DD00 and $D018 on what is displayed: 8bitshowandtell.com/downloads/BitmapAddress.png
Here's the .d64 file containing the art and code from this episode: 8bitshowandtell.com/downloads/grootube.d64
Or plain text to copy and paste in case TH-cam is munging the links:
8bitshowandtell.com/downloads/grootube.d64
Also, check the video description for more links.
Please make a video about how to animate graphics in C64. Simple smooth scrolling is good enough for starters
Jeez the speed of the info you’re throwing at idiots like me who thought the 64 was cool at playing games on 35 years ago. I struggle, but owning 5 of these things, I just can’t get past how friggn incredible this thing still is.
I’m grappling with 3 Gideon boards and MIDI and trying to find out what SID can REALLY do.
And you throw VIC2 at me. These numbers drive me nuts because I know them.
But nobody has ever told me why I have to SMASH the RESTORE key, or why the SID was “an organically grown silicon chip”. My head is exploding with this sort of stuff.
I can’t even explain why you type in 350800 the thing craps itself.
Darren's a pretty good artist.
Groo is the heart, baby.
I have no idea what’s going on but it’s somehow still interesting.
Me too 😅 bro
Something I recently found out - after 40 years! - is that when the C64 is in character mode, each individual character can either be interpreted as high res (mono color) or multicolor (unless I misunderstood what I read). I had always thought that the whole display had to be one or the other* but it appears the VIC-II designers were even more clever than I already thought they were! This opens up even more possibilities for what can be accomplished.
* Minus the usual tricks that utilize interrupts to change modes in one or more places on the screen of course.
Note, just to clarify on why you use OR: if you simply poked 32 into 53265, you would enable hires mode, but you would also turn off all the other bits which could effect other settings. You OR the current value in that location so that you only turn that particular bit on without effecting the other bits in that same location.
Another nice vid, really helpful. I just wish I had found it a couple of weeks ago when I was trying to load 1000 bytes of screen data with machine language. Bloody brilliant though, glad I found these.
I used to exclusively make PETSCII art and animation since I couldn't draw. It was a fun way to make my little adventure games a bit more exciting.
For only having 2 colours in each 8x8 pixel area, this is some great art.
It's so relaxing to see some clear 6502 assembly code solving well-defined problems before heading into work (got a morning meeting, presenting research to stake holders, defending approaches, etc.). A little 8-bit recreational thinking sets the world right before taking on the complexities of the day. Thanks!
Agree. Somehow relaxing.
8-bit Lego🙂
6510, not 6502 although almost identical
@@kaulbachskave It is 6502 assembly because there is no difference whatsoever (unlike, for example, 65C02 assembly, which is highly compatible but different). The ways in which the 6510 is different from the 6502 is that: 1) it replaces unused pins and some pins the C64 doesn't need with an 8-bit I/O port, which is accessed by the same old set of instructions at addresses 0 and 1; 2) the bus lines are all tri-stated (with a selectable high-impedance state); and 3) the pins are rearranged, so the 6510 is not pin-compatible with the 6502 at all. So while most of their silicon is the same, there are significant differences between the 6510 and 6502.
Their assembly/machine languages are absolutely 100% identical, however, including the original NMOS undocumented instructions and the manner in which memory is accessed during instruction decoding and execution (different from the 65C02, once again, but identical to each other). It would make no sense to say 6510 assembly because that implies there are differences, which there aren't.
I bought my Ben Eater 6502 breadboard computer kit and stripped all those wires myself, used a VIA chip, added my own interface buttons, learned assembly, was responsible for every damn physical wire to deal with all address and data lines. Don't get me wrong, I enjoy getting into the trenches of it to gain deep appreciation on how 8-bit architecture was put up. But man, seeing how convoluted it is to just display a color image on a screen, you absolutely respect how graphical user interfaces and dev environments went in the right direction to dumb this all down, away from this C64 paradigm which has you massaging pixel and color data into specific ram locations that you have to dig out of manuals. The entry barrier for budding game programmers is just insane.
Sergios Argones---a great one.
Does any of the paint programs use RLC(Run Length Code) to compress images so that they take up less space.
Impressive art for the computer :-)
I used to have Doodle and Micro Illustrator back in the day. Micro Illustrator got the most use. Great program! I had no mouse so I used to draw on graph paper then zoom in on Micro Illustrator and copy the drawing square by square into the computer. It actually worked out really well.
Big GROO fan here! need to fix the display on my C64 still though, may try the emulator.....Great Work, Mendicants! Mulch Love.....
Oh, the in-jokes! 😀
Wonderful video!! The trick I used to use as a kid to copy large amounts of memory in assembly was to actually write self-modifying code. I would copy 256 bytes in a nice tight loop using the X reg and then INC the high bytes of the source and destination and use the Y register to keep running that loop Y times. If the total amount number of bytes to copy was not a multiple of 256 then I would either have this loop stop short (e.g. at 768 bytes when copying 1000) and then do an extra little loop afterward to handle the last 232 bytes. The second way would be to just go ahead and copy more then you need (e.g. 1024 bytes when you only want 1000, or 8192 when you only want 8000). Of course this can only work if the extra bytes after the destination won't harm anything.
Or zero-page indirect X instructions. I think I used that a lot. Using 4 bytes, you can accomplish any memory move. Still have to increment high bytes after each 256-byte copy but at least it isn't self-modifying code. The code sets the initial values in zero page at the beginning of each copy. This is better when you need to perform the action more than once, like in my routine to display an Ultima-style tile on the screen.
Again a very interesting video, thanks! I also watched the GrooTube video... very very impressive!
Greetings, Doc64!
Well, you've got me going. Installed Vice, set it up, downloaded TMP and TAss, studying the 6502/6509/6510, learning about all registers of the C64. I'm pretty stunned what the C64 could/can actually do with so little memory (also understanding its limitations). Must say though that I'm not really comfortable with machine language yet; meaning understanding it towards its full fletched complex context; when to apply what exactly efficiently, etc. However, step by step... Thank you for all this work :)
Also looking into the C128 and CBM II 500 (with the VIC II, 40 column)... The latter is a super challenge but it can do so much more than ever seen I think.
This is pretty cool. I made a program for the CoCo 3 back in the day for my own game development that took 16 color 320x200 BMP files that had sprites of 8x8 within it and converted them to ML Binary Sprite data that loaded directly into memory for use by your program. Made making sprites for games so much easier.
Great video thank you - I am curious how you get the C64 video to display as a picture in picture on your video? (what hardware or software do you use for that?)
I still remember some the old commands from the day like poke 53280 ,1 i think that makes the outer boarder change color and 53281 was the inner color , Typing sys 64738 caused the system to restart but typing sys 64718 caused it to crash. No idea how i remember this its been years since ive been on a c64.
As a beginner in assembly, I am really impressed by this. The clever methods shown for loading and shifting data surely have many applications. The linked page with graphics file formats is splendid, now I understand the files produced by my favorite graphics program, Blazing Paddles.
Thanks for "opening secret's of C64 assembly language" and basic code examples. Basic to asm examples - really help me to forward understand bit more of C64 assembly language.
0:23 Love me some Groo
8:50 I think Programming the Commodore 64 does an okay job at explaining this, but even it isn't super clear. Hard to explain for sure.
11:45 I've been bitten by this inverted VIC location thing more than once. After the 3rd time you'd think I'd learn...
24:50 Awww, it's not ugly. It's fast ;-)
Oh good! An assembly video, my favorite! I like these programming videos.
On Amstrad Cpc theres .Scr graphics format,which you can load easilly.
fantastic video and exactly what I was looking for! Thank you!
Thank u for the easy and clear teaching!. Thinking about getting again a C64 and making art on that awesome machine..i had many C64's in my life and i started in 1983 or 1984 with the first one.
There's a Usaki Yojimbo game, Samurai Warrior, on C64, based on the Stan Sakai comic books. I would have loved a Groo game. The connection here is, not only both being sword wielding warriors, Sakai also did the lettering for the Groo comics, while Sergio Aragones (Groo's creator) did the art and Mark Evanier did most of the writing (early on, it was Sergio himself, but Mark later took over the writing duties).
Darren did a great job on the graphics.
I love Groo and his Dog. 👍
wait wait wait, kudos to the grootube dude for managing to draw that without undergoing 78 epileptic seizures: boy, what a cursor!
Just think how much nicer teletext graphics would have been with PETSCII graphics.
Thank you!!! Great video... I'm going to plug in my C128 and start playing around!! Keep posting please!
Thanks for showing us how to load files in assmebly. It's something I still get tripped up on these days :)
Used to wonder how the newer planar frame buffers of 1985 would ever be as fast as the character sets & sprites of the old days. We just overpowered the slower frame buffer with higher clockspeed, the same way interpreted languages replaced compiled languages.
The simple answer is that they never were as fast. One thing that annoyed me about my beloved Amiga was how slow a simple directory listing was compared to an old DOS machine using a dumb text display. Any way you sliced it, the planar display required 8 bytes of lookup and 8 bytes of writing per character, instead of just directly writing the character code to the screen. And the Amiga simply wasn't 16 times faster than an old DOS machine. It just wasn't.
@5:50 - 6:00 Correct me if I am wrong, but I think each 1541 block actually contains 256 data bytes, and the two bytes needed to point to the next block (track and sector) is somehow tucked away in there without using 2 bytes of the actual data block. I read this in the Transactor many years ago. I think. : ) ...later: Pretty sure I'm remembering something wrong :P
Yeah, there's 256 bytes per block but in a file (like a PRG or SEQ) the next track/sector does take up the first two bytes leaving 254 bytes of "payload" or whatever we want to call it. If you save a 256 byte file it needs two blocks because it won't quite fit in one. And actually for a PRG, the first block loses another 2 bytes because they're used for a "load address" for the program. If you skip the file system and save data directly to the disk, keeping track of the track/sectors yourself, then you get the full 256 bytes. I think Ultima IV did this for its maps, for example.
@@8_Bit True on all counts, including how _Ultima IV_ (and other games in this series) handles its maps. For that matter, even relative files, which have "side sectors" that contain the track and sector number of each data sector in the file, have data sectors that start with the next track and sector numbers (which are redundant) and hold 254 bytes of data each.
Question: can't you run LOAD "color-data",8,1 again using the IF THEN trick without poking kernel parameters and calling a procedure?
That would work if the load address in the colour data PRG file was set to $D800, where the data needs to load to. But the program file's load address was set to $8000 in this case, so that's why it required the extra sets. It'd be possible to change the load address of the program file with a utility (I showed that in the LOAD"*",8,1 vs. LOAD"*",8 episode recently) but knowing how to do this relocating load is also useful so I thought I'd show that in one of the example programs. Thanks for the question!
@@8_Bit I remember that you could set the load address from the episode you've mentioned, that's why I asked. Make sense to show how to relocate loaded file. All this turns into "aha!" moments for me.
To think I used ready-made Koala loader back then, stupid me, I want to invent time machine and go back to smack myself. My only excuse is that all the books were in German, the language I could only introduce myself and order a salad.
Love Groo and Aragones!
Great, that's what Darren's channel Groo Tube is all about! th-cam.com/video/b15rw48czAU/w-d-xo.html
I've been wanting a video like this but for the Vic 20
Another excellent video, well done
I really love the video and look forward to exploring this! I have a question - I am trying to load a bitmap I've exported as a prg file and run it alongside some audio code I have in basic, only there is no code executed once the bitmap is loaded, would you be able to advise how I could do such a thing?
Awesome! Awesome! Awesome!
The thing about not being able to loop 1000 times because the 6502 is an 8-bit processor isn't entirely true-the Z80 was just as 8-bit, but you could pair its registers to make 16-bit ones and do loops of 1000 directly. Not that you'd ever do that just to copy memory from one place to another, because it also had the LDIR (Load, Increment and Repeat) instruction to do that for you!
True, I wasn't being as precise as I could have been; I should have said "because the 6502 only has 8-bit index registers" or something along those lines.
I actually don't consider the Z80 and 8080 to be pure 8-bit CPUs because of the 16-bit abilities they have; like the 65816 in the SNES or Apple IIgs, I consider them to be 8/16-bit hybrids with an 8-bit data bus and some 16-bit register operations. I disagree with deciding the "bitness" of a CPU only on data bus width as it doesn't describe its abilities well enough. The Z80 has 16-bit index registers (IX and IY) and pairs of 8-bit registers that can do 16-bit operations and that should be part of its classification.
@@8_Bit That would make the 6502 the only 8-bit CPU, AFAIK (8080, Z80, 8085 and 6809 all had 16-bit registers)-were there any others? I tend to go with max 64K address space, myself, which I realise also excludes the TMS9900...
@@d2factotum I think the 8008 and F8 are "pure" 8-bit processors too. The 6800 only has 8-bit accumulators (can't be paired) but does have a 16-bit index register. I should take some time to study some of these other processors in more detail to see if I can really come up with a categorization scheme that works.
@@8_Bit I think the 8008 had a virtual 16-bit register M which was made by combining its H and L registers together-in fact, that might have been the only way to access memory on that chip. because I don't think it had instructions which included memory addresses.
@@8_Bit No single number can really classify a CPU. This includes clock speed, because whether it is 16 bit or not, no Z80 is going to out-process a 6502 running at the same clock speed.
This is interesting, not because I understand the code (I don't, even the explanation is somewhat magic to my mind) but because I finally understand a little more :) The whole OR 32 for example is just mind boggling for me hahah ::) Still, interesting :)
Bit-wise OR means that if either of the corresponding bits in the two values is set, it will also be set in the result. 32 is the value of bit 5, so it is made sure that this bit is set in the result. Other bits set in the first value will also be set in the result and thus not affected. Simply poking 32 would set bit 5, but erase all other bits. :-)
In retrospect, the aspect of C64 design that most annoyes me is color RAM. It has to be static RAM. It adds four data pins onto the VIC-II chip for ... eh ... limited benefit. It's just kinda weird. It made some since with how the previous VIC chip worked, but the VIC-II chip internally stores the character/color data anyway ...
It really should have been eliminated in favor of using normal RAM, and having two badlines per character row instead of just one badline. The previous scanline loads color data just after displaying a character. The next scanline loads character data just before displaying a character. Yes, this steals more cycles from the CPU, but the machine is less expensive and more flexible. Color RAM can now be located anywhere (well, within a 16K bank). You get to freely choose both background and foreground color in text mode. Multi-color bitmap mode allows you to freely choose the four colors instead of just three (this allows some nice 80x50 "chunky" pixel graphics). It's possible to achieve some VERY nice looking "interlace" effects switching colors every 1/60 sec. Double buffering is more workable, which can be particularly helpful with scrolling.
I mean ... of course any of us could rattle off an endless wishlist of what we wish the VIC-II could have done. But for me, adding badlines for color instead of the weird color RAM is the top wish. If I went back in time and could get myself hired into Commodore, I'd try and make that change in the VIC-II design, arguing for it on the grounds of saving production costs.
Apparently this is more-or-less how the TED in the Plus/4 and C-16 work? Losing another ~1000 cycles per frame to badlines would be a fairly high cost, but I agree with all the advantages and probably the advantage of movable colour RAM would outweigh the cycles cost. Even more than movable colour RAM, my top VIC-II wish list item would be a 10-bit screen memory offset register to allow whole-screen scrolling without shifting data (VSP without any tricks!).
@@8_Bit Yeah, although I'd argue that it would be better if the current character pointer were exposed as a register. That way, you simply shove the desired address for the first (or next) line via CPU. This gives you extra flexibility for independently scrolling regions.
Hmm... going with this idea, it would be easiest and most elegant to interleave color and character memory. The combined color/character memory takes up 2000 bytes. The two consecutive badlines simply read in 40 bytes of color and then 40 bytes of character.
With this flexibility, you could even have a tile/color map wider than 40 characters and scroll within it. The CPU has to add to the character pointer once every 8 scanlines to do this, but it could easily be worth it in many situations.
I've heard that Commodore had hoarded 2114 chips (maybe for their calculators after TI put the squeeze on them) that they might as well have used for something. Supposedly that's why each VIC-20 had 10 of them and, just speculating here, they stuck one in every C64, too. 🤔 And they should have advertised, quite honestly, that the C64 has 64.5K of RAM. 😉
@@8_Bit I've never owned one of the TED computers and haven't played with them much in emulation, either (at least yet), but it kind of looks as though they might do graphics DMA in the same manner that Atari 8-bit computers do. This is probably why the Plus/4 and C16 run at 1.79 MHz (NTSC). So there is a cost, of course, and it's the same (1000 cycles per frame), but it has a larger shared budget or pool of cycles for the CPU to start with, while another 1000 cycle per frame hit on the slower 1.023 MHz CPU of the C64, though fairly small, may be frowned upon by some.
By the way, when displaying the most commonly used graphics modes, the Atari 8-bit is effectively only about 17% faster than the C64, and the TED computers, given their additional graphics DMA cycles, must be slower than that, but they're still faster than the C64, at least by a little. Maybe Commodore just didn't want the C64 to fall any further behind the Atari 8-bit and even the Apple II series (and the VIC-20!) in effective CPU speed.🤔
Good work.
wow my best game Barbarian
Okay everyone. Nobody call Groo a mendicant and we'll all get out of this alive.
C64 art graphics is usually during cassette loading of games
D64??? Where is the fun in that? You should have posted the source code for us to type😄 Great vid as usual.
You can type it in off the screen if you prefer ;)
4:12 You could use the method on line 30 for the LOAD on line 20.
4:30 You could also use the registers and the Kernal calls SETNAM & SETLFS to set the filename, et al., though it'd be less convenient than using the BASIC subroutine that does this.
19:24 You could just load the Koala data into memory anywhere you wish.
23:47 Does the logical file number even matter for a LOAD operation?
I found this extremely interesting and informative! -𝓣𝒉𝒂𝒏𝒌 𝓨𝒐𝒖❣︎
⦅❓⦆ Correct me if I’m wrong but there’s no penalty for adding additional labels to your ASM code (ignoring the unassembled file size); Label reference get completely removed and/or replaced by the assembler? Are there rules or limitations to how and when label can be used? I appreciate that assemblers numerous and can vary, but I’m just asking in respect to the Commodore64/8510 and its popular assemblers.
That's right, all labels are replaced in the object code with the calculated addresses or offsets; the resulting binary file is the same size whether you used no labels at all or many labels. Labels need to be defined in the left-most column in most assemblers, and then can be referred to in the operand field pretty much without restriction as a substitute for a literal.
@@8_Bit - Just as a silly example, can you use labels as numeric constants like i've done below? Would the offsets work as written? Can you perhaps recommend a comprehensive reference document on turbo assembler?
_ADD_LABLES_:
scrdata = 32576
coldata = 33576
scrram = 23552
colram = 55296
_OFFS_LABLES_:
os1 = -1
os2 = 249
os3 = 499
os4 = 749
ldx #250
loop lda scrdata+os1,x
sta scrram+os1,x
lda scrdata+os2,x
sta scrram+os2,x
lda scrdata+os3,x
sta scrram+os3,x
lda scrdata+os4,x
sta scrram+os4,x
lda coldata+os1,x
sta colram+os1,x
lda coldata+os2,x
sta colram+os2,x
lda coldata+os3,x
sta colram+os3,x
lda coldata+os4,x
sta colram+os4,x
dex
bne loop
PS: Please don't take this as some kind of "suggestion"; I appreciate that you wrote your code to be exemplary to the topic of discussion. I'm just getting into assembly and am curious about the syntax structures.
@@SudaNIm103 Yes, that should work as written except the "label labels" like _OFFS_LABLES_: probably wouldn't work; PETSCII doesn't have a proper underscore character, though it does have a graphic character that looks like one. You could give it a try. But as they don't serve any functional purpose here anyway, best to just turn them into comments such as ; offset labels.
For documentation, this is the official site: turbo.style64.org/docs/table-of-contents and there is also some documentation "hidden" in the official distribution .zip file: style64.org/release/turbo-macro-pro-sep06-style The documentation could use some updating, but mostly everything is there if you hunt a bit.
When a C64 game loads it usually also displays a loader screen while loading. How does that work when even loading a simple image like this takes quite some time?
Showing a loader screen does add extra load time to many games; it's fairly common when games are cracked that they'll remove the title screen or make it optional to increase the load speed. However, the display can be sped up by 1) using a fast loader which many commercial games had built-in, 2) using all machine language instead of BASIC as shown in my last example and 3) compressing the bitmap with a light-weight scheme so the load time is shorter but it's not too CPU-intensive to uncompress, like the various "RLE" (run-length encoding) schemes.
at 5:56 I thought each block held 253 bytes, not 254. Aren't the first _two_ bytes of each block used to either link to the next used block, or to signify the last valid byte in a partially used block?
There's 256 bytes in a sector, and the first two bytes are used to link to the next track and sector, so that leaves 254 bytes in a block.
@@8_Bit Oh, right, duh. Off by one errors still trip me up from time to time :D
Something that still confuses me -- what's the difference in the Koala paint file between "screen RAM" and "bitmap"? You'd think those would mean the same thing. Isn't it just dot data + colour data?
Koala files have two 1000 byte areas for colour RAM. One goes in colour RAM like normal, the one called "screen RAM" goes in the usual screen RAM area, but the VIC-II interprets it as colour data also. Then bitmaps are 8000 bytes of the graphic data. This is what allows each 8x8 pixel cell to have 3 unique colours: 2 are defined by "screen" plus the usual one in regular "colour RAM".
In the first program, why not load the color data first? The image would only display with the right colors then.
I think it makes the loading process more interesting and illustrative to see the colour data after the bitmap is loaded, but yes, the order could be reversed and it would look more tidy. A more professional-looking program might blank the screen while the data is being loaded in and then present it all at once, completely loaded. Or display a "loading..." message while loading the graphics elsewhere in memory, and then quickly switch to display them at once. But I think the order I chose gives a bit more insight into what's going on behind the scenes.
95 seconds in and I know I am going learn a lot and have a good time doing it!!
Oh, come on. Everyone knows groos (grues) are a monster in the Zork text adventure game that will eat your character if you wander around in the dark without a light source! 😝 This looks more like the sort of adventurer that would wander around without a light source. 😏
It's interesting that both Zork and Groo were both created in the late 1970s too!
So, you are singing the outro?
Yeah, that's my fault. I put it at the end so it's easy to skip to the next video.
i am born in 75 and just so managed not to laugh out loud, when you referred to 320x200 as 'high resolution bit map'.... but then again, been there done it. try to explain that to kids growing up with smartphones.
That's the official name of the graphics mode in the C64 Programmer's Reference Guide, even if it hasn't aged well :) Did you know the original iPhone had a 320x480 screen? Not so far from the C64!
I have Groo #1.
I'm just curious, it's been ages since I did any real programming on the C64. At about 10:00 you talk about line 20. Is it more efficient to make the program do the math than to provide the value to be poked? Or is that line written like that for clarity? I assume the latter.
Yes, all these programs are written for clarity over efficiency. That's especially true in the 3rd program, lines 70 and 80 would execute much faster if those constants (like 23552 and 32576) were replaced with variables, as BASIC is very slow at parsing constants.
I should have watched the rest of the video before commenting :)
@@8_Bit Thank you
Gonna sleep well tonight, great info. Need to check if that sys / load / sys works on the c+4
It will probably be a different address in the +4 KERNAL, but the functionality is likely in there somewhere.
@@8_Bit right, I found a procedure similar to yours before, but id didn't work since it wasn't complete and also for c64. Gonna poke around. Thank you
Impressive, thanks 😀
i clicked on d64 download link and nothing happened. then went to site 8bitshowandtell.com but no download section. i would love to check this d64 image out. thanks.
Does this work? Strange that the link isn't working. 8bitshowandtell.com/downloads/grootube.d64
Or try copying and pasting this: 8bitshowandtell.com/downloads/grootube.d64
@@8_Bit , that did it. thanks. Love your channel. I started with a Timex Sinclair 1000 from Walgreens. still have. went to vic 20 then c-64. Still have. Now in my mid 60's and still play and enjoy my first computers. Keep up the great content.
Commodore BASIC was horrendous when it came to graphics support. With all the PEEKS and POKES, it was more like having to program in machine code.
But those graphics commands in more bloated BASIC dialects (boxes, circles, etc.) don't accomplish much. For great graphics, you have to do it the hard way anyway, so I think it was a good decision to have a sleek BASIC in ROM that saves memory space.
@@NuntiusLegis It's a fair point. At what point do you stop supporting graphics in BASIC? With the slow processors and limited memory of the 80s, having a bare-bones BASIC did save some memory and processor cycles. I just feel that since the purpose of BASIC was to provide a simple, easy to learn programming language, a few very simple graphics commands for the C64 would have gone a long way.
@@andymanaus1077 BASIC was designed to be more intuitive than other languages indeed, but not simpler. There are variants of BASIC in any complexity (also highly structured and object-orientated). But in the ROM of an 8-bit-computer, it better be sleek.
You also have a point, a command for fast plotting of graphs would have been neat I think. Besides graphics, commands for shifting chunks of memory faster than with PEEK / POKE is what I miss most in BASIC.
On the C64, the great graphics characters provide better graphics than circles and boxes already. Combined with some sprites, the result can be quite nice.
One of the annoying things about the C64 is how little its BASIC will do for you. With all of those cool graphics and sound features, you wouldn't know it looking through its language reference. You had to do everything, I mean EVERYTHING with POKEs and PEEKs, which was obtuse and, because it had no built-in routines for doing that stuff, made an already slow language even slower.
Those sound and graphics commands bloating other BASICS don't accomplish much; for interesting sound, you still have to tweak the SID registers, and for interesting hires graphics, you still have to do it the hard way. A good compromise for graphics in BASIC ist PETSCII + Sprites (which can be done with the sleek C64-ROM-BASIC and looks better than simple circles or boxes from the graphics-commands in "better" BASICs).
@@NuntiusLegis They would be more accessible to new users though. I mean, C64 BASIC does SO LITTLE. Why not give access to PETSCII drawing commands? Why not offer even a simple pixel plot command? Even simple SID interface commands would be better than the absolute nothing BASIC 2.0 gives you. Because of BASIC's sparseness, the number 53281 will be fixed in my brain probably until I die.
@@rodneylives Even new users learn to handle chip registers right from the start in the C64 manual. This provides a better understanding of the computer and makes it easier to learn machine language. On other computers with "comfortable" BASIC, the learning curve towards assembler is much steeper.
And the sleek C64-BASIC saves address space that can be better used for code and data, which is an important advantage with the limitation of 64 K which must also be used for the interpreter, the KERNAL, "extended zero page", stack, I/O, etc.
With mixed BASIC / machine programs that use data for different screens, sprites, sound, it is easy to reach the limit, so I'm glad the BASIC is sleek and not bloated.
And what would be "PETSCII drawing commands"? - You just type it in. :-)
And despite it's sparseness, C64-BASIC has powerful features that some other BASICs (for instance the ROM-BASIC in the Apple II) don't have, like floating point arithmetic and bit-wise operators.
@@NuntiusLegis The Apple II had multiple BASICs though, and one of them did have floating point. Plus, the cost of the C64 having floating point was it did ALL MATH in floating point, even math between integers, held in integer variables, at a huge performance cost! And while I enjoy bit fiddling as much as anyone, it's presence in a BASIC is not what I'd call a superstar feature, so long as we have logical operators.
Hi Robin 👋
Hello! :)
Commodore basic was just too hard for me as a kid to be honest I could never understand bit maps graphics all I ever wanted to do was draw a perfect circle, where my brother school had bbc micro model B, he took me once there and showed me how easy on it to draw in high res etc.. what a let down original basic was.. and no improvement from commodore at all still shipping c64 with old basic years later no wonder they went bust.. thats my rant.
Commodore did put a more feature-rich BASIC which included bitmap commands with circles in all their later models: Commodore 16, Plus/4, Commodore 128. They weren't able to put it in the C64 after the fact because it would affect compatibility with existing software too much. But just on your last point, the Commodore 64 was Commodore's biggest money maker they ever had and had nothing to do with them going bust at the end. If anything, their computers with CIRCLE commands contributed more to their downfall than those without ;)
Damm: No new Apple II announcement today 😞