Corning Community College
CSCS2650 Computer Organization
With a snake game bootstrapped in C, commence an implementation in Vircon32 assembly.
Please update your Vircon32 DevTools to at least version v24.02.04
Instead of relying on unoptimized compiler output to swipe internal Vircon32 symbol names, please make use of this reference instead:
You will want to go here to edit and fill in the various sections of the document:
To update your vircon DevTools to v24.2.4, go to this link
https://github.com/vircon32/ComputerSoftware/releases/tag/devtools-v24.2.4
Then, depending on the system you use for class, follow the appropriate steps on the github page to install. There is even a section labeled “How to Install.”
With the new version of dev-tools, you can use %define to clean up your code, making it more readable and easier to detect errors. (example of this is in the 06b_hello_define directory within the public directory.
The examples we went over in class can be found in the public class directory under “examples.” To get to the public class directory cd into /var/public/spring2024/comporg/examples.
To have your snake food spawn randomly, we will use the built-in random function that is offered by Vircon32. In C, it is extremely simple to implement. You would simply do the following:
#include "misc.h" #include "time.h" // Seeding srand srand(get_time()); // Getting random X and Y cords for apple int xApple = rand() % (screen_width); int yApple = rand() % (screen_height);
So we simply just include the .h file that holds the function, seed srand and then use rand() and specify the range. But in asm we dont need to include any files.
Seeding srand in asm:
in R0, TIM_CurrentTime out RNG_CurrentValue, R0
So this first spot is the equivalent of seeding srand with get_time. We are getting the time and storing it in R0 and then feeding it into RND_CurrentValue.
; X value in R0, RNG_CurrentValue imod R0, 620 mov R14, R0 ; Y value in R0, RNG_CurrentValue imod R0, 320 mov R15, R0
Looking at the above, we are getting a random value between 0 and 620 and storing that in R0. we then feed that into R14. This is our X value for the food. We then repeat the same steps for the y value for the food.
Make sure your object moves at a predictable speed (example: 1 pixel at a time), for if you don't. Then you run the risk of the objects not touching again, as the random value will have a random number assigned to it. Imagine your speed is 5 pixels, then your object will only be able to land on the food in the 2/10 chance it lands in a position ending in 0 or 5.
Remember to add one to the result if your region bounds happen to be at 0, as although unlikely, the fruit can still spawn at 0,0 causing an unfortunate game over. You can add to the random number with iadd R0, 1. This snippet of code will add one to R0.
Collision is extremely simple in Vircon assembly and can be done in just 20-ish lines. To start, we need to store our X and Y values of our snake head into temp registers so they do not get destroyed. We will first start with finding the position difference between the snake head and food (for me, an apple). Here is what that looks like:
; Collision Detection mov R10, R2 ; Snake head X isub R10, R14 ; Subtract apple X iabs R10 ; Absolute value of X difference mov R11, R3 ; Snake head Y isub R11, R15 ; Subtract apple Y iabs R11 ; Absolute value of Y difference
From the code snip above, we first store our X and Y values in temp registers that will get destroyed later on. Then we calculated the difference. It does not matter if the result is negative or positive because we take the abs value. We take the absolute value because the difference in position is a difference. It's hard to explain but it just needs to be the abs value (Someone please step in and make this clearer. I cannot figure out how to say it).
Next, we want to check if the snake head comes in contact with the food. Here is what that looks like:
; Check if within 30 pixels ile R10, 30 jf R10, _no_collision ; If false then go to _no_collision ; Check if within 48 pixels ile R11, 48 jf R11, _no_collision ; If false then go to _no_collision
Here, we are simply just checking the difference we got for the X and Y values and then either jumping out of this check because they are not in contact or falling through to what will happen if we are in contact with the food.
Vircon has 16 registers (0-15) with 14 and 15 being reserved for stack purposes.
mov R0, 1
iadd R0, 1
A register will also store a “yes” or “no” value from certain operation like IGE, which is “Integer Greater Than or Equal To”.
ige R0, 1
mov R1, R0
ile R0, 1
Instructions are things that can be done to effect registers, memory addresses, and where you are in your code. There are many different types of instruction sets, for example:
To be successful in this project, the following criteria (or their equivalent) must be met:
Let's say you have completed work on the project, and are ready to submit, you would do the following:
lab46:~/src/SEMESTER/DESIG/PROJECT$ submit DESIG PROJECT file1 file2 file3 ... fileN
You should get some sort of confirmation indicating successful submission if all went according to plan. If not, check for typos and or locational mismatches.
I'll be evaluating the project based on the following criteria:
130:cta0:final tally of results (130/130) *:cta0:implementation by hand in Vircon32 assembly [91/91] *:cta0:clarifying comments throughout [13/13] *:cta0:assembles cleanly with no warnings or errors [13/13] *:cta0:source and project resources tracked in semester repo [13/13]