NameDateSize

..22-Dec-201617

code.cH A D24-Jul-20145.7 KiB

local.cH A D22-Dec-201614.1 KiB

local2.cH A D22-Dec-201611.1 KiB

macdefs.hH A D22-Dec-20165.3 KiB

order.cH A D24-Jul-20143.9 KiB

READMEH A D24-Jul-20145.7 KiB

table.cH A D24-Jul-201429.5 KiB

README

1Calling conventions, stack frame and zero page:
2
3The variables that normally are placed on the stack or in registers in C
4are instead allocated in the zero page and saved on a (fictive) stack
5when calling functions.  Some locations have predefined functions though.
6Arrays allocated as automatics are stored on the stack with a pointer
7in zero page to its destination.
8
90-7	Unused (by us)
1010	Stack pointer
1111	Frame pointer
1212-14	Unused
1315	Prolog private word
1416	Prolog address, written in crt0
1517	Epilog address, written in crt0
1620-27	(Auto-increment), scratch
1730-37	(Auto-decrement), scratch
1840-47	Used by HW stack and MMPU
1950-77	Permanent, save before use.
20100-377	Addresses for subroutines, written by the linker
21
22The normal registers (AC0-AC3) are all considered scratch registers.
23
24Register classes are assigned as:
25	AC0-AC3: AREGs.
26	AC2-AC3: BREGs.
27	...and eventually register pairs/floats as EREGs, double in FREGs.
28
29In byte code the left half of a word is the first byte (big-endian).
30This is bit 0-7 in Nova syntax.
31The stack is growing towards lower adresses (as opposed to the Eclipse stack).
32Stack pointer points to the last used stack entry, which means:
33PUSH: dec sp, store value
34POP:  fetch val, inc sp
35
36Note that internally is the first 24 words stored in loc 50-77!
37So an offset is subtracted in adrput().
38
39Stack layout:
40
41	! arg1	! 1
42 fp ->	! arg0	! 0
43 	! old pc! -1
44 	! old fp! -2
45 sp ->	! saved ! -3
46
47
48Stack references to zero page are converted to NAMEs, using word addresses.
49References to the stack itself are using byte offsets.
50
51Arguments are transferred on the stack.  To avoid unneccessary double instructions
52they are copied to the zp use area initially. XXX? Need tests here.
53Return values in ac0 and ac1.
54
55A reference to a struct member in assembler, a = b->c; b is in ZP 50 (or on stack)
56+ is zeropage-addressing
57* is fp-adressing, assume fp in ac3
58
59# offset 0
60+	lda 0,@50	# load value from indirect ZP 50 into ac0
61or
62*	lda 2,,3	# load value from (ac3) into ac2
63*	lda 0,,2	# load value from (ac2) into ac0
64
65# offset 12
66+	lda 2,50	# load value from ZP 50 into ac2
67+	lda 0,12,2	# load value from (ac2+12) into ac0
68or
69*	lda 2,,3	# load value from (ac3) into ac2
70*	lda 0,12,2	# load value from 12(ac2) into ac0
71
72# offset 517
73+	lda %2,50	# load value from ZP 50 into ac2
74+	lda %0,.L42-.,%1	# load offset from .L42 PC-indexed
75+	addz %0,%2,skp	# add offset to ac2 and skip
76+.L42:	.word 517	# offset value
77+	lda %0,,%2	# load value from (ac2) into ac0
78or
79
80The prolog/epilog; they are implemented as subroutines.
81Both can be omitted if the function do not need it.
82
83
84	.word 012	# total words that needs to be saved
85func:
86	mov 3,0		# avoid trashing return address
87	jsr @prolog	# go to prolog
88	...
89	jmp @epilog	# jump to epilog
90
91#ifdef prolog
92	lda 0,sp
93	sta 3,@sp
94	lda 1,fp
95	sta 1,@sp
96	sta 0,fp
97	lda 1,[Css]
98	sub 1,0
99	sta 0,sp
100#endif
101
102...
103
104	lda 2,fp
105	lda 3,-1,2
106	lda 0,-2,2
107	sta 0,fp
108	sta 2,sp
109	jmp 0,3
110
111
112#
113# decrement from stack, and save permanent registers.
114#	push retreg
115#	push fp
116#	mov sp,fp
117#	sub $w,sp
118#	
119# prolog: return in ac3, fun in ac0.
120prolog:	lda 1,sp
121	sta 0,@sp
122	lda 0,fp
123	sta 0,@sp
124	sta 1,fp
125	lda 0,-3,3
126	sub 0,1
127	sta 1,sp
128	jmp 0,3
129
130epilog:	lda 3,fp
131	sta 3,sp
132	lda 3,@fp
133	lda 2,@fp
134	sta 2,fp
135	jmp 0,3
136
137	
138
139
140
141
142
143prolog:
144	lda 2,sp	# sp points to the first argument
145	sta 2,30	# store at auto-dec location
146	sta 0,@30	# store fun return address
147	lda 0,fp	# fetch old fp
148	sta 0,@30	# store saved fp
149	sta 2,fp	# save frame pointer
150
151	lda 0,-3,3	# stack size to subtract
152	neg 0,0,snr	# Any words?
153	jmp 1f		# no, get away
154	lda 1,$51	# fetch zp offset
155	sub 0,1		# get highest word
156	sta 1,31	# at auto-dec location
157
1582:	lda 1,@31	# fetch word to copy
159	sta 1,@30	# on stack
160	inc 0,0,szr	# count words
161	jmp 1b		# more to go
162
1631:	lda 0,30	# finished, get stackptr
164	sta 0,sp	#
165	jmp 0,3		# get back!
166
167# epilog, need save frame pointer in ac3
168epilog:
169	lda 0,-3,3	# get words to save
170	neg 0,0,snr	# any words to save?
171	jmp 1f		# No, get out
172
173	lda 1,$51	# get zp offset
174	sub 0,1		# Highest word
175	sta 1,31	# auto-dec loc
176
177	lda 2,fp	# get fp
178	adczl 1,1	# -2
179	add 1,2		# 2 now offset
180	sta 2,30	# auto-dec loc
181
1822:	lda 1,@30
183	sta 1,@31
184	inc 0,0,szr
185	jmp 2b
186
1871:	lda 2,fp	# fetch current fp
188	lda 3,-1,2	# return pc
189	lda 0,-2,2	# fetch old fp
190	sta 0,fp	# restore fp
191	sta 2,sp	# stack pointer restored
192	jmp 0,3		# Done!
193
194#if 0
195Assembler syntax and functions.
196
197The assembler syntax mimics the DG assembler but uses AT&T syntax.
198Load and store to addresses is written "lda 0,foo" to load from address foo.
199If foo is not in zero page then the assembler will put the lda in the
200text area close to the instruction and do an indirect pc-relative load.
201
202Arithmetic instruction: 	
203	subsl#	%0,%1,snr		skip code may be omitted
204	subsl#	%0,%1
205
206Load/store/jmp/jsr/isz/dsz:
207	lda %1,@disp,2		or
208	mov *disp(%2),%1
209		index may be omitted if 0 (ZP)
210		disp can only be +-127 words.
211
212	It's allowed to write "mov $32,%0" which will be converted
213	to an indirect load by the assembler.
214
215	Example of AT&T arguments:
216		01234	- Zero-page
217		L11	- Relative.  Will be converted to
218			  indirect + addr if distance too long
219		(%2)	- indexed
220		012(%2)	- indexed with offset
221		* in front of any of these will generate indirection
222#endif
223
224lbyte:  movr 2,2        # get byte ID into C bit
225        lda 0,,2        # word into ac0
226        mov 2,2,snc     # skip if right byte
227        movs 0,0        # swap bytes
228        jmp 0,3         # get back
229
230sbyte:  sta 3,@sp
231
232        movr 2,2        # get byte ID into C bit
233        lda 1,,2        # get word
234        lda 3,[377]     # get mask
235        and 3,0,snc     # clear left input + skip if right byte
236        movs 1,1        # swap bytes
237        and 3,1         # clear old bits
238        add 0,1,snc     # swap back if necessary
239        movs 1,1        # swap
240        sta 1,2
241
242        lda 3,sp
243        isz sp
244        jmp @0,3
245
246