Saturday, June 21, 2025

TUTORIAL #20 – SHPADR

 TUTORIAL #20 – SHPADR “Is used as a pointer for the SHAPE/TILE GRAPHICS used on the world map”. 


All the graphic-tiles/shapes in Ultima 1 are predefined within a database SHPADR.  These values consist of the type of shape used such as TREES, PLAINS, MOUNTAINS, OCEAN, etc…  They are structured and referenced exactly as the MAPADR data each shape on the map is defined by a value from 0 to 15.  This value is what represent a particular shape such as the fighter or the troll.

 

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

 

719  **********************************

 

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

 

720  * LOAD SHAPE ADDRESSES INTO SHPADR, LOW BYTE FIRST

 

This comment line tells the user what type of data will be referenced. 

 

721  SHPADR              DFB   >SHAPE1

 

Line 721 is used to “[D]e[F]ine [B]ype” of SHAPE1 data location from the LOW byte side.  Each SHAPE location is defined by a HIGH and LOW byte, which in this case is the > character representing the LOW byte location for the map addresses in MAP1.  An example of a memory region address from the HIGH and LOW byte reference could be HEX $8000 or 32768.  The HIGH side would be the 80 and the LOW side would be the 00 of the HEX value $8000.

 

Also, line 721 has a header titled SHPADR, which allows it to be called as a separate subroutine from the main subroutine.

 

722                                DFB   <SHAPE1

 

Line 722 is used to “[D]e[F]ine [B]ype” of MAP1 data location from the HIGH byte side.  Each MAP location is defined by a HIGH and LOW byte, which in this case is the < character representing the HIGH byte location for the map addresses in SHAPE1.  SHAPE1 will call to a database that will hold all the graphic tile types for a space on the horizontal line of the world map.  By using a HIGH and LOW byte reference the map address is location in a memory region based on the byte reference and can be called to reference the necessary data of that map line.

 

 

723                               DFB   >SHAPE2

 

THRU

 

752                                DFB   <SHAPE16

 

Line 723 THRU 752 are all reference the same way with “[D]e[F]ine [B]ype” of SHAPE# data location.  Each MAP location is defined by a HIGH and LOW byte will be referenced the exact same way and hold all the world map data information to help draw out the entire Ultima World map.

These are the following shape/graphic tile reference values and their equivalent shape.

 

SHAPE1            =          SHIP

 

SHAPE2            =          RAFT

 

SHAPE3            =          PLAINS

 

SHAPE4            =          TREES

 

SHAPE5            =          CASTLE

 

SHAPE6            =          TOWN

 

SHAPE7            =          SIGNPOST

 

SHAPE8            =          CHARACTER

 

SHAPE9            =          TROLL 

 

SHAPE10         =          DUNGEON

 

SHAPE11         =          CART  

 

SHAPE12         =          HORSE

 

SHAPE13         =          SPEEDER         

 

SHAPE14         =          SPACE SHIP

 

SHAPE15         =          OCEAN

 

SHAPE16         =          MOUNTAIN

 

Please email me any questions you might have,

 

Ultima_revisited@yahoo.com

 

Joe “kingspud”

 

 

TUTORIAL #19 – MAPADR

 TUTORIAL #19 – MAPADR “Is used as a pointer to the World Map data points for all the graphic tile reference values”. 

          































































All the graphic-tiles/shapes in Ultima 1 are predefined within a database.  These values consist of the type of shape used such as TREES, PLAINS, MOUNTAINS, OCEAN, etc…  plus the amount of each type of shape within the world map.  The world map is made up of 82 horizontal lines of graphic tiles; these tiles are drawn on the screen one at a time, line by line and byte by byte.  The data has to be read from the MAP data file statement and uncompressed to a form that states the type and amount and then draws just a portion of the world map that is 20 tiles wide by 10 tiles deep. 

 

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

 

553  **********************************

 

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

 

554  * LOAD MAP ADDRESS D

 

This comment line tells the user what type of data will be referenced. 

 

555  MAPADR             DFB   >MAP1

 

Line 555 is used to “[D]e[F]ine [B]ype” of MAP1 data location from the LOW byte side.  Each MAP location is defined by a HIGH and LOW byte, which in this case is the > character representing the LOW byte location for the map addresses in MAP1.  An example of a memory region address from the HIGH and LOW byte reference could be HEX $8000 or 32768.  The HIGH side would be the 80 and the LOW side would be the 00 of the HEX value $8000.

 

Also, line 555 has a header titled MAPADR, which allows it to be called as a separate subroutine from the main subroutine.

 

556                                DFB   <MAP1

 

Line 556 is used to “[D]e[F]ine [B]ype” of MAP1 data location from the HIGH byte side.  Each MAP location is defined by a HIGH and LOW byte, which in this case is the < character representing the HIGH byte location for the map addresses in MAP1.  MAP1 will call to a database that will hold all the graphic tile types and amounts for the first horizontal line of the world map.  By using a HIGH and LOW byte reference the map address is location in a memory region based on the byte reference and can be called to reference the necessary data of that map line.

 

 

557                                DFB   >MAP2

 

THRU

718                                DFB   <MAP82

 

Line 557 THRU 718 are all reference the same way with “[D]e[F]ine [B]ype” of MAP# data location.  Each MAP location is defined by a HIGH and LOW byte will be referenced the exact same way and hold all the world map data information to help draw out the entire Ultima World map.

 

 

 

 

 



TUTORIAL #18 – MVDOWN

 TUTORIAL #18 – MVDOWN “Is used to move the main character DOWN on a key press, plus follow all collision detection requirements per character shape used”. 


All the movement within Ultima 1 is based on “key press” functions because this game was created way before the mouse!  In the original Ultima 1 you have four keys representing the North, South, East, and West movement, which consisted of the following keys:  [ENTER],[ /], [ ; ] ,  [’ ].  Based on the represented shape on the screen ie. Fighter, horse, cart, etc… MVUP will also perform the required collision detections of the specific terrain on the screen based on the type of shape used.  Each shape has a different type of collision detection so for example; the horse can travel over plains, trees, but not ocean or mountains.  The ship and raft can travel over ocean tiles but not any other tiles.  The land speeder can travel over plains but not trees or mountains.  Etc…  These types of collision detections are performed within the MVDOWN subroutine.

 

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

 

510  ***** MOVE DOWN ******

 

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

 

 

511  *

 

This is just a comment line for use as a line spacer.

 

512  MVDOWN           LDA   CHAR

 

Line 512 is used to “[L]oa[D] register [A]” or register A with the value in the variable CHAR!  So, you are setting the register A to equal the value which was initial setup in the subroutine INITIAL.  As the transportation mode changes so does the CHAR value.  So when a numeric key from 1 thru 6 is pressed the value of CHAR get updated and modified.  

 

Also, line 512 has a header titled MVDOWN, which allows it to be called as a separate subroutine from the main BASIC PROGRAM; “ULTIMA”. 

 

513                                CMP  #$0B ;HORSE

 

Once the value of CHAR is loaded into register A, Line 513 is used to “[C]o[MP]are” what is in register A to the HEX value #$0B or decimal value of 11!  The value in CHAR is the number representing the shape/tile graphic for the main character shown on the computer screen.  Each character or graphic tile has a numeric value constant with the shape in the shape database.  So as CHAR changes it stores a new value of the main character shape/graphic tile such as fighter, horse, cart, ship, etc...  The [ ; ] symbol is a remark symbol that tell the compiler to ignore everything after the ;.  The HORSE reference tells anyone reading the code that #$0B is a value that represents the HORSE shape.

 

514                                BEQ DUMPY2

 

Line 514 is used to “[B]ranch on Result Zero Z[=]1”, which means that if the value in register A is compared to #$0B and it equals this value, in this case 11, then the program will branch or call jump to subroutine DUMPY2.   DUMPY2 is the collision detection part of the subroutine for the HORSE, which decides if it collides with specific terrain types and if the collision is legal.  Otherwise the program moves on to the next code line 515.

 

515                                CMP  #$00 ;SHIP

 

Line 515 is used to “[C]o[MP]are” what is in register A to the HEX value $00 or the decimal value of 0!  The value in CHAR will represent the shape/tile graphic for the SHIP in the middle of the screen.  The [ ; ] symbol is a remark symbol that tell the compiler to ignore everything after the ;.  The SHIP reference tells anyone reading the code that #$00 is a value that represents the SHIP shape.

 

516                                BEQ DUMPY

 

Line 516 is used to “[B]ranch on Result Zero Z=1”, which means that if the value in register A is compared to #$00 and it equals this value, in this case 0, then the program will branch or call jump to subroutine DUMPY.    DUMPY is the collision detection part of the subroutine for the SHIP, which decides if it collides with specific terrain types and if the collision is legal.  Otherwise the program moves on to the next code line 517.

 

517                                CMP  #$01 ;RAFT

 

Line 517 is used to “[C]o[MP]are” what is in register A to the HEX value $01 or the decimal value of 1!  The value in CHAR will represent the shape/tile graphic for the RAFT in the middle of the screen.  The [ ; ] symbol is a remark symbol that tell the compiler to ignore everything after the ;.  The RAFT reference tells anyone reading the code that #$01 is a value that represents the RAFT shape.

 

 

518                                BEQ DUMPY

 

Line 518 is used to “[B]ranch on Result Zero Z=1”, which means that if the value in register A is compared to #$01 and it equals this value, in this case 1, then the program will branch or call jump to subroutine RAFT1.   DUMPY is also the collision detection part of the subroutine for the RAFT, which decides if it collides with specific terrain types and if the collision is legal.  Otherwise the program moves on to the next code line 519.

 

519                               CMP  #$0A  ;CART

 

Line 519 is used to “[C]o[MP]are” what is in register A to the HEX value $0A or the decimal value of 10!  The value in CHAR will represent the shape/tile graphic for the CART in the middle of the screen.  The [ ; ] symbol is a remark symbol that tell the compiler to ignore everything after the ;.  The CART reference tells anyone reading the code that #$0A is a value that represents the CART shape.

 

 

520                                BEQ DUMPY2

 

Line 520 is used to “[B]ranch on Result Zero Z[=]1”, which means that if the value in register A is compared to #$0A and it equals this value, in this case 10, then the program will branch or call jump to subroutine DUMPY2.   DUMPY2 is the collision detection part of the subroutine for the CART, which decides if it collides with specific terrain types and if the collision is legal.  Otherwise the program moves on to the next code line 521.

 

521                                CMP  #$0C  ;SPEEDER

 

Line 521 is used to “[C]o[MP]are” what is in register A to the HEX value $0C or the decimal value of 12!  The value in CHAR will represent the shape/tile graphic for the LAND SPEEDER in the middle of the screen.  The [ ; ] symbol is a remark symbol that tell the compiler to ignore everything after the ;.  The LAND SPEEDER reference tells anyone reading the code that #$0C is a value that represents the SPEEDER shape.

 

 

522                                BEQ DUMPY1

 

Line 522 is used to “[B]ranch on Result Zero Z=1”, which means that if the value in register A is compared to #$0C and it equals this value, in this case 12, then the program will branch or call jump to subroutine LANDSPR.   DUMPY1 is the collision detection part of the subroutine for the LANDSPR, which decides if it collides with specific terrain types and if the collision is legal.  Otherwise the program moves on to the next code line 523.

 

 

523                                CMP  #$07  ;PLAYER

 

Line 523 is used to “[C]o[MP]are” what is in register A to the HEX value $07 or the decimal value of 7!  The value in CHAR will represent the shape/tile graphic for the main FIGHTER character in the middle of the screen.  The [ ; ] symbol is a remark symbol that tell the compiler to ignore everything after the ;.  The PLAYER reference tells anyone reading the code that #$07 is a value that represents the PLAYER shape.

 

 

524                                BEQ DUMPY2

 

Line 524 is used to “[B]ranch on Result Zero Z[=]1”, which means that if the value in register A is compared to #$07 and it equals this value, in this case 7, then the program will branch or call jump to subroutine DUMPY2.   DUMPY2 is also the collision detection part of the subroutine for the PLAYER, which decides if it collides with specific terrain types and if the collision is legal.  Otherwise the program moves on to the next code line 525.

 

525                                RTS

 

Line 525 is used to “[R]e[T]urn from [S]ubroutine”, which means that after the SUB-subroutine of each character tile shape reference is called and updated, it returns back and then subroutine MVDOWN will be complete and return to the original line statement that called it. 

 

526  DUMPY                 LDX  #$82

 

Line 526 is used to “[L]oa[D] register [X]” or register X with the value equal to 130!  So, you are setting the value of X to equal the HEX value of $82, which equals decimal value of 130.  NOTE: $82 is equal to the value of the square to the bottom of the main character on the screen.  So when you see $82 it is talking about one of four squares surrounding the main character on the screen.  Each of the movement subroutines does this check to the corresponding square next to the character tile on the screen.

 

Also, line 526 has a header titled DUMPY, which allows it to be called as a separate SUB-subroutine from the MVDOWN subroutine”.  The DUMPY subroutine is used to check the collision detection parameters for the SHIP and the RAFT, which only allows OCEAN movement.

 

527                               LDA   MAPSTORE,X

 

Line 527 is used to “[L]oa[D] register [A]” or register A with the value in the array MAPSTORE,X and stored it in register A.

 

528                                CMP  #$0E

 

Line 528 is used to “[C]o[MP]are” what is in register A to the HEX value $0E or the decimal value of 14!  This value is what is equal to the OCEAN graphic tile/shape and if the comparison matches then it is a valid movement and continues with the redraw of the screen.  If the comparison does not match then it is a collision and the subroutine returns back to the main subroutine.

 

529                                BEQ DUMPY3

 

Line 529 is used to “[B]ranch on Result Zero Z[=]1”, which means that if the value in register A is compared to #$0E and it equals this value, in this case 14, then the program will branch or call jump to subroutine DUMPY3.   DUMPY3 is the actual part of the MVDOWN subroutine that when called has passed all the collision detection and draws the new screen display of the new location for the character shape on the world map.  Otherwise the program moves on to the next code line 530.

 

530                                RTS

 

Line 530 is used to “[R]e[T]urn from [S]ubroutine”, which means that the collision detection did not pass for the movement direction so the subroutine is returned and awaits another movement command.

 

531  DUMPY1              LDX  #$82

 

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

 

Also, line 531 has a header titled DUMPY1, which allows it to be called as a separate SUB-subroutine from the MVDOWN subroutine”.  The DUMPY subroutine is used to check the collision detection parameters for the LAND SPEEDER, which allows for OCEAN and PLAIN movement but not through the TREES or MOUNTAINS.

 

532                                LDA   MAPSTORE,X

 

Line 532 is used to “[L]oa[D] register [A]” or register A with the value in the array MAPSTORE,X and stored it in register A.

 

533                                CMP  #$0F

 

Line 533 is used to “[C]o[MP]are” what is in register A to the HEX value $0F or the decimal value of 15!  The value of 15 is equal to the MOUNTAIN graphic tile and this is a collision check to see if the move will cause the character to move on top of the MOUNTAIN shape on the world map.

 

534                                BEQ DNCNT

 

Line 534 is used to “[B]ranch on Result Zero Z[=]1”, which means that if the value in register A is compared to #$0F and it equals this value, in this case 15, then the program will branch or call jump to subroutine DNCNT.   DNCNT is the direct call to the return statement, which says there was a collision and the subroutine is returning back to the main subroutine. 

 

535                                CMP  #$03

 

Line 535 is used to “[C]o[MP]are” what is in register A to the HEX value $03 or the decimal value of 3!  The value 3 is equal to the graphic tile/shape of the TREE.

 

536                                BEQ DNCNT

 

Line 536 is used to “[B]ranch on Result Zero Z[=]1”, which means that if the value in register A is compared to #$03 and it equals this value, in this case 3, then the program will branch or call jump to subroutine DNCNT.   DNCNT is the direct call to the return statement, which says there was a collision and the subroutine is returning back to the main subroutine. 

 

537                                JMP DUMPY3

 

Line 537 tells the program to “[J]u[MP]” to the subroutine DUMPY3.    DUMPY3 is the actual part of the MVDOWN subroutine that when called has passed all the collision detection and draws the new screen display of the new location for the character shape on the world map.

 

538  DUMPY2              LDX  #$82

 

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

 

539                                LDA   MAPSTORE,X

 

Line 539 is used to “[L]oa[D] register [A]” or register A with the value in the array MAPSTORE,X and stored it in register A.

 

540                                CMP  #$0E

 

Line 540 is used to “[C]o[MP]are” what is in register A to the HEX value $0E or the decimal value of 14!  The value 14 is equal to the graphic tile/shape of the OCEAN.

 

541                               BEQ DNCNT

 

Line 541 is used to “[B]ranch on Result Zero Z[=]1”, which means that if the value in register A is compared to #$14 and it equals this value, in this case 14, then the program will branch or call jump to subroutine DNCNT.   DNCNT is the direct call to the return statement, which says there was a collision and the subroutine is returning back to the main subroutine. 

 

542                                CMP  #$0F

 

Line 542 is used to “[C]o[MP]are” what is in register A to the HEX value $0F or the decimal value of 15!  The value 15 is equal to the graphic tile/shape of the MOUNTAIN.

 

543                                BEQ DNCNT

 

Line 543 is used to “[B]ranch on Result Zero Z[=]1”, which means that if the value in register A is compared to #$15 and it equals this value, in this case 15, then the program will branch or call jump to subroutine DNCNT.   DNCNT is the direct call to the return statement, which says there was a collision and the subroutine is returning back to the main subroutine. 

 

544  DUMPY3              JSR    CLRSET

 

Line 544 tells the program to “[J]ump to the [S]ub[R]outine” with the header CLRSET.   The subroutine CLRSET takes the specific variables used within the DRAW subroutine and clears them to zero when the screen is redrawn for the character movement.

 

Line 544 also has a header name DUMPY3 so it can also be referenced and can be called to run within the MVDOWN subroutine.  Sub-subroutine DUMPY3 is used to update the variables that define the new column value.  Since this is the move DOWN subroutine, we are only worried about the row and not the column values.   The column variable is for LEFT and RIGHT movement.

 

545                               INC   ROW

 

Line 545 is used to “[INC]rement” whatever value is in ROW and add 1 to it!

 

546                                LDA   ROW

 

Line 546 is used to “[L]oa[D] register [A]” or register A with the value obtained from the variable ROW. 

 

547                                STA   ROWNO

 

Line 547 is used to “[ST]ore the [A]ccumulator” which has the value obtained from ROW.  ROWNO will now be used as a temporary ROW variable that can be modified without disturbing the original ROW value.

 

548                                LDA   COLUMN

 

Line 548 is used to “[L]oa[D] the [A]ccumulator” or register A with the value from COLUMN.

 

549                                STA   COLUMN1

 

Line 549 is used to “[ST]ore the [A]ccumulator” which has the value obtained from COLUMN.  COLUMN1 will now be used as a temporary COLUMN variable that can be modified without disturbing the original COLUMN value.

 

 

550                                JSR    START8

 

Line 550 tells the program to “[J]ump to the [S]ub[R]outine” with the header START8.   The subroutine START8 is where the process of redrawing the screen takes place after the movement process has occurred.

 

551                                INC   $FC

 

Line 551 is used to “[INC]rement” the value held within memory location $FC and add 1 to it! 

 

552  DNCNT                  RTS

 

Line 552 is used to “[R]e[T]urn from [S]ubroutine”, which means that after the SUB-subroutine of each character tile shape reference is called and updated, it returns back to here and then subroutine MVDOWN will be complete and return to the original line statement that called it. 

 

Also, line 552 has a header titled DNCNT, which allows it to be called as a separate sub-subroutine from the MVDOWN subroutine.

 

After the MVDOWN subroutine completes you should have accomplished the following:

 

Depending on what type of shape/graphic tile you had as your main character shape, you will have pressed the enter key and wanted to move your character DOWN one space on the world map.  To be able to do this the subroutine will check what type of character shape is being used, then check to see if the terrain you are about to move into is non-collision type terrain.  The subroutine check the value of the terrain shape against the legal movement values and if it is ok it continue on to the Sub-subroutine DUMPY3 that modifies the variable and returns out of the subroutine getting ready to draw the new world map screen display.  If there is a collision detected against a terrain type that is not legal, then the subroutine just returns out of the main subroutine and waits for a new movement key press.

 

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

 

Ultima_revisited@yahoo.com

 

Joe “kingspud”

 

TUTORIAL #17 – MVUP

 TUTORIAL #17 – MVUP “Is used to move the main character UP on a key press, plus follow all collision detection requirements per character shape used”. 

All the movement within Ultima 1 is based on “key press” functions because this game was created way before the mouse!  In the original Ultima 1 you have four keys representing the North, South, East, and West movement, which consisted of the following keys:  [ENTER],[ /], [ ; ] ,  [’ ].  Based on the represented shape on the screen ie. Fighter, horse, cart, etc… MVUP will also perform the required collision detections of the specific terrain on the screen based on the type of shape used.  Each shape has a different type of collision detection so for example; the horse can travel over plains, trees, but not ocean or mountains.  The ship and raft can travel over ocean tiles but not any other tiles.  The land speeder can travel over plains but not trees or mountains.  Etc…  These types of collision detections are performed within the MVUP subroutine.

 

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

 

467  ***** MOVE UP ******

 

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

 

 

468  *

 

This is just a comment line for use as a line spacer.

 

469  MVUP                  LDA   CHAR

 

Line 469 is used to “[L]oa[D] register [A]” or register A with the value in the variable CHAR!  So, you are setting the register A to equal the value which was initial setup in the subroutine INITIAL.  As the transportation mode changes so does the CHAR value.  So when a numeric key from 1 thru 6 is pressed the value of CHAR get updated and modified.  

 

Also, line 469 has a header titled MVUP, which allows it to be called as a separate subroutine from the main BASIC PROGRAM; “ULTIMA”. 

 

470                                CMP  #$0B ;HORSE

 

Once the value of CHAR is loaded into register A, Line 470 is used to “[C]o[MP]are” what is in register A to the HEX value #$0B or decimal value of 11!  The value in CHAR is the number representing the shape/tile graphic for the main character shown on the computer screen.  Each character or graphic tile has a numeric value constant with the shape in the shape database.  So as CHAR changes it stores a new value of the main character shape/graphic tile such as fighter, horse, cart, ship, etc...  The [ ; ] symbol is a remark symbol that tell the compiler to ignore everything after the ;.  The HORSE reference tells anyone reading the code that #$0B is a value that represents the HORSE shape.

 

471                                BEQ CUMPY2

 

Line 471 is used to “[B]ranch on Result Zero Z[=]1”, which means that if the value in register A is compared to #$0B and it equals this value, in this case 11, then the program will branch or call jump to subroutine CUMPY2.   CUMPY2 is the collision detection part of the subroutine for the HORSE, which decides if it collides with specific terrain types and if the collision is legal.  Otherwise the program moves on to the next code line 472.

 

472                                CMP  #$00 ;SHIP

 

Line 472 is used to “[C]o[MP]are” what is in register A to the HEX value $00 or the decimal value of 0!  The value in CHAR will represent the shape/tile graphic for the SHIP in the middle of the screen.  The [ ; ] symbol is a remark symbol that tell the compiler to ignore everything after the ;.  The SHIP reference tells anyone reading the code that #$00 is a value that represents the SHIP shape.

 

473                                BEQ CUMPY

 

Line 473 is used to “[B]ranch on Result Zero Z=1”, which means that if the value in register A is compared to #$00 and it equals this value, in this case 0, then the program will branch or call jump to subroutine CUMPY.    CUMPY is the collision detection part of the subroutine for the SHIP, which decides if it collides with specific terrain types and if the collision is legal.  Otherwise the program moves on to the next code line 474.

 

474                                CMP  #$01 ;RAFT

 

Line 474 is used to “[C]o[MP]are” what is in register A to the HEX value $01 or the decimal value of 1!  The value in CHAR will represent the shape/tile graphic for the RAFT in the middle of the screen.  The [ ; ] symbol is a remark symbol that tell the compiler to ignore everything after the ;.  The RAFT reference tells anyone reading the code that #$01 is a value that represents the RAFT shape.

 

 

475                                BEQ CUMPY

 

Line 475 is used to “[B]ranch on Result Zero Z=1”, which means that if the value in register A is compared to #$01 and it equals this value, in this case 1, then the program will branch or call jump to subroutine RAFT1.   CUMPY is also the collision detection part of the subroutine for the RAFT, which decides if it collides with specific terrain types and if the collision is legal.  Otherwise the program moves on to the next code line 476.

 

476                                CMP  #$0A  ;CART

 

Line 476 is used to “[C]o[MP]are” what is in register A to the HEX value $0A or the decimal value of 10!  The value in CHAR will represent the shape/tile graphic for the CART in the middle of the screen.  The [ ; ] symbol is a remark symbol that tell the compiler to ignore everything after the ;.  The CART reference tells anyone reading the code that #$0A is a value that represents the CART shape.

 

 

477                                BEQ CUMPY2

 

Line 477 is used to “[B]ranch on Result Zero Z[=]1”, which means that if the value in register A is compared to #$0A and it equals this value, in this case 10, then the program will branch or call jump to subroutine CUMPY2.   CUMPY2 is the collision detection part of the subroutine for the CART, which decides if it collides with specific terrain types and if the collision is legal.  Otherwise the program moves on to the next code line 478.

 

478                                CMP  #$0C  ;SPEEDER

 

Line 478 is used to “[C]o[MP]are” what is in register A to the HEX value $0C or the decimal value of 12!  The value in CHAR will represent the shape/tile graphic for the LAND SPEEDER in the middle of the screen.  The [ ; ] symbol is a remark symbol that tell the compiler to ignore everything after the ;.  The LAND SPEEDER reference tells anyone reading the code that #$0C is a value that represents the SPEEDER shape.

 

 

479                                BEQ CUMPY1

 

Line 479 is used to “[B]ranch on Result Zero Z=1”, which means that if the value in register A is compared to #$0C and it equals this value, in this case 12, then the program will branch or call jump to subroutine LANDSPR.   CUMPY1 is the collision detection part of the subroutine for the LANDSPR, which decides if it collides with specific terrain types and if the collision is legal.  Otherwise the program moves on to the next code line 480.

 

 

480                                CMP  #$07  ;PLAYER

 

Line 480 is used to “[C]o[MP]are” what is in register A to the HEX value $07 or the decimal value of 7!  The value in CHAR will represent the shape/tile graphic for the main FIGHTER character in the middle of the screen.  The [ ; ] symbol is a remark symbol that tell the compiler to ignore everything after the ;.  The PLAYER reference tells anyone reading the code that #$07 is a value that represents the PLAYER shape.

 

 

481                                BEQ CUMPY2

 

Line 481 is used to “[B]ranch on Result Zero Z[=]1”, which means that if the value in register A is compared to #$07 and it equals this value, in this case 7, then the program will branch or call jump to subroutine CUMPY2.   CUMPY2 is also the collision detection part of the subroutine for the PLAYER, which decides if it collides with specific terrain types and if the collision is legal.  Otherwise the program moves on to the next code line 482.

 

482                                RTS

 

Line 482 is used to “[R]e[T]urn from [S]ubroutine”, which means that after the SUB-subroutine of each character tile shape reference is called and updated, it returns back and then subroutine MVUP will be complete and return to the original line statement that called it. 

 

483  CUMPY                 LDX  #$5A

 

Line 483 is used to “[L]oa[D] register [X]” or register X with the value equal to 90!  So, you are setting the value of X to equal the HEX value of $5A, which equals decimal value of 90.  NOTE: $5A is equal to the value of the square to the left of the main character on the screen.  So when you see $5A it is talking about one of four squares surrounding the main character on the screen.  Each of the movement subroutines does this check to the corresponding square next to the character tile on the screen.

 

Also, line 483 has a header titled CUMPY, which allows it to be called as a separate SUB-subroutine from the MVUP subroutine”.  The CUMPY subroutine is used to check the collision detection parameters for the SHIP and the RAFT, which only allows OCEAN movement.

 

484                               LDA   MAPSTORE,X

 

Line 484 is used to “[L]oa[D] register [A]” or register A with the value in the array MAPSTORE,X and stored it in register A.

 

485                                CMP  #$0E

 

Line 485 is used to “[C]o[MP]are” what is in register A to the HEX value $0E or the decimal value of 14!  This value is what is equal to the OCEAN graphic tile/shape and if the comparison matches then it is a valid movement and continues with the redraw of the screen.  If the comparison does not match then it is a collision and the subroutine returns back to the main subroutine.

 

486                                BEQ CUMPY3

 

Line 486 is used to “[B]ranch on Result Zero Z[=]1”, which means that if the value in register A is compared to #$0E and it equals this value, in this case 14, then the program will branch or call jump to subroutine CUMPY3.   CUMPY3 is the actual part of the MVUP subroutine that when called has passed all the collision detection and draws the new screen display of the new location for the character shape on the world map.  Otherwise the program moves on to the next code line 487.

 

487                                RTS

 

Line 487 is used to “[R]e[T]urn from [S]ubroutine”, which means that the collision detection did not pass for the movement direction so the subroutine is returned and awaits another movement command.

 

488  CUMPY1               LDX  #$5A

 

Line 488 is used to “[L]oa[D] register [X]” or register X with the value equal to 90!  So, you are setting the value of X to equal the HEX value of $5A, which equals decimal value of 90.

 

Also, line 488 has a header titled CUMPY1, which allows it to be called as a separate SUB-subroutine from the MVUP subroutine”.  The CUMPY subroutine is used to check the collision detection parameters for the LAND SPEEDER, which allows for OCEAN and PLAIN movement but not through the TREES or MOUNTAINS.

 

489                                LDA   MAPSTORE,X

 

Line 489 is used to “[L]oa[D] register [A]” or register A with the value in the array MAPSTORE,X and stored it in register A.

 

490                                CMP  #$0F

 

Line 490 is used to “[C]o[MP]are” what is in register A to the HEX value $0F or the decimal value of 15!  The value of 15 is equal to the MOUNTAIN graphic tile and this is a collision check to see if the move will cause the character to move on top of the MOUNTAIN shape on the world map.

 

491                                BEQ UPCNT

 

Line 491 is used to “[B]ranch on Result Zero Z[=]1”, which means that if the value in register A is compared to #$0F and it equals this value, in this case 15, then the program will branch or call jump to subroutine UPCNT.   UPCNT is the direct call to the return statement, which says there was a collision and the subroutine is returning back to the main subroutine. 

 

492                                CMP  #$03

 

Line 492 is used to “[C]o[MP]are” what is in register A to the HEX value $03 or the decimal value of 3!  The value 3 is equal to the graphic tile/shape of the TREE.

 

493                                BEQ UPCNT

 

Line 493 is used to “[B]ranch on Result Zero Z[=]1”, which means that if the value in register A is compared to #$03 and it equals this value, in this case 3, then the program will branch or call jump to subroutine UPCNT.   UPCNT is the direct call to the return statement, which says there was a collision and the subroutine is returning back to the main subroutine. 

 

494                                JMP CUMPY3

 

Line 494 tells the program to “[J]u[MP]” to the subroutine CUMPY3.    CUMPY3 is the actual part of the MVUP subroutine that when called has passed all the collision detection and draws the new screen display of the new location for the character shape on the world map.

 

495  CUMPY2               LDX  #$5A

 

Line 495 is used to “[L]oa[D] register [X]” or register X with the value equal to 90!  So, you are setting the value of X to equal the HEX value of $5A, which equals decimal value of 90.

 

496                                LDA   MAPSTORE,X

 

Line 496 is used to “[L]oa[D] register [A]” or register A with the value in the array MAPSTORE,X and stored it in register A.

 

497                                CMP  #$0E

 

Line 497 is used to “[C]o[MP]are” what is in register A to the HEX value $0E or the decimal value of 14!  The value 14 is equal to the graphic tile/shape of the OCEAN.

 

498                               BEQ UPCNT

 

Line 498 is used to “[B]ranch on Result Zero Z[=]1”, which means that if the value in register A is compared to #$14 and it equals this value, in this case 14, then the program will branch or call jump to subroutine UPCNT.   UPCNT is the direct call to the return statement, which says there was a collision and the subroutine is returning back to the main subroutine. 

 

499                                CMP  #$0F

 

Line 499 is used to “[C]o[MP]are” what is in register A to the HEX value $0F or the decimal value of 15!  The value 15 is equal to the graphic tile/shape of the MOUNTAIN.

 

500                                BEQ UPCNT

 

Line 500 is used to “[B]ranch on Result Zero Z[=]1”, which means that if the value in register A is compared to #$15 and it equals this value, in this case 15, then the program will branch or call jump to subroutine UPCNT.   UPCNT is the direct call to the return statement, which says there was a collision and the subroutine is returning back to the main subroutine. 

 

501  CUMPY3              JSR    CLRSET

 

Line 501 tells the program to “[J]ump to the [S]ub[R]outine” with the header CLRSET.   The subroutine CLRSET takes the specific variables used within the DRAW subroutine and clears them to zero when the screen is redrawn for the character movement.

 

Line 501 also has a header name CUMPY3 so it can also be referenced and can be called to run within the MVUP subroutine.  Sub-subroutine CUMPY3 is used to update the variables that define the new column value.  Since this is the move UP subroutine, we are only worried about the row and not the column values.   The column variable is for LEFT and RIGHT movement.

 

502                                DEC   ROW

 

Line 502 is used to “[DEC]rement” whatever value is in ROW and subtract 1 from it!

 

503                                LDA   ROW

 

Line 503 is used to “[L]oa[D] register [A]” or register A with the value obtained from the variable ROW. 

 

504                                STA   ROWNO

 

Line 504 is used to “[ST]ore the [A]ccumulator” which has the value obtained from ROW.  ROWNO will now be used as a temporary ROW variable that can be modified without disturbing the original ROW value.

 

505                                LDA   COLUMN

 

Line 505 is used to “[L]oa[D] the [A]ccumulator” or register A with the value from COLUMN.

 

506                                STA   COLUMN1

 

Line 506 is used to “[ST]ore the [A]ccumulator” which has the value obtained from COLUMN.  COLUMN1 will now be used as a temporary COLUMN variable that can be modified without disturbing the original COLUMN value.

 

 

507                                JSR    START8

 

Line 507 tells the program to “[J]ump to the [S]ub[R]outine” with the header START8.   The subroutine START8 is where the process of redrawing the screen takes place after the movement process has occurred.

 

508                                DEC   $FC

 

Line 508 is used to “[DEC]rement” the value held within memory location $FC and subtract 1 from it! 

 

509  UPCNT                  RTS

 

Line 509 is used to “[R]e[T]urn from [S]ubroutine”, which means that after the SUB-subroutine of each character tile shape reference is called and updated, it returns back to here and then subroutine MVUP will be complete and return to the original line statement that called it. 

 

Also, line 509 has a header titled UPCNT, which allows it to be called as a separate sub-subroutine from the MVUP subroutine.

 

After the MVUP subroutine completes you should have accomplished the following:

 

Depending on what type of shape/graphic tile you had as your main character shape, you will have pressed the enter key and wanted to move your character UP one space on the world map.  To be able to do this the subroutine will check what type of character shape is being used, then check to see if the terrain you are about to move into is non-collision type terrain.  The subroutine check the value of the terrain shape against the legal movement values and if it is ok it continue on to the Sub-subroutine CUMPY3 that modifies the variable and returns out of the subroutine getting ready to draw the new world map screen display.  If there is a collision detected against a terrain type that is not legal, then the subroutine just returns out of the main subroutine and waits for a new movement key press.

 

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

 

Ultima_revisited@yahoo.com

 

Joe “kingspud”