Stripping away all the fluff with the stack in essence all you need to set your drawing points are
1. Select your region
out GPU_SelectedRegion, R# ; register which holds the value for the region
2. Set your drawing points
out GPU_DrawingPointX, R# ; register that holds the X value out GPU_DrawingPointY, R# ; register that holds the Y value
3. Draw your stuff
out GPU_Command, GPUCommand_DrawRegion
It may prove useful to slap these commands into a subroutine, preferably with a nice name for easy tracking when debugging.
When selecting a texture it is similar to C but is far more simplified. Normally, in C you would do the following:
#define Texture 0
In asm this translates to the following:
mov R7, 0 out GPU_SelectedTexture, R7
What is happening in the above snip of code is that we are putting in our number ID for our texture into register 7 and then feeding R7 into the GPU_SelectedTexture.
After you have successfully selected your texture you need to select a region inside your texture file. To accomplish this in asm you are repeating similar steps as to selecting a texture. Here is a sample of what that would look like:
mov R7, 1 out GPU_SelectedRegion, R7
Similarly to above, we are putting the id for a region into R7 and then feeding R7 into GPU_SelectedRegion.
Before a region can be drawn, its borders have to be defined within the texture file.
This is done similarly to the define_region functions in C:
define_region(minX, minY, maxX, maxY, hotspotX, hotspotY);
Except that here, you have to input each coordinate value individually, including the hotspots.
Getting only the necessary lines from the compiled code, defining a region would look like so:
out GPU_RegionMinX, R? out GPU_RegionMinY, R? . . . out GPU_RegionHotSpotY, R?
Where “R?” refers to the register that stores that specific coordinate.
To display your regions you have to say where you want to display the region. That is done by putting in values for X and Y into 2 different registers. Here is what that looks like:
mov R2, 20 ; X coordinate mov R3, 40 ; Y coordinate
First off you want to select the gamepad. The best way to do this would be:
mov R0, 0 out INP_SelectedGamepad, R0
this would select gamepad 0 for the currently selected gamepad.
Next you would want to make your gamepad direction functions and read into them the current gamepad direction. The best way to do this would be:
__left: ;Left Function in R10, INP_GamepadLeft ;Gamepad state is loaded into R10 and will return a value mov R4, 0 ;Put 0 into R4 to rest its value ilt R4, R10 ;If R4 < R10 jf R4, __right ;If it is false then go to the right function mov R8, 1 ;Assigning region value that will print the region you want to print when going left isub R2, 1 ;If it is true then subtract one value from R2 which would be the sprites X
When you reach the last direction instead of putting
jf R4, __direction
You should do:
jf R4, __function_gamepad_direction_return
or whatever the end of your function or loop is called. As long as you don't modify R2 between now and using R2 to in printing your texture then it will print at R2.
On the Vircon specifications page, one can find a list of comparison evaluations. A few examples include:
"ilt" -> "integer less than" "ieq" -> "integer equal to" "ige" -> "integer greater than or equal to"
mov R0, 13 ilt R0, 14 ; would set the value in R0 to 0 as the result of the comparison is true.
*One needs to keep in mind that when these comparisons are passed, they are replaced with a resulting value, like 1 or 0. So do be careful when comparing a register to an integer or another register.
**A good idea is to move the value one wants evaluated to another register and have the second one evaluated, as to not overwrite memory and cause oneself trouble
While there are no loops as we recognize from C, (while, do while, for) we have the equivalent of the infamous go-to.
Further up in the Gamepad section we used the conditional jumps which are in essence a type of boolean loop.
The main loop that will run this and future programs is a well placed unconditional jump
jmp __label
where your label would be somethin akin to _main_loop
You'd also need a label such like _end_main_loop
which would hold your hlt
command
Implemented from scratch, in assembly: