Jump to content

vidak's Blog - Guerilla Game #5.1


Recommended Posts

Okay. I was off to the wrong start with my first kernel. On the WIP thread for this game in the forums we established what was really going on as Commando 2600 drew the screen. I will repeat the "discovery" here. Commando draws the screen in bands, what SpiceWare calls in Stay Frosty, "sections". So what we are able to do as we move down the screen is forget that we have drawn the playfield and Player1. This is one of the advantages of the 2600's "racing the beam". You are able to draw as many copies of the player graphics down the screen each line as you like, so long as you have enough memory to set everything up in the code. Perhaps an illustration would help:

not forgetting about GRP0 (the player character). Luckily SpiceWare provided me with the answer. He had already solved this problem in commented source code in Stay Frosty.

In the rest of this blog post I will explain how he achieves a free-moving GRP0 among bands of repeated GRP1s and playfield graphics. The simple answer for how SpiceWare achieves a GRP0 that can move between bands of repeated GRP1 is that he uses a mask to allow the GPR0 graphics to pass through on the correct lines. The kernel is programmed to calculate and draw the GRP0 graphics, but for the inclusion of the calculation of a mask which will either permit or block the graphics to the drawn. The big picture is easy to understand, but actually practically implementing this a little more complicated.

I How Stay Frosty Does It

The reason I am making this blog post is that I am having trouble understanding the complex process of setting up the pointers for GRP0 and GRP1 in SpiceWare's multi-band kernel.

A Macros

The kernel is implemented using DASM's ability to assemble code using macros.

What is a macro? A macro is different from a "function", "method", or "subroutine". When you type a macro into a file for DASM to assemble, you are not writing code which the Atari will end up running. You are using a set of instructions which DASM interprets and then uses to produce code that will be assembled for the Atari. The exact definition of a macro is that it is a sequence of characters that DASM will take and them map onto another sequence of characters. The purpose of having macros is to help reduce the need to repeat code mindlessly, or to reduce the conceptual complexity of producing the final characters which then go on to form the final code which is executed.

In this case the macro that SpiceWare has written is a sequence of characters which DASM is then told to repeat five times in order to construct an entire kernel to draw the five-banded screen. This can be seen in the source code here:
fairly accurate description of the acceptable syntax for macros in DASM here: http://www.macs.hw.ac.uk/~pjbk/scholar/dasm.html
        lda (FrostyImagePtr+.SEC*2),y         and (FrostyMaskPtr+.SEC*2),y           sta GRP0                               lda (FrostyColorPtr+.SEC*2),y          sta COLUP0                   
As you can see, there are pointers for the image, mask, and colour. The pseudo-variable that is passed into the code from the macro is also present. It is also multiplied by 2 with macro code. This means that if the number 4 is passed as an argument into the macro, the number 8 will be added to the pointer variable. Bear mind mind that each of these pointer variables are being used by Indirect Indexed instructions.

What happens when you type in LDA (Variable),Y is that the CPU fetches the data in the variable, and uses it as the location of 16 bit address in memory. The variable is in zero page memory. The variable is only 8 bits long, so it uses the next higher byte next to the variable in memory as the higher byte of the 16 bit address. Then, the number contained in the Y index register is added to this 16 bit address. That memory location is then fetched. Here is a graphical illustration of how this works:


The Zero Page memory location that contains the 16 bit address is called a pointer. It POINTS to the 16 bit location in memory that contains the real data we want to load. Because of the use of macros in this code, there is an extra step. We are adding the value of (.SEC x 2) to the address contained in the pointer. So we have the POINTER + (.SEC x 2) + Y which contains the final memory location which contains the data we want to load.

So, in order to understand how we are getting the data we want to load as graphics, we need to understand how this operation works.

We need to understand how we obtain the values for three elements:
  • The Y Index Register
  • The actual pointer
  • The (.SEC x 2) macro code

C The Y Index Register

The easiest element to trace inside the code is how the Y Register is set. This code at the beginning of the SECTION macro sets the Y Register:
Where does Heights come from? Heights is formed in the PrepLevel "subroutine" macro.
LINE 2338:     LevelData                         .word Level1                         .word Level2                         .word Level3                         .word Level4                         .word Level1                         .word Level2                         .word Level3                         .word Level4
There are therefore 8 levels in this game - levels 1 to 4 repeated once. You'll notice that under each ROM label there are 54 bytes of data. This agrees with the number of times .plLoop repeats.

So where is CurrentLevel formed? In a few places.

At the beginning of the game, CurrentLevel is set to zero:
          ; level cleared, advance to next levelLINE 1325:        ldx CurrentLevel                  inx                  cpx #8                  bne SaveLevel                  ldx #0          SaveLevel                          stx CurrentLevel                  jsr PrepLevel
This ends the tracing needed in order to understand how the Y Register in the kernel is obtained. To recap, this is how we obtain Y:
-> LevelData (Repeats through Level1 to Level4 twice)-> LevelDataPtr (54 bytes of information)-> Heights
D The Actual Pointer

I don't have enough time today to pick through everything! I will return to this tomorrow.

Please look forward to me finishing up the kernel tomorrow.


* I am now in such a state of concentration that the word "Level" looks strange and doesn't make sense.
Attached thumbnail(s)
  • blogentry-61331-0-65966500-1512100244.pn

Link to comment
Share on other sites

This topic is now closed to further replies.

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...