.title $$main Start of C programs .ident /000011/ ; ;+ ; ; Index C main program ; Index C library global variables ; Index Operating-system unique variables ; Index $$opsy -- Operating system id. ; Index $$rsts -- Test if RSTS/E ; Index $$vms -- Test if VMS emulation ; Index $$pos -- Test if P/OS (Professional) ; Index $$uic -- RSX-11M default UIC ; Index $$stnd -- Stack end point ; Index $$scca -- RT-11 Ctrl/C flag ; Index $$task -- RSX-11M task name ; Index $$tick -- Clock interrupt rate ; ; Usage ; ; $$main:: /* Start of C programs */ ; ; extern int $$opsy; /* Operating system */ ; extern int $$rsts; /* Non-zero if RSTS/E */ ; extern int $$vms; /* Non-zero if VMS */ ; extern int $$pos; /* Non-zero if P/OS */ ; extern int $$uic; /* RSX: Default uic */ ; extern int $$stnd; /* Stack end point */ ; extern int $$scca; /* RT11: .scca control */ ; extern char $$task[]; /* RSX: task name */ ; extern int $$tick; /* Clock interrupt rate */ ; ; Internal ; ; extern int (*$$pptr)(); /* Profile printer */ ; extern int $$argc; /* Argument count */ ; extern int *$$argv[]; /* Argument list ptr. */ ; extern char *$$mtop; /* Free memory start */ ; extern char *$$mend; /* Free memory end */ ; ; Description ; ; This module contains the run-time startoff for C programs. ; It intializes the C environment and calls the main() subroutine. ; On return from the main program, exit() is called to close ; all files and return to the operating system. ; ; The following globals are defined in this module: ; ; $$opsy Operating system unique value. This ; value is 7 on RT11, and set as per the ; GTSK$ directive on RSX-based systems: ; RSX11-D 0. ; RSX11-M 1. ; RSX11-S 2. ; IAS 3. ; RSTS/E V7 4. ; VMS 5. ; RSX11-M+ 6. ; RT11 7. ; P/OS 9. ; ; $$rsts This value is non-zero if the program is ; running on RSTS/E. It is zero if the ; program is running native RSX, RT11, ; P/OS or VMS compatibility mode. ; ; $$vms This value is non-zero if the program is ; running (in compatibility mode) on Vax ; VMS. It is zero if the program is ; running native RSX, RT11, P/OS or on ; RSTS/E. ; ; $$pos This value is non-zero if the program is ; running on the Professional P/OS. It is ; zero if the program is running native ; RSX, RT11, or on RSTS/E or VMS. ; ; $$stnd The (top) end of the stack on entrance. ; ; $$scca On RT11, the .scca control word. This ; is needed to allow RSTS/E programs to ; trap end of file. ; ; $$task On RSX, the task name in Ascii. ; ; $$tick The clock interrupt rate. This is set ; at initialization on RT11 and on the ; first call to time() or ftime() on RSX. ; ; $$uic On RSX, the default UIC word from GTSK$. ; ; Internal ; ; All $$ values are for internal communication among runtime ; library routines. I.e., let them alone. ; ; Diagnostics ; ; On RSX, the task aborts with a BPT if the standard error file ; did not open. Otherwise, explanatory error messages are printed. ; ; Bugs ; ;- ; ; Run time startoff. ; ; Edit history: ; 000001 22-May-80 MM Redone from scratch ; 000002 26-Jun-80 MM Added wild card slot in erriov ; 000003 27-Jun-80 MM Moved file stuff to iov.mac ; 000004 21-Jul-80 MM Added $$tick ; 000005 29-Jul-80 MM Added $$mtop, $$mfree ; 000006 10-Dec-80 MM Added $$vms ; 000007 01-Mar-82 MM $$tick on both systems now ; 000008 22-Jun-82 MM No environment (for now) ; 000009 02-Jul-82 MM Newer library ; 000010 19-Jul-82 MM Added $$pos ; 000011 22-Nov-82 JSL Added support for initializers (based on original ; implementation on 2-Aug-82) .iif ndf rsx rsx = 1 ; ; NOTE: This module may not depend on the value of C$$EIS ; ; $$main is the entrance to C programs. CSV$ refers to this ; global to pull support.obj from the RSX library. As main programs ; cannot be loaded from a library on RT11, suport.obj must ; be named explicitly on all RT11 link commands. ; .if ne rsx ; ; RSX-specific equivalences ; MAXMCR = 80. ;MCR command line size -- same as $$init .endc .globl $$init ;11 ; ; Global data. ; The '$' symbols are for internal use. ; The '.' symbols are set by the loader. ; .psect c$data $$pptr:: .word .+2 ;Ptr to profile printer return ;Just hop back $$opsy:: .word 7 ;Gets op sys unique value ; RSX11-D 0. ; RSX11-M 1. ; RSX11-S 2. ; IAS 3. ; RSTS/E V7 4. ; VMS 5. ; RSX11-M+ 6. ;10 ; RT11 7. ; P/OS 9. $$rsts:: .word 0 ;Set non-zero on RSTS/E $$vms:: ;06 .word 0 ;Set non-zero on VMS ;06 $$pos:: .word 0 ;Set non-zero on P/OS ;10 $$tick:: ;07+ .word 60. ;Set to 50 (on RT11) by $$init if ;necessary. Reset on calls to time() ;and ftime() on RSX ;07- $$stnd:: .blkw 1 ;High-point of stack $$argc:: .word 0 ;Number of command args $$argv:: .word 0 ;-> argv[] $$mend:: ;05+ .word 0 ; End of untouched memory $$mlim:: .limit ; Memory limits $$mtop == $$mlim+2 ; We need first byte unused ;05- .if ne rsx ; ; RSX-specific global data. ; $$uic:: .blkw 1 ;Task default uic from GTSK$ $$task:: .ascii "??????" ;Gets the task name .byte 0 ;Null terminated. .iff ; ; RT11-specific global data. ; $$scca:: .word 0 ;Set non-zero if CTRL/C typed .endc .even ; ;11+ ; Stuff for initializers - must declare all three psects in order! ; .psect $init init: ;Start of initializer list .word $$init ;$$init() is the first initializer .psect $init$ ;The list itself .psect $init. inite: ;End of the initializer list ;11- .psect c$code ; ; Run time startoff. ; Called from the operating system ; .if eq rsx nop ;Dummy reenter address .endc $$main:: mov sp,$$stnd ;Save end of stack clr r5 ;No environment linkage yet ; ;11+ ; Call $$init() to set up the state of the world, and then call the user's ; initializers. ; ; Warning: The following code depends on two facts: ; - There is always at least on initializer ($$init()) ; - This code cannot be entered except by flowing into it. ; If either of these may be false, a branch should be added to ; start the loop at the cmp, to ensure that r2 points to a valid ; address. ; ; Note: You may wonder why main() isn't called in the initializer loop. ; The problem is the arguments that must be passed to main. If we push ; them on the stack BEFORE the loop, they are incorrect, since $$argc and ; and $$argv are set up by $$init(), which is called in the loop. So ; we'd have to push and pop them each time around the loop - which costs ; more than the separate call. (Besides, $$init() is, logically, an ini- ; tializer; main() is not.) ; mov #init,r2 ;-> First initializer 10$: call @(r2)+ ;Call the next initializer cmp r2,#inite ;Any more? blo 10$ ;Do them, too ;11- clr -(sp) ;No environment ;08 mov $$argv,-(sp) ;Arg. vector mov $$argc,-(sp) ;Arg. count call main ;Off we go mov #E$$XOK,-(sp) ;Normal exit ;09 call exit ;Normal exit ;09 crash ;Can't happen ;09 .end $$main