867
|
1 ifp1
|
|
2 use ..../defs/os9defs.a
|
|
3 endc
|
|
4
|
|
5 pushzero macro
|
|
6 clr ,-s clear a byte on stack
|
|
7 endm
|
|
8
|
|
9 nfiles equ 2 stdin and stdout at least
|
|
10 Typ equ 1
|
|
11 Edit equ 1
|
|
12 Stk equ nfiles*256+128+256 stdin,stdout,stderr and fudge
|
|
13 psect cstart_a,$11,$81,Edit,Stk,_cstart
|
|
14
|
|
15 cr equ $0d
|
|
16 sp equ $20
|
|
17 comma equ ',
|
|
18 dquote equ '"
|
|
19 squote equ ''
|
|
20
|
|
21 MAXARGS equ 30 allow for 30 arguments
|
|
22
|
|
23 *
|
|
24 * rob the first dp byte so nothing gets assigned
|
|
25 * here. No valid pointer can point to byte zero.
|
|
26 *
|
|
27 vsect dp
|
|
28 __$$ fcb 0
|
|
29 endsect
|
|
30
|
|
31 vsect
|
|
32 argv rmb 2*MAXARGS pointers to args
|
|
33 argc rmb 2 argument counter
|
|
34 _sttop rmb 2 stack top
|
|
35 endsect
|
|
36
|
|
37 * the following are globally known
|
|
38 vsect
|
|
39 memend: rmb 2
|
|
40 _flacc: rmb 8 floating point & longs accumulator
|
|
41 _mtop: rmb 2 current non-stack memory top
|
|
42 _stbot: rmb 2 current stack bottom limit
|
|
43 errno: rmb 2 global error holder
|
|
44 endsect
|
|
45
|
|
46 *
|
|
47 * move bytes (Y=From addr, U=To addr, X=Count)
|
|
48 *
|
|
49 movbytes
|
|
50 lda ,y+ get a byte
|
|
51 sta ,u+ put a byte
|
|
52 leax -1,x dec the count
|
|
53 bne movbytes and round again
|
|
54 rts
|
|
55
|
|
56 _cstart:
|
|
57 pshs y save the top of mem
|
|
58 pshs u save the data beginning address
|
|
59
|
|
60 clra setup to clear
|
|
61 clrb 256 bytes
|
|
62 csta05 sta ,u+ clear dp bytes
|
|
63 decb
|
|
64 bne csta05
|
|
65
|
|
66 csta10 ldx 0,s get the beginning of data address
|
|
67 leau 0,x (tfr x,u)
|
|
68 leax end,x get the end of bss address
|
|
69 pshs x save it
|
|
70 leay etext,pcr point to dp-data count word
|
|
71
|
|
72 ldx ,y++ get count of dp-data to be moved
|
|
73 beq csta15 bra if none
|
|
74 bsr movbytes move dp data into position
|
|
75
|
|
76 ldu 2,s get beginning address again
|
|
77 csta15 leau dpsiz,u point to where non-dp should start
|
|
78 ldx ,y++ get count of non-dp data to be moved
|
|
79 beq clrbss
|
|
80 bsr movbytes move non-dp data into position
|
|
81
|
|
82 * clear the bss area - starts where
|
|
83 * the transferred data finished
|
|
84 clra
|
|
85 clrbss cmpu 0,s reached the end?
|
|
86 beq reldt bra if so
|
|
87 sta ,u+ clear it
|
|
88 bra clrbss
|
|
89
|
|
90 * now relocate the data-text references
|
|
91 reldt ldu 2,s restore to data bottom
|
|
92 ldd ,y++ get dat-text ref. count
|
|
93 beq reldd
|
|
94 leax btext,pcr point to text
|
|
95 lbsr patch patch them
|
|
96
|
|
97 * and the data-data refs.
|
|
98 reldd ldd ,y++ get the count of data refs.
|
|
99 beq restack bra if none
|
|
100 leax 0,u u was already pointing there
|
|
101 lbsr patch
|
|
102
|
|
103 restack leas 4,s reset stack
|
|
104 puls x restore 'memend'
|
|
105 stx memend,u
|
|
106
|
|
107 * process the params
|
|
108 * the stack pointer is back where it started so is
|
|
109 * pointing at the params
|
|
110 *
|
|
111 * the objective is to insert null chars at the end of each argument
|
|
112 * and fill in the argv vector with pointers to them
|
|
113
|
|
114 * first store the program name address
|
|
115 * (an extra name inserted here for just this purpose
|
|
116 * - undocumented as yet)
|
|
117 sty argv,u
|
|
118
|
|
119 ldd #1 at least one arg
|
|
120 std argc,u
|
|
121 leay argv+2,u point y at second slot
|
|
122 leax 0,s point x at params
|
|
123 lda ,x+ initialize
|
|
124
|
|
125 aloop ldb argc+1,u
|
|
126 cmpb #MAXARGS-1 about to overflow?
|
|
127 beq final
|
|
128 aloop10 cmpa #cr is it EOL?
|
|
129 beq final yes - reached the end of the list
|
|
130
|
|
131 cmpa #sp is it a space?
|
|
132 beq aloop20 yes - try another
|
|
133 cmpa #comma is it a comma?
|
|
134 bne aloop30 no - a word has started
|
|
135 aloop20 lda ,x+ yes - bump
|
|
136 bra aloop10 and round again
|
|
137
|
|
138 aloop30 cmpa #dquote quoted string?
|
|
139 beq aloop40 yes
|
|
140 cmpa #squote the other one?
|
|
141 bne aloop60 no - ordinary
|
|
142
|
|
143 aloop40 stx ,y++ save address in vector
|
|
144 inc argc+1,u bump the arg count
|
|
145 pshs a save delimiter
|
|
146
|
|
147 qloop lda ,x+ get another
|
|
148 cmpa #cr eol?
|
|
149 beq aloop50
|
|
150 cmpa 0,s delimiter?
|
|
151 bne qloop
|
|
152
|
|
153 aloop50 puls b clean stack
|
|
154 clr -1,x
|
|
155 cmpa #cr
|
|
156 beq final
|
|
157 lda ,x+
|
|
158 bra aloop
|
|
159
|
|
160 aloop60 leax -1,x point at first char
|
|
161 stx ,y++ put address in vector
|
|
162 leax 1,x bump it back
|
|
163 inc argc+1,u bump the arg count
|
|
164
|
|
165 * at least one non-space char has been seen
|
|
166 aloop70 cmpa #cr have
|
|
167 beq loopend we
|
|
168 cmpa #sp reached
|
|
169 beq loopend the end?
|
|
170 cmpa #comma comma?
|
|
171 beq loopend
|
|
172 lda ,x+ no - look further
|
|
173 bra aloop70
|
|
174
|
|
175 loopend clr -1,x yes - put in the null byte
|
|
176 bra aloop and look for the next word
|
|
177
|
|
178 * now put the pointers on the stack
|
|
179 final leax argv,u get the address of the arg vector
|
|
180 pshs x goes on the stack first
|
|
181 ldd argc,u get the arg count
|
|
182 pshs d stack it
|
|
183 leay 0,u C progs. assume data & bss offset from y
|
|
184
|
|
185 bsr _fixtop set various variables
|
|
186
|
|
187 lbsr main call the program
|
|
188
|
|
189 pushzero put a zero
|
|
190 pushzero on the stack
|
|
191 lbsr exit and a dummy 'return address'
|
|
192
|
|
193 * no return here
|
|
194 _fixtop leax end,y get the initial memory end address
|
|
195 stx _mtop,y it's the current memory top
|
|
196 sts _sttop,y this is really two bytes short!
|
|
197 sts _stbot,y
|
|
198 ldd #-126 give ourselves some breathing space
|
|
199
|
|
200 * on entry here, d holds the negative of a stack reservation request
|
|
201 _stkchec:
|
|
202 _stkcheck:
|
|
203 leax d,s calculate the requested size
|
|
204 cmpx _stbot,y is it lower than already reserved?
|
|
205 bhs stk10 no - return
|
|
206 cmpx _mtop,y yes - is it lower than possible?
|
|
207 blo fsterr yes - can't cope
|
|
208 stx _stbot,y no - reserve it
|
|
209 stk10 rts and return
|
|
210
|
|
211 fixserr fcc /**** STACK OVERFLOW ****/
|
|
212 fcb 13
|
|
213
|
|
214 fsterr leax <fixserr,pcr address of error string
|
|
215 ldb #E$MEMFUL MEMORY FULL error number
|
|
216
|
|
217 erexit pshs b stack the error number
|
|
218 lda #2 standard error output
|
|
219 ldy #100 more than necessary
|
|
220 os9 I$WRITLN write it
|
|
221 pushzero clear MSB of status
|
|
222 lbsr _exit and out
|
|
223 * no return here
|
|
224
|
|
225 * stacksize()
|
|
226 * returns the extent of stack requested
|
|
227 * can be used by programmer for guidance
|
|
228 * in sizing memory at compile time
|
|
229 stacksiz:
|
|
230 ldd _sttop,y top of stack on entry
|
|
231 subd _stbot,y subtract current reserved limit
|
|
232 rts
|
|
233
|
|
234 * freemem()
|
|
235 * returns the current size of the free memory area
|
|
236 freemem:
|
|
237 ldd _stbot,y
|
|
238 subd _mtop,y
|
|
239 rts
|
|
240
|
|
241 * patch - adjust initialised data which refer to memory locations.
|
|
242 * entry:
|
|
243 * y -> list of offsets in the data area to be patched
|
|
244 * u -> base of data
|
|
245 * x -> base of either text or data area as appropriate
|
|
246 * d = count of offsets in the list
|
|
247 *
|
|
248 * exit:
|
|
249 * u - unchanged
|
|
250 * y - past the last entry in the list
|
|
251 * x and d mangled
|
|
252
|
|
253 patch pshs x save the base
|
|
254 leax d,y half way up the list
|
|
255 leax d,x top of list
|
|
256 pshs x save it as place to stop
|
|
257
|
|
258 * we do not come to this routine with
|
|
259 * a zero count (check!) so a test at the loop top
|
|
260 * is unnecessary
|
|
261 patch10 ldd ,y++ get the offset
|
|
262 leax d,u point to location
|
|
263 ldd 0,x get the relative reference
|
|
264 addd 2,s add in the base
|
|
265 std 0,x store the absolute reference
|
|
266 cmpy 0,s reached the top?
|
|
267 bne patch10 no - round again
|
|
268
|
|
269 leas 4,s reset the stack
|
|
270 rts and return
|
|
271
|
|
272 endsect
|