
Data Structure

This illustrates a data structure, a means of storing data within a program.

You may see other such structures in the Data Structures category.
Get two integers from the user, then create a two-dimensional array where the two dimensions have the sizes given by those numbers, and which can be accessed in the most natural way possible. Write some element of that array, and then output that element. Finally destroy the array if not done by the language itself.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Array setup
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Create_2D_Array:
ARRAY_2D equ $100000
ARRAY_POINTER_VARIABLE equ $200000
; input: D0 = width, D1 = height
; assume the input is byte length and unsigned, ranging from 1 to FF.
 
AND.L #$000000FF,D0
AND.L #$000000FF,D1 ;sanitize the input to byte length.
 
LEA ARRAY_2D,A0     ;get base array address.
 
;The array's size will be measured in bytes, as this is how memory offsetting is measured. 
;For this example the elements will all be 32-bit.
;Therefore, the dimensions need to be multiplied by the byte count of each element.
 
LSL.W #2,D0         ;four bytes per element = multiply by 4
LSL.W #2,D1
 
;Next, these values are multiplied to get the array's size.
MOVE.L D0,D2
MULU D1,D2
;D2 is the array's size (measured in bytes) and will be placed at the beginning. 
;This does not count as an element of the array for the purposes of row/column indexing.
;The array's base address will be offset by 4 bytes prior to any indexing.
 
MOVE.L D2,(A0)+     ;store D2 in A0, add 4 to A0
MOVEA.L A0,[ARRAY_POINTER_VARIABLE]
 
;the brackets are optional, they show that this is a memory address label.
;this is still a move to a memory address with or without the brackets.
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Storing a value in the array
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
LEA ARRAY_POINTER_VARIABLE,A1    ;load the address where the array's base address is stored.
MOVE.L (A1),A1                   ;dereference the pointer and get ARRAY_2D+4 into A1.
 
; for this example the arbitrary row/column indices (2,5) will be used.
 
MOVE.L #2,D4
MULU D0,D4                       ;there are D0 entries per row, multiply row index by elements per row.
MOVE.L #5,D5 
MOVE.L #$00112233,D7             ;determine the value we want to store in the array.
 
; The bytes per element was factored into D0 when the array was created. So D4 is already where it should be.
LSL.L #2,D5                      ;column index still needs to be scaled by the bytes per element.
 
LEA (A1,D4),A1                   ;select the desired row.
 
;68000 doesn't allow you to use more than 1 data register at a time to offset. So we have to offset separately.
;Despite the use of parentheses this is NOT a dereference like it would be with "MOVE.L (A1),D7". D4 is merely added to the address in A1.
 
MOVE.L D7,(A1,D5)                ;store #$00112233 in row 2, column 5 of the array.     
 
;Loading a value is the same as storing it, except the operands in the last instruction are reversed, and MOVE.L #$00112233,D7
;is omitted.
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Destroying the array
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
; The array is destroyed by storing something else in its location. If you really want to reset it to zero, you can
; do so with the following:
 
LEA ARRAY_POINTER_VARIABLE,A1
MOVE.L (A1),A1
MOVE.L -(A1),D7                 
;get the array size into D7. Remember that the array's size was stored just before its data.
This value is potentially too large for a single DBRA, but it can be split up.
 
SWAP D7
MOVE.W D7,D6                    ;get the top half of D7 into D6. D6 will be the outer loop's DBRA value.
SWAP D7
SUBQ.L #1,D7                    ;D7 needs to be decremented by 1. D6 is fine the way it is.
 
MOVE.L (A0)+,D0                 ;dummy move to increment the pointer back to the array base.
MOVEQ #0,D0                     ;faster than MOVE.L #0,D0
 
loop_destroyArray:
MOVE.L D0,(A0)+
DBRA D7,loop_destroyArray       ;loop using bottom 2 bytes of the array size as a loop counter
DBRA D6,loop_destroyArray       ;decrement this, D7 is $FFFF each time execution gets here so this acts as a "carry" of sorts.
                                ;if this value was 0 prior to the loop, the loop ends immediately.