.TITLE SPOOL - MESSAGE SENDING ROUTINES ; ; ; MACROS CALLED ; .MCALL CALL,RETURN,ENTER,LEAVE .MCALL OPEN$,WRITE$,CLOSE$,DELET$,WAIT$ .MCALL RQST$S,SDAT$S .MCALL NMBLK$ .MCALL MVADR .MCALL SPOFF$ ; ; ; FORMAT OF MESSAGE SENT: ; ; DISP CONTENTS ; 0 OP-CODE ; 2 SIZE OF MESSAGE (WORDS) ; (HIGH BYTE IS NUMBER OF RECORDS) ; 4 RESERVED ; 6 FILENAME/REQUEST ID (3 WORDS, RADIX 50) ; 14 FILETYPE RADIX 50 ; 16 VERSION NUMBER ; 20 DIRECTORY ID (3 WORDS) ; 26 DEVICE NAME, ASCII ; 30 UNIT NUMBER ; ; ; SET UP SPOOL BLOCK OFFSETS: ; SPOFF$ ; ; ; ; ASSEMBLY PARAMETERS: ; SPLGRP=10 ;GROUP CODE FOR MESSAGE FILES SPLMEM=3 ;.. RUNGRP=10 ;AND FOR TASKS RUNMEM=1 ; .SBTTL >SPBGN - START MESSAGE ; ; ; SP$BGN SPBLK,TASK,ID,OP ; ; INITIALISES SPOOL BLOCK; CREATES OUTPUT FILE ; ; .SPBGN::ENTER R1,R2,R3 ;R0 CONTAINS SPOOL BLOCK POINTER MOV R0,R3 ;BUT WE KEEP IT IN R3 CLR SP.REC(R3) ;NO RECORDS WRITTEN YET CALL NEWBUF ;RESET BUFFER COUNT AND POINTER MVADR SP.FDB,R3,R0 ;GET FDB POINTER TST F.BDB(R0) ;FDB OPEN? BEQ 1$ ;NO DELET$ R0,IOERR ;YES, DELETE OLD FILE 1$: CALL .RDFFP ;GET OLD FILE PROTECTION WORD MOV R1,-(SP) ;AND SAVE IT CLR R1 ;WRITE THIS FILE SO ANYONE CALL .WDFFP ;CAN PLAY WITH IT MVADR SP.ID,R3,R1 ;GET ID FROM SPOOL BLOCK MOV #NMBLK+N.FNAM,R2 ;COPY INTO FILE NAME MOV (R1)+,(R2)+ MOV (R1)+,(R2)+ MOV (R1)+,(R2)+ OPEN$ R0,,,#DSPT,#NMBLK,,SP.PTR(R3),,IOERR ;OPEN (CREATE) THE FILE MOV (SP)+,R1 ;AND FILE PROTECTION WORD CALL .WDFFP MOV R3,R0 ;GET BACK SPOOL BLOCK POINTER LEAVE RETURN ; ; .MACRO XX A,B .ASCII /[A,B]/ .ENDM ; DIR: XX \SPLGRP,\SPLMEM LDIR=.-DIR .EVEN ; ; NMBLK: NMBLK$ ,SPL,0,DM,1 ; DSPT: .WORD 0,0 .WORD LDIR,DIR .WORD 0,0 .SBTTL >SPOOL - SEND MESSAGE ; ; ; SPOOL$ SPBLK,MES,LEN ; ; SENDS MESSAGE WHOSE ADDRESS IS MES AND WHOSE LENGTH IS LEN ; .SPOOL::ENTER R1,R2,R3,R4,R5 ;SPOOL BLOCK POINTER IN R0 MOV R0,R3 ;WHICH WE KEEP IN R3 MOV SP.MES(R3),R2 ;GET LENGTH MOV SP.MES+2(R3),R1 ;AND ADDRESS MOV R2,R4 ;SAVE TOTAL LENGTH 1$: SUB R2,SP.CNT(R3) ;CAN IT FIT? BGE 2$ ;NO PROBLEM ADD SP.CNT(R3),R2 ;NO, R2 IS AMOUNT WHICH WILL FIT 2$: SUB R2,R4 ;AMOUNT LEFT TO DO MOV SP.PTR(R3),R5 ;WHERE TO PUT STUFF 3$: MOV (R1)+,(R5)+ ;AND STASH IT IN SOB R2,3$ MOV R4,R2 ;AMOUNT LEFT TO DO BEQ 4$ ;NONE LEFT CALL SPOUT ;OUTPUT WHAT WE HAVE BR 1$ ;AND ON TO REST ; 4$: MOV R5,SP.PTR(R3) ;REMEMBER WHERE TO PUT STUFF MOV R3,R0 ;GET BACK SPOOL BLOCK POINTER LEAVE RETURN .SBTTL >SPEND - COMPLETE MESSAGE PROCESSING ; ; ; SP$END SPBLK ; ; EMPTIES MESSAGE BUFFER, CLOSES FILE, AND SENDS MESSAGE ; ; .SPEND::ENTER R1,R2,R3 ;R0 CONTAINS SPOOL BLOCK POINTER MOV R0,R3 ;WHICH WE KEEP IN R3 MOV #MESS,R1 ;MESSAGE AREA POINTER MOV SP.OP(R3),(R1)+ ;COPY OP CODE MOV SP.BFL(R3),R2 ;BUFFER LENGTH (WORDS) SUB SP.CNT(R3),R2 ;LESS LEFT TO GO CLRB (R1)+ ;WILL GO HERE IN A MINUTE MOVB SP.REC(R3),(R1)+ ;NUMBER OF COMPLETE RECORDS ADD R2,-(R1) ;ADD IN LAST BUFFER COUNT CMP (R1)+,(R1)+ ;SKIP OVER RESERVED WORD MVADR SP.FDB+F.FNB+N.FNAM,R3,R2 ;ADDRESS OF FILENAME IN FDB .REPT 5 MOV (R2)+,(R1)+ ;COPY NAME(3), TYPE AND VERSION .ENDR ADD #N.DID-2-N.FVER,R2 ;ADVANCE TO DIRECTORY STUFF .REPT 5 MOV (R2)+,(R1)+ ;COPY DIRECTORY ID(3), DEVICE, UNIT .ENDR CALL SPOUT ;OUTPUT LAST RECORD CLOSE$ R0,IOERR SDAT$S R3,#MESS,,DIRERR ;SEND MESSAGE RQST$S R3,,,#RUNGRP,#RUNMEM ;REQUEST TASK SPOOLED TO BCC 1$ ;OK, GOT IT STARTED CMP #IE.ACT,$DSW ;TASK ALREADY ACTIVE? BEQ 1$ ;OK, SO SEND ALREADY CALL DIRERR 1$: MOV R3,R0 ;GET BACK SPOOL BLOCK POINTER LEAVE RETURN ; ; MESS: .BLKW 15 .SBTTL >SPOUT ; ; OUTPUTS CURRENT MESSAGE BUFFER FROM SPOOL BLOCK INTO MESSAGE FILE ; ; PARAMETERS: ; R3 SPOOL BLOCK POINTER ; ; RESULTS: ; R0 FDB POINTER ; ; SPOUT: MVADR SP.FDB,R3,R0 ;GET FDB POINTER WRITE$ R0,,,,,,,IOERR ;OUTPUT BLOCK WAIT$ R0,,,IOERR ;WAIT FOR IT TO FINISH INC SP.REC(R3) ;ONE MORE BLOCK OUTPUT NEWBUF: MOV SP.BFL(R3),SP.CNT(R3) ;RESET BUFFER POINTER MVADR SP.BUF,R3,SP.PTR(R3) ;.. RETURN ; ; ; .END