-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy path6809_NDIM.s
162 lines (160 loc) · 4.78 KB
/
6809_NDIM.s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
; Title: N-dimensional array indexing
;
; Name: NDIM
;
; Purpose: Calculate the address of an element in an N-dimensional array
; given the base address, N pairs of size in bytes and subscripts,
; and the number of dimensions of the array.
; The array is assumed to be stored in row major order
; (e.g., A[0,0,0],A[0,0,1],...,A[0,1,0], A[0,1,1],...).
; Also, it is assumed that all dimensions begin at 0
; as in the following Pascal declaration:
;
; A:ARRAY[0..10,0..3,0..5] OF SOMETHING
; Entry:
; TOP OF STACK
; High byte of return address
; Low byte of return address
; High byte of number of dimensions
; Low byte of number of dimensions
; High byte of dim N-1 size
; Low byte of dim N-1 size
; High byte of dim N-1 subscript
; Low byte of dim N-1 subscript
; High byte of dim N-2 size
; Low byte of dim N-2 size
; High byte of dim N-2 subscript
; Low byte of dim N-2 subscript
; .
; .
; .
; High byte of array base address
; Low byte of array base address
;
; NOTE: ALL sizes are in bytes.
;
; Exit: Register X = Element's base address
;
;
; Registers Used: All
;
; Time: Approximately 720 cycles per dimension
; plus 67 cycles overhead
;
; Size: Program 49 bytes
;
;
; EXIT IMMEDIATELY IF NUMBER OF DIMENSIONS IS ZERO
;
NDIM:
PULS U ; SAVE RETURN ADDRESS
LDX 2,S ; GET BASE ADDRESS IF ZERO DIMENSIONS
LDY ,S++ ; GET NUMBER OF DIMENSIONS
BEQ EXITNDIM ; BRANCH IF NUMBER OF DIMENSIONS IS ZERO
;
; ELEMENT ADDRESS = BASE ADDRESS + SIZE(I)*SUBSCRIPT(I) FOR
; I = 0 TO N-1
;
LDD #0 ; START ELEMENT ADDRESS AT ZERO
;
; MULTIPLY ROW SUBSCRIPT
; ROW SIZE USING SHIFT AND
; ADD ALGORITHM
;
NEXTDIM:
LDX #16 ; SHIFT COUNTER = 16
MUL16:
LSR ,S ; SHIFT HIGH BYTE OF ROW SIZE
ROR 1,S ; SHIFT LOW BYTE OF ROW SIZE
BCC LEFTSH ; JUMP IF NEXT BIT OF RDW SIZE IS 0
ADDD 2,S ; OTHERWISE, ADD SHIFTED ROW SUBSCRIPT
; TO ELEMENT ADDRESS
LEFTSH:
LSL 3,S ; SHIFT LOW BYTE OF ROW SUBSCRIPT
ROL 2,S ; SHIFT HIGH BYTE PLUS CARRY
LEAX -1,X ; DECREMENT SHIFT COUNTER
BNE MUL16 ; LOOP 16 TIMES
;
; MOVE STACK POINTER PAST FINISHED DIMENSION
;
LEAS 4,S ; REMOVE SIZE, SUBSCRIPT FROM STACK
;
; CONTINUE IF MORE DIMENSIONS LEFT
;
LEAY -1,Y ; DECREMENT NUMBER OF DIMENSIONS
BNE NEXTDIM ; BRANCH IF ANY DIMENSIONS LEFT
;
; ADD TOTAL OFFSET TO BASE ADDRESS OF ARRAY
;
ADDD ,S ; ADD BASE ADDRESS OF ARRAY
TFR D,X ; MOVE ELEMENT ADDRESS TO X
EXITNDIM:
STU ,S ; PUT RETURN ADDRESS BACK IN STACK
RTS
;
; SAMPLE EXECUTION
;
; CALCULATE ADDRESS OF AY1[1,3,0]
; SINCE LOWER BOUNDS OF ARRAY 1 ARE ALL ZERO,
; IT IS NOT NECESSARY TO NORMALIZE THEM
LDU #AY1 ; BASE ADDRESS OF ARRAY
LDY #1 ; FIRST SUBSCRIPT
LDX A1SZ1 ; SIZE OF FIRST SUBSCRIPT
LDD #3 ; SECOND SUBSCRIPT
PSHS U,X,Y,D ; PUSH PARAMETERS
LDU #A1SZ2 ; SIZE OF SECOND SUBSCRIPT
LDY #0 ; THIRD SUBSCRIPT
LDX #A1SZ3 ; SIZE OF THIRD SUBSCRIPT
LDD #A1DIM ; NUMBER OF DIMENSIONS
PSHS U,X,Y,D ; PUSH PARAMETERS
JSR NDIM ; CALCULATE ADDRESS
;
; CALCULATE ADDRESS OF
; SINCE LOWER BOUNDS 0F ARRAY 2 D0 NOT START AT 0, SUBSCRIPTS
; MUST BE NORMALIZED
;
LDX #AY2 ; BASE ADDRESS OF ARRAY
LDD #-1 ; GET UNNORMALIZED FIRST SUBSCRIPT
SUBD #A2D1L ; NORMALIZE FIRST SUBSCRIPT
; (SUBTRACT LOWER BOUND
PSHS D,X ; PUSH PARAMETERS
LDX #A2SZ1 ; SIZE OF FIRST SUBSCRIPT
LDD #6 ; GET UNNORHALIZED SECOND SUBSCRIPT
SUBD #A2D2L ; NORMALIZE SECOND SUBSCRIPT
; (SUBTRACT LOWER BOUND
PSHS D,X ; PUSH PARAMETERS
LDX #A2SZ2 ; SIZE OF SECOND SUBSCRIPT
LDD #AZDIM ; NUMBER OF DIMENSIONS
PSHS D,X ; PUSH PARAMETERS
JSR NDIM ; CALCULATE ADDRESS
; AY = STARTING ADDRESS OF AY2(-1,16)
; = AY2+(((-1)-(-5))*18)+((6-2)*2)
; = AY2+80
; DATA
; AY1: ARRAY[A1D1L..A1D1H,A1D2L..A1D2H,A1D3L..A1D3H] ELEMENTS
; [0..3, 0..5, 0..6]
;
A1DIM EQU 3 ; NUMBER OF DIMENSIONS
A1D1L EQU 0 ; LOW BOUND OF DIMENSION 1
A1D1H EQU 3 ; HIGH BOUND OF DIMENSION 1
A1D2L EQU 0 ; LOW BOUND OF DIMENSION 2
A1D2H EQU 5 ; HIGH BOUND OF DIMENSION 2
A1D3L EQU 0 ; LOW BOUND OF DIMENSION 3
A1D3H EQU 6 ; HIGH BOUND OF DIMENSION 3
A1SZ3 EQU 3 ; SIZE OF ELEMENT IN DIMENSION 3
A1SZ2 EQU ((A1D3H-A1D3L)+1)*A1SZ3 ; SIZE OF ELEMENT IN D2
A1SZ1 EQU ((A1D2H-A1D2L)+1)*A1SZ2 ; SIZE OF ELEMENT IN D1
AY1: RMB ((A1D1H-A1D1L)+1)*A1SZ1 ; ARRAY
;
; AY2: ARRAY [A2D1L..A2D1H,A2D2L..A2D2H] OF WORD
; [ -5 .. -1, 2 .. 10 ]
;
AZDIM EQU 2 ; NUMBER OF DIMENSIONS
A2D1L EQU -5 ; LOW BOUND OF DIMENSION 1
A2D1H EQU -1 ; HIGH BOUND OF DIMENSION 1
A2D2L EQU 2 ; LOW BOUND OF DIMENSION 2
A2D2H EQU 10 ; HIGH BOUND OF DIMENSION 2
A2SZ2 EQU 2 ; SIZE OF ELEMENT IN D2
A2SZ1 EQU ((A2D2H-A2D2L)+1)*A2SZ2 ; SIZE OF ELEMENT IN D1
AY2: RMB ((A2D1H-A2D1L)+1)*A2SZ1 ; ARRAY
END