Monday, November 28, 2011

TUTORIAL #8 – FRNTBYT “Is used to strip out the HIGH and LOW byte of each map address reference number”



TUTORIAL #8 – FRNTBYT “Is used to strip out the HIGH and LOW byte of each map address reference number”.  You might say it is the uncompressing process for the compressed map address database.



This mean, for each horizontal world map line reference number which was stored within the previous MAPROW array, the subroutine will be stripped down each HEX number into two separate bytes.   The HIGH byte will represent the number of tiles within the reference number and the LOW byte will represent the type of shape/graphic tile used on the world map.  So for example:  if one of the reference HEX numbers is equal to HEX $FE then the HIGH byte would be F, which is equal to 15 shapes.  The LOW byte would be E, which is equal to the 14th shape/tile graphic on the shape database index.



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



150  ********************************



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



151   FRNTBYT            LDX   #$00



Line 151 is used to “[L]oa[D] register [X]” with the value equal to zero!  So, you are setting X to equal the HEX value of $00, which equals decimal value of 0.  Also, line 151 has a header titled FRNTBYT, which allows it to be called from a separate statement as a subroutine.  In this case it is used to strip out the HIGH and LOW byte of each HEX value that represents the number and type of shapes within a Map Address line.



152                                LDY   #$00



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



153   FRNT1                 LDA   MAPROW,X



Line 153 is used to “[L]oa[D] the [A]ccumulator” or register A with the value from array MAPROW location X, which mean as X is incremented then so will the array MAPROW.  Remember previously we stored the value of HEX $FE in MAPROW,0 on the first go around. So is this example we are storing the HEX value of $FE or binary address 11111110 in register A.

Line 153 has a header titled FRNT1, which allows it to be called again from a separate statement to be used as a loop.  In this case the loop is used to obtain each progressive HEX reference number from array MAPROW,X.  You will see X incremented so the MAPROW array can be used to store each progressive reference value into the accumulator.  This will step through and store each of the HEX $FE values until it gets to the last HEX $AE value into register A.  Every time this subroutine is called it is used to process each horizontal world map line.



154                               LSR   A



Line 154 is used to “[S]hift [R]ight one bit” which takes the binary value in register A and shifts in one bit to the right.  So, for this example, if register A equals HEX $FE or the binary value 11111110, after the LSR statement you would get 01111111.



155                               LSR   A



Line 155 is again used to “[S]hift [R]ight one bit” which takes the binary value in register A and shifts in one bit to the right.  So, if register A now equals the binary value 01111111, after the LSR statement you would get 00111111.



156                               LSR   A



Line 156 is again used to “[S]hift [R]ight one bit” which takes the binary value in register A and shifts in one bit to the right.  So, if register A equals the binary value 00111111, after the LSR statement you would get 00011111.



157                               LSR   A



Line 157 is used one last time to “[S]hift [R]ight one bit” which takes the binary value in register A and shifts in one bit to the right.  So, if register A equals the binary value 00011111, after the LSR statement you would get 00001111.  This final binary value is equal to HEX $0F or decimal 15, which as you can see is the equivalent to the HIGH byte of the HEX reference $FE.





158                                STA   HBYTE,Y



Line 158 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 HBYTE,Y which in this example equal HEX value $0F or binary address 00001111 or decimal value 15.   Remember, this value is equal to the number of shapes/graphic tiles on the world map line #1 is this example.



159                                          LDA   MAPROW,X



Line 159 is used again to “[L]oa[D] the [A]ccumulator” or register A with the value in the array MAPROW from array location 0.  Remember previously we stored the value of HEX $FE in MAPROW,0 on the first go around. So is this example we are storing the HEX value of $FE again in register A to strip the LOW byte from it.



160                               ASL   A



Line 160 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, in this example if register A equals the binary value 11111110, after the ASL statement you would get 11111100.

161                               ASL   A



Line 161 is again 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 to continue this example, if register A equals the binary value 11111100, after the ASL statement you would get 11111000.



162                               ASL   A



Line 162 is again 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 to continue this example, if register A equals the binary value 11111000, after the ASL statement you would get 11110000.





163                               ASL   A



Line 163 the ASL statement is used one last time 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 after the four ASL statements have completed you will have shifted the binary value over 4 bits which will give you the value of one byte. In this example, if the accumulator had the HEX value $FE, which is equal to 11111110 then you would end up with the binary value of 11100000. But you are not finished because although you have the HEX value for E shifted over to the far left, you need to get it shifted back to the right so it has the actual value of HEX $0E.  To do this you need to run through the process again but shift everything to the right 4 bits.



164                               LSR   A



Line 164 is used to “[S]hift [R]ight one bit” which takes the binary value in register A and shifts in one bit to the right.  So, since register A equals the binary value 11100000, after the LSR statement you would get 01110000.



165                               LSR   A



Line 165 is again used to “[S]hift [R]ight one bit” which takes the binary value in register A and shifts in one bit to the right.  So, if register A equals the binary value 01110000, after the LSR statement you would get 00111000.



166                               LSR   A



Line 166 is again used to “[S]hift [R]ight one bit” which takes the binary value in register A and shifts in one bit to the right.  So, if register A equals the binary value 00111000, after the LSR statement you would get 00011100.



167                               LSR   A



Line 167 is used one last time to “[S]hift [R]ight one bit” which takes the binary value in register A and shifts in one bit to the right.  So, since register A equals the binary value 00011100, after the last LSR statement you would get 00001110, which is equal to HEX $0E or the decimal value of 14.  This is the shape reference number for OCEAN on the shape database table.



168                                STA   LBYTE,Y



Line 168 is used to “[ST]ore the [A]ccumulator” or take the value that has been stored in register A and place it in variable LBYTE,Y which in this example is equal to HEX value $0E or decimal value 14.   So at this point we have stored the HIGH byte in the HBYTE array and then stored the LOW byte in the LBYTE array.  This loop will do this for all the HEX reference numbers on this world map horizontal line.



169                                INY



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



170                                INX



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



171                                CPX   PREPMAP



Line 171 is used to “[C]om[P]are [X]” what is in register X to the value that is held within PREPMAP.  Since the value of PREPMAP is equal to, in this case, HEX $0C or 12, so X will continue to be compared to this value and if it doesn’t equal this value it will call FRNT1 again, increment X again, and continue to try to compare X against PREPMAP until it does equal to PREPMAP.  This loop continues until X finally equal PREPMAP and when this is accomplished it will finish the FRNT1 subroutine loop and then return to the subroutine that called it.



172                                BLT   FRNT1



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



173                                RTS



Line 173 is used to “[R]e[T]urn from [S]ubroutine”, which means that all the actions in the PREPMAP subroutine have been completed.   In this case, since PREMAP 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 START8 instead.



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



It will take each HEX reference number within the world map horizontal line such as an example, HEX $FE and decompress it so you will get the HIGH byte value $0F and the LOW byte value $0E.  To get these values it needs to process the binary value of each HEX reference number and shift it 4 bits to the right to get the HIGH byte value of 00001111 or $0F.  Next it will again take the HEX reference number $FE and shift it first to the left 4 bits 11100000 and then back to the right 4 bits 00001110 to get the final LOW byte value of $0E.  Once these two values are obtained they will be stored in separate HIGH and LOW arrays.  These two arrays will contain all the HIGH and LOW values of every HEX reference pertaining to that horizontal line of the world map.  These values are critical because they represent the number of shape/graphic tiles AND the type of shape/graphic tile used on each horizontal line of the entire world map section 1 & 2.



This is actually a pretty cool process because if you were to just use single byte memory locations to store each individual shape on the map you would end up using over 45K or RAM, which is almost the entire 48K of Apple memory leaving you with nothing left for the program!  This process cuts the memory usage down to about 6K or memory!!

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

ultima_revisited@yahoo.com

Joe

No comments:

Post a Comment