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