Wednesday, November 23, 2011

TUTORIAL #4 - INITIAL "Initialize all starting variables"



TUTORIAL #4 – INITIAL “Initialize all variables for the program”



I will be going through the subroutine INITIAL line-by-line and explaining what each line of code is doing and how it affects the outcome of the program.



The subroutine INITIAL is used to initialize all variables used within the Ultima 1 Revisited program.  You have to define each variable that is in the program and give it either a memory region size of 1 byte or more.  Remember that you cannot store a value within a byte higher that 256 or it will error.  Each byte can only hold a value of 0 to 255.  You can set each variable to a HEX value, a decimal value, or a binary value.  The symbols used to define the type of variable are as follows:

               

                # is for a constant

                $ is for HEX values

                ! is for Decimal values

                % is for Binary values



You can think of the Apple 6502 as having a large collection of boxes in which you can store numbers.  Each box on the 6502 contains eight bits; this is, it can contain any binary number from 00000000 through 11111111, which is one and only one number at any given time!



There are two kinds of boxes.  One is called the register and the 6502 has many registers.  The three basic registers we are concerned about are called A, X, and Y.  The other kind of box is called a cell and the cells taken together are known as Main Memory, which come from the 48K or 64K memory you find in the Apple computer.   The cells in the main memory have cell numbers, called addresses, and these addresses start from zero.  So you cell number 0, cell number 1, etc…  The largest possible address is 65535.  So when you see the line LDA HIGH, you can think of this as A is the register, which can only hold a value from 0 to 255, and HIGH is the variable which you are loading the value from A into HIGH.



84     ********** SUBROUTINES ********



This is just a comment line to separate each subroutine and helps to define the start of all the subroutines. 



85     INITIAL               LDA   #$00



Line 85 is used to “[L]oa[D] the [A]ccumulator” or register A with the value equal to zero!  So, you are setting the value of A to equal the HEX value of $00, which equals decimal value of 0.  Also, line 85 has a header titled INITIAL, which allows it to be called from a separate statement as a subroutine.  In this case it is used to initialize all the variables with either a zero, a HEX value, a DECIMAL value, or a CONSTANT.



86                                  STA   TPCNT



Line 86 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable TPCNT, which in this case equal HEX value $00 or the decimal value of 0.   TPCNT is used within the LOADMAP subroutine which stands for "Temp Counter".  It is used within a loop routine to count up to 20 for the number of tiles stored to be displayed on the each column of the screen.



87                                  STA   TMAPCNT



Line 87 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable TPCNT, which in this case equal HEX value $00 or the decimal value of 0.   TMAPCNT is used within the LOADSHP subroutine, which stand for "Temp Map Counter".



88                                  STA   CHKER1



Line 88 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable CHKER1, which in this case equal HEX value $00 or the decimal value of 0.   CHKER1 is used within the MAIN PROGRAM subroutine and is part of an incremental counter with the LOADMAP subroutine to check when all 10 screen line of tiles has been stored in the MAPSTORE array.



89                                  STA   STEPR1



Line 89 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable STEPR1, which in this case equal HEX value $00 or the decimal value of 0.   STEPR1 is used within the TILEPLC subroutine and is part of an incremental counter that checks when the number of tiles drawn equals the 20th tile after COLMADD.



90                                  STA   TCOUNT



Line 90 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable TCOUNT, which in this case equal HEX value $00 or the decimal value of 0.   TCOUNT is a simple loop incremental counter used within the LOADSHP subroutine to check when 10 rows of tiles have been drawn.



 91                                  STA   MAPCOUNT



Line 91 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable MAPCOUNT, which in this case equal HEX value $00 or the decimal value of 0.   MAPCOUNT is a used within LOADMAP and LOADSHP subroutines.  It is used as an incremental counter within these subroutines and will be explained more with these two subroutines.



92                                  STA   STEPPB



Line 92 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable STEPPB, which in this case equal HEX value $00 or the decimal value of 0.   STEPPB is a used within the LOADSHP subroutine.  It is used as an incremental counter to check when each of the two byes for each shape has been drawn on the screen line by line.



93                                  STA   LINEA



Line 93 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable LINEA, which in this case equal HEX value $00 or the decimal value of 0.   LINEA is a used as a loop counter to keep track of the160 bytes lines that a referenced from line 0 to 159 down the screen. As LINEA increments by 1 then the next line byte is referenced and displayed until LINEA reaches 159.



94                                  STA   BYTEA



Line 94 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable BYTEA, which in this case equal HEX value $00 or the decimal value of 0.   BYTEA is a used as a loop counter to keep track of the 40 bytes that a referenced across the screen.  As BYTEA increments by 1 then the next tile byte is referenced and displayed until BYTEA reaches 39.



95                                   LDA   #$07



Line 95 is used to “[L]oa[D] the [A]ccumulator” or register A with the value equal to seven!  So, you are now changing the register of A from the value of 0 to the new value equal the HEX value of $07, which equals decimal value of 7.  This value is what represents the character shape number in the SHAPE ADDRESS table used to define each character shape.  Since there are six different types of character types used in the game, such as Fighter, ship, raft, cart, horse, and land speeder, when the game starts you what the fighter character shape to be the one that shows up first!  You will see this explained more clearly in the CHARTILE subroutine.



96                                  STA   CHAR



Line 96 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable CHAR, which in this case equal HEX value $07 or the decimal value of 7.   Again, CHAR is a used to represents the character shape number in the SHAPE ADDRESS table used to define each character shape.  Since there are six different types of character types used in the game, such as Fighter, ship, raft, cart, horse, and land speeder, when the game starts the fighter character will be the one that shows up in the middle of the screen.



97                                   LDA   ROWINIT



Line 97 is used to “[L]oa[D] the [A]ccumulator” or register A with the value held in variable ROWINIT!  Since you defined ROWINIT as a cell registered to HEX $EC, which is cell 236, it doesn’t get initialized with a set value but gets its value from the basic program.  Within the ULTIMA BASIC program that is used to start the assembly program you POKE a specific value into cell 236.  The poke statement is what bridges the gap between assembly code and basic.  This decimal value is what will be the starting ROW location for the world map. 



98                                  STA   ROW



Line 98 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable ROW.   Again, ROW is a used to represent the starting row of the world map where the map will be shown on the display screen based on the upper-left corner of the screen.



99                                   LDA   COLINIT



Line 99 is used to “[L]oa[D] the [A]ccumulator” or register A with the value held in variable COLINIT!  Since you defined COLINIT as a cell registered to HEX $ED, which is cell 237, it doesn’t get initialized with a set value but gets its value from the basic program.  Within the ULTIMA BASIC program that is used to start the assembly program you POKE a specific value into cell 237.  The poke statement is what bridges the gap between assembly code and basic.  This decimal value is what will be the starting COLUMN location for the world map. 



100                                STA   COLUMN



Line 100 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable COLUMN.   Again, COLUMN is a used to represent the starting column of the world map where the map will be shown on the display screen based on the upper-left corner of the screen.



101                                 LDA   COLUMN



Line 101 is used to “[L]oa[D] the [A]ccumulator” or register A with the value held in variable COLUMN!  Since you just defined COLUMN with the value of register HEX $ED, which is cell 237.  You are going to be using this value within another variable to will be used as a temp column variable.



102                                STA   COLUMN1



Line 102 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable COLUMN1.   COLUMN1 is going to be used as a temporary COLUMN value that can be incremented or decremented without affecting the original COLUMN value.  This is important because while this variable is getting updated to a larger or smaller value and the screen is shifting up, down, left, or right, you are always able to recall the original starting column value to reset the starting location of the world map on the screen.



103                                LDA   COLUMN



Line 103 is used to again “[L]oa[D] the [A]ccumulator” or register A with the value held in variable COLUMN!  Since you just defined COLUMN with the value of register HEX $ED, which is cell 237.  You are going to be using this value to help define where the last column will be read from. 



104                                CLC  



Line 104 is used to “[CL]ear [C]arry” which loads zero into the carry flag.  On the 6502, the carry is kept in a one-bit register called the carry status flag.  Like the A, X, and Y registers, the carry status flag can be loaded with a constant, either zero or one.  Loading a zero is called clearing, and there is the instruction, CLC (Clear Carry), which loads zero into the carry flag.  This is similar to the way LDA #!0 is often referred to as clearing the A register with zero.



105                                ADC  #20



Line 105 is used to “[A]d[D] with [C]arry” which adds to the A register.  It also adds the number in the carry flag (either zero or one). If the result is less than 256, it clears the carry flag; otherwise, it sets the carry flag.  The ADC instruction is the only add instruction on the 6502.  So in this case you are taking the value of COLUMN and adding 20 to it.  So for example:  If column was to start at 30 the program needs to know that since the screen only holds 20 graphic tiles on a horizontal line, then 30 + 20 would be 50, which should be the last column read for the map database address.  Since all hundred and something map tiles are in the database, it would be a waste of memory to have to store all those tiles at one time.  This make is easier to just check for the 20 tiles after the original column tile value.



106                                STA   COLMADD



Line 106 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable COLMADD.   COLMADD is used to store the value which references the 20th tile set from the initial column value. On the world map the initial starting tile reference is created from a ROW and COLUMN value. These values tell the program where the upper left corner of the map will start from; example 20, 45. So if the initial column value was 45 then COLMADD would equal 65. This 65 is used to reference the last tile number that will be displayed on the screen, since only 20 tiles can be shown per line on the screen at one tile.



107                                 LDA   ROW



Line 107 is used to “[L]oa[D] the [A]ccumulator” or register A with the value held in variable ROW!  Since you just defined ROW with the value of register HEX $Ec, which is cell 236.  You are going to be using this value to help define where the last ROW will be read from. 



108                                STA   ROWNO



Line 108 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable ROWNO.   ROWNO is going to be used as a temporary ROW value that can be incremented or decremented without affecting the original ROW value.  This is important because while this variable is getting updated to a larger or smaller value and the screen is shifting up, down, left, or right, you are always able to recall the original starting row value to reset the starting location of the world map on the screen.





109                                RTS



Line 109 is used to “[R]e[T]urn from [S]ubroutine”, which means that everything in the INITIAL subroutine has and all variables have been setup and initialized with starting values.   In this case, since the subroutine BEGIN on line 41 called to this subroutine, it will return back to the end of the same line and continue on to the next code line.

As always, please email me any questions you might have.

ultima_revisited@yahoo.com

Joe

No comments:

Post a Comment