; move comments over 1 tab C/;/ ;/ ; move back 1 tab C/ ;/;/ ; find leading spaces and convert to tabs 4y5y6y ; put 24 leading 1,$c/^ / /4p ; 16 1,$c/^ / /5p ; 8 1,$c/^ / /6p ; $MACRO callr here (use this for co-routine call - won't use stack) jmp #@1 $ENDM $MACRO moveb from to nbytes ?? 4 mov #@1,r0 mov #@2,r1 mov #@3,r2 #@4=. movb (r0)+,(r1)+ sob r2,#@4 $ENDM / PROGRAM trn ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; This program monitors the lines and spawns the receiver and sender ; (its active on both ends) when it detects either a send data (to send) ; or inputs a char (to be receiver). ; ; The following are the handshake codes between this program ; and the ones the sender/receiver send back and forth. ; ; sender receiver ; 4 S's 4 R's these are sync codes ; A ack ; null nack ; F fatal, next 2 bytes are error code ; ; G S Sender starts receiver with a G ; X after a send completes, receiver sends ; an S if it wants to become next sender ; or an X if it does not. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; The xmt program (or whatever it is called) does a send data to this ; this task with the following format: ; word 1 - default uic ; word 2 - protection uic (login uic) ; word 3-13 - rest of file name (22 chars max) ; This task passes on the default uic, and spawns with the prot uic. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .title tran .enabl lc .enabl ama .nlist sym .psect tran .mcall qiow$,dir$,alun$,srda$s,astx$s,ustp$ .mcall rcvd$,spwn$,wtse$,qiow$s,exit$s,stop$s cr = 15 ;ascii return esc = 33 ;ascii escape key blank = 40 ;ascii space bar lun = 1 ;lun for communications ef = 1 ;ef for " " ugc = 0 ;uic group code - non priv'd umc = 0 ; member ugcp = 1 ;uic group code - priveled (receiv) umcp = 1 ; member efs = 20. ;spawn event flag begin: ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outch: qiow$ io.wal,lun,ef ,,ios,, ;output 1 char inch: qiow$ io.ral,lun,ef ,,ios,, ;input 1 char att: qiow$ io.ata,lun,ef ,, ,, ;char ast det: qiow$ io.det,lun,ef ;detach terminal assign: alun$ lun,CM,0 ;assign lun ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ recdat: rcvd$ ,rtask ;receive rtask: .word 0,0 ;received data task name uic: .word 0 ;default uic puic: .word 0 ;protection uic rbuf: .blkw 11. ;receive buffer ;spawnr: spwn$ MCR...,,,ugcp,umcp,efs,,status,rcmdln,rcmd,0,CO ;spawn receiver spawnr: spwn$ RECEIV,,,ugcp,umcp,efs,,status,,,0,CO ;spawn receiver spawns: spwn$ SENDER,,,ugcp,umcp,efs,,status,scmdln,scmd ;spawn sender wait: wtse$ efs ;wait for spawn (can't stop in an ast) unstop: ustp$ tasknm ;to be filled in later ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;rcmdln: .ascii 'ins $receive/TASK=RECEIV/uic=[1,1]/run=rem' ;CO: MUST be priv'd ;rcmd=.-rcmdln scmdln: .byte 1,0,0,40 ;encode uic here scmd=.-scmdln sbuf: .blkb 90.-scmd ;allocate remainder .even ios: .word 0,0 char: .byte 0,0 ch: .byte 0,0 ;save the c ast char status: .blkw 8. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ start: srda$s #rast ;spec receive ast dir$ #assign ;assign lun to communications line dir$ #att ;attach and specify ast on comm line stop$s ;stop, do all work in asts exit$s ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ rast: ;receive ast mov r0,-(sp) mov r1,-(sp) mov r2,-(sp) mov r3,-(sp) mov r4,-(sp) mov r5,-(sp) dir$ #det ;detach comm line DO FOREVER dir$ #recdat ;then receive data IF $dsw NE #is.suc ;rsx won't work correctly so we must BREAK ;propogate ourselves and exit only FI ;when nothing in receive queue. ;what happens if we receive right here ??? ;do we lose an ast, I don't know. mov #'G,char ;send the Go signal dir$ #outch ;by outputing a char G call snd ;spawn the snd program OD dir$ #att ;re-attach here mov (sp)+,r5 mov (sp)+,r4 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,r1 mov (sp)+,r0 astx$s ;exit (no data need be clear from stack) ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cast: ;input char ast mov (sp)+,ch ;save the char mov r0,-(sp) mov r1,-(sp) mov r2,-(sp) mov r3,-(sp) mov r4,-(sp) mov r5,-(sp) dir$ #det ;detach comm line IFB ch = #'G ;check for garbage, only a G is ok call rcv ;spawn the receiving end FI dir$ #att ;re-attach here mov (sp)+,r5 mov (sp)+,r4 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,r1 mov (sp)+,r0 astx$s ;exit ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ rcv: ;get receiver going dir$ #spawnr ;spawn receiver dir$ #wait ;and wait for it dir$ #recdat ;see if any thing queued up here IF $dsw = #is.suc ;if yes, then we will be sender mov #'S,char ; for a while dir$ #outch ; so, send an 'S back callr snd ; and shift to snd routine ELSE mov #'X,char ;otherwise just return an 'X dir$ #outch ;to indicate were done FI rts pc ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ snd: ;get the sender going movb #blank,sbuf moveb #sbuf,#sbuf+1,#80. ;blank out remainder of buffer moveb #rbuf,#sbuf,#22. ;copy it all in call spwns ;spawn sender with file name call restart ;restart the sender dir$ #inch ;get other sides response IFB char = #'S ;if he wants to send, then callr rcv ;we will receive FI ;for a while rts pc ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ restart: ;restart the sender mov rtask,unstop+u.sttn ;first part of name mov rtask+2,unstop+u.sttn+2 ;second part of name dir$ #unstop ;do it rts pc ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ spwns: LOOP for r0 = #sbuf+24. DOWNTHRU #sbuf step #-1 BREAK IFB (r0) NE #blank NEXT r0 inc r0 movb #cr,(r0) sub #sbuf,r0 add #4,r0 mov r0,spawns+s.pwcl movb puic,spawns+s.pwum ;member movb puic+1,spawns+s.pwug ;group movb #1,scmdln ;stuff movb uic,scmdln+1 ;the command line to include movb uic+1,scmdln+2 ;the default uic dir$ #spawns ;spawn sender dir$ #wait ;and wait for it rts pc .end start