PodCast for the Machine Language Project
New: You can now listen to a summary review of the 7 pages for this YouTube project in an audio file (below). The Podcast passes communication back and worth between two bots bouncing information off each other. The audio is great in case you want to get a review of the pages before spending a lot of time reading something you are not familiar with. The Commodore 64 is the scope of this project built using the VICE C64 Emulator.
Setup game for memory and sprites
In this section you are going to learn how to setup CBM Prg Studio for your game project, add VICE C64 emulator to your project, setup Google Hangouts for streaming, download SpritePad, create a simple sprite example, animate sprites in SpritePad, reserve memory for graphics, save sprites in SpritePad, setup a delay loop, and generate sprite animation on the C64 screen. This is a great editor for the C64 Machine Language Project.
I
n October 2016, I made a public announcement on my YouTube channel that I would be recruiting a group that would become part of constructing a 100% game or demo developed in machine language for the Commodore 64. I used some Microsoft Powerpoint slides to explain the process, rules, and what would make it interesting to join.
Within a two month wait, I had finally launched the first live project for the C64 Machine Language Project broadcast using the Google Hangouts screen capture software. This was an experiment in process because I had no idea how long it would last or if members would lose interest. However, I was willing to devote the hours into making it work and kept promoting it everywhere I could, such as on YouTube, Twitter, Facebook, Lemon64 (website), and any other place where I could locate a C64 Machine Language Gaming community.
So when it finally reach inception, a small team had assembled together to begin laying plans to work on the project. I couldn’t begin to tell you how happy I was then as some of the previous members dropped by and some newcomers as well.
Tools used for the C64 Machine Language Gaming Project
Some of the application tools that were used for the project included Infilitrator, SpritePad, and the CBM Prg Studio editor. Infiltrator can be used to look at compiled code, view Sprites in memory, examine character sets, display bitmap graphics, includes a hex editor, view memory as a sine wave, and so much more. SpritePad is a wonderful utility that allows a user to prefabricate their own game sprites (including animation), and CBM Prg Studio is used to write code in both Basic and Assembly language, allowing an emulator like VICE C64 to be attached for output.
A long time friend joined in the early stage of the project. His name is Bo Goren. He is known on YouTube for the channel called Squidian The Bo Fish. He suggested for us to break down and “have a couple of goals for each week”. This made perfect sense for the C64 Machine Language Gaming project since assembly language evolves in small increment steps. You don’t just create a giant loop quickly and get a demo going. It takes a long time to build effective code to get operations running smoothly. So breaking down the project into ‘chunks’ would help us reach us goals more realistically and hopefully quickly enough. It also would keep the group on track while maintaining a focus to achieve results each week.
To keep pace with the creation of a successful project, in the early stages of the live YouTube promotions, I mentioned that we should model after a completed game already. At this time we attempted to evolve the project around a game called The Bear Essentials. The developer already had a website that showed how to build a game step by step, included with screenshots and attached code samples.
Beginning stages of the machine language project
Bo suggested in the beginning we could utilize CBM Prg Studio and get some sample sprites up on the screen. The logic here works because we can explain to our audience how to construct some sprites, load them into memory, and get them displayed in VICE C64. This would also hopefully keep our viewers and straddlers engaged until we could start later developing more thing such as the background maps, animation, and some sprite to sprite interaction.
My approach before this was to demonstrate to our spectators how to download the CBM Prg Studio tool that would be used in the development environment. The website is at www.ajordison.co.uk/download.html.
CBM Prg Studio Character Editor
Next I returned to the CBM Prg Studio that was already resident on the screen and indicated to our viewers some of the features that are packaged with it. There is a built in Character Editor. This can be opened by clicking on the icon to the far top right above the editor window or by selecting the Tools menu and choosing the Character Editor option. This cool utility allows you to change character graphics in memory and save them so they can be loaded directly into your program via some commands. It contains a small 8×8 graph, a multicolor switch, color selector, and displays all 256 characters available (known as PET ascii) for the C64. I won’t go into heavy detail as we will be discussing it much later.
CBM Prg Studio Screen Editor
There is also a built in Sprite Editor with CBM Prg Studio. Again this can be launched by clicking on the icon at the top right or selecting from the Tools menu and choosing Screen Editor. This one includes a display of the default character set, drawing modes, color changer, and a screen editor to the right.
Options window for CBM Prg Studio
To allow the VICE C64 emulator to communicate with the tool, it is necessary to attach it. I demonstrated this by clicking on the Tools menu and selecting Options. This loads up the CBM prg Studio Options dialogue window. There is a panel on the left that selections various preferences, in the center is the Assembler/Editing Options control, and on the right are some selections to set the starting address, export, etc.
Downloading VICE C64
Before you can attach the VICE C64 emulator you will need to be sure it is accessible on your desktop computer. The website can be found at http://vice-emu.sourceforge.net/index.html#download. You will then choose the platform you want to execute it on (Windows, Mac OS, Linux, etc.). It will download as a zip file and can be opened with a utility such as WinZip, JZip, or just using the extract feature built into most Windows operating systems.
VICE C64 is used to write code in either Commodore 64 Basic or assembly language and is a mirror to the original systems. In the example for the display, I showed how the Batman movie game could be run.
Attaching VICE C64 emulator to CBM Prg Studio
Inside the Options window, be sure that the selector called Project is highlighted on the left. Then in the right panel under the area called Default Location click on the Change button to the far right. This will open a Window labeled Browse for Folder that is used to mark the location of the application to attach. In our example obviously we will have it pointing to the VICE C64 emulator. Once you have it selected, click in the OK button and then CBM Prg Studio will use this directory location to search for the tool each time the project is compiled and run. Be sure that the Project Options area is set to C64 for our example.
Preferences of CBM Prg Studio Options
Clicking on the General tab will give you access to other selectors for the editor. As an example you can manage the columns, spacing, file info displays, and much more. I mentioned in the video that you can turn the line numbering on or off using the Auto Line Numbering checkbox option.
The Assembler tab on the left presents you will options to control features that occur as the program is compiling into memory. Many of these are too advanced for the beginning. However, if you don’t want the program to display pop up windows for the output each time you can turn them off here. Just change the Var/label dump to None and Assembly Dump to None.
The selector called Emulator Control is of primary importance since it marks the directory path where the VICE C64 emulator is found. Glancing to the window to the right under the title ‘Emulator and path’ you will see that CBM Prg Studio shows that VICE C64 has a permanent path where it can run the editor each time the program is executed.
The tab called Debugger provides the user with the ability to swap between using VICE or CBM Prg Studio debugger. A debugger is used to analyze program code at an advanced level to view code that is resident in memory, such as the Batman game that was running in VICE C64. It will be covered later as well. I suggest leaving this set to the selection called Use VICE Debugger. The other tabs are not of primary importance for now. You can click the OK button to close the Options window
The VICE C64 emulator keyboard layout
Surrendering the floor back to Bo, he began talking about some important concepts that VICE C64 contains. He stated that it emulates a Commodore 64 keyboard when you are typing in programs in the VICE environment. Many of the keys are placed in different places in contrast to the PC keyboard. As an example if you press the plus key you get the minus key control. For a new user this can be overwhelming if you never owned a Commodore 64 system. Therefore it is necessary to get pretty familiar with a C64 system by typing in some programs and allowing your brain to ‘think’ like the system and see where the keys compare to a standard PC keyboard.
Setting Google Hangouts to a specific User
In order to allow successful output delivery for each user, Bo discussed how we need to be certain each user can share their desktop screen. Once this is configured it will show the active user talking to be captured live in Google Hangouts. He was able to confirm that it wasn’t currently alternating between users by checking the YouTube live stream. He stated to ‘fix’ this that I should click twice on my user icon and it should lock in that user to the screen as they begin talking. The icons can be seen in this screenshot. Clicking on each user enclosed a white box around it. This signals that would be the primary user talking during the duration of the stream.
Google Hangouts Presenter feature
Another feature that Google Hangouts offers is choosing who the ‘Presenter’ will be during a broadcast as Bo chimed in to advise. Your screen sharing and presenting to everyone was listed at the top of my screen to signal that I was in primary control of the screen sharing at the moment. Bo stated if you are the ‘Presenter’ only your screen will show. He explained that ‘You do want to screen share, but you want to stop being the Presenter’. Ensuring this setting is correct would wrestle control over to the person in changing of sharing their screen. Finally Bo’s screen was captured on the screen as seen in the screenshot in this example.
Downloading SpritePad for the C64
A great utility to create your own Commodore 64 sprites is a tool called SpritePad. Visit the link at http://csdb.dk/release/?id=100657 to get the latest SpritePad version. It was created by Subchrist Software in June of 2011. Some other versions are also available at http://www.subchristsoftware.com/spritepad.htm. The nice thing about this utility is having the ability to view a lot of sprites, animate them, rotate them, and so much more. There are even some starter sprites included with the file. Also like all of the Commodore 64 applications circulating on the Internet, it is completely free.
Creating a C64 CBM Prg Studio Project
To keep all users consistent with the project, Bo mentioned that we should demonstrate how to setup CBM Prg Studio for a new project. To create a new project, click on the File menu and then select New Project. There is also an icon at the top left of the window that performs the same action. After that a window appears that is labeled ‘Create a New Project’. There is a category for Project Type and by default it is set to C 64. This ca be left here for this example. Then click on the Next button to see a screen called Name and Location. This is where the project is named by changing the default setting of NewProject to a name. Below this is an area called Project Location that points to where the project will be saved on the current computer. Finally, clicking on the Next button again will provide an overview of the results received in a section titled ‘Summary’. If everything is correct, pressing the Create button will set up CBM Prg Studio to be used for our game project.
The Project Explorer window on the left will now populate with the project name. In the example here I called it Machine Language Project. Below this several folder categories appeared called BASIC Files, Assembly Files, Character Sets, Sprite Data, and Screen Design. These areas can be used to place files that the project will use. To start a new place for our assembly language example, I clicked on ‘Assembly Files’. This opened a dialogue box titled New Assembly File. In the Filename window I titled it ‘mlproject’ and then I pressed the OK button. Soon afterward, CBM Prg Studio created a new empty area on the right that awaited our new program instructions.
A simple Basic sprite example
So for our sprite example, I returned to the VICE C64 emulator to demonstrate some simple commands to get a sprite on the screen. The sprite is first activated in Basic by typing in POKE 53269,1. Then the sprite needs to identify coordinates to place it on the screen. First I set the sprite’s horizontal location by typing POKE 53248,100. The vertical location was synced to the sprite by executing the command POKE 53249,120. The placed the locations as X=100 and Y=120. X represents the horizontal position and Y is the vertical position. Suddenly a white box appeared close to the center left of the screen.
Each individual sprite contains an area in memory where it is defined at. This shape area is made up of pixels of 24 x 21. That is 24 rows by 21 columns. This was demonstrated in our example, by typing in POKE 2040,13. Since there was no resident data in this memory bank area, the white square disappeared from view. I isolated this in some bullet points for clarity below.
- POKE 53269,1 – Enables the sprite (turns it on)
- POKE 53248,100 – Positions the sprite horizontally (left to right)
- POKE 53249,120 – Positions the sprite vertically (up and down)
- POKE 2040,13 – Points the current sprite in memory
Breakout Clone game example
Desiring to present a live game example, I decided to load up a game that was previously created by a member called Darren. He goes by the username ‘Sausage Toes’ on YouTube. He created a Breakout game clone in Basic that was later converted to assembly language (as seen in this example). The game wasn’t complete at the time, but it was playable and enjoyable enough. In a future session that section will be completed so you can learn how we coded parts of it. However, I figured this was a good example to get us started. It contained several sprites. The player controlled a paddle sprite (blue) and had to deflect a ball on the screen to clear the boxes at the top to accumulate points.
Animating a C64 sprite in SpritePad
For the next session, I wanted to demonstrate how to animation sprites using the SpritePad application. Since I already had some example sprites I created, I was able to present this to our audience. To activate the animation, a user can click on the Tools menu and selector the Animator tool. The Start and End Frame can be managed here. This counts how many sprites are activating being cycled through in memory (if you recall memory location 2040). To see the sprite animation in action there is an arrow icon at the type that is used to analyze SpritePad and cycle through each sprite individually. The animation is live in a window to the left in the SpritePad application. I mentioned also that the speed can be tweaked by setting a Playback Rate for the frames.
Bo mentioned that we need to get a project activated that will allow us to execute it within VICE C64 with the RUN command after it assembles into memory. He presented an example code snippet. He set the starting address for the program counter at $0801 which puts in right into Basic’s memory. Then he had a string of bytes that loaded to force Basic to load the Basic code as 10 sys 2064. On the next lines he set the program counter there to $0810 (2064). Then the program ended with an rts (Return from Subroutine).
Next clicking on the Build menu, he selected Program and then And Run from the submenu. The program can also be executed by pressing the F5 button as well.
Soon afterward, VICE C64 appeared on the screen. On the screen the LOAD command was executed to show that the main code was now resident in memory. Typing the word LIST he showed the viewers that VICE created some Basic code extracted from the byte example generated earlier.
Emulating the Basic code example that was created earlier, I was able to replicate Bo Goren’s earlier example in VICE C64. So the program contained the following code sample the screen shot to achieve the same display. Once again, I have bullet points to illustrate the programming code used to get a sprite displayed on the screen. I have also appended comments to each part to explain what that specific line is doing.
- lda #$01 – Load the accumulator with the immediate value of 1.
- sta $d015 – Store the value of 1 in memory register $d015 (53269)
- lda #$64 – Load the accumulator with the immediate value of $64 (100)
- sta $d000 – Place the 100 in memory location $d000 (532248) for the X register
- lda #$78 – Load the accumulator with the immediate value of $78 (120)
- sta $d001 – Place the 120 in memory location $d001 (53249) for the Y register.
- rts – Return from subroutine (will exit back to Basic)
Reserving memory for the graphics
After this Bo briefed us on having the Commodore 64 locate the VIC bank is essential to reserving an area in memory for our sprite. He educated that the Commodore 64 has 64k of RAM. It is necessary to set aside 16k somewhere in its memory that would be reserved for graphics, such as for the sprites, background graphics, and the screen that we would be drawing. If the VIC Bank is set there the program would be eating up memory space for the VIC bank. So it needs to be in an area that is not conflicting with reserved areas.
Setting the VIC Bank to reserve graphics
Utilizing the book Mapping the Commodore 64, we were eventually able to locate the register that is responsible for preserving the memory. It is located in memory location $dd00 (56576). This register lets tells the C64 what area to set for this to work. By default it is set to Bank 0, which means that memory registers 0-16383 would be reserved for the graphics. However, he clarified that that section of memory set to Bank 0 is where we want to put our program. He recommended to set it to Bank 1 so that the graphics would be pointing to memory locations 16384-32767 which is outside the range of the area of our program. Therefore the sprites, graphics, etc. would not overwrite our program or cause any conflicts. By setting Bank 1 we would have 16k free where the sprites, screens, and background graphics would exist at. In return 14k would be free to write our program.
Darren wanted to know what was contained in the block of memory between 16384-32767. Bo mentioned that when a user is writing a program in Basic this is the area of memory occupying that space. However, since we are not using Basic and writing in assembly language it is safe to use as it doesn’t conflict with any other registers of value to us.
Bo stated there is a problem when we switch over to Bank 1. He stated in Bank 0 we have the character set (for example) residing there. This includes the letters, numbers, and the Pet ascii characters. After you switch to Bank 1 there is no character ROM set anymore. He said then we could create our own font and copy it over.
Utilizing my Excel document for Mapping the Commodore 64, I was able to pinpoint some Basic sample code that achieved the results we were trying to accomplish. There will be a later session that discusses the value in using this tool. The example explained Commodore 64 Basic sets screen memory at $8000 (32768) and that Basic text begins at $0401 (1025), but this can be emulated to relocate memory with a simple program. Our goal then was to transcribe this to work for our program example. Bo counter argued though if we set the bank that high the 16k would get mixed in with the SID registers, color RAM, and other things. This was all kind of trial and error for us since we were still getting our ‘feet wet’ using these techniques.
Output to Screen Memory
So we began testing our code samples to see what types of results we could achieve. Bo mentioned that since we had changed the VIC Bank we would need to write to the screen to see if the results showed up. This is done by incrementing memory locations $4000 and beyond that now control the screen memory. I have attached the new sample code below. Since we were not yet implementing the sprite display we set a loop to lock in only the area of focus, which was to essentially test the screen write example was functional. The result turned out to write some blocks to the screen.
- lda $dd00 – Access the VIC Bank
- and #$fe – Turn off bit 0
- sta $dd00 – Transfer the new result to memory
- jumper
- inc $4000 – Increment screen memory at $4000 (16384)
- inc $4001 – Increment screen memory at $4001 (16385)
- inc $4002 – Increment screen memory at $4002 (16386)
- inc $4003 – Increment screen memory at $4003 (16387)
- jmp jumper
So now that we managed to get data displayed on the VICE C64 screen, Bo advised to remove the code for the inc $4000 lines that were added and remove the jmp jumper so the program could now access the sprite routine created much earlier. We were finally on our way to getting a simple sprite to display on the screen reserved within memory registers 0-16383 ($0 – $3fff).
Choosing a SpritePad sprite
The next task was to load a sprite example onto the square instead of the white square we loaded within defining any sprite shape. I was going to use the sprite example I created, but Todd suggested to make it easier for everyone following along just to use the sprite graphics that came included with SpritePad. As my Math teacher used to state (KISS – Keep it simple Stupid). So it was agreed to use the SpritePad file named io.spd. Another command is required to load the sprite into memory. It is also vital to set the program counter to point to the start of the sprite memory at $4000.
Save Spritepad images as a Binary File
Now in order to load the sprite into our program it has to be saved as a binary file in SpritePad. So in SpritePad the user would click on the File menu, select Import, Export, hover over the arrow on the menu and then choose Raw/PRG. Then another arrow appears where the user would then finally choose Export Sprite Data.
The Export Sprites window opens. There are three categories. The first is labeled File Format. The second is called PRG File, and the third shows Attribute Byte Format. Leave the first set to Raw Data. Then PRG File can be left at $4000 for the memory. Finally Sprite Pad is the option for the third category. Then click on the OK button to retain these settings. This opens up a Save As window where you can name the file. I called my sprite char and SpritePad added the .bin extension to the end. This is also identified in the selector listed as Save as type: Binary file (*.bin). Hence that is where the sprite name ‘char.bin’ came from.
Once again I have listed the rest of the code below for convenience.
- * = $4000 ; Set the program counter to $4000 (16384)
- incbin “char.bin”
After further discovery, we realized that the code for incbin was somehow overwriting the data for our sprite. This is likely because we still didn’t have it pointing to the correct area in memory that was moved after we changed the bank. Much later also, Bo suggested to remove the code that changes the VIC bank so that we could get the sprite loaded into memory after uncommenting the incbin code again. Then lo and behold, the sprite appeared on the screen and we were on our way.
Once the sprite was active on the screen, Bo mentioned that I should enable the multicolor mode. So I added an extra line for sta $d01c and the sprite now had all colors. The next thing to do would be to set the individual colors to reflect the colors present in SpritePad. The code sample is listed below as a reference.
- lda #$01
- sta $d015 ; Enable the sprite
- sta $d01c ; Activate the multicolor
- lda #$64
- sta $d000 ; Position sprite at X position
- lda #$78
- sta $d001 ; Position sprite at Y position
- rts
- *= $3f80
- incbin “char.bin”
Delay Loop
The next perceived mission was to attempt to animate the sprite. Since we are using assembly language and not Basic it is essential to slow down the cycles processing otherwise the sprite would move to fast and hard to see. This is done by creating a simple nested loop that slows down the program as it encounters the subroutine below for the C64 Machine Language project we are evaluating.
- ldy #$32 ; Load y register with $32 (50)
- ldx #$fa ; Load x register with $fa (250)
- loop dex ; x=x-1
- bne loop
- dey ; y=y-1
- bne loop
- rts
A simple Basic example can arrive at the same results of the nested loop in our example. For the beginners it is always beneficial to try seeing the example in a Basic program since it is much easier to comprehend. So for precision I have appended a Basic example below as was demonstrated in the video stream.
- FOR Y=1 TO 50
- FOR X=1 to 250
- NEXT X: NEXT Y
Sprite animation
I also added a shape label to keep track of the sprite in memory and increase it as the loop is being executed. Finally to see the sprite moving on the screen, I added a sta $d000 to get the horizontal position changed. Likely this was getting too complicated for everyone so Darren mentioned that he had accomplished Todd’s request to animate a sprite in an idle location. The result was an Atari Berzerk game character come to life. The code is listed below and the screenshot is above.
- loop
- lda #$fd
- sta $7f8 ; sprite pointer
- jsr wait
- lda #$fe
- sta $7f8
- jsr wait
- lda #$ff
- sta $7f8
- jsr wait
- lda #$fe
- sta $7f8
- jsr wait
- jsr loop
- ldy #$32
- ldx #$fa
- wait dex
- bne wait
- dey
- bne wait
- rts
Extra Additions to the C64 sprite example
I added this area for those wanting to extend a little further past the video’s goal of generating a sprite on the screen and providing a little animation. As Darren mentioned so elegantly, “These Google Hangouts are more for a development environment, rather than being tutorial based.” For those watching the video, this part begins after 3:10 hours into the stream, so stay tuned for the C64 Machine Language Gaming project.
The example we worked on above achieved animation in a single standing position with a sprite. However, always being the game programmer enthusiast, I wanted to see a sprite move across the screen. So I spent a considerable amount of time tweaking the previous code sample, until finally I was able to get the ship moving smoothly across the screen. Therefore I have listed the code below for reference.
- * = $0801byte $0b,$08,$0a,$00,$9e,$32,$30,$36,$34,$00,$00,$00
- * = $0810 lda $dd00 and #$fe sta $dd00 jumper
- lda #$93 ;;CHROUT – output jsr $ffd2 ;a character
- lda #$01 sta $d015 ;enable sprite 0 lda #$07 sta $d01c ;enable multicolor lda #$64 sta $d000 ;position sprite at x=100 lda #$78 sta $d001 ;position sprite at y=120 lda shape sta $7f8 ;sprite shape pointer lda #$fe sta shape sprite_ani jsr delay ;create a loop lda shape ;shape=254 inc shape cmp #$ff bcc shp lda #$fd sta $7f8 shp lda shape sta $7f8 ;sprite shape dec $d000 ;pos. x 53248 jmp sprite_ani
- delay ldy #$15 ;y=50 loop1 ldx #$fe ;x=250 loop2 dex bne loop2 ;x=0 dey bne loop1 rts
- shape byte $fe counter byte 0 ; * = $3f80
- incbin “char.bin”
[…] article on Commodore 64 Assembly Sprites be sure to check out the section on this website called Machine Language Project which demonstrates how to create a professional application regarding […]