Annotation of 43BSD/contrib/icon/iconx/start.s, revision 1.1.1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.