88 lines
4.2 KiB
Plaintext
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.
|