.title NLSYMB - Null symbiont .ident /01.0/ ; ; Free software BY ; Project Software & Development, Inc. ; ; This software is furnished for free and may be used and copied as ; desired. This software or any other copies thereof may be provided ; or otherwise made available to any other person. No title to and ; ownership of the software is hereby transferred or allowed. ; ; The information in this software is subject to change without notice ; and should not be construed as a commitment by PROJECT SOFTWARE ; AND DEVELOPMENT, INC. ; ; PROJECT SOFTWARE assumes no responsibility for the use or reliability ; of this software on any equipment whatsoever. ; ; Project Software & Development, Inc. ; 14 Story St. ; Cambridge, Ma. 02138 ; 617-661-1444 ; ;++ ; FACILITY: VAX/VMS NULL SYMBIONT ; ; ABSTRACT: This symbiont is used to delete files. ; ; This is a null symbiont - its sole purpose in life is to spool ; files to the null device and then delete them. It really doesn't ; spool them to NL:, it just looks that way. All files are deleted ; unless there was a problem accessing it. ; ; ; ENVIRONMENT: NATIVE/USER MODE NON-PRIVILEGED CODE ; ; AUTHOR: M. Erik Husby, PSDI Inc., CREATION DATE: 3-mar-1981 ; With many thanks to Neal Lippman, MIT-JCF for the template of ; a symbiont for the VARIAN plotter. ; ; MODIFIED BY: ; MEH 10-apr-1981, To ignore file not found errors. ; ;-- .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 > $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 > .=<.+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 Null 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 /NLSYMB/ 20$: .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 <@8>- ;send to central ,-(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 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 .page ;++ ; 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 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 deleted. ; ;-- ; ; this is the data segment ; impure_section vsd_g_data:: .blkb vsd_k_size pure_section vsmb_main: $hiber_s ;wait for something todo movb #state__active,vsd_b_state(r11) ;set us active bbc #vsd_v_openerr,vsd_b_err_flags(r11),35$ ;br if opened successfully cmpl #rms$_fnf,- ; Was error file not found? vsd_g_fab+fab$l_sts(r11) ; Ignore if so. beql 35$ ; ... 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 35$: ; ; 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 bbs #vsd_v_abort,vsd_b_err_flags(r11),115$ ;br if aborting 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__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) ; deasign the null device. 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 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 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 $rewind vsd_g_rab(r11) ;rewind the file blbs r0,30$ ;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 ; ; end of symbiont ; .end vsmb_start