.TITLE XMIT - MESSAGE HANDLER ; ; ; MACROS REFERENCED ; .MCALL CALL,RETURN,ENTER,LEAVE .MCALL OFNB$,READ$,WAIT$,DELET$ .MCALL FDBDF$,FDRC$A,FDBK$A,FDOP$A .MCALL MVADR .MCALL GTSK$S .MCALL DSAR$S,ENAR$S,SRDA$ .MCALL CLEF$,SETF$,WTSE$ .MCALL SDAT$,RCVD$S,RCVX$S .MCALL ASTX$S,EXIT$S .MCALL TINIT,PSTR,PRAD50,POCT .MCALL XM$LQU ; ; ; XM$LQU .SBTTL >MAIN PROGRAM TOP LEVEL ; .SBTTL > INITIALISATION ; MAIN: TINIT XM.TLN,XM.TEF,CO,0 ;INITIALISE QUOTE ;WK. TO CO: (JUNE 7, 1977) MOV #XM.QUE,QIN ;INITIAL WRITB POINTER MOV #XM.QUE,QOUT ;AND READ POINTER SUB #40,SP ;CREATE SOME ROOM ON THE STACK MOV SP,R0 ;POINT TO IT GTSK$S R0,DIRERR ;GET TASK INFO MOV (R0)+,PNAME ;FIRST TWO WORDS ARE OUR TASK NAME MOV (R0),PNAME+2 ADD #40,SP ;RECLAIM STACK SPACE DIR$ #SETAST,DIRERR ;SET UP AST FOR RECEIVE DATA BR GO ;START UP WAIT LOOP ; .SBTTL > PROCESS A MESSAGE ; WLUP: DIR$ #WAIT,DIRERR ;WAIT FOR A MESSAGE MOV QOUT,R1 ;GET MESSAGE POINTER PLUP: MOV 4(R1),R0 ;GET OP CODE COM R0 ;(ALWAYS NEG FOR DEFERRED) ASL R0 ;R0=2*(ABS(OP)-1) CMP R0,#XM.MOP ;IN RANGE? BLT 1$ ;YES, GO DO IT CALL BADMES ;FLAG ERROR BR 2$ ;ON TO NEXT ONE 1$: MOV #XM.MES,R2 ;MESSAGE AREA MOV #XM.LMS,R3 ;LENGTH THEREOF CALL GETMES ;ASSEMBLE MESSAGE INTO BUFFER BCS 2$ ;IMPOSSIBLE CALL @XM.OP(R0) ;CALL ROUTINE 2$: DSAR$S ;DISABLE AST'S WHILE WE FIDDLE THE QUEUE ADD #XM.LQU,R1 ;ADVANCE TO NEXT QUEUE ENTRY CMP R1,#XM.QUE+ ;STILL IN QUEUE BLO 3$ ;YES MOV #XM.QUE,R1 ;NO, WRAP AROUND 3$: MOV R1,QOUT ;UPDATE IN DATA BASE CMP R1,QIN ;NEXT SLOT FILLED IN? BEQ GO ;NOT YET, GO AWAY A WHILE ENAR$S ;LET THINGS HAPPEN NOW BR PLUP ;AND GO DO ANOTHER ONE ; GO: DIR$ #CLEARF,DIRERR ;CLEAR FLAG WE WILL WAIT ON ENAR$S ;LET AST'S HAPPEN DIR$ #TRIG,DIRERR ;WAKE HIM UP BR WLUP ;AND WAIT FOR HIM .SBTTL >AST HANDLER FOR RECEIVED MESSAGES ; ; RCV: ENTER R0,R1,R2,R3 MOV QIN,R1 ;GET WRITE POINTER INTO QUEUE RCVLUP: RCVD$S ,R1 ;GET A MESSAGE BCC RCV0 ;GOT ONE CMPB #IE.ITS,$DSW ;NO MESSAGE? BEQ RCVEXT ;OK, GO AWAY AND WAIT CALL DIRERR ;SOMETHING ELSE WRONG RCV0: MOV 4(R1),R0 ;GET OP CODE BMI DEFER ;DEFERRED OPERATION DEC R0 ;POSITIVE IS IMMEDIATE OP BMI 2$ ;ZERO IS NO-OP ASL R0 ;CONVERT TO INDEX CMP R0,#XM.MIP ;IN RANGE? BLT 1$ ;YES, DO IT CALL BADMES ;NO, FLAG AS ERROR BR 2$ ;AND GET NEXT ONE 1$: MOV #XM.IMS,R2 ;GET MESSAGE BUFFER MOV #XM.LIM,R3 ;AND LENGTH CALL GETMES ;GET THE MESSAGE BCS 2$ ;MESSAGE WAS TOO LONG CALL @XM.IOP(R0) ;CALL HANDLER 2$: .IF DF,DEBUG ;TRY TO FLUSH TASK BR RCVLUP ;UNLESS WE ARE DEBUGGING .IFF CMP R1,QOUT ;ANYTHING IN QUEUE? BNE RCVLUP ;YES, WAIT FOR A MESSAGE RCVX$S ,R1,DIRERR ;NO, IF NO MESSAGE, GIVE UP BR RCV0 ;OTHERWISE, PROCESS MESSAGE .ENDC ; ; DEFER: DIR$ #SETF,DIRERR ;TELL MAIN LEVEL HE CAN GO AHEAD ADD #XM.LQU,R1 ;ADVANCE TO NEXT QUEUE ENTRY CMP R1,#XM.QUE+ ;HAVE TO WRAP AROUND? BLO 1$ ;NO MOV #XM.QUE,R1 ;YES, GO BACK TO START 1$: MOV R1,QIN ;UPDATE WRITE POINTER CMP R1,QOUT ;ANY ROOM LEFT? BNE RCVLUP ;SURE, READ SOME MORE DSAR$S DIRERR ;NO, GIVE UP LISTENING RCVEXT: LEAVE ASTX$S .SBTTL >GETMES - MESSAGE ASSEMBLY ROUTINE ; ; ; GETMES - ASSEMBLES A MESSAGE. ; ; PARAMETERS: ; R1 POINTER TO MESSAGE BLOCK ; R2 POINTER TO MESSAGE BUFFER ; R3 LENGTH OF MESSAGE BUFFER ; ; RESULTS: ; R3 LENGTH OF MESSAGE ; OTHER REGS ARE PRESERVED ; CARRY CLEAR IF SUCCESSFUL, SET OTHERWISE ; ; GETMES: ENTER R0,R2,R4,R5 DSAR$S ;ONLY ONE GETMES AT A TIME MOVB $DSW,DSARF ;IF DSAR FAILED, DON'T ENAR CLRB SUCF ;INITIALLY ASSUME WILL SUCCEED TST 6(R1) ;LENGTH NON-ZERO? BEQ 4$ ;NO, DON'T HAVE TO READ MVADR 12,R1,R4 ;GET POINTER TO NAME MOV #MESFDB+F.FNB+N.FNAM,R5 ;AND POINTER TO FILENAME BLOCK .REPT 5 MOV (R4)+,(R5)+ ;COPY FILENAME (3), TYPE, VERSION .ENDR ADD #N.DID-2-N.FVER,R5 ;ADVANCE TO DIRECTORY AREA .REPT 5 MOV (R4)+,(R5)+ ;COPY DIRECTORY ID(3), DEVICE, UNIT .ENDR OFNB$ #MESFDB,,,,,,,,IOERR ;OPEN MESSAGE FILE CMP R3,6(R1) ;CHECK THAT IT WILL FIT BHIS 1$ ;OK, NO TROUBLE CALL TOLONG ;TROUBLE COMB SUCF ;INDICATE FAILURE BR 3$ ;AND RETURN ; 1$: MOV #512.,R3 ;RECORD LENGTH (BYTES) MOVB 7(R1),R4 ;NUMBER OF FULL BLOCKS TSTB 6(R1) ;LENGTH OF LAST BLOCK BEQ 2$ ;IF ANY INC R4 ;NUMBER OF BLOCKS 2$: READ$ R0,R2,,,,,,IOERR ;READ RECORD WAIT$ R0,,,IOERR ;WAIT FOR IT TO HAPPEN ADD R3,R2 ;ADVANCE TO NEXT RECORD SOB R4,2$ ;AND READ IT 3$: DELET$ R0,IOERR ;DELETE FILE 4$: MOV 6(R1),R3 ;SET UP ACTUAL LENGTH TSTB DSARF ;DID DSAR WORK? BMI 5$ ;NO, DON'T ENAR ENAR$S DIRERR ;YES, RE-ENABLE AST'S 5$: LEAVE ROLB SUCF ;COPY SUCCESS FLAG INTO CARRY RETURN .SBTTL >ERROR MESSAGES ; ; BADMES::CALL ERRPFX ;SIGNAL ERROR PSTR ^*/INVALID OPERATION. REQUESTING TASK=/* BR ERR1 ;AND PRINT REST OF MESSAGE ; TOLONG: CALL ERRPFX PSTR ^*/REQUEST TOO LONG. REQUESTING TASK=/* ERR1: PRAD50 (R1) PRAD50 2(R1) PSTR ^*/ ID=/* PRAD50 12(R1) ;FILENAME FROM MESSAGE PRAD50 14(R1) ;.. PRAD50 16(R1) ;.. PSTR ^*/;/* POCT 22(R1) ;AND VERSION NUMBER PSTR ^** RETURN ; .SBTTL >QUOTE STUFF ; ; ERRPFX::PSTR ^** PRAD50 PNAME PRAD50 PNAME+2 PSTR ^*/ - /* RETURN ; ; DIE:: .IF DF,DEBUG .WORD 0 .IFF EXIT$S .ENDC .SBTTL >VARIABLES AND CONSTANTS ; ; QIN: .BLKW 1 ;WRITE POINTER INTO QUEUE QOUT: .BLKW 1 ;READ POINTER INTO QUEUE ; ; TRIGGR: .WORD 0,0 ;NO-OP MESSAGE FOR AST TRIGGERING .BLKW 13 ; DSARF: .BLKB 1 ;(BYTE) POSITIVE IF GETMES SHOULD RE-ENABLE AST'S SUCF: .BLKB 1 ;(BYTE) 0 IF GETMES SUCCESSFUL, ELSE -1 ; MESFDB: FDBDF$ ;MESSAGE READING FDB FDRC$A FD.RWM FDBK$A ,512.,,XM.MEF FDOP$A XM.MLN,,,FO.RD ; ; ; CLEARF: CLEF$ XM.REF SETF: SETF$ XM.REF WAIT: WTSE$ XM.REF ; SETAST: SRDA$ RCV ; TRIG: SDAT$ ,TRIGGR PNAME=TRIG+S.DATN ;OUR NAME IN RADIX 50 ; ; ; .END MAIN ;