
			       ALPHA VERSION!
			       ALPHA VERSION!
			       ALPHA VERSION!
			       ALPHA VERSION!
			       ALPHA VERSION!
			       ALPHA VERSION!


		------------------------------------------------- 
		A Little Tutorial About 2D Arrays in ASM Key Generators
		------------------------------------------------- 
				   BY
				     Gij
		

Since The point of this whole thing is to illustrate the use of 2D arrays
in ASM Key Generators, that's the only part i'm going to explain, and since 
this is a really messy thing, that's all i hope you'll concentrate on :-) .

the array, Data_Table, is 4 rows of 8 items each, in c that would be:

 char Data_Table[4][8];

you'll notice that the sizes of the array are multiples of 2 (2^2=4,2^3=8).
this is on purpose, and will help us later when we try to reference an item 
from the table.

up to the point of addressing an item off the table, the code just plays
around with the serial, twiddeling bits, fooling around.
at some point, after the fun is over, i use the values to reference the table,
this is where explanations starts to be in order.

The first thing you might have trouble with as a newbie when trying to use 
2D arrays in ASM,  is probably the use of the IDIV's in the code. 
the purpose of these is to limit the values to the size of the array.
let me explain this:

if we use one value as the line number, and the table only has 4 lines,
we must make sure that the value isn't larger then 3, ( since lines are counted
from 0, as in: 0,1,2,3) this is what the IDIV is used for.

here's a handy little math law for this :

"The remainder of a division, can't be larger then the number you divide by"

for example:

( "20 % 4" gives the remainder, in this case of 20 / 4, which is 0 )


8  %  4 = 0
9  %  4 = 1
10 %  4 = 2
11 %  4 = 3
12 %  4 = 0

do you see the pattern? the remainder is always smaller then the number 
u divide by.


so after the IDIV's we have 2 numbers limited to the size of the array.
the first is divided by 4 and will have a value no larger then 3.
the second is divided by 8 and will have a value no larger then 7.


so now what do we do with them? we use them to reference the array.

how? easy!


we have 1 value which is the line number (limited to the line numbers by IDIV).
we have another value which is the item number (limited to the number of items).

you can think of them as vertical and horizontal. the line number tells us how 
many lines down the referenced value is. the item number tells us how many 
slots right the referenced value is.
 

now to understand the way we calculate the address of the item number you need 
to understand that a 2D dimensional array is really only 1-dimensional.
confused yet? good.

look at this diagram:

|1|2|3|4|5|6|7|8|

this is meant to represent an 8 item array.

this is 1-dimensional. we could also look at it as a 2-dimensional array:

Line 0: |1|2|3|4|
Line 1: |5|6|7|8|

why can we do this? because the array, weather 1 or 2 dimensional, is stored
contiguously in memory. as far as the computer is concerned, both the above 
arrays are stored in the same way. we only use 2D-dimensional arrays because
it offers us an easier to represent data in some cases.

enough theory, back to practice.

how do we calculate the address of an item, if we have it's line number, and 
item/offset number? some of you may know this by intuition.

the formula is: (line*item_count)+offset.

let's see some examples:

we have a 2D array, 2 lines, 4 items each.
the item we want is in the 2nd line, the item number/offset is 3.

(REMEMBER! we are counting from 0, IMPORTENT! ).

so:

line = 1;
offset=3;
item_count=4;



Line 0: |a|b|c|d|
Line 1: |e|f|g|h|

if we look at the array, this gives us the char "h".

let's put it in the formula:

(1*4)+3=7;

let's see how this works with the equivalent 1D array


|a|b|c|d|e|f|g|h|

 ^ ^ ^ ^ ^ ^ ^ ^
 | | | | | | | |

 0 1 2 3 4 5 6 7              


so item number 7, gives us "h". it works, imagine that!. 

the last thing to remember is that the final offset we get from the formula,
(7 in the example), is an offset relative to the beginning of the table.
that's why you need to add the final item offset to the address of the table in 
memory.


Last Note
---------

There's a more efficient way of restricting a value to a range, instead of using 
IDIV's. if the maximum value is represented by all 1's in binary.

1111b = 15 ( range 0-15, or 16  )

in that case you can either just mask off the extra bits: and ax,1111b
or you can shift the number right 4 places, only 0's are shifted in on
the left, so you'll get a valid (0-15) number.
same goes for 1b,11b,111b,etc... just change the mask/shift count.


remember that the way i'm using arrays in here may not be the usual
use for them, i just used some input to generate values which i use 
to reference table items. 
if you use arrays for a different purpose, some of this may not apply,
but the formula mentioned should always work for your needs, and you 
can always the 2D/shr/mask ways too generate index's into the table.


I'm Gij, and this was......
    ------>> A Little Tutorial About 2D Arrays in ASM key generators <<------

