;++ ; ; Installation notes: ; ; This program performs the general functions of a device symbiont ; under VAX/VMS. It is designed to perform multiple forms of output to the ; device, in keeping with the Varian plotter for which it was written, on ; which both plots can be made, and alphanumeric text generated for the ; printing of files. ; ; Files entered on the queues have a specific format, based on the ; implementation of the plot-queueing command at the JCF. The symbiont ; recognizes such files, and processes them in a special way; ie each record ; is assumed to contain a specification of a file to plot; that file is then ; plotted by calling the routine PLOT_VARIAN. Plot_varian is not supplied; ; and can be locally implemented in specific for the devices desired. ; ; If there are any problems, please feel free to contact us at: ; Joint Computer Facility ; Room 1-106 ; Massachusettes Institue of Technology ; Cambridge, Mass, 02139 ; Phone: (617) 253-2041 ; .title VSMB VAX/VMS VARIAN SYMBIONT .ident /01.1/ ;++ ; FACILITY: VAX/VMS VARIAN SYMBIONT ; ; ABSTRACT: This program serves as the sybmiont to control ; the Varian electrostatic plotter. ; ; ENVIRONMENT: NATIVE/USER MODE NON-PRIVILEGED CODE ; ; AUTHOR: Neal Lippman, MIT-JCF, CREATION DATE: 22-JUN-80 ; ; MODIFIED BY: ; ; 7/16/80 [NL001] -- Do form feed on resume/top_of_file ; ;-- .page .sbttl Data segment declaration .library \sys$library:lib\ ; ;macros: ; ; ;program section declaration macros: ; ; arguments are: ; ; 1) NAME = psect section name ; 2) ALIGN = alignment keyword (d=LONG) ; ; generate a pure section -- code and read only data ; .macro pure_section name=vsmb_pure,align=long .psect name,rd,nowrt,exe,align .endm pure_section ;generate an inpure section -- read/write data .macro impure_section name=vsmb_impure,align=long .psect name,rd,wrt,noexe,align .endm impure_section ; ;macros for error signalling: ; .macro signal condition,p1,p2,p3,p4,p5,p6,p7,p8 $$$args=1 .irp arg, .if nb arg pushl arg $$$args=$$$args+1 .endc .endr pushl #condition calls #$$$args,lib$signal .endm signal ; ; system wide symbolic name definitions: ; $shrdef ;shared message definitions $opcdef ;opcom definitions $jbcmsgdef ;job controller message definitions $iodef ;I/O function code definitions $pcbdef ;process control block definitions $msgdef ;message definitions $fabdef ;file access block definitions $rabdef ;record access block definitions $namdef ;name block definitions $dibdef ;device information block offsets $chfdef ;condition handling facility definitions $rmsdef ;define RMS status codes $accdef ;accounting values ; ; definition of message modifiers ; $gblini $defini mod $equlst mod__,,1,8,<- - ;success > $equlst mod__,,4,8,<- - ;printing aborted - ;error from RMS - ;varian device error > $defend mod ; ; a few constants: ; vsmb_k_usernamesz=12 ;size of username string vsmb_c_bufsz=256 ;size of cruft buffer ; ; define symbiont states: ; $defini state $equlst state__,,0,1,<- - ;symbiont idle - ;assigning device - ;suspended - ;plotting file - ;doing rundown - ;opening file > $defend state ; ; define offset to delete flag in flag byte of symbiont message ; $vield pqr,0,<- ,- ;delete flag > ;ignore rest of flags ; ; define message from job controller format ; $defini sim $def sim$w_msgtyp .blkw 1 ;symbiont manager message type code $def sim$w_rest .blkw 1 ;rest of short messages $def sim$l_uic .blkl 1 ;UIC of requesting process $def sim$t_usernam .blkb vsmb_k_usernamesz ;username, not counted, blank filled $def sim$q_qtime .blkq 1 ;time job was queued $def sim$t_volnam .blkb 16 ;device ID field - counted string $def sim$g_fileid .blkb 6 ;file ID field $def sim$g_dirid .blkb 6 ;directory ID field $def sim$b_flags .blkb 1 ;file print flags $def sim$b_filcopy .blkb 1 ;number of copies to print $def sim$w_pagcnt .blkw 1 ;max pages to print $def sim$t_prtnam .blkb 16 ;device name for printing - counted ;string $def sim$t_filnam .blkb 20 ;filename to print - counted string $def sim$t_acntname .blkb 16 ;user's account name $def sim$k_size ;size of this structure $defend sim vsmb_mbefn = 0 ;event flag for send to JBC mailbox ; ; define symbiont global data base ; $defini vsd $def vsd_w_mbchan .blkw 1 ;mailbox input channel $def vsd_b_state .blkb 1 ;current state $def vsd_w_unit .blkw 1 ;mailbox unit $def vsd_q_userdesc .blkq 1 ;username descriptor $def vsd_t_simmsg .blkb sim$k_size ;simbiont message buffer $def vsd_w_jbcchan .blkw 1 ;JBC mailbox channel $def vsd_g_msgtomgr ;message to job controller $def vsd_t_tbuf .blkb vsmb_c_bufsz ;temp buffer $def vsd_q_iosb .blkq 1 ;an I/O status block $def vsd_w_vchan .blkw 1 ;channel to plot to $def vsd_b_dcode .blkb 1 ;dispatch code for processing routine $def vsd_b_err_flags .blkb 1 ;error flags _vield vsd,0,<- ,- ;aborting ,- ;error getting a record ,- ;error opening file ,- ;error on output device - ;file is a varian plot specification > ;file (from plot command) ;adjacency of the next two assumed $def vsd_q_plotdata ;accounting info $def vsd_l_numvecs .blkl 1 ;number of vectors plotted $def vsd_l_numplots .blkl 1 ;number of plots made .=<.+3>&-4 ;long word align $def vsd_g_fab .blkb fab$c_bln ;fab for file $def vsd_g_rab .blkb rab$c_bln ;rab for file $def vsd_g_nam .blkb nam$c_bln ;name block to open file by file ID $def vsd_w_mbreadlen .blkw 1 ;length of read from mailbox $def vsd_k_size ;size of this data structure $defend vsd .page .sbttl Condition Handler ;++ ; FUNCTIONAL DESCRIPTION: ; ; Condition Handler for the VAX/VMS Varian symbiont. ; It sends the appropriate messages to ; the operator(s), and exits on a system error or returns to the ; symbiont on a signalled condition. ; ; CALLING SEQUENCE: ; ; Entered when and exception occurs, or when an error is signalled. ; Called by CALLS/G by condition handling facility ; ; INPUT PARAMETERS: ; ; As per condition handling standard ; ; IMPLICIT INPUTS: ; ; None ; ; OUTPUT PARAMETERS: ; ; None ; ; IMPLICIT OUTPUTS: ; ; None ; ; COMPLETION CODES: ; ; None ; ; SIDE EFFECTS: ; ; On system error, symbiont is exited ; ;-- ;own storage impure_section sig_name: .blkl 1 pure_section facility_desc: .long 20$-10$ .long 10$ 10$: .ascii /VARSMB/ 20$: ;storage for signal name .page vsmb_handler: .word ^m ;entry mask movl chf$l_sigarglst(ap),r2 ;get addr of signal argument ;list subw2 #2,chf$l_sig_args(r2) ;don't pass PC,PSL movl chf$l_sig_name(r2),sig_name ;save signal name pushaq facility_desc ;push facility name pushaw putmsg_action ;push putmsg action routine pushl r2 ;push addr of signal arg list calls #3,g^sys$putmsg ;call putmgs facility tstw sig_name+2 ;system exception (=0) bneq 10$ ;branch if not $exit_s ;else exit 10$: ret ; ; putmsg action routine ; putmsg_action: .word ^m ;entry mask movl 4(ap),r2 ;get addr of message ;descriptor movzbl #120,r6 ;assume max message length cmpw (r2),r6 ;compare with actual len bgeq 5$ ;branch if greater -- truncate movzwl (r2),r6 ;else use actual length 5$: subl2 r6,sp ;make room on stack for movc3 r6,@4(r2),(sp) ;move string onto stack pushl #0 ;no reply ID movzwl #opc$_rq_rqst!- ;request type <- ;send to print @8>,-(sp) pushl sp ;create descriptor addl3 r6,#8,-(sp) ;... movl sp,r0 ;get descriptor addr $sndopr_s (r0) ;send message to opers clrl r0 ;inhibit sending to sys$output ;and sys$error ret .page .sbttl Initialization Routine ;++ ; FUNCTIONAL DESCRIPTION: ; ; Once only init routine ; ; CALLING SEQUENCE: ; ; Entered as main symbiont entry point ; ; INPUT PARAMETERS: ; ; None ; ; IMPLICIT INPUTS: ; ; None ; ; OUTPUT PARAMETERS: ; ; r11 = address of symbiont data base ; ; IMPLICIT OUTPUTS: ; ; Init done message send to Job Controller ; Channel assigned to Job Controller's mbox ; Mailbox created to recieve messages ; ; COMPLETION CODES: ; ; None ; ; SIDE EFFECTS: ; ; None ; ;-- ;own data jbcmailbox: ;name of job controller's mailbox .long 20$-10$ .long 10$ 10$: .ascii /_/ .long sys$c_jobctlmb .ascii /:/ 20$: vsmb_start:: .word 0 ;entry mask moval vsmb_handler,(fp) ;set condition handler in stack frame $setast_s #0 ;disable AST delivery during init moval vsd_g_data,r11 ;set address of data base movb #state__idle,vsd_b_state(r11) ;set state initially to idle ; ; assign channel to job controller's mailbox ; $assign_s jbcmailbox,- ;device to assign to vsd_w_jbcchan(r11) ;addr for channel blbs r0,20$ ;successful? signal jbc$_mbasgn,#0,r0 ;signal the error 10$: $exit_s ;exit ; ; create symbiont's mailbox ; 20$: $crembx_s - ;create the mbox promsk=#0,- ;protection maxmsg=#sim$k_size,- ;max size of message bufquo=#2*sim$k_size,- ;two messages, max chan=vsd_w_mbchan(r11) ;addr for channel blbs r0,30$ ;success? signal jbc$_symbcre,#0,r0 ;signal the error brb 10$ ;and exit 30$: ; ; init some values in the data segment ; clrb vsd_b_err_flags(r11) ;clear all flags moval vsd_g_fab(r11),r6 ;get fab addr moval vsd_g_rab(r11),r7 ;get rab addr moval vsd_g_nam(r11),r8 ;get nam block addr movb #fab$c_bid,fab$b_bid(r6);create fab movb #fab$c_bln,fab$b_bln(r6);... movb #rab$c_bid,rab$b_bid(r7);create rab movb #rab$c_bln,rab$b_bln(r7);... movb #nam$c_bid,nam$b_bid(r8);create nam block movb #nam$c_bln,nam$b_bln(r8);... movl r8,fab$l_nam(r6) ;set nam block addr in fab movl r6,rab$l_fab(r7) ;set fab addr in rab movl #fab$m_nam,fab$l_fop(r6);set nam block open in fab movw #sim$k_size,vsd_w_mbreadlen(r11) ;set initial mbox read length ; ; get mailbox channel info ; movw vsd_w_mbchan(r11),r0 ;get channel number subl2 #dib$k_length,sp ;make buffer on stack movl sp,r2 ;r2 is buffer pointer pushl r2 ;push addr on stack movzwl #dib$k_length,-(sp) ;and put length on movl sp,r1 ;get descriptor address $getchn_s chan=r0,- ;channel scdbuf=(r1) ;buffer movw dib$w_unit(r2),vsd_w_unit(r11) ;save unit number ; ; set unsolicited AST to jbc mailbox ; bsbw vsmb_setmbast movw vsd_w_unit(r11),r0 ;get unit number of our mailbox bsbw vsmb_init_done ;send init done message $setast_s #1 ;enable ASTs brw vsmb_main ;enter main loop .page .sbttl Subroutines -- Uic routines ;++ ; FUNCTIONAL DESCRIPTION: ; ; These routines are used to set/restore the symbiont's UIC ; ; CALLING SEQUENCE: ; ; BSB/JSB ; Registers: ; r0,r1 -- scratch ; ; INPUT PARAMETERS: ; ; r11 = address of data segment ; ; IMPLICIT INPUTS: ; ; Requestor's UIC in the symbiont start print message buffer ; ; OUTPUT PARAMETERS: ; ; None ; ; IMPLICIT OUTPUTS: ; ; None ; ; COMPLETION CODES: ; ; None ; ; SIDE EFFECTS: ; ; The symbiont's UIC is set/reset ; ;-- .enabl lsb vsmb_setuic: movl sim$l_uic+vsd_t_simmsg(r11),r5 ;get uic of requestor brb 10$ vsmb_restoreuic: movl #<<1@16>+4>,r5 ;get our uic [1,4] 10$: $cmkrnl_s routin=20$ ;set the uic rsb 20$: ;kernel mode routine to set uic .word 0 ;save no regs movl @#sch$gl_curpcb,r1 ;get PCB addr movl r5,pcb$l_uic(r1) ;set the uic movl #1,r0 ;must return success ret .dsabl lsb .page .sbttl Subroutine -- Accounting Routine ;++ ; FUNCTIONAL DESCRIPTION: ; ; This routine sets up an accounting information buffer ; for the accounting system and used the sndacc system service ; to submit it. ; ; CALLING SEQUENCE: ; ; BSB/JSB ; Registers: ; r2 = movc5 destroyed ; r3 = descriptor address,scratch ; r4,r5 - movc5 destroyed ; r6 = buffer pointer ; ***These registers are restored on exit ; ; INPUT PARAMETERS: ; ; r11 = address of data segment ; ; IMPLICIT INPUTS: ; ; Data in data segment ; ; OUTPUT PARAMETERS: ; ; None ; ; IMPLICIT OUTPUTS: ; ; None ; ; COMPLETION CODES: ; ; None ; ; SIDE EFFECTS: ; ; None ; ;-- ; ; some symbols defns ; space=^a/ / vectors=31 ;bucket # for vectors plots=30 ;bucket # for plots acc$k_genlchg=^x1111 ;general charge code (JCF defined) acc_varcharge: .long ^x200 ;code for varian charges pure_section vsmb_account: pushr #^m ;save registers subl2 #132,sp ;make buffer on stack movl sp,r6 ;r2 is buffer pointer movw #acc$k_insmesg,0(r6) ;insert message code movw #130,2(r6) ;used by JCF accounting system movw #acc$k_genlchg,4(r6) ;general charge clrw 6(r6) ;zero fill movl acc_varcharge,8(r6) ;varian charge movc3 #12,vsd_t_simmsg+sim$t_usernam(r11),12(r6) movl #plots,24(r6) ;code for plots movl vsd_l_numplots(r11),28(r6) ;number of plots movl #vectors,32(r6) ;code for vectors movl vsd_l_numvecs(r11),36(r6) ;number of vectors movc5 #0,0,#0,#92,40(r6) ;zero fill the rest pushl r6 ;create descriptor on stack movzbl #132,-(sp) ;... movl sp,r3 ;get descriptor address $sndacc_s (r3) ;send the accounting buffer blbs r0,30$ ;br if okay signal jbc$_acntwrt,#0,r0 ;signal the error 30$: addl3 #132,r6,sp ;pop buffer off stack popr #^m ;pop regies rsb .page .sbttl Subroutines -- Send messages to Job Controller ;++ ; FUNCTIONAL DESCRIPTION: ; ; This routines sends the init done message to the Job Controller ; ; CALLING SEQUENCE: ; ; BSB/JSB ; ; Registers: ; r0,r1 -- scratch ; ; INPUT PARAMETERS: ; ; r0 = unit number of symbiont's mailbox ; r11 = address of data base ; ; IMPLICIT INPUTS: ; ; None ; ; OUTPUT PARAMETERS: ; ; None ; ; IMPLICIT OUTPUTS: ; ; Init done message sent ; ; COMPLETION CODES: ; ; None ; ; SIDE EFFECTS: ; ; None ; ;-- vsmb_init_done: movw r0,vsd_g_msgtomgr+2(r11) ;set mb unit in buffer movw #msg$_smbini,vsd_g_msgtomgr(r11) ;set init_done message type $qiow_s - ;send the message efn=#vsmb_mbefn,- ;event flag chan=vsd_w_jbcchan(r11),-;channel func=#io$_writevblk!io$m_now,- ;write with no wait iosb=vsd_q_iosb(r11),- ;iosb p1=vsd_g_msgtomgr(r11),- ;message p2=#4 ;length blbc r0,20$ ;error? movzwl vsd_q_iosb(r11),r0 ;get I/O status blbs r0,30$ ;br if okay 20$: signal jbc$_mbwrite,#0,r0 ;signal the error 30$: rsb ;++ ; FUNCTIONAL DESCRIPTION: ; ; This routine is called to send a file_done message to the ; Job Controller ; ; CALLING SEQUENCE: ; ; BSB/JSB ; ; Registers: ; r0-r5 are destroyed ; ; INPUT PARAMETERS: ; ; r3 = reason for termination ; r11 = address of data segment ; ; IMPLICIT INPUTS: ; ; None ; ; OUTPUT PARAMETERS: ; ; None ; ; IMPLICIT OUTPUTS: ; ; None ; ; COMPLETION CODES: ; ; None ; ; SIDE EFFECTS: ; ; Mailbox read length is reset to init message length ; ;-- vsmb_file_done: movw #msg$_smbdon,vsd_g_msgtomgr(r11) ;set message done code movw r3,vsd_g_msgtomgr+2(r11) ;set reason code movc5 #0,0,#0,#14,vsd_g_msgtomgr+4(r11) ;zero fill rest $qiow_s - ;send the message efn=#vsmb_mbefn,- ;event flag number chan=vsd_w_jbcchan(r11),- ;channel func=#io$_writevblk!io$m_now,- ;write with no wait iosb=vsd_q_iosb(r11),- ;iosb p1=vsd_g_msgtomgr(r11),- ;buffer p2=#16 ;len blbc r0,20$ ;error? movzwl vsd_q_iosb(r11),r0 ;get iosb blbs r0,30$ ;okay? 20$: signal jbc$_mbwrite,#0,r0 ;signal the error 30$: movw #sim$k_size,vsd_w_mbreadlen(r11) ;reset mb read length to max rsb .page .sbttl Subroutine -- Set mailbox AST ;++ ; FUNCTIONAL DESCRIPTION: ; ; This routine sets an unsolicited AST on the Job Controller's ; mailbox ; ; CALLING SEQUENCE: ; ; BSB/JSB ; ; Registers: ; r0 destroyed ; INPUT PARAMETERS: ; ; None ; ; IMPLICIT INPUTS: ; ; r11 = address of data segment ; ; OUTPUT PARAMETERS: ; ; None ; ; IMPLICIT OUTPUTS: ; ; None ; ; COMPLETION CODES: ; ; None ; ; SIDE EFFECTS: ; ; None ; ;-- vsmb_setmbast: $qiow_s - ;set unsolicited AST efn=#vsmb_mbefn,- ;event flag chan=vsd_w_mbchan(r11),-;channel func=#io$_setmode,- ;set mode function iosb=vsd_q_iosb(r11),- ;iosb p1=vsmb_mbast ;AST routine blbc r0,10$ ;error? movzwl vsd_q_iosb(r11),r0 ;get iosb blbs r0,20$ ;okay? 10$: signal jbc$_mbsetast,#0,r0 ;signal the error 20$: rsb .page .sbttl Subroutines -- FORTRAN support routines ;++ ; FUNCTIONAL DESCRIPTION: ; ; This routine is for use by FORTRAN routines. It sets the device ; error flag, and signals the input error. ; ; CALLING SEQUENCE: ; ; CALLS/G ; ; INPUT PARAMETERS: ; ; @4(ap) = condition code to signal ; ; IMPLICIT INPUTS: ; ; None ; ; OUTPUT PARAMETERS: ; ; None ; ; IMPLICIT OUTPUTS: ; ; None ; ; COMPLETION CODES: ; ; None ; ; SIDE EFFECTS: ; ; The VARERR bit in the error flags is set ; ;-- ; ; Note that the address of the data segment is reset, as the status of ; the registers is unpredictable on entry. ; vsmb_prterr:: .word ^m ;entry mask moval vsd_g_data,r11 ;set address of data segment bisb #vsd_m_varerr,vsd_b_err_flags(r11) ;set the device error bit signal jbc$_printout,#0,@4(ap) ;signal the error ret ;++ ; FUNCTIONAL DESCRIPTION: ; ; This routine is called by FORTRAN routines to check the abort ; bit in the error flags. ; ; CALLING SEQUENCE: ; ; CALLS/G ; ; INPUT PARAMETERS: ; ; None ; ; IMPLICIT INPUTS: ; ; None ; ; OUTPUT PARAMETERS: ; ; None ; ; IMPLICIT OUTPUTS: ; ; None ; ; COMPLETION CODES: ; ; The value of the abort bit is returned (0/1) ; ; SIDE EFFECTS: ; ; None ; ;-- ; ; Note that the address of the data segment is reset, as the status of ; the registers is unpredictable on entry. ; vsmb_chkabort:: .word ^m ;entry mask clrl r0 ;assume not set moval vsd_g_data,r11 ;get address of data segment bbc #vsd_v_abort,vsd_b_err_flags(r11),10$ ;branch if not set incl r0 ;return set 10$: ret .page .sbttl Symbiont Mainline ;++ ; FUNCTIONAL DESCRIPTION: ; ; This is the symbiont mainline. It is entered directly from ; the init routine, and loops around, processing files. ; ; CALLING SEQUENCE: ; ; BR ; ; INPUT PARAMETERS: ; ; None ; ; IMPLICIT INPUTS: ; ; r11 = address of data segment ; At wake, the file is open, and the dispatch code is in the data ; segment; a channel has been assigned to the requested device. ; ; OUTPUT PARAMETERS: ; ; None ; ; IMPLICIT OUTPUTS: ; ; None ; ; COMPLETION CODES: ; ; None ; ; SIDE EFFECTS: ; ; The file is plotted/printed as requested. ; ;-- ; ; this is the data segment ; impure_section vsd_g_data:: .blkb vsd_k_size pure_section ; ; declaration of processing routine dispatch table. ; ; the first byte of each record of a file placed on the queue ; contains a dispatch code which specifies the routine ; to be used to process the file. ; dispatch_table: ;used to dispatch to processing routine .long vsmb_vplot ;plot specification file max_d=1 vsmb_main: moval dispatch_table,r2 ;get addr of dispatch table 10$: $hiber_s ;wait for something todo movzbl vsd_b_dcode(r11),r4 ;get dispatch code cmpb #max_d,r4 ;is it valid? bgtr 15$ ;br onward if okay signal vmg_invdcod ;signal the error brb 10$ ;and branch back 15$: movb #state__active,vsd_b_state(r11) ;set us active bbc #vsd_v_openerr,vsd_b_err_flags(r11),35$ ;br if opened successfully moval vsd_t_simmsg+sim$t_filnam+1(r11),-(sp) ;push file name addr movzbl vsd_t_simmsg+sim$t_filnam(r11),-(sp) ;push length of file name movl sp,r3 ;save descriptor address pushl vsd_g_fab+fab$l_stv(r11) ;push RMS status value pushl vsd_g_fab+fab$l_sts(r11) ;push RMS status code pushl r3 ;push filename descriptor pushl #1 ;one FAO arg pushl #<4@16>!shr$_openin!4 ;condition code calls #5,lib$signal ;signal the error addl2 #8,sp ;pop the descriptor off the stack brw 90$ ;and exit ; ; now dispatch to the appropriate processing routine ; 35$: movl (r2)[r4],r3 ;get addr of routine to use jsb (r3) ;and subroutine to it ; ; perform rundown on file: ; 90$: $setast_s #0 ;disable AST delivery tstw vsd_g_fab+fab$w_ifi(r11) ;has open been done? beql 120$ ;br if not bicl #fab$m_dlt,vsd_g_fab+fab$l_fop(r11) ;clear delete bit tstw vsd_g_nam+nam$w_did(r11);does file have a directory? beql 113$ ;if no, delete, no matter what bbs #vsd_v_abort,vsd_b_err_flags(r11),115$ ;br if aborting 112$: bbs #vsd_v_vplot,vsd_b_err_flags(r11),113$ ;branch if plot file bbc #pqr$v_delete,vsd_t_simmsg+sim$b_flags(r11),115$ ;branch if not delete 113$: bisl #fab$m_dlt,vsd_g_fab+fab$l_fop(r11) ;set delete bit 115$: bsbw vsmb_setuic ;set UIC to requestor's $close vsd_g_fab(r11) ;close the file clrw vsd_g_rab+rab$w_isi(r11) ;quick disconnect bsbw vsmb_restoreuic ;set uic back to [1,4] ; ; set ending status ; 120$: movzbl #mod__rmserr,r3 ;assume input error bitb #vsd_m_openerr!- ;check open error, vsd_m_geterr,- ;get error vsd_b_err_flags(r11) ;was either set? bneq 130$ ;br if no movzbl #mod__varerr,r3 ;assume device error bbs #vsd_v_varerr,vsd_b_err_flags(r11),130$ ;br if print error movzbl #mod__abort,r3 ;set abort bbs #vsd_v_abort,vsd_b_err_flags(r11),130$ ;br if aborting movzbl #mod__success,r3 ;okay, successful ; ; final cleanup ; 130$: clrb vsd_b_err_flags(r11) ;reset all flags $dassgn_s vsd_w_vchan(r11);deassign the varian movb #state__idle,vsd_b_state(r11) ;set state to idle bsbw vsmb_file_done ;send file done message $setast_s #1 ;enable ASTs brw vsmb_main ;and loop back for another go .page .sbttl Plot Routine ;++ ; FUNCTIONAL DESCRIPTION: ; ; This routine is called to process a plot specification file ; (input from the PLOT command). ; ; CALLING SEQUENCE: ; ; BSB/JSB ; ; Registers: ; r0,r1 - scratch ; r2 - rab addr ; r8 - scratch ; r7 - scratch ; r9 - saved stack pointer ; r10 - buffer pointer ; INPUT PARAMETERS: ; ; None ; ; IMPLICIT INPUTS: ; ; r11 = addr of data segment ; File is open on rab/fab ; ; OUTPUT PARAMETERS: ; ; None ; ; IMPLICIT OUTPUTS: ; ; None ; ; COMPLETION CODES: ; ; None ; ; SIDE EFFECTS: ; ; The file is processed. ; ;-- ; ; define offsets into data record ; delete=0 expan=1 copies=2 .extrn plot_varian vsmb_vplot: movl sp,r9 ;save SP for return subl2 #100,sp ;make a buffer on stack movl sp,r10 ;make R10 buffer pointer clrq vsd_q_plotdata(r11) ;init vecs,plots moval vsd_g_rab(r11),r2 ;get rab addr movl r10,rab$l_ubf(r2) ;set buffer addr in rab movw #100,rab$w_usz(r2) ;set buffer size in rab pushaw vsd_w_vchan(r11);push channel address calls #1,var$setchan ;set channel addr in varutil common block read: bitb #vsd_m_varerr!vsd_m_abort,vsd_b_err_flags(r11) ;are we aborting or device error? bneq 9$ ;branch if so $get rab=(r2) ;get a record blbs r0,20$ ;success? cmpl #rms$_eof,r0 ;end of file? beql 10$ ;br if so bisb #vsd_m_geterr,vsd_b_err_flags(r11) ;set error bit brb 10$ 9$: bsbw vsmb_form_feed ;advance paper on varian 10$: movzbl #state__done,vsd_b_state(r11) ;set done state bsbw vsmb_account ;do accounting movl r9,sp ;reset stack pointer rsb 20$: pushab 4(r10) ;save address of file name string movzbl 3(r10),-(sp) ;put length of filename on stack movl sp,r8 ;save descriptor addr pushab vsd_t_simmsg+sim$t_usernam(r11) ;push username addr movzwl #12,-(sp) ;push length of username pushl sp ;and save username address pushab expan(r10) ;push expansion count pushab copies(r10) ;push copy count pushab delete(r10) ;push delete flag pushl r8 ;push filename descriptor calls #6,plot_varian ;plot the file cmpl #<-1>,r0 ;unsuccessful plot returns -1 bneq 24$ ;br if successful pushab vsd_t_simmsg+sim$t_usernam(r11) ;push username addr movzwl #12,-(sp) ;push length movl sp,r7 ;save username addr pushl r8 ;push filename descr pushl r7 ;push username descr pushl #2 ;fao count pushl #vmg_filerr ;push message code pushl #4 ;argument count movl sp,r7 ;get message vector addr pushaq facility_desc ;push facility name pushaw vsmb_tell_varian ;push action routine pushl r7 ;push message vector addr calls #3,g^sys$putmsg ;call putmsg brw 25$ ;and loop 24$: addl2 r0,vsd_l_numvecs(r11) ;add in plotted vectors movzbl copies(r10),r0 ;get copy count addl2 r0,vsd_l_numplots(r11) ;add in number of plots 25$: movl r10,sp ;reset stack pointer brw read ;and read the next record .page .sbttl Subroutine -- assign channel to dev ;++ ; FUNCTIONAL DESCRIPTION: ; ; This routine assigns a channel to the device specified in the ; start print message ; ; CALLING SEQUENCE: ; ; BSB/JSB ; ; Registers: ; r7 - buffer pointer ; r8 - device name string length ; r9 - pointer to device name string ; ***NOTE: r7-r9 are restored on exit ; INPUT PARAMETERS: ; ; None ; ; IMPLICIT INPUTS: ; ; r11 = addr of data segment ; Device name string in symbiont start print message ; ; OUTPUT PARAMETERS: ; ; None ; ; IMPLICIT OUTPUTS: ; ; None ; ; COMPLETION CODES: ; ; The return code from the assign system service is returned in R0 ; ; SIDE EFFECTS: ; ; A channel is assigned to the device ; ;-- vsmb_assigndev: pushr #^m ;save registers subl2 #20,sp ;make buffer on stack movl sp,r7 ;make r7 buffer pointer pushl r7 ;put addr on stack for descriptor movzbl vsd_t_simmsg+sim$t_prtnam(r11),r8 ;get device name length movab vsd_t_simmsg+sim$t_prtnam+1(r11),r9 ;device name addr movb #^a/_/,(r7)+ ;put on leading underscore 10$: movb (r9)+,(r7)+ ;move a character into buffer sobgtr r8,10$ ;done? movb #^a/:/,(r7)+ ;end with a colon subl3 (sp),r7,-(sp) ;compute length of string onto ;stack for descriptor movl sp,r7 ;get descriptor addr movab vsd_w_vchan(r11),r8 ;get channel addr $assign_s (r7),(r8) ;assign the channel addl2 #28,sp ;clear buffer+descriptor from stack popr #^m ;pop registers rsb .page .sbttl AST level routines ;++ ; FUNCTIONAL DESCRIPTION: ; ; These routines are called at AST level when something is put ; in the mailbox. They process the message and adjust the appropriate ; parts of the data segment. ; ; CALLING SEQUENCE: ; ; CALLS/G from AST dispatcher ; ; INPUT PARAMETERS: ; ; None ; ; IMPLICIT INPUTS: ; ; None ; ; OUTPUT PARAMETERS: ; ; See each routine for a description of return codes, if any. ; ; IMPLICIT OUTPUTS: ; ; None ; ; COMPLETION CODES: ; ; None ; ; SIDE EFFECTS: ; ; The file is opened/connected on init print. Various actions ; are taken by the subroutines. ; ;-- vsmb_mbast: .word ^m ;entry mask moval vsd_g_data,r11 ;get addr of data segment movzbl vsd_b_state(r11),r10 ;get current state read_mb_again: cmpb #state__asndev,r10 ;assigning device? bneq 10$ ;br if no bsbw asndev ;try again 10$: bsbw read_mb_now ;read the mbox blbs r0,chk_mbrd ;check read if successful bsbw vsmb_setmbast ;reque the AST movb r10,vsd_b_state(r11) ;reset state in data segment ret ; ; This routine is used to case to the appropriate handler ; for each message type. We really want this to look like a subroutine call, ; so a return addr is pushed for the rsb instruction. ; chk_mbrd: pushab read_mb_again ;push return addr case vsd_t_simmsg+sim$w_msgtyp(r11),- ;dispatch code <,- ;start print ,- ;abort printing ,- ;suspend printing ,- ;resume printing ,- ;exit symbiont >,limit=#msg$_iniopr ;start at first message signal jbc$_invmsg ;signal invalid message brb read_mb_again ;try again .enabl lsb 5$: .long <-1*50000000>,-1 ;five minutes, delta time ; ; this routine processes an init print message ; init: cmpb #state__idle,r10 ;are we idle? beql 1$ ;okay if so brw unexpect ;else unexpected 1$: movzbl #state__asndev,r10 ;set assigning device state asndev: movw #4,vsd_w_mbreadlen(r11) ;set read length to minimum 12$: bsbw vsmb_assigndev ;try to assign device blbs r0,17$ ;br if okay bsbw read_mb_now ;read again blbc r0,2$ ;br if failed brw chkmb1 ;else check the read 2$: $setimr_s #10,5$ ;wait for five minutes $waitfr_s #10 ;... brw 12$ ;try again 17$: movzbl #state__open,r10 ;set opening file state movc3 #16+6+6,vsd_t_simmsg+sim$t_volnam(r11),- vsd_g_nam+nam$t_dvi(r11) ;set device, file, and dir ;fields in nam block bsbw vsmb_setuic ;set uic to requestor's $open fab=vsd_g_fab(r11) ;open the file blbs r0,20$ ;br if okay 9$: bsbw vsmb_restoreuic ;reset uic to [1,4] bisb #vsd_m_openerr,vsd_b_err_flags(r11) ;set open error bit 10$: movzbl #state__done,r10 ;set done state brw 40$ ;and exit 20$: $connect rab=vsd_g_rab(r11) ;connect to file blbc r0,9$ ;take care of connect error bsbw vsmb_restoreuic ;set UIC to [1,4] movab vsd_g_rab(r11),r2 ;get rab addr movab vsd_t_tbuf(r11),r3 ;get buffer addr movl r3,rab$l_ubf(r2) ;set buffer addr in rab movw #256,rab$w_usz(r2) ;set buffer size in rab $get rab=(r2) ;get first record blbc r0,10$ ;error? clrb vsd_b_dcode(r11) ;assume plot bisb #vsd_m_vplot,vsd_b_err_flags(r11) ;set plot bit cmpb #0,(r3) ;is first byte plot code? ;The files entered on the que by the ;plot command contain a header record ;with a type code of 0 in the first ;byte. ;Subsequent records contain ;specifications of files to plot, and ;information to control the plotting. ;If the type code is not zero, it is ;currently assumed that there is an ;error; no additional type codes are ;currently defined. beql 40$ ;br if so $rewind (r2) ;else, rewind file incb vsd_b_dcode(r11) ;set to print code bicb #vsd_m_vplot,vsd_b_err_flags(r11) ;and clear plot bit 40$: $wake_s ;wake up rsb .dsabl lsb ; ; Local subroutines to read the mailbox ; ; ; Read with no wait: ; read_mb_now: movzwl #io$_readvblk!io$m_now,r0 ;set I/O function code ;read the mb read_mb: movaq -(sp),r1 ;make iosb on stack $qiow_s - ;do the read chan=vsd_w_mbchan(r11),-;channel func=r0,- ;function iosb=(r1),- ;iosb p1=vsd_t_simmsg(r11),- ;buffer p2=vsd_w_mbreadlen(r11) ;size to read movq (sp)+,r0 ;get iosb rsb ; ; This routine processes the abort file message. ; The abort bit is set, and outstanding I/O canceled. ; abort: cmpb #state__done,r10 ;are we done? beql 30$ ;then ignore it cmpb #state__idle,r10 ;were we idle? bneq 10$ ;br if not brw unexpect ;else unexpected 10$: bisb #vsd_m_abort,vsd_b_err_flags(r11) ;set abort bit $cancel_s vsd_w_vchan(r11) ;cancel I/O on channel cmpb #state__suspend,r10 ;were we suspended? bneq 20$ ;br if not movzbl r9,r10 ;restore previous state 20$: cmpb #state__asndev,r10 ;are we assigning device? bneq 30$ ;br if no movzbl #state__idle,r10 ;else make us idle 30$: rsb ; ; This routine is the symbiont exit point ; exit: cmpb #state__idle,r10 ;are we idle beql 10$ ;br if so brw unexpect ;else unexpected 10$: $dassgn_s vsd_w_jbcchan(r11) ;deassign channel to JBC's mbox blbc r0,20$ ;br on error $dassgn_s vsd_w_mbchan(r11) ;deassign my mb blbs r0,30$ ;br if okay 20$: signal jbc$_mbdeas,#0,r0 ;signal the error 30$: $delmbx_s vsd_w_unit(r11) ;kill my mb (just in case) $exit_s ; ; signal unexpected message ; unexpect: signal jbc$_unesymmsg ;signal brw read_mb_again ;read again ; ; Handle suspend message ; .enabl lsb suspend: cmpb #state__done,r10 ;done? beql 20$ ;ignore it cmpb #state__idle,r10 ;were we idle? bneq 10$ ;okay if not brw unexpect ;else unexpected 10$: movzbl r10,r9 ;save old state movzbl #state__suspend,r10 ;set suspend state movzwl #io$_readvblk,r0 ;set function code bsbw read_mb ;wait for something in mbox chkmb1: movab chk_mbrd,(sp) ;set new ret addr 20$: rsb .dsabl lsb ; ; This routine performs a resume print ; resume: cmpb #state__done,r10 ;are we done? beql 30$ ;then ignore it cmpb #state__suspend,r10 ;are we suspended beql 1$ ;okay if so brw unexpect ;else unexpected 1$: movzbl r9,r10 ;restore old state movw vsd_t_simmsg+sim$w_rest(r11),r0 ;get rest of message beql 30$ ;no flags, just resume cmpw #^x8000,r0 ;top of file requested? bneq 30$ ;br if no bsbw vsmb_form_feed ;generate a form feed $rewind vsd_g_rab(r11) ;rewind the file blbs r0,20$ ;br if okay signal shr$_rmserror!<4@16>,#0,r0 ;signal the error bisb #vsd_m_geterr,vsd_b_err_flags(r11) ;set error bit 30$: rsb 20$: bbc #vsd_v_vplot,vsd_b_err_flags(r11),30$ ;br if not vplot file $get rab=vsd_g_rab(r11) ;punt first record of plot file brb 30$ ;and exit .page .sbttl Subroutine -- output form_feed to the varian ;++ ; FUNCTIONAL DESCRIPTION: ; ; This routine outputs a form feed to the varian ; ; CALLING SEQUENCE: ; ; BSB/JSB ; ; INPUT PARAMETERS: ; ; None ; ; IMPLICIT INPUTS: ; ; None ; ; OUTPUT PARAMETERS: ; ; None ; ; IMPLICIT OUTPUTS: ; ; None ; ; COMPLETION CODES: ; ; None ; ; SIDE EFFECTS: ; ; None ; ;-- slew: .long ^o263 ;form feed char for varian vsmb_form_feed: ;send form feed to varian pushal slew ;push code calls #1,var$command ;do the form feed rsb ;and return .page .sbttl Error to varian action routine ;++ ; FUNCTIONAL DESCRIPTION: ; ; This is a putmsg action routine which outputs the message to ; the varian. Output to sys$error and sys$output is supressed. ; ; CALLING SEQUENCE: ; ; CALLS/G ; ; INPUT PARAMETERS: ; ; 4(ap) = address of descriptor of the error message to output ; ; IMPLICIT INPUTS: ; ; None ; ; OUTPUT PARAMETERS: ; ; None ; ; IMPLICIT OUTPUTS: ; ; None ; ; COMPLETION CODES: ; ; None ; ; SIDE EFFECTS: ; ; Message is output on varian between form-feeds ; ;-- alph: .long ^o100 vsmb_tell_varian:: .word ^m ;entry mask bsbw vsmb_form_feed ;generate a form feed movl 4(ap),r2 ;get message descriptor address pushal alph ;push alphanumeric command code calls #1,var$command ;set alpanumeric mode pushl 4(r2) ;push addr of message pushl r2 ;push addr of length of message calls #2,var$send_buf ;output the message bsbw vsmb_form_feed ;generate a form feed clrl r0 ;no send to sys$output/error ret ; ; end of symbiont ; .end vsmb_start