Monday, December 12, 2011

TUTORIAL #13 – LOADSHP “Is used to store each of the 10 graphic tile/shapes that will be displayed on the vertical column of the display screen”



TUTORIAL #13 – LOADSHP “Is used to store each of the 10 graphic tile/shapes that will be displayed on the vertical column of the display screen”



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



At this point you have stored all the shapes with the array MAPSTORE and will now pull each shape reference number out at an increment of 20 to obtain each 20th shape on the column. These will be used to store the two sets of bytes that make up the entire shape that will be drawn to the screen.



324  ********************************



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



325   LOADSHP            LDA   MAPCOUNT



Line 325 is used to “[L]oa[D] register [A]” with the value held in MAPCOUNT.  Right before the subroutine LOADSHP is called, MAPCOUNT is set equal to zero through line 56-57.  So, register A will have the value zero placed in it.   



Also, line 325 has a header titled LOADSHP, which allows it to be called as a separate subroutine from the main program.  This subroutine is a key part of the program because it loads and stores the bytes of the 10 graphic tiles/shapes that are displayed on the each line of the 160 horizontal lines that display a column of shapes of the mapworld on the screen.  This subroutine will read each of the 32 lines that make up each shape/tile graphic and store it temporarily which saves memory since we don’t have to save all 200 tiles at one time.  Once the subroutine has stored all 10 shapes/tile graphics, it will move to the next subroutine that writes the tiles to the screen.



326                                STA   TMAPCNT



Line 326 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable TMAPCNT, which in this case equals 0!   By setting TMAPCNT to 0 it establishes can be used as a temp counter along with MAPCOUNT.  This allows the original MAPCOUNT variable to increment up as it is used to eventually load all 160 graphics lines that represent all the shapes on the screen.  TMAPCNT can then be reset each time it goes though the 32 line loop of each graphic tile/shape and this way MAPCOUNT can keep a running total.  So, let’s say MAPCOUNT goes through a couple of loops and is now equal to 64, TMAPCNT will have reset twice to those 32 line increments and will continue to increment through each 32 line loop but will start at the MAPCOUNT value that was left off.  This give a loop within a loop so to speak.  The main loop with MAPCOUNT will increment up to 160 and the TMAPCNT loop will loop 5 times at 32 line increments yet each time TMAPCNT gets used it starts from 0 thru 32, then starts at 32 thru 64, then 64 thru 96, then 96 thru 128, and finally 128 to 160!  So you can see it was necessary to have a temp counter loop along with the main counter of MAPCOUNT to keep track of each 32 line loop without resetting or a affecting the original MAPCOUNT variable.



327   LOADSP1            LDX   MAPCOUNT



Line 327 is used to “[L]oa[D] register [X]” with the value held in MAPCOUNT.  So, register X will now have the value that is held in MAPCOUNT, which in the beginning is zero.   The reason you MAPCOUNT is used with the X register is because register A is being used and X will be used to call each 20th shape from the MAPSTORE array out of the entire 200 shapes.



Also, line 327 has a header titled LOADSHP1, which allows it to be called within the main LOADSHP subroutine since it will be used within the main loop.



328                                 LDA   MAPSTORE,X



Line 328 is used to “[L]oa[D] the [A]ccumulator” or register A with the value held in array MAPSTORE,X!  So, you will be setting the value of A to equal each shape reference number from 0 to 199 in increments of 20 held within array MAPSTORE.



329                               ASL   A



Line 329 is used to “[A]ccumulator [S]hift [L]eft one bit” which takes the binary value in register A and shifts in one bit to the left.  So, if register A equals HEX 34 or decimal 52, then the binary value equals 00110100, which is in the accumulator.  Now you shift the binary value to the left by one and you get 01101000, which equals HEX 68 or decimal 104.



330                               TAX



Line 330 is used to “[T]ransfer [A]ccumulator to index X” which takes the value in register A and transfers it to register X.  So, if register A equals HEX 34 or decimal 52, then register X will now equal HEX 34 or decimal 52.



331                                LDA SHPADR,X



Line 331 is used to “[L]oa[D] the [A]ccumulator” or register A with the value equal to that held in array SHPADR,X!  As mentioned above, the SHAPE1 address is stored in a memory location for example in HEX memory location $6800.  When you load A with the address from SHPADR,X you will get the 00 byte from the $6800 address and load it in register A.



332                                STA   LOW



Line 332 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable LOW, which in this case is equal to HEX value $00.   Again, LOW is a used to represents the low byte of the memory address location where SHPADR 0 starts.



333                                LDA   SHPADR+1,X



Line 333 is used to “[L]oa[D] the [A]ccumulator” or register A with the value equal to that held in array SHPADR+1,X!  As mentioned above, the SHAPE1 address is stored in a memory location for example $6800.  When you load A with the address from SHPADR+1,X you will get the 68 byte from the $6800 address and load it in register A.



334                                STA   HIGH



Line 334 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable HIGH, which in this case is equal to HEX value $68.   Again, HIGH is a used to represents the high byte of the memory address location where SHPADR 1 starts.



335                                LDX   STEPPB



Line 335 is used to “[L]oa[D] register [X]” or register X with the value equal to zero!  So, you are setting the value of X to equal the HEX value of $00, which equals decimal value of 0



336                                LDY   #$00



Line 336 is used to “[L]oa[D] register [Y]” or register Y with the value equal to one!  So, you are setting the value of Y to equal the HEX value of $01, which equals decimal value of 1.



337   LOADSHP1          LDA   (LOW),Y



Line 337 is used to “[L]oa[D] the [A]ccumulator” or register A with the value in the array LOW from array location 0.  Remember when we used Map Address 1 on line 841, well now we are using the format Shape address instead and it is setup like an array with a starting memory location and all the bytes in the address are stored within the array.  So, as in Tutorial #6 when we needed to retrieve the HEX value $0C, now we will get the next number in the sequence since Y equals 0 we are going to retrieve the first shape/tile graphics byte:



So a shape address example is:



800   SHAPE1   DFB $00,$00,$40,$00,$40,$07,$40,$03,$40,$00,$44,$09,$4C,$1B,$5C,$3B,$4C,$19,$44,$08,$7E,$7F,$6F,$36,$7E,$1F,$7C,$0F,$00,$00



Earlier in the blog I showed examples of how a shape is created and how the bytes represent where each pixel will be displayed to create the specific shape such as a horse, a knight, a ship, etc.  With this Sub-subroutine we will be loading all the bytes that make up the specific tile graphic/shape into two temporary arrays.  We need two sets of arrays because each shape is two bytes wide and we will be drawing two bytes at a time. So as each set of bytes are loaded into the TEMP arrays, they will be drawn as two sets of bytes line by line on the screen in 32 lines.



Line 337 has a header titled LOADSHP1, which allows it to be called again from a separate statement to be used as a loop.  In this case the loop is used 32 times to store each of the two sets of bytes which are each 16 bytes high, making for a shape that is 2x2 or 32 lines deep.



338                                STA   TEMP,X



Line 338 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable TEMP,X, which in this example would equal HEX value $00, the first HEX in this particular shapes database index. 



800   SHAPE1   DFB $00,$00,$40,$00,$40,$07,$40,$03,$40,$00,$44,$09,$4C,$1B,$5C,$3B,$4C,$19,$44,$08,$7E,$7F,$6F,$36,$7E,$1F,$7C,$0F,$00,$00



339                                INY



Line 339 is used to “[IN]crement register [Y]” or take the value that has been stored in register Y and add 1 to it.



340                                          LDA   (LOW),Y



Line 340 is used to “[L]oa[D] the [A]ccumulator” or register A with the next value in the array LOW from array location 1, since it was just incremented.  So, as in Tutorial #6 when we needed to retrieve the HEX value $00, now we will get the next number in the sequence since Y equals 1 we are going to retrieve the second shape/tile graphics byte:



So the next shape address example is:



800   SHAPE1   DFB $00,$00,$40,$00,$40,$07,$40,$03,$40,$00,$44,$09,$4C,$1B,$5C,$3B,$4C,$19,$44,$08,$7E,$7F,$6F,$36,$7E,$1F,$7C,$0F,$00,$00



With this Sub-subroutine we will be loading all the bytes that make up the specific tile graphic/shape into two temporary arrays.  We need two sets of arrays because each shape is two bytes wide and we will be drawing two bytes at a time. So as each set of bytes are loaded into the TEMP arrays, they will be drawn as two sets of bytes line by line on the screen in 32 lines.



341                               STA   TEMP1,X



Line 341 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable TEMP1,X, which in this case equal HEX value $00.  



342                                INC   STEPPB



Line 342 is used to “[INC]rement” the variable STEPPB by 1 or take the value that has been stored variable STEPPB and add 1 to it.  STEPPB is used to increment each stage of the 32 lines for each shape.  So as each shape is stored with 32 lines of bytes, when the next loop starts again it will maintain an incremental of 32 and store the next shapes byte values for the next shapes of the column.



343                                INY



Line 343 is used to “[IN]crement register [Y]” or take the value that has been stored in register Y and add 1 to it.



344                                INX



Line 344 is used to “[IN]crement register [X]” or take the value that has been stored in register X and add 1 to it.



345                                CPY   #$20



Line 345 is used to “[C]om[P]are [Y]” what is in register Y to the value HEX $20 or the decimal value of 32.  Since the value is equal to, in this case, 32, then Y will continue to be compared to this value and if it doesn’t equal this value it will call LOADSHP1 again, increment X and Y again, and try to compare Y against value 32 again.  This happens until Y finally equal 32.  Once this is accomplished it will finish the LOADSHP1 subroutine loop and then return to the subroutine that called it.   Remember, 32 is equal to the number of lines that make up two stacked images for a 2x2 graphic tile.  Each shape has 16 lines and the two shapes together make up the 32 lines total.



346                                BLT   LOADSHP1



Line 346 is used to “[B]ranch on [L]ess [T]han”, which means that as long as the value in register Y is less than [<] 32 it will continue to call the subroutine with the header LOADSHP1.  Once the value of Y is greater than [>] 32 it will bypass line 346 and continue to line 347.



347                               LDA   MAPCOUNT



Line 347 is used to again “[L]oa[D] the [A]ccumulator” or register A with the value held in variable MAPCOUNT!  Since MAPCOUNT will have incremented up 32 times within the loop, this time you will be entering the value of MAPCOUNT into register A as it is finished the 32 line loop.



348                               CLC  



Line 348 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.



349                               ADC  #20



Line 349 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 MAPCOUNT 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.



350                                STA   MAPCOUNT



Line 350 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.



351                                INC   TCOUNT



Line 351 is used to “[INC]rement” the variable TCOUNT by 1 or take the value that has been stored variable TCOUNT and add 1 to it.  Variable TCOUNT or “Temporary Count” is used as a temporary 10 count loop cycle that gets reset after each 10 counts.



352                                LDA   TCOUNT



Line 352 is used to “[L]oa[D] the [A]ccumulator” or register A with the value equal to what has been stored in variable TCOUNT!  So, you are setting the value of A to equal the decimal value of TCOUNT, which in this case has just been increased by 1.



353                                CMP  #$0A



Once the value of TCOUNT is loaded into register A, Line 353 is used to “[C]o[MP]are” what is in register A to the HEX value #$0A or decimal value of 10!  The value in TCOUNT is the number of shapes/graphic tiles that will be drawn down each column on the screen.  So as TCOUNT increments it is used to help store the shapes that will be drawn on a vertical column totaling 10 separate shapes/graphic tiles.



354                                BLT   LOADSP1



Line 354 is used to “[B]ranch on [L]ess [T]han”, which means that as long as the value in register A is less than [<] 10 it will continue to call the subroutine with the header LOADSP1.  Once the value of A is greater than [>] 10 it will bypass line 354 and continue to line 355.  



355                                LDA   #$00



Line 355 is used to “[L]oa[D] the [A]ccumulator” with the HEX value of zero!  So you could think of it as [A] holding the value of [0].



356                                STA   STEPPB



Line 356 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 equals zero!  



357                                STA   TCOUNT



Line 357 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 equals zero!   By setting TCOUNT to zero it lets the variable TCOUNT to be reset and used again within another counter loop for the next 10 shapes.



358                                INC   TMAPCNT



Line 358 is used to “[INC]rement” the variable TPCNT by 1 or take the value that has been stored variable TPCNT and add 1 to it.  Variable TPCNT or “Temporary Point Count” is used as a temporary 20 count loop cycle that gets reset after each 20 counts.



359                                LDA   TMAPCNT



Line 359 is used to “[L]oa[D] the [A]ccumulator” or register A with the value equal to what has been stored in variable TMAPCNT!  So, you are setting the value of A to equal the decimal value of TMAPCNT, which in this case has just been increased by 1.



360                                STA   MAPCOUNT



Line 360 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.



361                                RTS



Line 361 is used to “[R]e[T]urn from [S]ubroutine”, which means that all the actions in the LOADMAP subroutine have been completed.   In this case, since LOADSHP was initiated from BEGIN when the program it will return to that subroutine.  On further call to this subroutine it will continue to be called from subroutine START1 instead.



So, when subroutine LOADSHP finishes you should have the following accomplished: 



Each time the subroutine LOADSHP is called it will store the 10 shapes/graphic tiles that make up a single vertical column of shapes on the display screen.  Remember that there are a total of 200 shapes that make up the section of viewed world map that is displayed on the screen.  So it first goes through the MAPSTORE array and pulls out each shape reference number then takes that number and stores each byte of information in the two arrays TEMP and TEMP1 through a loop that increments up to 32.  It does 32 times because there are 32 lines in each shape.  After it finishes storing the shapes it jumps the loop by 20, which is the next shape in the array MAPSTORE that would be displayed.  It has to jump by 20 because there are 20 shapes that are drawn across the screen so it would be 0 to 19, then 20 to 39, etc…  for each 20th shape is will store the next column shape in the sequence till it stores all 10 shapes/graphic tiles.  The main reason why it is done this way instead of drawing the horizontal shapes is because of the 256 limitation.  If I were to count up in a loop for the 20 shapes that go across the screen I would surpass the 256 limit and cause an error in the loop.



So now I have 10 shapes temporarily stored in two arrays and next I will start drawing them to the display screen.  Once the 10 shapes are drawn to the screen I can store over the values I just used for TEMP and TEMP1 arrays. 



This subroutine will get called 20 times to store all 200 shapes/graphic tiles for the section of world map that will be drawn on the display screen.

As always, please email any questions you might have.


Joe

Wednesday, December 7, 2011

TUTORIAL #12 – TRANSPORT MODES “Is used to switch between different transportation shapes by pressing a numerical key corresponding to that type of transportation mode”



TUTORIAL #12 – TRANSPORT MODES “Is used to switch between different transportation shapes by pressing a numerical key corresponding to that type of transportation mode”.



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



At this point you have transferred the value of CHAR into a specific shape type and loaded it into the MAPSTORE array.  This sets up the type of transportation mode shape that will be displayed on the screen when you press the [1 thru 6] numerical keys.



250  ********************************



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



251  *** TRANSPORT MODES



This is just a comment line to detailing the section covering all the transportation mode shapes subroutines.



252   HORSE2              LDA   #$0B          ; HORSE



Line 252 is called from BASIC when a player presses the #1 key on the keyboard.  This subroutine is used to “[L]oa[D] the [A]ccumulator” or register A with the value HEX $0B!  So, you are setting the value of A to equal the HEX value $0B, which in this case is the representing value of the character shape for the HORSE.  The ;HORSE is used as a description reference line similar to a comment to give detail about the specific code line.  Anything after the ; is ignored by the compiler.



Also, line 252 has a header titled HORSE2, which allows it to be called as a separate statement from the BASIC program as a subroutine.  In this case it is used immediately change the shape type and characteristics of the main character graphic tile in the middle of the screen.  When the player presses a specific numerical key this calls the subroutine and instantly changes the graphic tile image and the characteristics of how it moves and its collision detection.



This is the value used to represent the character shape of the HORSE.



253                                STA   CHAR



Line 253 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 equals 11!   By setting CHAR to 11 it establishes the variable CHAR with a new value that represents the HORSE and will stay this value until another numeric key is pressed to change the mode of transportation or the original character shape of the fighter is designated in the game.



254                                LDX   #$6E



Line 254 is used to “[L]oa[D] register [X]” or register X with the value equal to 110!  So, you are setting the value of X to equal the HEX value of $6E, which equals decimal value of 110.



255                                STA   MAPSTORE,X



Line 223 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in the array MAPSTORE at location X which in this example would be the value in CHAR or decimal 11, stored in array MAPSTORE at location X equal to 110, where 110 is represented by the graphic tile in the middle of the screen out of the 200 tiles.  Remember, tiles are counted 0 to 19 for the top horizontal screen line and then they go down one tile screen line and count 20 to 39, etc… till you get to tile 199!



256                                JSR    DRAW5



Line 256 tells the program to “[J]ump to [S]ub[R]outine” to the subroutine with the header DRAW5.   Subroutine DRAW5 is used to immediately update the shape value of the character tile to a HORSE and draw this graphic tile in the middle of the screen.



257                                RTS



Line 257 is used to “[R]e[T]urn from [S]ubroutine”, which means that after the Subroutine HORSE2 has updated the new shape and drawn it to the screen, it returns back to the BASIC program that called it originally.



258   SHIP2                  LDA   #$00



Line 258 is called from BASIC when a player presses the #2 key on the keyboard.  This subroutine is used to “[L]oa[D] the [A]ccumulator” or register A with the value HEX $00!  So, you are setting the value of A to equal the HEX value $00, which in this case is the representing value of the character shape for the SHIP. 



Also, line 258 has a header titled SHIP2, which allows it to be called as a separate statement from the BASIC program as a subroutine.  In this case it is used immediately change the shape type and characteristics of the main character graphic tile in the middle of the screen.  When the player presses a specific numerical key this calls the subroutine and instantly changes the graphic tile image and the characteristics of how it moves and its collision detection.



This is the value used to represent the character shape of the SHIP.



259                                STA   CHAR



Line 259 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 equals 0!   By setting CHAR to 0 it establishes the variable CHAR with a new value that represents the HORSE and will stay this value until another numeric key is pressed to change the mode of transportation or the original character shape of the fighter is designated in the game.



260                                LDX   #$6E



Line 260 is used to “[L]oa[D] register [X]” or register X with the value equal to 110!  So, you are setting the value of X to equal the HEX value of $6E, which equals decimal value of 110.



261                                STA   MAPSTORE,X



Line 261 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in the array MAPSTORE at location X which in this example would be the value in CHAR or decimal 0, stored in array MAPSTORE at location X equal to 110, where 110 is represented by the graphic tile in the middle of the screen out of the 200 tiles.  Remember, tiles are counted 0 to 19 for the top horizontal screen line and then they go down one tile screen line and count 20 to 39, etc… till you get to tile 199!



262                                JSR    DRAW5



Line 262 tells the program to “[J]ump to [S]ub[R]outine” to the subroutine with the header DRAW5.   Subroutine DRAW5 is used to immediately update the shape value of the character tile to a SHIP and draw this graphic tile in the middle of the screen.



263                                RTS



Line 263 is used to “[R]e[T]urn from [S]ubroutine”, which means that after the Subroutine SHIP2 has updated the new shape and drawn it to the screen, it returns back to the BASIC program that called it originally.



264   RAFT2                 LDA   #$01



Line 264 is called from BASIC when a player presses the #3 key on the keyboard.  This subroutine is used to “[L]oa[D] the [A]ccumulator” or register A with the value HEX $01!  So, you are setting the value of A to equal the HEX value $01, which in this case is the representing value of the character shape for the RAFT. 



Also, line 264 has a header titled RAFT2, which allows it to be called as a separate statement from the BASIC program as a subroutine.  In this case it is used immediately change the shape type and characteristics of the main character graphic tile in the middle of the screen.  When the player presses a specific numerical key this calls the subroutine and instantly changes the graphic tile image and the characteristics of how it moves and its collision detection.



This is the value used to represent the character shape of the RAFT.



265                                STA   CHAR



Line 265 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 equals 1!   By setting CHAR to 1 it establishes the variable CHAR with a new value that represents the RAFT and will stay this value until another numeric key is pressed to change the mode of transportation or the original character shape of the fighter is designated in the game.



266                                LDX   #$6E



Line 266 is used to “[L]oa[D] register [X]” or register X with the value equal to 110!  So, you are setting the value of X to equal the HEX value of $6E, which equals decimal value of 110.



267                                STA   MAPSTORE,X



Line 267 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in the array MAPSTORE at location X which in this example would be the value in CHAR or decimal 0, stored in array MAPSTORE at location X equal to 110, where 110 is represented by the graphic tile in the middle of the screen out of the 200 tiles.  Remember, tiles are counted 0 to 19 for the top horizontal screen line and then they go down one tile screen line and count 20 to 39, etc… till you get to tile 199!



268                                JSR    DRAW5



Line 268 tells the program to “[J]ump to [S]ub[R]outine” to the subroutine with the header DRAW5.   Subroutine DRAW5 is used to immediately update the shape value of the character tile to a RAFT and draw this graphic tile in the middle of the screen.



269                                RTS



Line 269 is used to “[R]e[T]urn from [S]ubroutine”, which means that after the Subroutine RAFT2 has updated the new shape and drawn it to the screen, it returns back to the BASIC program that called it originally.



270   CART2                 LDA   #$0A



Line 270 is called from BASIC when a player presses the #4 key on the keyboard.  This subroutine is used to “[L]oa[D] the [A]ccumulator” or register A with the value HEX $0A!  So, you are setting the value of A to equal the HEX value $0A, which in this case is the representing value of the character shape for the CART. 



Also, line 270 has a header titled CART2, which allows it to be called as a separate statement from the BASIC program as a subroutine.  In this case it is used immediately change the shape type and characteristics of the main character graphic tile in the middle of the screen.  When the player presses a specific numerical key this calls the subroutine and instantly changes the graphic tile image and the characteristics of how it moves and its collision detection.



This is the value used to represent the character shape of the CART.



271                                STA   CHAR



Line 271 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 equals 10!   By setting CHAR to 10 it establishes the variable CHAR with a new value that represents the CART and will stay this value until another numeric key is pressed to change the mode of transportation or the original character shape of the fighter is designated in the game.



272                                LDX   #$6E



Line 272 is used to “[L]oa[D] register [X]” or register X with the value equal to 110!  So, you are setting the value of X to equal the HEX value of $6E, which equals decimal value of 110.



273                                STA   MAPSTORE,X



Line 273 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in the array MAPSTORE at location X which in this example would be the value in CHAR or decimal 10, stored in array MAPSTORE at location X equal to 110, where 110 is represented by the graphic tile in the middle of the screen out of the 200 tiles.  Remember, tiles are counted 0 to 19 for the top horizontal screen line and then they go down one tile screen line and count 20 to 39, etc… till you get to tile 199!



274                                JSR    DRAW5



Line 274 tells the program to “[J]ump to [S]ub[R]outine” to the subroutine with the header DRAW5.   Subroutine DRAW5 is used to immediately update the shape value of the character tile to a SHIP and draw this graphic tile in the middle of the screen.



275                                RTS



Line 275 is used to “[R]e[T]urn from [S]ubroutine”, which means that after the Subroutine CART2 has updated the new shape and drawn it to the screen, it returns back to the BASIC program that called it originally.





276   LANDSPR2          LDA   #$0C



Line 276 is called from BASIC when a player presses the #5 key on the keyboard.  This subroutine is used to “[L]oa[D] the [A]ccumulator” or register A with the value HEX $0C!  So, you are setting the value of A to equal the HEX value $0C, which in this case is the representing value of the character shape for the LABDSPR. 



Also, line 276 has a header titled LANDSPR2, which allows it to be called as a separate statement from the BASIC program as a subroutine.  In this case it is used immediately change the shape type and characteristics of the main character graphic tile in the middle of the screen.  When the player presses a specific numerical key this calls the subroutine and instantly changes the graphic tile image and the characteristics of how it moves and its collision detection.



This is the value used to represent the character shape of the LANDSPR.



277                                STA   CHAR



Line 277 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 equals 12!   By setting CHAR to 12 it establishes the variable CHAR with a new value that represents the LANDSPR and will stay this value until another numeric key is pressed to change the mode of transportation or the original character shape of the fighter is designated in the game.



278                               LDX   #$6E



Line 278 is used to “[L]oa[D] register [X]” or register X with the value equal to 110!  So, you are setting the value of X to equal the HEX value of $6E, which equals decimal value of 110.



279                                STA   MAPSTORE,X



Line 279 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in the array MAPSTORE at location X which in this example would be the value in CHAR or decimal 12, stored in array MAPSTORE at location X equal to 110, where 110 is represented by the graphic tile in the middle of the screen out of the 200 tiles.  Remember, tiles are counted 0 to 19 for the top horizontal screen line and then they go down one tile screen line and count 20 to 39, etc… till you get to tile 199!



280                                JSR    DRAW5



Line 280 tells the program to “[J]ump to [S]ub[R]outine” to the subroutine with the header DRAW5.   Subroutine DRAW5 is used to immediately update the shape value of the character tile to a LANDSPR and draw this graphic tile in the middle of the screen.



281                                RTS



Line 281 is used to “[R]e[T]urn from [S]ubroutine”, which means that after the Subroutine LANDSPR2 has updated the new shape and drawn it to the screen, it returns back to the BASIC program that called it originally.



282   CHARC2              LDA   #$07



Line 282 is called from BASIC when a player presses the #6 key on the keyboard.  This subroutine is used to “[L]oa[D] the [A]ccumulator” or register A with the value HEX $07!  So, you are setting the value of A to equal the HEX value $07, which in this case is the representing value of the character shape for the main CHARaCter. 



Also, line 282 has a header titled CHARC2, which allows it to be called as a separate statement from the BASIC program as a subroutine.  In this case it is used immediately change the shape type and characteristics of the main character graphic tile in the middle of the screen.  When the player presses a specific numerical key this calls the subroutine and instantly changes the graphic tile image and the characteristics of how it moves and its collision detection.



This is the value used to represent the character shape of the main CHARaCter on the screen.



283                                STA   CHAR



Line 283 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 equals 7!   By setting CHAR to 7 it establishes the variable CHAR with a new value that represents the main CHARaCter and will stay this value until another numeric key is pressed to change the mode of transportation or the original character shape of the fighter is designated in the game.



284                                LDX   #$6E



Line 284 is used to “[L]oa[D] register [X]” or register X with the value equal to 110!  So, you are setting the value of X to equal the HEX value of $6E, which equals decimal value of 110.



285                                STA   MAPSTORE,X



Line 285 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in the array MAPSTORE at location X which in this example would be the value in CHAR or decimal 7, stored in array MAPSTORE at location X equal to 110, where 110 is represented by the graphic tile in the middle of the screen out of the 200 tiles.  Remember, tiles are counted 0 to 19 for the top horizontal screen line and then they go down one tile screen line and count 20 to 39, etc… till you get to tile 199!



286   DRAW5               LDA MAPSTORE,X



Line 286 is used to “[L]oa[D] the [A]ccumulator” or register A with the value from array MAPSTORE  location X, which mean as X is incremented so will each value within the array MAPSTORE increment.  Remember previously we stored the value in array MAPSTORE on the first go around. So in this example we are going to load each type of shape that was stored in MAPSTORE and place it in the accumulator, and as X is incremented so will the shape that goes into register A.



Line 286 has a header titled DRAW5, which allows it to be called again from a separate statement to be used as a DRAW loop.  In this case the DRAW loop is used to take the value from the array MAPSTORE,X and draw the graphic tile/shape over the existing character shape that is in the middle of the screen.



287                               ASL   A



Line 287 is used to “[A]ccumulator [S]hift [L]eft one bit” which takes the binary value in register A and shifts in one bit to the left.  So, if register A equals HEX 34 or decimal 52, then the binary value equals 00110100, which is in the accumulator.  Now you shift the binary value to the left by one and you get 01101000, which equals HEX 68 or decimal 104.



288                               TAX



Line 288 is used to “[T]ransfer [A]ccumulator to index X” which takes the value in register A and transfers it to register X.  So, if register A equals HEX 34 or decimal 52, then register X will now equal HEX 34 or decimal 52.



289                                LDA   SHPADR,X



Line 289 is used to “[L]oa[D] the [A]ccumulator” or register A with the value equal to that held in array SHPADR,X!  As mentioned above, the SHAPE1 address is stored in a memory location for example in HEX memory location $7200.  When you load A with the address from SHPADR,X you will get the 00 byte from the $7200 address and load it in register A.



290                                STA   LOW



Line 290 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable LOW, which in this case is equal to HEX value $00.   Again, LOW is a used to represents the low byte of the memory address location where MAPADR 1 starts.



291                                LDA   SHPADR+1,X



Line 291 is used to “[L]oa[D] the [A]ccumulator” or register A with the value equal to that held in array SHPADR+1,X!  As mentioned above, the SHAPE1 address is stored in a memory location for example $7200.  When you load A with the address from SHPADR+1,X you will get the 72 byte from the $7200 address and load it in register A.



292                                STA   HIGH



Line 292 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable HIGH, which in this case is equal to HEX value $72.   Again, HIGH is a used to represents the high byte of the memory address location where SHPADR 1 starts.



293                                LDX   #$50



Line 293 is used to “[L]oa[D] register [X]” or register X with the value equal to the decimal value of 80!  So, you are setting the value of X to equal the HEX value of $50, which equals decimal value of 80.  The value of 80 represents the mid-point of halfway point of the vertical draw on the screen since there are 160 lines horizontally drawn lines from top to bottom, the shape of the new transportation mode will start at line 80 and draw line by line done the total of 32 lines or the equivalent of [2] graphic tiles one stacked on top of the other.  Remember that each graphic tile/shape in Ultima 1 is made up of 4 shapes or 2x2 shapes.  Two shapes on top of two shapes make a single graphic tile in Ultima.  Since the drawing of the shape starts at line 80 this would indicate that the shape is going to be displayed in the middle of the screen.



294                                LDY   #$00



Line 294 is used to “[L]oa[D] register [Y]” or register Y with the value equal to one!  So, you are setting the value of Y to equal the HEX value of $00, which equals decimal value of 0.



295   CHRCT1               LDA   (LOW),Y



Line 295 is used to “[L]oa[D] the [A]ccumulator” or register A with the value in the array LOW from array location 0.  Remember when we used Map Address 1 on line 841, well now we are using the format Shape address instead and it is setup like an array with a starting memory location and all the bytes in the address are stored within the array.  So, as in Tutorial #6 when we needed to retrieve the HEX value $0C, now we will get the next number in the sequence since Y equals 0 we are going to retrieve the first shape/tile graphics byte:



So a shape address example is:



800   SHAPE1   DFB $00,$00,$40,$00,$40,$07,$40,$03,$40,$00,$44,$09,$4C,$1B,$5C,$3B,$4C,$19,$44,$08,$7E,$7F,$6F,$36,$7E,$1F,$7C,$0F,$00,$00



Earlier in the blog I showed examples of how a shape is created and how the bytes represent where each pixel will be displayed to create the specific shape such as a horse, a knight, a ship, etc.  With this Sub-subroutine we will be loading all the bytes that make up the specific tile graphic/shape into two temporary arrays.  We need two sets of arrays because each shape is two bytes wide and we will be drawing two bytes at a time. So as each set of bytes are loaded into the TEMP arrays, they will be drawn as two sets of bytes line by line on the screen in 32 lines.



Line 295 has a header titled CHRCT1, which allows it to be called again from a separate statement to be used as a loop.  In this case the loop is used 32 times to store each of the two sets of bytes which are each 16 bytes high, making for a shape that is 2x2 or 32 lines deep.



296                                STA   TEMP,X



Line 296 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable TEMP,X, which in this example would equal HEX value $00, the first HEX in this particular shapes database index. 



800   SHAPE1   DFB $00,$00,$40,$00,$40,$07,$40,$03,$40,$00,$44,$09,$4C,$1B,$5C,$3B,$4C,$19,$44,$08,$7E,$7F,$6F,$36,$7E,$1F,$7C,$0F,$00,$00



297                                INY



Line 297 is used to “[IN]crement register [Y]” or take the value that has been stored in register Y and add 1 to it.



298                                          LDA   (LOW),Y



Line 298 is used to “[L]oa[D] the [A]ccumulator” or register A with the next value in the array LOW from array location 1, since it was just incremented.  So, as in Tutorial #6 when we needed to retrieve the HEX value $00, now we will get the next number in the sequence since Y equals 1 we are going to retrieve the second shape/tile graphics byte:



So the next shape address example is:



800   SHAPE1   DFB $00,$00,$40,$00,$40,$07,$40,$03,$40,$00,$44,$09,$4C,$1B,$5C,$3B,$4C,$19,$44,$08,$7E,$7F,$6F,$36,$7E,$1F,$7C,$0F,$00,$00



With this Sub-subroutine we will be loading all the bytes that make up the specific tile graphic/shape into two temporary arrays.  We need two sets of arrays because each shape is two bytes wide and we will be drawing two bytes at a time. So as each set of bytes are loaded into the TEMP arrays, they will be drawn as two sets of bytes line by line on the screen in 32 lines.



299                                STA   TEMP1,X



Line 299 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable TEMP1,X, which in this case equal HEX value $00.  



300                                INY



Line 300 is used to “[IN]crement register [Y]” or take the value that has been stored in register Y and add 1 to it.



301                                INX



Line 301 is used to “[IN]crement register [X]” or take the value that has been stored in register X and add 1 to it.



302                                CPY   #$20



Line 302 is used to “[C]om[P]are [Y]” what is in register Y to the value HEX $20 or the decimal value of 32.  Since the value is equal to, in this case, 32, then Y will continue to be compared to this value and if it doesn’t equal this value it will call CHRCT1 again, increment X and Y again, and try to compare Y against value 32 again.  This happens until Y finally equal 32.  Once this is accomplished it will finish the CHRCT1 subroutine loop and then return to the subroutine that called it.   Remember, 32 is equal to the number of lines that make up two stacked images for a 2x2 graphic tile.  Each shape has 16 lines and the two shapes together make up the 32 lines total.



303                                BLT   CHRCT1



Line 303 is used to “[B]ranch on [L]ess [T]han”, which means that as long as the value in register Y is less than [<] 32 it will continue to call the subroutine with the header CHRCT1.  Once the value of Y is greater than [>] 32 it will bypass line 303 and continue to line 304.



304  ***********



This is a comment line to separate the PICK MODE subroutine from the actual DRAW8 subroutine.  After the transportation mode has been picked the new DRAW8 subroutine will be used to help draw the actual graphic tile/shape on the screen.



305                                LDA   #$00



Line 305 is used to “[L]oa[D] the [A]ccumulator” or register A with the value equal to HEX $00! 



306                                STA   STEPR1



Line 306 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 is equal to HEX value $00.  



307                                LDX   #$50



Line 307 is used to “[L]oa[D] register [X]” or register X with the value equal to HEX $50!  So, you are setting the value of X to equal the HEX value of $50, which equals decimal value of 80.   Remember, the value of 80 is equal to half the number of horizontal lines that make up the graphic screen.  So you are loading X with a value that will equal the starting point of the half way mark on the computer screen when you draw the graphic tile/shape to the center of the screen.



308   DRAW8               LDY  #$14



Line 308 is used to “[L]oa[D] register [Y]” or register Y with the value equal to HEX $14!  So, you are setting the value of Y to equal the HEX value of $14, which equals decimal value of 20.



Also, line 308 has a header titled DRAW8, which allows it to be called as a separate subroutine.  In this case it is used immediately to change the graphic tile/shape type and image of the main character graphic tile in the middle of the screen.  When the player presses a specific numerical key this calls a separate subroutine and instantly changes the graphic tile image in the middle of the screen and brings with it the new movement parameters and its collision detection.



309                                LDA   HI,X



Line 309 is used to “[L]oa[D] the [A]ccumulator” or register A with the value equal to that held in array HI,X! 



310                                STA   HIGH



Line 310 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable HIGH.   Again, HIGH is a used to represents the HIGH byte of the memory address location where SHPADR starts.



311                                LDA   LO,X



Line 311 is used to “[L]oa[D] the [A]ccumulator” or register A with the value equal to that held in array LO,X! 



312                                STA   LOW



Line 312 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable LOW.   Again, LOW is a used to represents the high byte of the memory address location where SHPADR starts.



313                                          LDA   TEMP,X



Line 313 is used to “[L]oa[D] the [A]ccumulator” or register A with the next value in the array TEMP from array location X.   So, in subroutine CHRCT1 when we loaded TEMP and TEMP1 with the shape values, now we are transferring those same values into ARRAY (LOW),Y to be used for the DRAW8 subroutine. This is for the first graphic tile/shape reference values that will be drawn to the screen.





314                                STA   (LOW),Y



Line 314 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in array (LOW),Y.   Again, this array will be used to help draw the new transportation mode shape from the TEMP arrays.



315                                INY



Line 315 is used to “[IN]crement register [Y]” or take the value that has been stored in register Y and add 1 to it.



316                                          LDA   TEMP1,X



Line 316 is used to “[L]oa[D] the [A]ccumulator” or register A with the next value in the array TEMP1 from array location X.  This is for the second graphic tile/shape reference values that will be drawn to the screen.



317                                STA   (LOW),Y



Line 317 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable (LOW),Y.



318                                INX



Line 318 is used to “[IN]crement register [X]” or take the value that has been stored in register X and add 1 to it.



319                                INC   STEPR1



Line 319 is used to “[INC]rement” the variable STEPR1 by 1 or take the value that has been stored variable STEPR1 and add 1 to it.



320                                LDA   STEPR1



Line 320 is used to “[L]oa[D] the [A]ccumulator” or register A with the value equal to what has been stored in variable STEPR1!  So, you are incrementing STEPR1 and then setting that value into register A, which in this case has just been increased by 1.



321                                CMP  #$10



Once the value of STEPR1 is loaded into register A, Line 321 is used to “[C]o[MP]are” what is in register A to the HEX value #$10 or decimal value of 16!  The value 16 is the number of horizontal lines which make up a type of shape/tile graphic for a line on the world map that is shown on the computer screen. 



322                                BLT   DRAW8



Line 322 is used to “[B]ranch on [L]ess [T]han”, which means that as long as the value in register A is less than [<] 16 it will continue to call the subroutine with the header DRAW8.  Once the value of A is greater than [>] 16 it will bypass line 322 and continue to line 323.  



323                                RTS



Line 323 is used to “[R]e[T]urn from [S]ubroutine”, which means that all the actions in this subroutine have been completed and is return to the subroutine that called it.



So, when this subroutine finishes you should have the following accomplished: 



The player should be able to hit a number key from 1 to 6 and instantly the main character image on the screen will change to a new mode of transportation shape.  Once this new graphic tile/shape is drawn to the screen it will have updated the movement requirements and the collision aspects of that type of graphic tile/shape.   Such as, if the player were to pick the #5 key then the LAND SPEEDER would show up on the middle of the screen and it would have the following movement characteristics; moves freely on ocean and land tiles but can’t move through trees and mountains!  You will also have updated the value for the variable CHAR, which represents the main character graphic tile/shape.

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

ultima_revisited@yahoo.com

Joe