Displaying Commodore 64 Graphics in BASIC and Assembly (Featuring: Art by Groo Tube)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi it's robin my patron michael durnboss asked for some advice about programming the commodore 64 to display graphics so i thought i'd make an episode about that but i needed some images to display so i asked my friend darren who runs the youtube channel grewtube if he would be interested in drawing some commerce 64 art that i could use for my program examples here's an image he drew in koala paint and he provided a couple other images as well darren put together his own video on how he drew this art so i'd suggest you check out his video to see how he went about creating the art on his commodore 64. so today i'll be showing you how to write basic programs to display petsky art bitmap images such as those created with the doodle program and multi-color bitmaps such as this one produced with koala paint or other multi-color paint programs there will be a downloadable d64 file in the video description so you can download this example code and images and run them on your own commodore 64 or emulator and finally i'll convert the basic program that displays koala images into machine language as an example of how to load a file from disk move memory around and set the vic registers okay so here's the disk directory first we're going to load up p disp that's short for pet ski display and we'll list the program we'll run it and then we'll walk through it and there this image was created completely with the built-in character set all those little symbols that are shown on the c64 keyboard darren used to create this image of gru and his dog referto this type of art can be very challenging to pull off i think darren's done a great job here and you can actually make this art right here in the editor for example if i put reverse on i'll change the cursor to black and give gru one really big eye anyway i'm no artist i'm the programmer here so let's take a look at that listing you can see it's really quite short first in the program we poke five three two eight oh and eight one with zero that's setting the border and background colors to color zero which is black this line here is necessary because of a quark in kilometer basic we want to load the screen data to location 400 or that's 10 24 decimal regular screen memory but as discussed in the recent episode about load star comma 8 comma 1 whenever a load command is executed in basic the program runs again but variables are left intact so this ensures that the first time the program is run a is set to zero by default but then when the program restarts after loading this file it won't run again because a has been set to one this is simply loading the character data from file into screen memory to show the image of gru and when we run the program here you see how he's first loaded in but there's no color data that's because we're just loading the character values right into screen memory here and this next line is something i learned i think from either fender tucker or dave moorman at lodestar magazine this sis sys57812 followed by a file name will allow you to load a file into memory at a different address than is specified in the program file these next three pokes are for the accumulator at 780 the x register at 781 and the y register at 782 this is how you can pass parameters into a machine language routine that's called here at sis 65493 which is the load command so the important ones here are x and y here in the y register is the high byte of the load address that you want the file to load to so you take that 216 and multiply it by 256 and you end up with 55296 and then you would add in whatever's in the x register which is just zero so this is 55296 also known in hex as d800 this is color ram our color data file happens to be actually saved at 8 000 hex but the vic expects it to be at d800 so that's what we're doing we're causing this file to be loaded directly into color ram and that's it let's do an endless loop so that the program doesn't end and print ready on the screen so again we'll run that one more time there's the screen data loaded and there's the color data loaded and we're done i can see here that each of these files is only four blocks long that's because they're only a thousand bytes each the screen is 40 by 25 characters 1000 bytes of screen data and color data okay moving on to the doodle image d display short for doodle display this time i'll load with the slash which is a shortcut built into the super snapshot and most other wedges and we'll run the program and there is gru you can see how the old image used to be a memory and now it's loading in the new one okay so this is a high-res bitmap 320 pixels wide 200 tall but has the limitation that in each eight by eight pixel square area there can only be two colors so it actually makes doing art like this very challenging darren explains the process in his video and he says he's not entirely happy with the results i think he did a great job but he gets into how challenging it can be to give the appearance of lots of color and yet in any given area you can only have two colors so again we'll look at the listing here this first line sets bit 5 to enable bitmap mode and that's here in register 53265. this is a common pattern in commodore basic in the programmers reference guide you pick one of the vic registers you modify it for example if you or 32 that is setting bit 5 to a 1. this is binary arithmetic that 32 is the same as 2 to the power of 5 and then we poke it right back into 53265. that's all it takes to tell a video chip that we want to display a bitmap instead of this regular character mode that we're currently in in basic next we need to tell the vic where the bitmap is and that's here in register 53272 which actually is controlling two different things the upper nibble that is the upper four bits control where the video matrix is so i've split it up here this this value 7 times 16 plus 8 equals 120 but that's extremely cryptic it's actually very difficult to explain clearly i've been working on this a bit basically in the upper nibble you put a number there from 0 to 15 or 0 to f in hex and that is which one kilobyte page 1024 byte page is going to be used for the video matrix the video chip can see 16k at a time so there are 16 different 1k pages i'm going to call them or possible video matrices and i'm going to choose number 7 numbered from 0 to 15. and to put a 7 in the upper nibble you multiply it by 16 that's because of the place value in hexadecimal the second digit just like the second digit in decimal is 10 times the value as if you go from 9 to 90 that 9 in the second position has 10 times the value in hexadecimal it has 16 times the value so that's 7 times 16 and then we add in 8 8 is in the low nibble which controls where the dot data is that is the bitmap definition and when you're in bitmap mode the bitmap is actually uses 8 000 bytes almost 8k so you can only either put the bitmap data in the low half of the vix 16k of memory space or in the upper 8k so your choices here in bitmap mode are either 0 or 8. and note that in the video matrix normally in like in this basic mode in the vic the video matrix is just a series of numbers representing what characters will appear here on the screen but in high-res bitmap mode it actually represents the colors of each cell so if you have a zero zero here then both colors will be black if you had zero one hex up in this top left corner then the two colors available would be black and white 0m1 now since you don't have to worry about that we're just trying to get the image on the screen really all we have to do is get the data in the correct locations and then tell the vic where it is so that's what we've done here enable bitmap mode told it where the video data is and this third step is poking 56576 this is actually a cia the input output chip register that controls which of the four 16k blocks of ram the vic is looking at the commerce 64's 64k is split up into four 16k banks the cia will just point the vic to one of those four banks so if you take the existing location and it with 252 to zero out the two low bets and then you or it with three minus the bank number that you want because it's inverted in short we want bank one which starts at hex 4000 in c64 ram so this is the poke to make the vic address from 4000 to 7fff if we put a 0 here then it would be at bank 0 which goes from 0 to 3 ff okay then next we finally actually load the doodle image in and that's just the straightforward line just the same as we saw in the petsky example so that loads the doodle image in to 5c00 hacks which is 23552 decimal so there'll be a link in the video description to an excellent website that shows many different commerce 64 graphic formats and what the data is and where in memory it loads into it's an excellent resource i used it for making this then these two pokes set the top of basic memory again low by high byte format 92 represents the high byte they multiply it by 256 to come up with 23552 which is 5c00 this isn't totally necessary but if you want to do more with the program after you've loaded the bitmap image these pokes in the clear protect that bitmap image from commodore basic accidentally overwriting it with variables or code so it's a good practice so that's it okay moving on to k display which of course is for koala display and we'll run that so i might speed this up a bit you can see it's loading the bitmap data first and then it starts loading in the color values so this is quite slow and basic so i'll probably speed it up a bit when i'm not talking so i think that's a fantastic image very well done darren so let's look at the code here again you just hold stop and hit restore to break out of the program that resets the vic registers so you can start coding in basic again so here's the koala display you see it is the longest program some of this we can go over quickly because we've already looked at it again we turn bitmap mode on just like the previous program but we also have to set bit 4 of this 53270 register to turn on multi-color mode if this is off it's the regular high-res mode that we saw for the doodle image with referrto with this bit force turned on we're in multi-color mode what that does is instead the vic treating each bit as one of two colors a one bit image it treats it as a 2-bit image so there's a potential four colors for each area except the pixels are double wide for many kinds of art it's a very acceptable trade-off to get more colors into the image at the expense of less pixel resolution setting the video matrix and the dot data are exactly the same with register 53272 so it gets two of the colors from the video matrix but then it also gets a universal background color from five three two eight one we'll look at that in a moment and it also gets the fourth color from color ram at 55296 or d800 and again this line is the same as the previous doodle program telling the cia to point the vic at bank 1 at 4 000 hex or 16 384 decimal and line 40 is the same deal except we're loading this koala file 16 dot kla which loads into 6 000 hacks 6 0 0 0 2 4 5 7 six decimal again there's a good write up on that website about the koala painter format then we set the top of basic the same again so this is the new part of the program is that we have to parse some extra information out of that data file once the qualifier has been loaded then here at location 34576 or 8710 hacks is the background color of the image it's embedded in the qualifier and then there's two thousand bytes that we have to process we can do it in one loop from zero to nine nine nine which is a thousand unique values where we're going to transfer the screen ram from 32576 or 7f40 down to 5c00 or 23552 so the koala file saves the screen data as a contiguous block of data some of that data isn't in the correct place for the vic to display it it's actually overflowed from bank one into bank two so we need to do is copy it from bank two back to the correct spot in bank one where the vic expects it to be so really displaying these images again is just about putting the right data in the right place and then telling the vic where it is so screen ram and the koala file is loaded to 7 f 4 0 but we need to move it down to 5 c 0 0 hex which is 2 3 5 5 2 decimal and likewise the color ram is stored immediately after the screen data here at 8328 in the koala file and it needs to be moved down to oh that's a typo so again we're just copying it from the koala data file up into color ram that's at d800 which is fixed in the commerce 64. unfortunately you can't change where that is in memory by the way i've been deliberately setting the vic registers before i load the data just so we can kind of see the process of the data being loaded in and moved into the correct places it might be more professional to blank the screen while this kind of work is done and then display the image complete at the end of the process that's up to you but just for the sake of making a bit more uh clear for this explanation i've switched around that order okay and then the loop completes and just again an endless loop just so that the basic prompt doesn't corrupt the display in any way okay and on to the our final step here okay so i've decided to use an older version of turbo assembler it's here on this disc turbo v6 and the reason i've chosen this is because it uses a bit less ram turbo macro pro that i usually use for assembly language starts at 8 000 hex or 32768 which actually overlaps with the data space of the koala image that we load and just to keep things simpler i used this version of turbo assembler that starts up at 9000 hex or 36864 that's how you start it with sys36864 now you see how down the bottom it says bot 8f eb that means that the bottom of its memory is currently using down to 8f eb and when we load the source file k disp source back arrow l to load k disp source watch that bottom drops to 8 e a b so that means our source code is going from under the turbo assembler working its way down in memory where the koala image loads in memory up to eight seven one zero we have a a few hundred hex bytes free we'll run it first back arrow 3 turbo assemblers compiling it and press s to start you can see it's loading the file in and this is a bit faster than loading it from basic and what's especially fast is getting the colors into memory they're going to still load from disk for a moment and then they should just appear there we go so assembly language is fast enough it can instantly move the colors into the correct place on screen let's just look through that source code so i've gone for a very literal translation of the basic code to make it as easy as possible for you to follow if you understand the basic code then this is a good little gateway or bridge into assembly language so i've used a lot of decimal values normally i would use more hexadecimal when writing assembly language but to keep it consistent with the basic i'm going to use these decimal values so again this is very similar to the basic loading in from 53265 and oring it with 32 and storing it back in that enables bitmap mode 53270 and orient with 16 sets bit 4 to enable multi-color mode i didn't do that convoluted uh seven times 16 plus 8 here but you can see how in hexadecimal i did use that here because it's so much more clear that where the 120 decimal i broke into the 7 times 16 plus 8 in the basic listing here i can just put the dollar sign for hex and then put 7 8 to point the vic to the correct locations for the video matrix and dot data here again is a very literal loading five six five seven six just like the basic where we loading is like peaking anding and oring the values is just the same as and and or in basic and then storing it back in okay here's where it gets a bit more interesting or new to load the file from disk this is how you do it in assembly it's a bit more work than in basic but not terrible you have to tell it how long is the file name that we want to load and it's down here name 16 dot kla this is the same file that we load with basic and that is six characters long with a label of name okay so here we tell it it's six characters long we load the x and the y registers with the low and high bytes of the file name and then we call this ffbd routine which sets the name of the file on disk next we have to load a x and y with the file number that can be whatever one is common the device number is device eight by default and one means we wanna load the file from the program address it's just like comma eight comma one this is how you do an assembly language and then we jump to the subroutine ffba this is setting the file parameters and then finally we load the accumulator with zero if we want to actually load and one or more if we want to verify but whoever verifies right and then jumping subroutine ffd5 is the actual load next we set the background color with the value in the qualifier that was at three four five seven six just the same as the basic memory okay now this next bit is a bit ugly but this is this is how you do it in assembly a lot of the time we're just going to set labels to screen data color data screen ram and color ram this is the screen data in the qual file and this is where we're going to move it to in ram again here's the color data and this is where we're going to move it to and ram we're just going to use these labels instead of these big nasty constants over and over again it'll make this next section just slightly easier so what we're doing is we want to copy a thousand bytes but we can't you know for example load x with a thousand because the 6502 is only an 8-bit processor so what we do instead is split the 1000 bytes we want to copy into four chunks of 250 which is the largest eight bit value that can be divided into a thousand for a bit of extra speed we're going to start 250 and go down to one when we get to zero that means our loop is done and we won't actually process that zero so the smallest number we're gonna have in this loop is the value one and that means that to get down to the very first byte of screen data and screen ram we actually have to subtract one so that when the x register is added this indexed addressing we end up at the first byte of that range so this covers the first 250 bytes of the screen data getting copied then we do the same thing but add 249 that is -1 plus 250 and copy another 250 bytes here another 250 499 749 and we do exactly the same with the color data from copying from color data to color ram from -1 to plus 249 499 and 749 then we decrement x and if it's not equal zero we go back up to the loop and do it again so there are other ways of doing this but this is about the fastest and i find it fairly easy to understand that's a bit of a trick i guess and then finally we just jump forever again an endless loop just to display the image and there's the file name we already looked at okay i hope that was helpful to get kind of an overview of vic programming displaying images i don't know if i need to get more in detail in another episode about some of that thanks again to darren at grewtube for making that great art for us to use today so please do check out his video on how he made that art i think he'll really enjoy seeing him use doodle koala paint and get into some of the nuances of making art on the commodore 64. again if you like what he's doing consider subscribing hey thanks to my patrons for support especially to michael for the question that prompted this episode thank you for watching and we'll talk to you next time [Music] cartoons [Music] [Music] my own computer in my bedroom [Music] create new worlds of computerized brain masons and dungeons dragons and kings explore outer space
Info
Channel: 8-Bit Show And Tell
Views: 28,458
Rating: undefined out of 5
Keywords:
Id: KWydVEX0n3g
Channel Id: undefined
Length: 29min 29sec (1769 seconds)
Published: Tue Apr 20 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.