Monday, November 28, 2011

TUTORIAL #6 - PREMAP "Define Defines the initial value for the number of address references within the map address line”



TUTORIAL #6 – PREMAP “Defines the initial value for the number of address references within the map address line”  This mean that for each world map horizontal line there are a number of shapes and the type of shape involved that are defined within a database map address and there is an initial number that tell the system just how many of these references there are.



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



The subroutine PREMAP is used to retrieve the number, which represent the number of data address values, within each map address database.  In the map address section of the program there are values that represent the type and number of shapes/graphic tiles that will be displayed on the world map.  As I mentioned before, I had to create a compression process for the map addresses to help save memory because there are so many bytes representing each shape/graphic tile on the map, I would have run out of memory trying to use one memory cell for each graphic tile.  So, to save space I used a method “Thanks to help from BETH!” that would compress the number of graphic tile that represent each row on the world map.  An example would be; if you started from the left side on one row of the world map and started counting shapes you might have a row that goes as follows:  [3] ocean tiles, [4] land tiles, [1] mountain tile, [1] dungeon entrance tile, [1] mountain tile, [5] tree tiles, etc…   Well this is done for each horizontal line on the world map and all the tiles and shapes are predefined within the map address database.  This is why the ULTIMA 1 world map is always the same and you don’t see a random world map creator because all the shapes/tile graphics are predefined in a database.



 One example of a map address line is shown below:



841         MAP1                    DFB        $0C,$FE,$FE,$FE,$FE,$FE,$FE,$FE,$FE,$FE,$FE,$FE,$AE



To break down the map address compression process in line 841 above think of line 841 as being one of many map address lines that contain all the information regarding the world map shapes/tile graphics.  The first HEX value:  $0C = 12, which is the number of map addresses within the map address line.  Count the number of $FE and the last $AE and you will come up with the number 12!  Next, the HEX value $FE represents a HIGH byte and a LOW byte for the number of that type of shape and the shape type that will be used.  The HIGH byte is equal to F, which in HEX is equal to 15, represents the total number of shapes that will be displayed.  The LOW byte is equal to E, which in HEX is equal to 14, this represents the OCEAN tile!   So this tells you that you have 15 OCEAN tiles for the very first shapes on world map horizontal line #1. 

 So to further break down the map address #1 you have 12 total HEX values:  which equal 15 [OCEAN’s], 15 [OCEAN’s], 15 [OCEAN’s], 15 [OCEAN’s], 15 [OCEAN’s], 15 [OCEAN’s], 15 [OCEAN’s], 15 [OCEAN’s], 15 [OCEAN’s], 15 [OCEAN’s], 15 [OCEAN’s], and finally 10 [OCEAN’s]!  All of these shapes map up the entire Horizontal MAP line #1 of the world map 1 & 2.  This gets repeated over and over through each horizontal map line.





121  ********************************



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



122   PREMAP             LDA   ROWNO



Line 122 is used to “[L]oa[D] the [A]ccumulator” or register A with the value equal to the value held in ROWNO!  So, you are setting the value of A to equal the predefined value of ROWNO, which is defined within the INITIAL subroutine.  Also, line 122 has a header titled PREMAP, which allows it to be called from a separate statement as a subroutine.  In this case it is used to obtain the HEX value that represents the number and type of shapes within a Map Address line.



123                               ASL   A



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



124                               TAX



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



125                                LDA   MAPADR,X



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



126                                STA   LOW



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



127                                LDA   MAPADR+1,X



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



128                                STA   HIGH



Line 128 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 MAPADR 1 starts.



129                                LDY   #$00



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



130                                LDA   (LOW),Y



Line 130 is used to “[L]oa[D] the [A]ccumulator” or register A into the array LOW in array location 0.  Remember that Map Address 1 on line 841 is setup like an array with a starting memory location and all the bytes in the address are stored within the array. So, for the map address line below:



841         MAP1                    DFB        $0C,$FE,$FE,$FE,$FE,$FE,$FE,$FE,$FE,$FE,$FE,$FE,$AE



Think of the line above as translated into a memory location starting a memory address HEX $6800:



6800: 0C  FE  FE  FE  FE  FE  FE  FE  FE  FE  FE  FE  AE



So when you want to obtain a specific HEX value from a defined memory array location you would count through the address location starting a zero and count up to the address you want.



Let’s say that MAP1 is stored in HEX location $6800 and the rest of the byte addresses are stored in each array address counting from 0 to 11.  So you have the starting address $6800 and HEX $0C would be in array address zero, HEX $FE would be in address array one, etc…  What this gives us is in line 130, the accumulator or register A is stored with the HEX address $0C because (LOW),Y address has the value HEX $0C within it.  If Y was equal to 5 then register A would store the value HEX $FE, which if you counted from left to right starting with zero you would get [0] $0C, [1] $FE, [2] $FE, [3] $FE, [4] $FE, [5] $FE! 





131                                STA   PREPMAP



Line 131 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable PREPMAP, which in this case equal HEX value $0C or decimal value 12.  



132                                RTS



Line 132 is used to “[R]e[T]urn from [S]ubroutine”, which means that all the variables in the CLRSET subroutine have been RESET and initialized with ZERO values.   In this case, since PREMAP was initiated from BEGIN when the program starts and will continue to be called from subroutine START8 after.

So, when subroutine PREMAP finishes you should have the following value stored:

PREPMAP = $0C  or decimal 12

This value is after the program starts but will change each time subroutine PREMAP is called and the next map address line is referenced!

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

ultima_revisited@yahoo.com

Joe

No comments:

Post a Comment