-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcstartdata_ext.a
461 lines (385 loc) · 9.14 KB
/
cstartdata_ext.a
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
ifp1
use os9defs.a
endc
DEBUGCS equ 0
ifne DEBUGCS
panic macro
leas \1,s
os9 F$Exit
endm
string macro
\1 fcc \2
fcb $0d
_\1 equ *-\1
endm
writeln macro
pshs a,x,y
lda #\1 path number
leax \2,pcr
ifne \# - 3
ldy #_\2
else
ldy \3
endc
OS9 I$WritLn
puls a,x,y
endm
writeidx macro
pshs a,x,y
lda #\1 path number
leax \2
ldy \3
OS9 I$WritLn
puls a,x,y
endm
dumpreg macro
pshs \1
lbsr dump2b
puls \1
endm
endc
pushzero macro
clr ,-s clear a byte on stack
endm
nfiles equ 2 stdin and stdout at least
Typ equ 1
Edit equ 1
Stk equ nfiles*256+128+256 stdin,stdout,stderr and fudge
psect cstart_a,$11,$81,Edit,Stk,_cstart
cr equ $0d
sp equ $20
comma equ ',
dquote equ '"
squote equ ''
MAXARGS equ 30 allow for 30 arguments
*
* rob the first dp byte so nothing gets assigned
* here. No valid pointer can point to byte zero.
*
vsect dp
__$$ fcb 0
endsect
vsect
argv rmb 2*MAXARGS pointers to args
argc rmb 2 argument counter
_sttop rmb 2 stack top
endsect
* the following are globally known
vsect
memend: rmb 2
_flacc: rmb 8 floating point & longs accumulator
_mtop: rmb 2 current non-stack memory top
_stbot: rmb 2 current stack bottom limit
errno: rmb 2 global error holder
endsect
* Some DEBUG messages
ifne DEBUGCS
string scstart,/cstart/
string scalcmn,/calc_mod_name/
string srddpdt,/read_dpdata/
string srddata,/read_data/
string sfndnam,/found_name/
string sopnfil,/open_file/
string sfilopn,/file_open/
string sclrbss,/clear_bss/
newline fcb $0d
_newline equ *-newline
endc
datatext fcc /$DATA/
fcb $0d
_cstart:
leax 0,pcr Get execution point address
* save bottom of mem (u), top of mem (y)
pshs u,y 4 bytes on stack
ifne DEBUGCS
writeln 1,scstart
endc
* Clear DP page
clra setup to clear
clrb 256 bytes
csta05 sta ,u+ clear dp bytes
decb
bne csta05
ifne DEBUGCS
writeln 1,scalcmn
endc
* Calc address of module name
leax etext,pcr point to dp-data count word
ldd ,x++ get dat-text ref. count
leax d,x add 2 times dat-text count to x
leax d,x
ldd ,x++ get the count of data refs.
leax d,x add 2 times dat refs count to x
leax d,x
cont1
ifne DEBUGCS
writeln 1,sfndnam
endc
* copy module name to a buffer
leas -32,s reserve buffer for filename 36 bytes on stack
tfr s,u
mncp lda ,x+
sta ,u+
bne mncp keep copying while the byte is not zero
leau -1,u point back to zero byte for next append
* append '$DATA\n' to filename
ldd datatext,pcr
std ,u++
ldd datatext+2,pcr
std ,u++
ldd datatext+4,pcr
std ,u terminate with newline
tfr s,x beginning of filename
ifne DEBUGCS
writeidx 1,",x",#8
writeln 1,sopnfil
endc
* open the file
* file mode (must have exec to find in exec dir)
lda #READ.+EXEC.
OS9 I$Open
leas 32,s free filename buffer 4 bytes on stack
lbcs ebderr1 4 bytes on stack
* save path number, reserve two bytes for buffer
pshs a,x 7 bytes on stack
ifne DEBUGCS
writeln 1,sfilopn
endc
* read first two bytes for dp data initialize size
leax 1,s point at 2 byte buffer
ldy #2 number of bytes to read
OS9 I$Read
lbcs ebderr2 7 bytes on stack
ifne DEBUGCS
writeln 1,srddpdt
endc
* read the initialized dp data from file to dp mem
ldy 1,s dp data size
lda ,s path number
ldx 5,s Mem Bottom
OS9 I$Read
lbcs ebderr2 7 bytes on stack
ifne DEBUGCS
writeln 1,srddata
endc
* read next two bytes for data initialize size
lda ,s path number
leax 1,s point at 2 byte buffer
ldy #2 number of bytes to read
OS9 I$Read
lbcs ebderr2 7 bytes on stack
* read the initialized data from file to data mem
ldx 5,s mem Bottom
leax dpsiz,x point to where non-dp should start
puls a,y path number and size of intialized data
OS9 I$Read
lbcs ebderr1 4 bytes on stack
ifne DEBUGCS
writeln 1,sclrbss
endc
* Get top of intialized mem address
ldu 2,s get beginning address again
leau end,u get end of bss address
pshs u save it 6 bytes on stack
tfr y,d make u point to end of intialized data
leax d,x by adding y size of init data to x
tfr x,u and saving in u
* clear the bss area - starts where
* the transferred data finished
clra
clrbss cmpu 0,s reached the end?
beq reldt bra if so
sta ,u+ clear it
bra clrbss
* now relocate the data-text references
reldt leay etext,pcr
ldu 4,s restore to data bottom
ldd ,y++ get dat-text ref. count
beq reldd
leax btext,pcr point to text
lbsr patch patch them
* and the data-data refs.
reldd ldd ,y++ get the count of data refs.
beq restack bra if none
leax 0,u u was already pointing there
lbsr patch
* Restore the stack to be in the same state
* as in the original cstart
restack leas 2,s reset stack
puls x restore 'memend'
leas 2,s set stack
stx memend,u
* process the params
* the stack pointer is back where it started so is
* pointing at the params
*
* the objective is to insert null chars at the end of each argument
* and fill in the argv vector with pointers to them
* first store the program name address
* (an extra name inserted here for just this purpose
* - undocumented as yet)
sty argv,u
ldd #1 at least one arg
std argc,u
leay argv+2,u point y at second slot
leax 0,s point x at params
lda ,x+ initialize
aloop ldb argc+1,u
cmpb #MAXARGS-1 about to overflow?
beq final
aloop10 cmpa #cr is it EOL?
beq final yes - reached the end of the list
cmpa #sp is it a space?
beq aloop20 yes - try another
cmpa #comma is it a comma?
bne aloop30 no - a word has started
aloop20 lda ,x+ yes - bump
bra aloop10 and round again
aloop30 cmpa #dquote quoted string?
beq aloop40 yes
cmpa #squote the other one?
bne aloop60 no - ordinary
aloop40 stx ,y++ save address in vector
inc argc+1,u bump the arg count
pshs a save delimiter
qloop lda ,x+ get another
cmpa #cr eol?
beq aloop50
cmpa 0,s delimiter?
bne qloop
aloop50 puls b clean stack
clr -1,x
cmpa #cr
beq final
lda ,x+
bra aloop
aloop60 leax -1,x point at first char
stx ,y++ put address in vector
leax 1,x bump it back
inc argc+1,u bump the arg count
* at least one non-space char has been seen
aloop70 cmpa #cr have
beq loopend we
cmpa #sp reached
beq loopend the end?
cmpa #comma comma?
beq loopend
lda ,x+ no - look further
bra aloop70
loopend clr -1,x yes - put in the null byte
bra aloop and look for the next word
* now put the pointers on the stack
final leax argv,u get the address of the arg vector
pshs x goes on the stack first
ldd argc,u get the arg count
pshs d stack it
leay 0,u C progs. assume data & bss offset from y
bsr _fixtop set various variables
lbsr main call the program
pushzero put a zero
pushzero on the stack
lbsr exit and a dummy 'return address'
* no return here
_fixtop leax end,y get the initial memory end address
stx _mtop,y it's the current memory top
sts _sttop,y this is really two bytes short!
sts _stbot,y
ldd #-126 give ourselves some breathing space
* on entry here, d holds the negative of a stack reservation request
_stkchec:
_stkcheck:
leax d,s calculate the requested size
cmpx _stbot,y is it lower than already reserved?
bhs stk10 no - return
cmpx _mtop,y yes - is it lower than possible?
blo fsterr yes - can't cope
stx _stbot,y no - reserve it
stk10 rts and return
fixserr fcc /**** STACK OVERFLOW ****/
fcb 13
ebderr2 leas 3,s clear 7 bytes from stack
ebderr1 leas 4,s clear 4 bytes from stack
bra erexit
fsterr leax <fixserr,pcr address of error string
ldb #E$MemFul MEMORY FULL error number
erexit pshs b stack the error number
lda #2 standard error output
ldy #100 more than necessary
os9 I$WritLn write it
pushzero clear MSB of status
lbsr _exit and out
* no return here
* stacksize()
* returns the extent of stack requested
* can be used by programmer for guidance
* in sizing memory at compile time
stacksiz:
ldd _sttop,y top of stack on entry
subd _stbot,y subtract current reserved limit
rts
* freemem()
* returns the current size of the free memory area
freemem:
ldd _stbot,y
subd _mtop,y
rts
* patch - adjust initialised data which refer to memory locations.
* entry:
* y -> list of offsets in the data area to be patched
* u -> base of data
* x -> base of either text or data area as appropriate
* d = count of offsets in the list
*
* exit:
* u - unchanged
* y - past the last entry in the list
* x and d mangled
patch pshs x save the base
leax d,y half way up the list
leax d,x top of list
pshs x save it as place to stop
* we do not come to this routine with
* a zero count (check!) so a test at the loop top
* is unnecessary
patch10 ldd ,y++ get the offset
leax d,u point to location
ldd 0,x get the relative reference
addd 2,s add in the base
std 0,x store the absolute reference
cmpy 0,s reached the top?
bne patch10 no - round again
leas 4,s reset the stack
rts and return
ifne DEBUGCS
bin2hex tfr b,a
lsrb
lsrb
lsrb
lsrb
bsr ToHex
exg b,a 1st digit in A
andb #%00001111 keep msn
ToHex
addb #'0 convert to ascii
cmpb #'9
bls ToHex1
addb #7 convert plus 9 to A..F
ToHex1
rts
* Print the ascii hex from stack ( no registers affected )
dump2b
pshs d
lda #$0D push a newline
ldb 5,s LSB
pshs a
bsr bin2hex LSB of reg
pshs a,b push last two hex
ldb 7,s get back MSB of reg
bsr bin2hex MSB of reg
pshs a,b push first two hex
writeidx 1,"5,s",#5 write out ascii hex from stack
leas 5,s clear string off stack
puls d
rts
endc
endsect