.title $$init One-time initialization code .ident "V02.01" ;+ ; Index C program initialization ; ; Usage ; ; Internal ; ; $$init() ; ; Description ; ; This is a one-time initialization routine for C programs. It ; sets up the trap vectors, initializes the free memory pointers, ; determines the task name, assigns the terminal lun to 1, prompts ; for a command line if one was not given and proceeds to parse ; the command line if one was given and form the argv[] array. ; argv[0] is set to the task name. ; ; Diagnostics ; ; No memory ; ; This message suggests a severe case of program ; immensity. ; ; Cannot parse command line ; ; The user supplied an illegal command line. ;- ; Edit history: ; V02.00 19-Oct-82 TTC Rework of old CS library. ; V02.01 25-Jan-83 TTC Fixed argv[0] (task name) bug. ; .mcall GPRT$S, GTSK$S, ALUN$S, QIOW$S, SVTK$S MAXMCR = 80. ; Mcr command line size R.PARM = 30 ; RSX emulator chain line number SPACE = 40 .psect c$data iosb: .word 0,0 nullst: .word 0 $$erec:: .blkw 41. ; used by GTSK $$esiz == .-$$erec ; Error record size badmem: .asciz <015><012>/?????? - No memory./<12> memsz = . - badmem badcmd: .asciz <015><012>/?????? - Cannot parse command line./<12> cmdsz = . - badcmd .even .psect c$code $$init:: jsr r5,csv$ ; Link environments ; ; Set up the sst vector. ; SVTK$S #$$sstt,#10 ; Table is in "traps" module ; ; Initialize free memory pointers ; sub #3*2,sp ; Get partition return area mov sp,r1 ; r1 -> gprt$ buffer GPRT$S ,r1 ; Get partition parameters mov 2(r1),r1 ; Partition size in clicks ash #6,r1 ; Shift left to mul. by 32 add $dsw,r1 ; Top of memory (correctly) mov r1,$$mend ; Save true top of memory add #3*2,sp ; Dump the stack ; ; Do a get task to get the task name and default UIC ; GTSK$S #$$erec ; Get task parameters mov #2,(sp) ; Get task name (2 words) mov #$$erec+<0.*2>,-(sp) ; From here mov #$$task,-(sp) ; To here call r50toa ; Using C library routine cmp (sp)+,(sp)+ ; Cleanup stack clr (sp) ; Assume no task name needed ;01 mov $$erec+<7.*2>,$$uic ; Default uic word (word 07) ; ; Allocate the output buffer to the default size ; mov #$$bsiz,-(sp) ; Push default buffer size call outbuf ; call allocation routine tst (sp)+ ; ; Assign terminal lun ; ALUN$S #tty.lun,#"TI,#0 ; ; Get command line. ; mov #MAXMCR+2,r0 ; Get command line buffer call $$aloc tst r0 ; zero means trouble bne 20$ ; Ok, continue mov #$$task,r0 ; Put task name into mov #badmem,r1 ; error message. add #2,r1 10$: movb (r0)+,(r1)+ tstb (r0) ; End of task name? bne 10$ ; (no) mov #memsz,-(sp) ; push error message size mov #badmem,-(sp) ; and error meassage jmp fail ; Exit. 20$: mov r0,-(sp) ; Push GMCR buffer adderss mov (pc)+,(r0) ; Fake MCR dispatch (GMCR$S) .byte 127.,41. ; as RSX can't do it at runtime emt 377 bcs 30$ ; Branch if failure mov $dsw,r1 ; r1 has number of bytes add r0,r1 ; r1 --> last byte in buffer clrb 2(r1) ; nullify it br domcr ; continue onward 30$: tst $$narg ;Really want a command line? bne 80$ ;If ne, supresss prompt, and go on. mov #$$task,r2 ;get address of our task name mov r0,r1 ;copy mcr buffer address tst (r1)+ ;bump up by two mov (r2)+,(r1)+ ;Copy task name mov (r2)+,(r1)+ mov (r2)+,(r1)+ 40$: cmpb #SPACE,-(r1) ;Any spaces in the name? beq 40$ ;Check 'em all ; ; Note: the above loop depends on the fact that the GMCR directive ; has put a non-space character (actually, '1') at the left end of ; the MCR buffer. ; inc r1 ;r1 -> first blank character mov r1,r2 ;Save location movb #'>,(r1)+ ;Make it look like an RSX prompt movb #SPACE,(r1) ;Space it out a little sub r0,r2 ;Get length with terminators tst (r0)+ ;Skip over GMCR DPB code tst $$prmt ;User supply prompt? beq 55$ ;No, use task name mov $$prmt,r3 ;r3 --> user prompt string clr r2 ;r2 used for prompt length 45$: tstb (r3)+ ;end of string? beq 50$ ;yes inc r2 ;no, count it br 45$ ;keep goin' 50$: qiow$s #IO.WVB,#1,#1,,#iosb,,<$$prmt,r2,#'$> ; prompt for args br 60$ 55$: qiow$s #IO.WVB,#1,#1,,#iosb,, ; prompt for argv 60$: bcs 80$ ;No arg line if error tst -(r0) ;Reset pointer to the buffer movb #SPACE,-1(r1) ;Overwrite the '>' qiow$s #IO.RVB,#1,#1,,#iosb,, ; read command line bcs 80$ ;No command if error cmpb iosb,#IS.SUC ;Finish ok? bne 80$ ;No command if error finish add iosb+2,r1 ;Point to the end of the string clrb (r1) ;Terminate the string clr (sp) ;Task name is in buffer, so don't pass another br domcr 80$: ; ; No GMCR command line. ; mov #$$task,(sp) ; Make sure there is a task name call $$free ; If no line, release buffer mov #nullst-2,r0 ; Point to null string domcr: mov #$$argv,-(sp) ; Gets argv pointer tst (r0)+ ; Point at command line mov r0,-(sp) ; And stuff it, too ; ; Common code -- parse the command line ; docmd: call $$gcmd ; Parse it cmp r0,#-1 ; Badly parsed? beq cmderr ; Sorry. mov r0,$$argc ; and save the count add #<3*2>,sp ; Clear the stack jmp cret$ ; All finished cmderr: mov #$$task,r0 ; Put task name mov #badcmd,r1 ; into error message. tst (r1)+ 90$: movb (r0)+,(r1)+ tstb (r0) ; End of task name? bne 90$ ; (no) mov #cmdsz,-(sp) ; Push message size mov #badcmd,-(sp) ; and address on stack fail: call ttosf ; and output to terminal. jmp $$fail ; Exit. .end