@@ -13,6 +13,7 @@ __START_PROGRAM:
1313 ld (__CALL_BACK__) , hl
1414 ei
1515 call __MEM_INIT
16+ call _test
1617 ld hl , 0
1718 ld b , h
1819 ld c , l
@@ -36,16 +37,25 @@ _test:
3637 ld hl , 0
3738 push hl
3839 push hl
40+ ld hl , __LABEL1
41+ push hl
3942 ld hl , - 4
4043 ld de , __LABEL0
41- ld bc , 176
42- call __ALLOC_LOCAL_ARRAY
44+ ld bc , 9
45+ call __ALLOC_INITIALIZED_LOCAL_ARRAY
46+ ld hl , 1
47+ push hl
48+ ld hl , 1
49+ push hl
4350 push ix
4451 pop hl
4552 ld de , - 4
4653 add hl , de
47- ld de , 84
48- add hl , de
54+ call __ARRAY
55+ push hl
56+ ld a , 99
57+ pop hl
58+ ld (hl) , a
4959_test__leave:
5060 ex af , af'
5161 exx
@@ -57,6 +67,135 @@ _test__leave:
5767 ld sp , ix
5868 pop ix
5969 ret
70+ #line 1 "array.asm"
71+ ; vim: ts=4:et:sw=4:
72+ ; Copyleft (K) by Jose M. Rodriguez de la Rosa
73+ ; (a.k.a. Boriel)
74+ ; http://www.boriel.com
75+ ; -------------------------------------------------------------------
76+ ; Simple array Index routine
77+ ; Number of total indexes dimensions - 1 at beginning of memory
78+ ; HL = Start of array memory (First two bytes contains N-1 dimensions)
79+ ; Dimension values on the stack, (top of the stack, highest dimension)
80+ ; E.g. A(2, 4) -> PUSH <4>; PUSH <2>
81+ ; For any array of N dimension A(aN-1, ..., a1, a0)
82+ ; and dimensions D[bN-1, ..., b1, b0], the offset is calculated as
83+ ; O = [a0 + b0 * (a1 + b1 * (a2 + ... bN-2(aN-1)))]
84+ ; What I will do here is to calculate the following sequence:
85+ ; ((aN-1 * bN-2) + aN-2) * bN-3 + ...
86+ #line 1 "mul16.asm"
87+ __MUL16: ; Mutiplies HL with the last value stored into de stack
88+ ; Works for both signed and unsigned
89+ PROC
90+ LOCAL __MUL16LOOP
91+ LOCAL __MUL16NOADD
92+ ex de , hl
93+ pop hl ; Return address
94+ ex ( sp ) , hl ; CALLEE caller convention
95+ __MUL16_FAST:
96+ ld b , 16
97+ ld a , h
98+ ld c , l
99+ ld hl , 0
100+ __MUL16LOOP:
101+ add hl , hl ; hl << 1
102+ sla c
103+ rla ; a,c << 1
104+ jp nc , __MUL16NOADD
105+ add hl , de
106+ __MUL16NOADD:
107+ djnz __MUL16LOOP
108+ ret ; Result in hl (16 lower bits)
109+ ENDP
110+ #line 20 "array.asm"
111+ #line 24 "/zxbasic/library-asm/array.asm"
112+ __ARRAY_PTR: ;; computes an array offset from a pointer
113+ ld c , (hl)
114+ inc hl
115+ ld h , (hl)
116+ ld l , c
117+ __ARRAY:
118+ PROC
119+ LOCAL LOOP
120+ LOCAL ARRAY_END
121+ LOCAL RET_ADDRESS ; Stores return address
122+ LOCAL TMP_ARR_PTR ; Stores pointer temporarily
123+ ld e , (hl)
124+ inc hl
125+ ld d , (hl)
126+ inc hl
127+ ld (TMP_ARR_PTR) , hl
128+ ex de , hl
129+ ex ( sp ) , hl ; Return address in HL, array address in the stack
130+ ld (RET_ADDRESS + 1 ) , hl ; Stores it for later
131+ exx
132+ pop hl ; Will use H'L' as the pointer
133+ ld c , (hl) ; Loads Number of dimensions from (hl)
134+ inc hl
135+ ld b , (hl)
136+ inc hl ; Ready
137+ exx
138+ ld hl , 0 ; HL = Offset "accumulator"
139+ LOOP :
140+ #line 62 "/zxbasic/library-asm/array.asm"
141+ pop bc ; Get next index (Ai) from the stack
142+ #line 72 "/zxbasic/library-asm/array.asm"
143+ add hl , bc ; Adds current index
144+ exx ; Checks if B'C' = 0
145+ ld a , b ; Which means we must exit (last element is not multiplied by anything)
146+ or c
147+ jr z , ARRAY_END ; if B'Ci == 0 we are done
148+ ld e , (hl) ; Loads next dimension into D'E'
149+ inc hl
150+ ld d , (hl)
151+ inc hl
152+ push de
153+ dec bc ; Decrements loop counter
154+ exx
155+ pop de ; DE = Max bound Number (i-th dimension)
156+ call __FNMUL
157+ jp LOOP
158+ ARRAY_END:
159+ ld a , (hl)
160+ exx
161+ #line 101 "/zxbasic/library-asm/array.asm"
162+ LOCAL ARRAY_SIZE_LOOP
163+ ex de , hl
164+ ld hl , 0
165+ ld b , a
166+ ARRAY_SIZE_LOOP:
167+ add hl , de
168+ djnz ARRAY_SIZE_LOOP
169+ #line 111 "/zxbasic/library-asm/array.asm"
170+ ex de , hl
171+ ld hl , (TMP_ARR_PTR)
172+ ld a , (hl)
173+ inc hl
174+ ld h , (hl)
175+ ld l , a
176+ add hl , de ; Adds element start
177+ RET_ADDRESS:
178+ jp 0
179+ ;; Performs a faster multiply for little 16bit numbs
180+ LOCAL __FNMUL , __FNMUL2
181+ __FNMUL:
182+ xor a
183+ or h
184+ jp nz , __MUL16_FAST
185+ or l
186+ ret z
187+ cp 33
188+ jp nc , __MUL16_FAST
189+ ld b , l
190+ ld l , h ; HL = 0
191+ __FNMUL2:
192+ add hl , de
193+ djnz __FNMUL2
194+ ret
195+ TMP_ARR_PTR:
196+ DW 0 ; temporary storage for pointer to tables
197+ ENDP
198+ #line 56 "arr_addr_local.bas"
60199#line 1 "arrayalloc.asm"
61200#line 1 "calloc.asm"
62201; vim: ts=4:et:sw=4:
@@ -451,7 +590,7 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY:
451590 ; DE = new data area
452591 ldir
453592 ret
454- #line 46 "localdim .bas"
593+ #line 57 "arr_addr_local .bas"
455594#line 1 "free.asm"
456595; vim: ts=4:et:sw=4:
457596 ; Copyleft (K) by Jose M. Rodriguez de la Rosa
@@ -608,14 +747,24 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed
608747 ld (hl) , d ; Next saved
609748 ret
610749 ENDP
611- #line 47 "localdim .bas"
750+ #line 58 "arr_addr_local .bas"
612751ZXBASIC_USER_DATA:
613752__LABEL0:
614753 DEFB 01h
615754 DEFB 00h
616- DEFB 08h
755+ DEFB 03h
756+ DEFB 00h
757+ DEFB 01h
758+ __LABEL1:
617759 DEFB 00h
760+ DEFB 01h
618761 DEFB 02h
762+ DEFB 03h
763+ DEFB 04h
764+ DEFB 05h
765+ DEFB 06h
766+ DEFB 07h
767+ DEFB 08h
619768ZXBASIC_MEM_HEAP:
620769 ; Defines DATA END
621770ZXBASIC_USER_DATA_END EQU ZXBASIC_MEM_HEAP + ZXBASIC_HEAP_SIZE
0 commit comments