|
|
1.1 root 1: #include "../h/config.h"
2: /*
3: * Icon runtime startup. This routine gets Icon rolling and is called
4: * by main. The basic functions of this routine are to initialize
5: * memory with a call to init, and then invoke the main procedure with
6: * single argument that is a list composed of command line arguments.
7: */
8: Global(__cleanup) /* close files on exit */
9: Global(_init) /* initialize memory */
10: Global(_invoke) /* procedure invocation */
11: Global(_llist) /* form a literal list */
12: #ifdef AZ
13: Global(_monitor) /* turn profiling on/off */
14: #endif AZ
15: Global(_runerr) /* runtime error processor */
16: Global(_globals) /* icon global data region */
17: Global(_monres) /* profile resolution */
18: Global(_c_exit)
19: Global(_boundary)
20: Global(_tended)
21: Global(_etended)
22: Global(_mstart)
23: #ifdef VAX
24: .text
25: _mstart:
26: /*
27: * mstart(argv) -- start up Icon.
28: */
29: Mask 0x0000 # don't need to save any registers
30: movl 8(ap),r9 # point r9 at first word of argv list
31:
32: /*
33: * Call init to initialize memory and set environment variables
34: */
35: pushl 4(r9) # pass file name to be interpreted to init
36: calls $1,_init # init(file)
37: /*
38: * Create a dummy expression frame so that main procedure is no
39: * different from other procedures.
40: */
41: pushl $0 # old expression frame pointer
42: movl sp,efp # point the expression frame pointer
43: # at this word.
44: pushl $0 # old generator frame pointer
45: pushl $flab # failure label, we branch to flab
46: # if the expression (the evaluation
47: # of main()) fails
48:
49: /*
50: * Prepare to invoke main(), which should be first global variable.
51: * Note that _globals contains the address of the first
52: * global variable.
53: */
54: movl _globals,r0 # point r0 at first global variable
55: cmpl $D_PROC,(r0) # see if it's a procedure [*]
56: bneq nomain
57: movq (r0),-(sp) # Push variable 'main' onto stack
58: clrq -(sp) # Push &null to receive result of llist()
59:
60: tstl (r9)+ # r9 points to arg0, which is program
61: # name. We ignore it, moving r9
62: # on to point at the first actual
63: # argument to the program
64: tstl (r9)+ # arg1 is the name of the file to
65: # interpret, so we ignore it as well
66: /*
67: * Now we're ready to make an Icon list out of the program arguments.
68: * We build string descriptors one at a time on the stack and then
69: * call llist which makes a list out of its arguments.
70: */
71: clrl r8 # r8 counts args, 0 to start with
72: b1:
73: movl (r9)+,r7 # get address of next argument
74: beql f2 # if 0, we're at end of argument list,
75: pushl r7 # otherwise we push the address of the arg
76: incl r8 # count one more argument
77: locc $0,$0xffff,(r7) # calculate length of string, the 0xffff
78: # constant is 65k, which specifies the
79: # maximum distance to look to for the
80: # 0 (null byte) that terminates the string
81: subl3 r7,r1,-(sp) # push length of string, note that r1
82: # was automagically set by the locc
83: # instruction
84: jbr b1 # loop around until we get to the 0 word
85: # at the end of the argument list
86:
87: /*
88: * llist is called as llist(nargs,argn,...,arg1). We now have argn through
89: * arg1 on the stack. We push nargs (number of arguments) and then
90: * we calculate the number of words occupied by the argument list
91: * because the calls instruction uses it.
92: */
93: f2:
94: pushl r8 # push nargs
95: calls $0,_llist # make a list of the arguments
96: ashl $1,r8,r8 # calc number of words in the argument list,
97: # each descriptor is 2 words, so we multiply
98: # nargs by 2.
99: incl r8 # nargs itself also takes a word, so we add 1
100: ashl $2,r8,r8 # r8 is length in bytes of argument list
101: addl2 r8,sp
102:
103: /*
104: * Invoke main() with one argument (the list of command line arguments).
105: */
106: clrl gfp # clear generator frame pointer
107: clrl r13 # clear procedure frame pointer
108: pushl $1 # push nargs
109: calls $3,_invoke
110:
111: /*
112: * If main() returns we end up here. Call _c_exit to exit with 0 status.
113: */
114: f9:
115: pushl $0 # exit status = 0
116: calls $1,_c_exit
117:
118: /*
119: * If there was no main procedure we call runerr(117,0).
120: */
121: nomain:
122: pushl $0
123: pushl $117
124: calls $2,_runerr
125: pushl $1
126: calls $1,_c_exit
127:
128:
129: /*
130: * c_exit(i) - flush all buffers and exit with status i.
131: */
132: _c_exit:
133: Mask 0
134: #ifdef AZ
135: tstl _monres # if we're monitoring,
136: beql f1
137: pushl $0 # we turn it off with
138: calls $1,_monitor # monitor(0)
139: #endif AZ
140: /*
141: * We call __cleanup to clean up the i/o system and then
142: * call exit(i), where "i" is the argument to _c_exit.
143: */
144: f1:
145: calls $0,__cleanup
146: pushl 4(ap)
147: calls $1,_exit
148: .data
149:
150: /*
151: * waste first few bytes of memory, because all pointers must be
152: * greater than MAXTYPE, lest we confuse the garbage collector.
153: */
154: .space 60
155:
156: /*
157: * flab is "branched to" by the interpreter if the main procedure
158: * fails. The 0 is a "quit" opcode for the interpreter.
159: */
160: flab:
161: .byte 0
162:
163: /*
164: * The boundary marks the point where the stack is C above and
165: * Icon below.
166: */
167: _boundary:
168: .long 0
169: /*
170: * The tended descriptors.
171: */
172: _tended:
173: .long 0,0 # tended[0]
174: .long 0,0 # tended[1]
175: .long 0,0 # tended[2]
176: .long 0,0 # tended[3]
177: .long 0,0 # tended[4]
178: .long 0,0 # tended[5]
179: _etended:
180:
181:
182: #endif VAX
183: #ifdef PORT
184: DummyFcn(_mstart)
185: DummyFcn(_c_exit)
186: DummyData(_boundary)
187: DummyData(_tended)
188: DummyData(_etended)
189: #endif PORT
190:
191: #ifdef PDP11
192: Global(csv)
193: #include <sys.s>
194: /
195: / Icon runtime startup
196: /
197: #ifdef NOFP
198: Global(fptrap)
199: signal = 48.
200: #endif NOFP
201:
202: .text
203: _mstart:
204: /*
205: * mstart(argv) -- start up Icon
206: */
207: / Register usage:
208: / r1: counter for scanning argument list
209: / r2: nargs - number of arguments to the program
210: / r3: character pointer, for finding length of each argument string
211: / r4: pointer to dummy expression frame marker
212: / r5: pointer to command line argument list
213:
214: jsr r5,csv
215: clr _boundary / undo boundary setting
216: #ifdef NOFP
217: / Use software floating point
218: sys signal; 4; fptrap
219: setd
220: #else
221: / Enable floating point traps, double precision.
222: ldfps $3200
223: #endif NOFP
224:
225: / Create a dummy expression frame.
226:
227: clr -(sp) / old r4
228: mov sp,r4
229: clr -(sp) / old r3
230: mov $flab,-(sp) / failure label
231:
232: / Initialize memory.
233: mov 6(r5),r0 / point at argv
234: mov 2(r0),-(sp) / push address of arg1, the file name
235: clr -(sp) / pass nargs to init() for set/clrbound
236: jsr pc,_init
237: tst (sp)+
238: / Prepare to invoke procedure main, which should be first global variable.
239: mov _globals,r0
240: cmp $D_PROC,(r0) / make sure procedure main exists
241: bne nomain
242: mov 2(r0),-(sp) / push variable "main" on stack
243: mov (r0),-(sp)
244: / Build a list from the command line arguments.
245:
246: clr -(sp) / push &null for result from llist()
247: clr -(sp)
248: mov 4(r5),r1 / r1 <- nargs
249: mov 6(r5),r5 / point r5 at argv[0]
250: add $4.,r5
251: dec r1 / don't count argument 0 (command name)
252: dec r1 / or argument 1 (icon program name)
253: mov r1,r2
254: bgt 1f
255: clr r2
256: br 3f
257: 1:
258: mov (r5)+,r3 / build string descriptors for args
259: mov r3,-(sp) / push pointer to string
260: clr -(sp) / push string length of 0
261: 2:
262: tstb (r3)+ / calculate length of string
263: beq 2f
264: inc (sp) / increment string length
265: br 2b
266: 2:
267: sob r1,1b
268: 3:
269: mov r2,-(sp) / push nargs
270: jsr pc,_llist / make a list of the arguments
271:
272: / Invoke main() with one argument (the list of command line arguments).
273:
274: mov $1,-(sp)
275: clr r3 / clear generator frame pointer
276: clr r5 / clear procedure frame pointer
277: jsr pc,_invoke
278:
279: / If main() fails or returns, exit with 0 status.
280: 9:
281: clr -(sp) / exit status = 0
282: jsr pc,*$_c_exit
283: sys exit
284:
285: / Issue runerr(117,NULL) if main() is missing.
286:
287: nomain: / runtime error if procedure main missing
288: clr -(sp)
289: mov $117.,-(sp)
290: jsr pc,_runerr
291: sys exit
292:
293: / c_exit(i) - flush all buffers and exit with status i.
294:
295: _c_exit:
296: mov r5,-(sp)
297: mov sp,r5
298: #ifdef AZ
299: tst _monres / is monitoring on?
300: beq 1f
301: clr -(sp)
302: jsr pc,_monitor / yes, turn it off
303: tst (sp)+
304: #endif AZ
305: 1:
306: jsr pc,__cleanup
307: mov 4(r5),r0
308: sys exit
309:
310: .data
311:
312: / Waste first 30 or so bytes of memory, because all pointers must be
313: / greater than MAXTYPE.
314:
315: .=.+30.
316:
317: / Failure label for outermost expression (used if main() fails)
318:
319: flab: 0 / terminate program
320:
321: / Reserve storage for general use tended descriptors.
322:
323:
324: _tended:
325: 0; 0 / tended[0]
326: 0; 0 / tended[1]
327: 0; 0 / tended[2]
328: 0; 0 / tended[3]
329: 0; 0 / tended[4]
330: 0; 0 / tended[5]
331: _etended:
332:
333: _boundary: 0
334:
335: .bss
336: .data
337: #endif PDP11
338:
339: /*
340: * The following DummyRefs force the loader to load everything that
341: * iconx needs.
342: */
343: DummyRef(_clrbound)
344: DummyRef(_ckadd)
345: DummyRef(_ckmul)
346: DummyRef(_cksub)
347: DummyRef(_coact)
348: DummyRef(_cofail)
349: DummyRef(_coret)
350: DummyRef(_efail)
351: DummyRef(_efail)
352: DummyRef(_esusp)
353: DummyRef(_fail)
354: DummyRef(_gcollect)
355: DummyRef(_interp)
356: DummyRef(_invoke)
357: DummyRef(_lsusp)
358: DummyRef(_pfail)
359: DummyRef(_pret)
360: DummyRef(_psusp)
361: DummyRef(_setbound)
362: DummyRef(_suspend)
363:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.