RosettaCodeData/Task/Create-a-two-dimensional-ar.../68000-Assembly/create-a-two-dimensional-ar...

88 lines
4.2 KiB
Plaintext

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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.