|
|
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.