Annotation of 43BSD/contrib/icon/iconx/start.s, revision 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.