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)

Defined functions

_c_exit defined in line 295; used 5 times
_mstart defined in line 203; used 2 times
b1 defined in line 72; used 1 times
  • in line 84
f1 defined in line 144; used 1 times
f2 defined in line 93; used 1 times
  • in line 74
f9 defined in line 114; never used
nomain defined in line 287; used 2 times

Defined variables

_boundary defined in line 333; used 3 times
_etended defined in line 331; used 2 times
_tended defined in line 324; used 2 times
flab defined in line 319; used 2 times
signal defined in line 199; used 1 times
Last modified: 1984-11-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1209
Valid CSS Valid XHTML 1.0 Strict