.TITLE SND SEND/RECEIVE DATA .SBTTL .IDENT /V03.1/ ; ;************************************************************ ; ; R S X 1 1 M U T I L I T Y P R O G R A M ; ;============================================================ ; ; PROGRAM NAME: GENERAL SEND/RECEIVE DATA TASK ; ; PROGRAM: SND.MAC ; ; AUTHOR: M.J.STEVENSON ; ; DATE: 06-SEPT-77 LAST REVISION: 30-MAR-78 ; ; Slightly modified by:- ; ; Phil Stephensen-Payne, ; c/o Systime Ltd., ; Concourse Computer Centre, ; 432 Dewsbury Road, ; LEEDS LS11 7DF, ; England. ; ; EDIT SEQUENCE NUMBER: 66 ; ; OVERVIEW: ; THIS TASK ENABLES A USER TO SEND DATA PACKETS TO ANY INSTALLED ; TASK & TO DE-QUEUE DATA PACKETS QUEUED TO THIS TASK. THIS TASK ; MAY BE RUN UNDER ANY INSTALLED TASK NAME, TO SIMULATE AN ACTUAL ; APPLICATION/UTILITY TASK, ALLOWING THE USER TO EXAMINE THE DATA ; PACKETS. ; BUFFERS ARE RESERVED FOR 8 RECEIVE PACKETS & 8 SEND PACKETS. ; ANY BUFFER MAY BE USED FOR SENDING DATA. TWO COMMAND LEVELS ARE ; PROVIDED. THE FIRST LEVEL IS USED TO SEND/RECEIVE DATA PACKETS. ; THE SECOND LEVEL IS USED TO EXAMINE OR EDIT ANY ONE OF THE 16 ; PACKET BUFFERS. ; THIS TASK MAY BE INVOKED BY THE MCR "RUN...." REQUEST, OR AS AN ; INSTALLED TASK, OR AS AN "MCR" ROUTINE. IF IT IS INVOKED AS AN ; "MCR" ROUTINE, ONLY ONE COMMAND LINE CAN BE PROCESSED & THE ; SECOND LEVEL COMMAND IS PROHIBITED. ; ; ASSEMBLY PROCEDURE: ; MAC>SND,LP:=SND ; ; TASK BUILD PROCEDURE: ; TKB>SND,LP:=SND ; TKB>/ ; TKB>TASK=...SND ; TKB>UNITS=2 ; TKB>ASG=TI:1:2 ; TKB>STACK=64 ; TKB>// ; ;------------------------------------------------------------ ; .MCALL DIR$,GMCR$,RQST$,QIO$,SPWN$ .MCALL ALUN$S,ASTX$S,CLEF$S,EXIT$S,GLUN$S,GTIM$S,GTSK$S .MCALL MRKT$S,QIO$S,RCVD$S,SDAT$S,SRDA$S,SPRA$S,WTSE$S .MCALL CSI$,CSI$SW,CSI$SV,CSI$ND,CSI$1,CSI$2 ; .NLIST MEB,BEX .SBTTL LOCAL MACROS ; ; --- DEFINE EDIT COMMAND ; .MACRO $EDCMD CHR,SIZ,ACTION,TRANS .BYTE CHR,SIZ .IF B .WORD 0 .IFF .WORD ACTION .ENDC .IF B .WORD 0 .IFF .WORD TRANS .ENDC .ENDM $EDCMD ; ; --- DEFINE PACKET DESCRIPTOR ; .MACRO $PKTID TYP,ID,ADDR .BYTE TYP,ID .WORD ADDR,0 .ENDM $PKTID ; ; --- DEFINE EDIT COMMAND PARSING TRANSITION ; .MACRO $EDTRN STAT,CHAR,OPT .BYTE STAT .IF B .BYTE 0 .IFF .BYTE CHAR .ENDC .IF B .WORD 0 .IFF .WORD OPT .ENDC .ENDM $EDTRN .SBTTL SYMBOL EQUATES ; ;***** ;***** COMMAND SWITCH VALUES ;***** ; SW.ED = 1 ;EDIT PACKET SW.TS = 2 ;USE DEFINED TASK FOR SEND SW.DQ = 4 ;DE-QUEUE DATA PACKET SW.RC = 10 ;SEND RECEIVE(D) PACKET SW.SN = 20 ;SEND "SEND" PACKET SW.WT = 40 ;PERFORM DELAY SW.OP = 100 ;REPEAT COMMAND SW.CL = 200 ;FLUSH RECEIVE QUEUE SW.ID = 400 ;APPEND PROMPT TO TASK NAME SW.LI = 1000 ;LIST PACKET STATUSES SW.PR = 2000 ;OVER-RIDE TEMPORARY TASK NAME FOR SEND SW.IM = 4000 ;TASK NAME IS THE NAME OF THIS IMMAGE SW.AL = 10000 ;USE ALL TASK NAMES SW.TR = 20000 ;USE DEFINED TASK FOR RECEIVE SW.PS = 40000 ;OVER-RIDE TEMPORARY TASK NAME FOR RECEIVE SW.RQ = 100000 ;REQUEST NAMED/REFERENCED TASK SWALL = 177776 ;ALL SWITCHES EXCEPT "ED" SW.HE = 1 ; Help ; ;***** ;***** EDIT CONTROL STATUS BITS ;***** ; ED.ASC = 1 ;ASCII MODE ED.OCT = 2 ;OCTAL MODE ED.R50 = 4 ;RADIX-50 MODE ED.DEC = 10 ;DECIMAL MODE ED.MSK = 400 ;MASK OPERATION ED.DMP = 200 ;PACKET DUMP ED.BYT = 100000 ;BYTE ADDRESSING ; ;***** ;***** PACKET DESCRIPTOR OFFSETS ;***** ; PK.TYP = 0 ;PACKET TYPE PK.ID = 1 ;PACKET ID PK.PKT = 2 ;PACKET DATA AREA PK.CNT = 4 ;PACKET SEND/RECEIVE COUNT PK.LEN = 6 ;DESCRIPTOR SIZE ; ;***** ;***** EDIT COMMAND DESCRIPTOR OFFSETS ;***** ; D.CHR = 0 ;COMMAND CHARACTER D.SIZ = 1 ;MAXIMUM SIZE OF COMMAND D.RTN = 2 ;PROCESSING ROUTINE ADDRESS D.PRS = 4 ;PARSING TRANSITION TABLE ADDRESS D.LEN = 6 ;DESCRIPTOR SIZE ; ;***** ;***** EDIT PARSING TRANSITION + STATUS BITS ;***** ; $NOP = 0 ;NO OPERATION $CHR = 1 ;MATCH CHARACTER $SIZ = 2 ;MATCH COMMAND SIZE $OCT = 4 ;CONVERT & STORE OCTAL NUMBER $ASC = 10 ;CONVERT & STORE ASCII $R50 = 20 ;CONVERT & STORE RADIX-50 $XIT = 200 ;END OF PARSING TRANSITIONS ; ET.STS = 0 ;STATUS BYTE ET.CHR = 1 ;CHARACTER OR VALUE ET.OPT = 2 ;OPTION POINTER ET.LEN = 4 ;ENTRY SIZE ; ;***** ;***** MISCELANEOUS IDENTIFIERS ;***** ; TI = 1 ;TI: DEVICE LUN & EVENT-FLAG MAXPKT = 8. ;MAXIMUM SEND/RECEIVE PACKETS (EVEN NUMBER) PKTBUF = <2*30.>*MAXPKT ;DATA BUFFER AREA (WORDS) .SBTTL DATA BASE - PREDEFINED TEXT STRINGS ; .BLKW 1 ; ;***** ;***** ASCII TEXT STINGS FOR OUTPUT MESSAGES ;***** ; MS0: .ASCII <15><12>\SND -- \ ML0 = .-MS0 MS1: .ASCII \*FATAL* - RSX-11M EMPT REQUEST FAILURE\ ML1 = .-MS1 MS2: .ASCII \COMMAND SYNTAX ERROR = \ MS2A: .ASCII \ \ ML2 = .-MS2 MS3: .ASCII \NO \ MS4: .ASCII \DATA PACKET(S) QUEUED\ ML3 = .-MS3 ML4 = .-MS4 MS8: .ASCII \ \\ - DIRECTIVE ERROR = \ MS8A: .ASCII \ \ ML8 = .-MS8 MS9: .ASCII \ \\ PACKET(S) FLUSHED FROM QUEUE\ ML9 = .-MS9 ; ;***** ;***** PROMPTS ;***** ; P0: .ASCII <15><12> P0ID: .ASCII \ \\ SND>\ P0L = .-P0 P1: .ASCII <15><12>\SND>\ P1L = .-P1 P2: .ASCII <15><12> P2ID: .ASCII \ \\ *\ P2L = .-P2 P3: .ASCII <15><12>\*\ P3L = .-P3 ; ;***** ;***** DATA DISPLAY TEXTS ;***** ; LG: .ASCII <15><12><12>\ TASK PARAMETERS FOR THIS IMAGE OF\ .ASCII \ "...SND"\<11>\(V03.1)\<15><12><11>\TASK NAME\<11>\- \ LGTSK: .ASCII \ \<11>\PARTITION\<11>\- \ LGPAR: .ASCII \ \<15><12><11>\TOTAL LUNS\<11>\- \ LGLUN: .ASCII \ \<11>\TI: DEVICE\<11>\- \ LGTI: .ASCII \ \<15><12><11>\PRIORITY\<11>\- \ LGPRI: .ASCII \ \<11>\UIC\<11><11>\- \ LGUIC: .ASCII \ \<15><12><11>\MAX NO PACKETS\<11>\- \ LGMAX: .ASCII \ \<11>\WITH ID'S\<11>\= \ $ID = 101 .REPT MAXPKT .BYTE $ID $ID = $ID + 1 .ENDR .ASCII <15><12> LGL = .-LG ; ;***** ;***** GENERAL PURPOSE TEXT STRINGS ;***** ; MSKTXT: .ASCIZ /MASK =/<11> LSTTXT: .ASCIZ /EDIT =/<11> .EVEN HLSPWN: SPWN$ MCR...,,,,,1,,,HELCMD,HELCML HELCMD: .ASCII /HELP SND/ HELCML=.-HELCMD .EVEN ; ;***** ;***** PROMPT ADDRESS & LENGTH TABLE ;***** ; PTXT: .WORD P1,P3,PRNTBF PLEN: .WORD P1L,P3L,0 ; ;**** ;***** GENERAL DATA BUFFERS ;***** ; GMCR: GMCR$ ;"MCR" & COMMAND BUFFER . = GMCR+G.MCRB CMDBF: .BLKB 132. ;REDEFINE COMMAND BUFFER CMDSZ = .-CMDBF PRNTBF: .BLKB 80. ;OUTPUT BUFFER PRNTSZ = .-PRNTBF ; ; --- COMMAND INPUT QIO & ERROR MESSAGE IDENTIFIER ; INPUT: QIO$ IO.RLB,TI,TI,,IOS,, MSGID: QIO$ IO.WLB,TI,TI,,,, ; .SBTTL DATA BASE - FUNCTION COMMAND PARSING TABLES ; ;***** ;***** FIRST LEVEL COMANDS - PROMPT = "SND>" ;***** ; CSI$ CSI: .BLKW C.SIZE ; CSISW: CSI$SW DQ,SW.DQ,,,,DQVAL CSI$SW SN,SW.SN,,,,SNVAL CSI$SW RC,SW.RC,,,,RCVAL CSI$SW WT,SW.WT,,,,WTVAL CSI$SW OP,SW.OP,,,,OPVAL CSI$SW ID,SW.ID,,,NEG CSI$SW ED,SW.ED,,,,EDVAL CSI$SW TS,SW.TS,,,,TSVAL CSI$SW TR,SW.TR,,,,TRVAL CSI$SW LI,SW.LI,,,,LIVAL CSI$SW CL,SW.CL,,,,CLVAL CSI$SW PS,SW.PS,,,,PSVAL CSI$SW PR,SW.PR,,,,PRVAL CSI$SW IM,SW.IM CSI$SW AL,SW.AL CSI$SW RQ,SW.RQ,,,,RQVAL CSI$SW HE,SW.HE,SWMSK$ CSI$ND ; ; --- SWITCH VALUE PARSING DESCRIPTORS ; DQVAL: CSI$SV ASCII,DQLST,MAXPKT CSI$ND SNVAL: CSI$SV ASCII,SNDLST,MAXPKT CSI$ND RCVAL: CSI$SV ASCII,RCVLST,MAXPKT CSI$ND WTVAL: CSI$SV ASCII,WTTXT,1. CSI$SV OCTAL,WTMAG,2 CSI$SV ASCII,WTMOD,1 CSI$ND OPVAL: CSI$SV OCTAL,REPEAT,2 CSI$ND EDVAL: CSI$SV ASCII,EDPKT,2 CSI$ND LIVAL: CSI$SV ASCII,LITYP,3 CSI$ND TSVAL: CSI$SV OCTAL,TSKSID,2 CSI$ND TRVAL: CSI$SV OCTAL,TSKRID,2 CSI$ND PSVAL: CSI$SV ASCII,PSTSK,6 CSI$ND PRVAL: CSI$SV ASCII,PRTSK,6 CSI$ND CLVAL: CSI$SV ASCII,CLTSK,6 CSI$ND RQVAL: CSI$SV ASCII,PARNAM,6 CSI$SV OCTAL,RQST+R.QSPR,2 CSI$SV OCTAL,GUIC,2 CSI$SV OCTAL,OUIC,2 CSI$ND .SBTTL DATA BASE - EDIT COMMAND PARSING TABLES ; ;***** ;***** SECOND LEVEL COMMANDS - PROMPT = "*" ;***** ; EDICMD: $EDCMD 0,13. $EDCMD 'A,6, EDIASC,ED$ASC $EDCMD 'B,1, EDIBYT $EDCMD 'C,13., EDICPY,ED$CPY $EDCMD 'F,6, EDIFIL,ED$FIL $EDCMD 'I,5, EDIINS,ED$INS $EDCMD 'L,1, EDILST $EDCMD 'M,3, EDIMSK,ED$MSK $EDCMD 'O,10., EDIOCT,ED$OCT $EDCMD 'R,7, EDIR50,ED$R50 $EDCMD 'S,3, EDISEL $EDCMD 'W,1, EDIWRD $EDCMD 'X,1, EDIXIT $EDCMD 'Z,6, EDICLR,ED$FIL .WORD 0 ; ; --- EDIT COMMAND PARSING TRANSITIONS ; ; --- ASCII ; ED$ASC: $EDTRN $SIZ!$XIT,1,DUMPA $EDTRN $OCT,,E.OFF $EDTRN $NOP,,EDYMOD $EDTRN $ASC,,E.REP $EDTRN $NOP!$XIT,,EDLIM1 ; ; --- COPY ; ED$CPY: $EDTRN $NOP,,EDIDST $EDTRN $OCT,,E.DST+2 $EDTRN $CHR,'= $EDTRN $NOP,,EDISRC $EDTRN $OCT,,E.SRC+2 $EDTRN $NOP,,EDYMOD $EDTRN $OCT!$XIT,,E.REP ; ; --- FILL & ZERO ; ED$FIL: $EDTRN $OCT,,E.OFF $EDTRN $NOP,,EDYMOD $EDTRN $OCT,,E.REP $EDTRN $NOP!$XIT,,EDLIM2 ; ; --- INSERT (SEQUENTAIL OPEN FOR MODIFICATION) ; ED$INS: $EDTRN $OCT,,E.OFF $EDTRN $NOP,,EDYMOD $EDTRN $NOP!$XIT,,EDYDAT ; ; --- MASK ; ED$MSK: $EDTRN $NOP,,EDYMOD $EDTRN $XIT,,EDYDAT ; ; --- OCTAL ; ED$OCT: $EDTRN $SIZ!$XIT,1,DUMPO $EDTRN $OCT,,E.OFF $EDTRN $NOP,,EDYMOD $EDTRN $OCT,,E.REP $EDTRN $NOP!$XIT,,EDLIM1 ; ; --- RADIX-50 ; ED$R50: $EDTRN $SIZ!$XIT,1,DUMPR $EDTRN $OCT,,E.OFF $EDTRN $NOP,,EDYMOD $EDTRN $R50,,E.REP $EDTRN $NOP!$XIT,,EDLIM1 .SBTTL DATA BASE - PACKET DESCRIPTORS, EDIT & GENERAL STORAGE ; ;***** ;***** RECEIVE PACKETS ;***** ; $TEMP = 0 $ID = 101 RCVTAB: .REPT MAXPKT $PKTID 'R,$ID,START+$TEMP $ID = $ID + 1 $TEMP = $TEMP+<15.*2> .ENDR .WORD 0 ; ;***** ;***** SEND PACKETS ;***** ; $ID = 101 SNDTAB: .REPT MAXPKT $PKTID 'S,$ID,START+$TEMP $TEMP = $TEMP+<2*15.> $ID = $ID+1 .ENDR .WORD 0 ; ;***** ;***** EDIT COMMAND PROCESSING DESCRIPTOR ;***** ; E.PKT: .WORD 0 ;PACKET ADDRESS E.TYP: .BYTE 0 ;PACKET TYPE E.ID: .BYTE 0 ;PACKET ID E.STS: .WORD 0 ;EDIT STATUS E.OFF: .WORD 0 ;PACKET OFFSET E.REP: .WORD 0 ;REPEAT COUNT E.DST: .WORD 0,0 ;COPY - DESTINATION PACKET + OFFSET E.SRC: .WORD 0,0 ;COPY - SOURCE PACKET + OFFSET MASK: .WORD 0 ;EDIT MASK ; ;***** ;***** GENERAL DATA STORAGE ;***** ; MCRFLG: .BYTE 0 ; 0 = NOT "MCR" ROUTINE EDIFLG: .BYTE 0 ; 0 = NOT IN EDIT (ALSO PROMPT ID) RCVFLG: .BYTE 0 ; 0 = RECEIVE AST NOT FIRED .EVEN IOS: .WORD 0 ;TI: I/O STATUS SIZE: .WORD 0 ;SIZE OF TI: INPUT SNDTSK: .WORD 0,0 ;INSTALLED NAME OF THIS TASK ; ; --- TASK REQUEST ; RQST: RQST$ ...SND,GEN,50.,200,200 ; ;***** ;***** COMMAND PROCESSING DATA STORAGE ;***** ; WRK: ;START OF STORAGE SWMSK$: .WORD ; Switch Mask Word DQLST: .BLKB MAXPKT+1 ;"/DQ" LIST RCVLST: .BLKB MAXPKT+1 ;"/RC" LIST SNDLST: .BLKB MAXPKT+1 ;"/SN" LIST PRTSK: .BLKB 6 ;"/PR" - TEMPORARY OVER-RIDE TASK NAME (RECEIVE) PSTSK: .BLKB 6 ;"/PS" - TEMPORARY OVER-RIDE TASK NAME (SEND) .EVEN PARNAM: .BLKB 6 ;"/RQ" - PARTITION NAME CLTSK: .BLKB 6 ;"/CL" - OPTIONAL TASK NAME WTTXT: .BYTE 0 ;"/WT" TEXT = TIME MAGNITUDE WTMOD: .BYTE 0 ;"/WT" USAGE MODE LINES: .BYTE 0 ;DUMP LINE COUNT COLS: .BYTE 0 ;DUMP COLUMN COUNT FLAG: .BYTE 0 ;GENERAL PROCESSING FLAG RQFLG: .BYTE 0 ;"/RQ" PROCESSING FLAG TKINDX: .BYTE 0 ;TASK LIST INDEX (FOR "/AL") .EVEN LITYP: .BLKB 4 ;STATUS LISTING TYPE EDPKT: .BYTE 0,0 ;"/ED" PACKET TYPE + ID ; REPEAT: .WORD 0 ;COMMAND REPEAT COUNT ERROR: .WORD 0 ;ERROR VALUE LOC: .WORD 0 ;DUMP LOCATION COUNTER WTMAG: .WORD 0 ;"/WT" DURATION TSKSID: .WORD 0 ;CURRENT TASK NAME POINTER (SEND) TSKRID: .WORD 0 ;CURRENT TASK NAME POINTER (RECEIVE) COUNT: .WORD 0 ;PROCESSING COUNT GUIC: .WORD 200 ;"/RQ" - UIC GROUP CODE OUIC: .WORD 200 ;"/RQ" - UIC OWNER CODE WRKSZ = .-WRK .SBTTL PROGRAM INITIALISATION ; ;***** ;***** GET "MCR" COMMAND LINE. IF SUCCESSFUL THEN SET "MCR" ;***** ; START: MOV #XIT,-(SP) ;SET ERROR RETURN ADDRESS DIR$ #GMCR ;GET "MCR" COMMAND LINE BCS 10$ ;BR IF NOT AN "MCR" ROUTINE CMP #4,$DSW BGE 10$ ;BR IF NO COMMAND LINE INCB MCRFLG ;SET "MCR" ROUTINE MOV $DSW,SIZE SUB #4,SIZE ; & SET SIZE OF COMMAND ; ;***** ;***** DECLARE RECEIVE, POWER FAIL/RESTART AST'S ;***** & ASSIGN TI: DEVICE - ALSO TEST MARK-TIME ;***** ; 10$: SRDA$S #RCVAST ;SPECIFY RECEIVE AST BCS 20$ ;ERROR ; SPRA$S #PWFAST ;SPECIFY POWER FAIL AST ; BCS 20$ ;ERROR ALUN$S #TI,#"TI,#0 ;ASSIGN TI: DEVICE BCS 20$ ;BR IF ERROR MRKT$S #1,#10,#1 ;REQUEST 8 TICK WAIT BCS 20$ ;BR IF ERROR WTSE$S #1 BCC 30$ ;BR IF MARK-TIME SUCCESSFUL ; ; --- RSX-11M EMPT FAILURE - FATAL ERROR CAN NOT CONTINUE ; 20$: INCB MCRFLG ;FORCE PROGRAM EXIT JMP ERR1 ;FATAL ERROR - EMT FAILURE ; ;***** ;***** GET & FORMAT ALL INFORMATION RELATING TO TASK IMAGE. ;***** USE THE ABOVE CODE AREA FOR "GLUN$S" & "GTSK$S" BUFFERS ;***** ; 30$: MOV #START,R5 ; ; --- GET TI: DEVICE DATA & FORMAT TI: DEVICE ; GLUN$S #1,R5 ;GET TI: DEVICE DATA BCS 20$ ;BR IF ERROR MOVB (R5),LGTI MOVB 1(R5),LGTI+1 ;SET DEVICE NAME MOV #LGTI+2,R0 MOVB 2(R5),R1 CLR R2 CALL $CBOMG ;CONVERT UNIT NUMBER MOVB #':,(R0)+ ; ; --- GET TASK DATA ; GTSK$S R5 ;GET TASK DATA BCS 20$ ;BR IF ERROR ; ; --- SAVE THE INSTALLED NAME OF THIS TASK IMAGE & FORMAT ; --- THE NAME FOR THE TASK DATA & PROMPT DISPLAYS ; MOV #LGTSK,R0 MOV (R5),R1 MOV R1,SNDTSK ;SAVE INSTALLED NAME (PART 1) CALL $C5TA ;CONVERT FIRST 3 CHARS MOV 2(R5),R1 MOV R1,SNDTSK+2 ;SAVE INSTALLED NAME (PART 2) CALL $C5TA ;CONVERT LAST 3 CHARS MOV #P0ID,R0 MOV (R5),R1 CALL $C5TA ;CONVERT FIRST 3 CHARS FOR PROMPT "SND" MOV 2(R5),R1 CALL $C5TA ;CONVERT LAST 3 CHARS FOR PROMPT "SND" MOV #P2ID,R0 MOV (R5),R1 CALL $C5TA ;CONVERT FIRST 3 CHARS FOR PROMPT "*" MOV 2(R5),R1 CALL $C5TA ;CONVERT LAST 3 CHARS FOR PROMPT "*" ; ; --- FORMAT PARTITION NAME ; MOV #LGPAR,R0 MOV 4(R5),R1 CALL $C5TA ;CONVERT FIRST 3 CHARS MOV 6(R5),R1 CALL $C5TA ;CONVERT LAST 3 CHARS ; ; --- FORMAT TOTAL LUN COUNT ; MOV #LGLUN,R0 MOVB 20(R5),R1 CLR R2 CALL $CBDMG ;CONVERT LUN COUNT ; ; --- FORMAT RUN PRIORITY ; MOV #LGPRI,R0 MOVB 14(R5),R1 CLR R2 CALL $CBDMG ;CONVERT RUN PRIORITY MOVB #'.,(R0) ; ; --- FORMAT RUN UIC ; MOV #LGUIC,R2 MOV 16(R5),R3 CLR R4 ;SET FOR ZERO SUPPRESS + FORMAT CALL .PPASC ;CONVERT UIC ; ; --- FORMAT NUMBER OF "SEND" + "RECEIVE" PACKETS AVAILABLE ; MOV #LGMAX,R0 MOV #,R1 CLR R2 CALL $CBDMG ;CONVERT PACKET COUNT ; ; --- IF NOT AN "MCR" ROUTINE THEN DISPLAY TASK DATA ; TSTB MCRFLG BNE 50$ ;BR IF "MCR" ROUTINE MOV #LG,R5 MOV #LGL,R4 CALL PRINT ;DISPLAY DATA ; 50$: JMP INIT ;NOW INITIALISE DATA AREAS ; ;***** ;***** THE PRECEEDING START-UP CODE IS USED ONCE ONLY & CAN ;***** NOW BE ALLOCATED AS A BUFFER AREA FOR THE RECEIVE & ;***** SEND PACKETS. IF THE LOCATION COUNTER IS LESS THAN ;***** THE REQUIRED STORAGE THEN DEFINE THE REQUIRED AREA. ;***** ; $TEMP = <.-START>/2 ;WORDS USED BY PRECEEDING CODE .IF LE <$TEMP - >> . = START $PKTS: .BLKW PKTBUF ;DEFINE PACKET AREA $TSKS: .BLKW ;TASK NAME LIST .ENDC ; TASKS = START + DATOVR = <.-START>/2 ; ;***** ;***** NOW INITIALISE THE PACKET DATA AREA ;***** ; INIT: MOV #START,R5 MOV #DATOVR,R4 ; 10$: CLR (R5)+ ;CLEAR DATA AREA SOB R4,10$ ADD #2,(SP) ;REMOVE ERROR RETURN BR NXTCMD ; ;***** ;***** NOW RE-USE THE INITIALISATION CODE FOR A DUMMY ;***** RECEIVE BUFFER & TEMPORARY WORK BUFFER ;***** ; $TEMP = <.-INIT>/2 ;WORDS USED BY INITIALISATION CODE .IF LE <$TEMP-15.> . = INIT ;RESET LOCATION COUNTER .BLKW 15. ;RESERVED SPACE FOR WORK AREA .ENDC OVRTSK = INIT TEMP = INIT ;LABEL ASSIGNMENTS DUMMY = INIT .SBTTL OBTAIN, ANALYSE & PARSE COMMAND ; ;***** ;***** IF AN "MCR" ROUTINE THEN PARSE COMMAND. ;***** OTHERWISE OBTAIN COMMAND FIRST ;***** ; NXTCMD: TSTB MCRFLG BNE PARSE1 ;BR IF "MCR" ROUTINE CALL GETCMD ;ELSE - GET COMMAND ; ;***** ;***** ANALYSE COMMAND LINE ;***** IGNORE ANY ERROR - SINCE TASK NAMES MAY BE PRESENT ;***** ; PARSE1: CSI$1 #CSI,#CMDBF+4,SIZE ; ;***** ;***** PARSE EACH COMMAND IN THE COMMAND LINE ;***** FIRST SET UP DEFAULTS FOR THE COMMAND ;***** ; PARSE2: MOV #WRK,R5 MOV #WRKSZ,R4 ; 10$: CLRB (R5)+ ;CLEAR WORK AREA SOB R4,10$ CLR CSI+C.MKW1 CLR CSI+C.MKW2 INC REPEAT ;ACTION REPEATABLE COMMAND ONCE ONLY MOVB #'A,DQLST MOVB #'A,RCVLST ;DEFAULT TO PACKET 'A' MOVB #'A,SNDLST MOV #"SA,EDPKT ;DEFAULT PACKET FOR EDIT MOVB #'C,WTMOD ;DEFAULT TO WAIT BEFORE ACTIONING COMMAND MOV #"AL,LITYP ;DEFAULT TO ALL LISTS MOV #"GE,PARNAM ;SET PARTITION NAME MOV #"E ,PARNAM+2 ; ... TO "GEN" MOV #50.,RQST+R.QSPR;PRIORITY = 50. MOV #200,GUIC MOV #200,OUIC ;UIC = [200,200] ; ;***** ;***** PARSE A COMMAND IN THE COMMAND LINE ;***** ; PAR2A: CSI$2 #CSI,OUTPUT,#CSISW BCC 5$ ;BR IF PARSE OK MOV #2,ERROR JMP CMDERR ;COMMAND PARSE ERROR ; 5$: BIT #SW.HE,SWMSK$ ; Help switch? BEQ 10$ ; If EQ no - process normally DIR$ #HLSPWN ; Yes - ask for help WTSE$S #1 ; Wait for it to finish JMP XIT ; Get next line ; ; --- SEE IF "/ED" IS THE ONLY SWITCH ; 10$: CMP #SW.ED,CSI+C.MKW1 BNE 50$ ;BR IF ONLY SWITCH IS NOT EDIT ; ; --- EDIT - NOT ALLOWED IF "MCR" ; 20$: TSTB MCRFLG BEQ 30$ ;BR IF NOT "MCR" ROUTINE MOV #3.,ERROR JMP CMDERR ;CANT EDIT IN "MCR" ; ; --- EDIT - REQUEST MUST BE ONLY/LAST COMMAND IN LINE ; 30$: TSTB CSI+C.STAT BEQ 40$ ;BR IF NO OTHER DATA CMPB #CS.EQU,CSI+C.STAT BEQ 40$ ;BR IF ONLY TASK NAME LIST MOV #4,ERROR JMP CMDERR ;CAN ONLY HAVE EDIT SWITCH ; ; --- EDIT REQUEST IS VALID ; 40$: JMP EDIT ;OK - SO EDIT ; ; --- MORE THAN ONE SWITCH - MUST NOT HAVE "/ED" ; 50$: MOV CSI+C.MKW1,R1 BIC #SWALL,R1 ;CLEAR ALL POSSIBLE SWITCH BITS TST R1 BEQ PARSE3 ;BR IF ONLY LEGAL SWITCHES PRESSENT MOV #4,ERROR JMP CMDERR ;CANT HAVE EDIT + OTHER DATA ; ;***** ;***** IF ONE OR MORE TASK NAMES ARE PRESENT, THEN CONVERT ;***** & STORE THEM. THE TASK NAMES ARE TO THE RIGHT OF THE '='. ;***** ; PARSE3: BITB #CS.DVF,CSI+C.STAT BEQ PARSE4 ;BR IF NO TASK NAME IDENTIFIER MOV CSI+C.DEVD+2,R0 CMPB #'T,(R0)+ BNE 90$ ;BR IF NOT 'T' CMPB #'K,(R0)+ BNE 90$ ;BR IF NOT 'TK' MOV #,R4 ;SET MAXIMUN NUMBER OF TASK NAMES MOV #TASKS,R5 ; & POINT TO TASK NAME LIST CMPB #':,(R0) BEQ 10$ ;BR IF TERMINATOR FOUND CALL $COTB ;ELSE - CONVERT ENTRY START NUMBER TST R1 BLT 90$ CMP R4,R1 BLE 90$ ;BR IF ENRTY NUMBER EXCEEDS MAX CMPB #':,R2 BNE 90$ ;BR IF INVALID TERMINATOR SUB R1,R4 ;SET COUNT OF ENTRIES TO END OF LIST ASL R1 ASL R1 ;SET ENTRY NUMBER ADD R1,R5 ; & POINT TO IT ; ; --- NOW SCAN COMMAND LINE FOR '=' & START OF TASK NAME LIST ; 10$: MOV #CMDBF+4,R0 MOV SIZE,R1 ; 20$: CMPB #'=,(R0)+ BEQ 30$ ;BR IF START OF TASK NAMES FOUND SOB R1,20$ ;ELSE - CONTINUE SCAN MOV #12.,ERROR BR 99$ ;ERROR - '=' NOT FOUND ; ; --- NOW CONVERT TASK NAMES - IF TERMINATED BY ',' THEN REPEAT ; 30$: MOV #7,R1 CALL $CAT5 BCC 40$ ;BR IF 3 CHARS CONVERTED MOV R1,(R5)+ CLR (R5)+ ;CLEAR LAST 3 CHARS BR 50$ ;SEE IF TERMINATOR PRESENT ; 40$: MOV R1,(R5)+ ;STORE FIRST 3 CHARS CALL $CAT5 MOV R1,(R5)+ ;STORE LAST 3 CHARS ; 50$: CMPB #',,R2 BEQ 60$ ;BR IF TERMINATOR FOUND CMPB #',,(R0)+ BNE PARSE4 ;BR IF NO TERMINATOR - END OF NAMES ; 60$: SOB R4,30$ ;CONTINUE IF LIST NOT FULL ; ; --- ERROR IN PARSING/CONVERTING TASK NAMES ; 90$: MOV #10.,ERROR ; 99$: JMP CMDERR ; ;***** ;***** CHECK FOR THE PRESSENCE OF A SPECIFIC TASK NAME ;***** IF NOT, DEFAULT TO THE FIRST ONE IN THE LIST ;***** ; ; ; --- IF A SEND TASK IS REFERENCED SET UP THE TASK NAME POINTER ; PARSE4: MOV #TASKS,R0 BIT #SW.TS,CSI+C.MKW1 BEQ 10$ ;BR IF NO SEND TASK ID MOV TSKSID,R1 CALL TSKREF ;ELSE - SET UP TASK NAME POINTER BCC 10$ ;BR IF OK JMP CMDERR ;ELSE - REPORT ERROR ; 10$: MOV R0,TSKSID ;SAVE SEND TASK POINTER ; ; --- IF A RECEIVE TASK IS REFERENCED SET UP THE TASK NAME POINTER ; MOV #TASKS,R0 BIT #SW.TR,CSI+C.MKW1 BEQ 20$ ;BR IF NO RECEIVE TASK ID MOV TSKRID,R1 CALL TSKREF ;ELSE - SET UP TASK NAME POINTER BCC 20$ ;BR IF OK JMP CMDERR ;ELSE - REPORT ERROR ; 20$: MOV R0,TSKRID ;SAVE RECEIVE TASK POINTER ; ; --- IF THE DESTINATION OR SOURCE TASK IS THIS TASK IMAGE ("/IM") - ; --- THEN OVER-RIDE THE "/TS:N" AND THE "/TR:N" SETTING ; --- NB: "/PS:X" AND "/PR:X" CON OVER-RIDE "/IM". ; BIT #SW.IM,CSI+C.MKW1 BEQ 30$ ;BR IF DESTINATION/SOURCE TASK NOT THIS IMMAGE MOV #SNDTSK,TSKSID ;ELSE - SET RECEIVER = SENDER MOV #SNDTSK,TSKRID ; & SET SENDER = RECEIVER ; ; --- IF THE AN OVER-RIDING SENDING TEMPORARY TASK NAME IS PRESENT - USE IT ; 30$: BIT #SW.PS,CSI+C.MKW1 BEQ 40$ ;BR IF NO TEMPORARY SEND NAME PRESENT MOV #PSTSK,R0 MOV #7,R1 CALL $CAT5 ;CONVERT FIRST 3 CHARS MOV R1,OVRTSK CALL $CAT5 ;CONVERT LAST 3 CHARS MOV R1,OVRTSK+2 MOV #OVRTSK,TSKSID ;SET TASK NAME POINTER ; ; --- IF AN OVER-RIDING RECEIVING TEMPORARY TASK NAME IS PRESSENT - USE IT ; 40$: BIT #SW.PR,CSI+C.MKW1 BEQ PAR4A ;BR IF NO TEMPORAY RECEIVE TASK NAME MOV #PRTSK,R0 MOV #7,R1 CALL $CAT5 ;CONVERT FIRST 3 CHARS MOV R1,OVRTSK+4 CALL $CAT5 ;CONVERT LAST 3 CHARS MOV R1,OVRTSK+6 MOV #OVRTSK,TSKRID ;SET TASK NAME POINTER ; ;***** ;***** CHECK THE REPEATABLE OPERATION RANGES ;***** ; ; --- CHECK THE VALUE OF THE REPEAT COUNT ; PAR4A: TST REPEAT BLE 10$ ;BR IF < 1 CMP #99.,REPEAT BGE PAR4B ;BR IF IN RANGE ; 10$: MOV #9.,ERROR JMP CMDERR ;ERROR - INVALID REPEAT RANGE ; ;***** ;***** NOW PERFORM ALL REPEATABLE OPERATIONS ;***** ; ; --- IF A MARK-TIME IS REQUESTED, VALIDATE & ISSUE IT ; PAR4B: BIT #SW.WT,CSI+C.MKW1 BEQ 10$ ;BR IF NO DELAY REQUESTED CMPB #'C,WTMOD BNE 10$ ;BR IF NOT "COMMAND WAIT" CALL TIMER ;ELSE - PERFORM A MARK-TIME BCC 10$ ;BR IF OK JMP CMDERR ; ; --- SEND ANY RECEIVE(D) PACKETS IF REQUIRED ; 10$: BIT #SW.RC,CSI+C.MKW1 BEQ 20$ ;BR IF NOT SENDING RECEIVE PACKETS MOV #RCVLST,R0 MOV #RCVTAB,R1 CALL SEND ;ELSE - SEND RECEIVE PACKETS BCC 20$ ;BR IF OK JMP CMDERR ; ; --- SEND ANY 'SEND' PACKETS IF REQUIRED ; 20$: BIT #SW.SN,CSI+C.MKW1 BEQ 30$ ;BR IF NOT SENDING "SEND" PACKETS MOV #SNDLST,R0 MOV #SNDTAB,R1 CALL SEND ;ELSE - SEND 'SEND' PACKETS BCC 30$ ;BR IF OK JMP CMDERR ; ; --- DE-QUEUE PACKETS INTO THE RECEIVE BUFFERS IF REQUIRED ; 30$: BIT #SW.DQ,CSI+C.MKW1 BEQ 40$ ;BR IF NOT DE-QUEUING PACKETS MOV #DQLST,R0 MOV #RCVTAB,R1 CALL RECEVE ;ELSE - DE-QUEUE PACKETS BCC 40$ ;BR IF OK JMP CMDERR ; ; --- IF TASKS ARE TO BE ACTIVATED - THEN REQUEST THE TASK TO BE ; --- RUN THIS IS ATTEMPTED FOR EACH REPEAT CYCLE. ; 40$: BIT #SW.RQ,CSI+C.MKW1 BEQ 90$ ;BR IF NO TASK INVOKATION TO PERFORM TSTB RQFLG BNE 80$ ;BR IF REQUIRED DEFAULTS HAVE BEEN SET TSTB PARNAM BEQ 50$ ;BR IF NO PARTITION NAME MOV #PARNAM,R0 MOV #7,R1 CALL $CAT5 ;CONVERT FIRST 3 CHARS MOV R1,RQST+R.QSPN CALL $CAT5 ;CONVERT LAST 3 CHARS MOV R1,RQST+R.QSPN+2 ; 50$: TST GUIC BEQ 60$ ;BR IF NO UIC GROUP CODE MOVB GUIC,RQST+R.QSGC ; 60$: TST OUIC BEQ 70$ ;BR IF NO UIC OWNER CODE MOVB OUIC,RQST+R.QSPC ; 70$: INCB RQFLG ;NOW SET PARTION NAME CONVERTED ; 80$: MOV TSKSID,R0 ;GET TASK NAME MOV (R0)+,RQST+R.QSTN MOV (R0)+,RQST+R.QSTN+2 DIR$ #RQST ;REQUEST TASK BCC 90$ ;BR IF SUCCESSFUL CMP #IE.ACT,$DSW BEQ 90$ ;BR IF TASK IS ALREADY ACTIVE MOV $DSW,ERROR ;ELSE - COPY ERROR CODE MOV #<^RRQS>,R1 CALL ERR3 ;REPORT ERROR JMP CMDERR ; ; --- USE ALL AVAILABLE TASK NAMES IF REQUIRED ("/AL") BUT ONLY ; --- THOSE ENRTIES WHICH CONTAIN TASK NAMES ; 90$: BIT #SW.AL,CSI+C.MKW1 BEQ 120$ ;BR IF ONLY ONE TASK NAME IN USE ; 100$: INCB TKINDX ;ELSE - ADJUST INDEX MOVB TKINDX,R1 CMP #,R1 BLE 120$ ;BR IF ALL ENTRIES SCANNED ASL R1 ASL R1 ADD #TASKS,R1 ;POINT TO TASK NAME TST (R1) BNE 110$ ;BR IF TASK NAME PRESENT TST 2(R1) BEQ 100$ ;BR IF NO TASK NAME AVAILABLE IN THIS ENTRY ; 110$: MOV R1,TSKSID ;ELSE - SET SEND TASK NAME ADDRESS MOV R1,TSKRID ; & ALSO RECEIVE TASK NAME ADDRESS JMP PAR4B ; & REPEAT OPERATION FOR THIS TASK ; ; --- IF A REPEAT IS REQUIRED THEN REPEAT /WT, /RC, /SN, /DQ, /RQ & /AL ; 120$: BIT #SW.OP,CSI+C.MKW1 BEQ PAR4C ;BR IF NO OPERATION REPEATS CLRB TKINDX ;RESET TASK LIST INDEX DEC REPEAT BLE PAR4C ;BR IF REPEAT COUNT EXHAUSTED JMP PAR4B ;ELSE - REPEAT ALL OPERATIONS ; ;***** ;***** NOW PROCESS NON-REPEATABLE SWITCHES ;***** ; ; --- FLUSH RECEIVE QUEUE IF REQUIRED ; PAR4C: BIT #SW.CL,CSI+C.MKW1 BEQ 10$ ;BR IF QUEUE NOT TO BE CLEARED CALL CLRQUE ;ELSE - FLUSH QUEUE ; ; --- IF THE PROMPT IS REQUIRED TO BE CHANGED THEN CHANGE IT ; 10$: BIT #SW.ID,CSI+C.MKW1 BEQ 40$ ;BR IF NOT CHANGING PROMPT BIT #SW.ID,CSI+C.MKW2 BEQ 30$ ;BR IF BASIC PROMPT REQUIRED ; ; --- SET UP PROMPT OF INSTALLED TASK NAME + 'SND>' & TASK NAME + '*' ; MOV #P0,PTXT ;SET ADDRESS OF "TASK + 'SND>'" MOV #P0L,PLEN ; & LENGTH MOV #P2,PTXT+2 ;SET ADDRESS OF "TASK + '*'" MOV #P2L,PLEN+2 ; & LENGTH BR 40$ ; ; --- SET UP BASIC PROMPT - 'SND>' & '*' ; 30$: MOV #P1,PTXT ;SET ADDRESS OF 'SND>' MOV #P1L,PLEN ; & LENGTH MOV #P3,PTXT+2 ;SET ADDRESS OF '*' MOV #P3L,PLEN+2 ; & LENGTH ; ; --- LIST ANY CHOSEN STATUSES THAT ARE REQUIRED ; 40$: BIT #SW.LI,CSI+C.MKW1 BEQ PAR4EX ;BR IF STATUSES NOT REQUIRED CALL STATUS ;ELSE - LIST STATUSES BCS CMDERR ;BR IF COMMAND ERROR ; ;***** ;***** A COMMAND HAS BEEN PROCESSED - ;***** IF ANOTHER COMMAND IS PRESSENT IN THE COMAND LINE ;***** PROCESS IT, OTHERWISE GET ANOTHER COMMAND LINE. ;***** ; PAR4EX: BITB #CS.MOR,CSI+C.STAT BEQ 10$ ;BR IF NO MORE COMMANDS IN LINE JMP PARSE2 ;ELSE - PROCESS NEXT COMMAND ; 10$: JMP XIT ;ATTEMP TO EXIT IF "MCR" ROUTINE ; ; --- COMMAND ERROR PROCESSING ; CMDERR: TST ERROR BLE 10$ ;BR IF ERROR NOT TO BE REPORTED CALL ERR2 ;ELSE - REPORT ERROR ; 10$: JMP XIT ;SEE IF EXIT IS TO BE PERFORMED .SBTTL VALIDATE & ACTION MARK-TIME ; ;***** ;***** IF A VALID MARK-TIME REQUEST IS FOUND - THEN ;***** ISSUE THE MARK-TIME & WAIT FOR IT TO EXPIRE ;***** THE TIME DELAY REQUEST IS OF THE FORM - X:NN ;***** WHERE 'X' = MAGNITUDE & 'NN' = NUMBER OF UNITS ;***** ; TIMER: BIT #SW.WT,CSI+C.MKW1 BEQ 50$ ;BR IF NO WAIT (IF CALLED FROM SEND/RECEIVE) MOV #1,R5 CMPB #'T,WTTXT BEQ 10$ ;BR IF TICKS INC R5 CMPB #'S,WTTXT BEQ 10$ ;BR IF SECONDS INC R5 CMPB #'M,WTTXT BEQ 10$ ;BR IF MINUTES BR 60$ ;INVALID MAGNITUDE ; ; --- TIME PARAMETERS ARE OK - SO ISSUE MARK TIME ; 10$: MRKT$S #3,WTMAG,R5 BCC 20$ ;BR IF ACCEPTED MOV #<^RTIM>,R1 ;SET DIRECTIVE ID MOV $DSW,ERROR CALL ERR3 ;REPORT ERROR BR 70$ ; 20$: WTSE$S #3 ;NOW DELAY ; 50$: CLC RETURN ; ; --- ERROR IN PARAMETERS ; 60$: MOV #5,ERROR ; 70$: SEC RETURN ;EXIT - ERROR .SBTTL SEND DATA PACKETS TO DESTINATION TASK ; ;***** ;***** PACKETS ARE SENT TO THE NAMED TASK. THE PACKETS ARE ;***** DEFINE BY A LIST OF THEIR ASCII IDENTIFICATIONS. ;***** A LIST MAY DEFINE UP TO 8 PACKETS ;***** R0 = PACKET ID LIST ;***** R1 = PACKET DESCRIPTOR TABLE ;***** ; SEND: MOV R1,R3 ;COPY DESCRIPTOR TABLE POINTER ; ; --- LOCATE PACKET DESCRIPTOR ; 10$: MOVB (R0)+,R4 ;GET PACKET ID CALL GETPKT ; & GET PACKET ADDRESS BCS 90$ ;BR IF PACKET NOT FOUND ; ; --- PACKET DESCRIPTOR FOUND - WAIT FOR DEFINED PERIOD IF REQUIRED ; 20$: CMPB #'S,WTMOD BEQ 30$ ;BR IF "WAIT BEFORE SEND" CMPB #'P,WTMOD BNE 40$ ;BR IF NO WAIT ; 30$: CALL TIMER ;PERFORM WAIT BCS 90$ ;BR IF MARK-TIME ERROR ; ; --- SEND PACKET TO DESTINATION TASK ; 40$: MOV PK.PKT(R3),R4 ADD #4,R4 SDAT$S TSKSID,R4 BCC 50$ ;BR IF SEND OK MOV #<^RSND>,R1 ;SET DIRECTIVE ID MOV $DSW,ERROR CALL ERR3 ;REPORT ERROR BR 90$ ; ; --- SEND SUCCESSFUL - CONTINUE IF NOT END OF LIST ; 50$: INC PK.CNT(R3) ;COUNT TIMES PACKET SENT MOV PK.PKT(R3),R3 MOV TSKSID,R4 MOV (R4)+,(R3)+ ;SAVE DESTINATION MOV (R4)+,(R3)+ ; ... TASK NAME TSTB (R0) BNE SEND ; & REPEAT IF NOT END-OF-LIST CLC RETURN ; ; --- ERROR EXIT ; 90$: SEC RETURN .SBTTL DE-QUEUE PACKETS IN RECEIVE QUEUE ; ;***** ;***** RECEIVE DATA PACKETS (IF PRESSENT) ARE DE-QUEUED ;***** INTO THE DEFINED RECEIVE PACKET BUFFERS. THE BUFFERS ;***** ARE DEFINED BY A LIST OF THEIR ASCII IDENTIFICATIONS. ;***** UP TO 8 PACKETS MAY BE DE-QUEUED IN ONE OPERATION. ;***** ; RECEVE: CLR COUNT MOV R1,R3 ;COPY DESCRIPTOR TABLE POINTER ; ; --- LOCATE PACKET DESCRIPTOR ; 10$: MOVB (R0)+,R4 ;GET PACKET ID CALL GETPKT ; & GET PACKET ADDRESS BCC 20$ ;BR IF PACKET FOUND RETURN ; ; --- PACKET DESCRIPTOR FOUND - WAIT IF REQUIRED ; 20$: CMPB #'R,WTMOD BEQ 30$ ;BR IF "WAIT BEFOR RECEIVE" CMPB #'P,WTMOD BNE 40$ ;BR IF NO WAIT ; 30$: CALL TIMER ;REQUEST MARK TIME BCC 40$ ;BR IF MARK-TIME SUCCESSFUL RETURN ; ; --- RECEIVE PACKET INTO DEFINED RECEIVE BUFFER ; 40$: RCVD$S TSKRID,PK.PKT(R3) BCC 50$ ;BR IF RECEIVE OK CLRB RCVFLG ;ELSE - NOTE NO MORE PACKETS TST COUNT BNE 60$ ;BR IF PACKET PREVIOUSLY DE-QUEUED MOV #MS3,R5 MOV #ML3,R4 CALL OUTPUT ;REPORT NO PACKETS SEC RETURN ;EXIT - ERROR ; 50$: INC PK.CNT(R3) ;COUNT PACKETS RECEIVED INTO BUFFER INC COUNT ;COUNT TOTAL PACKETS TSTB (R0) BNE 10$ ;BR IF MORE PACKETS REQUIRED ; 60$: CLC RETURN ;ELSE NO MORE - EXIT .SBTTL FLUSH RECEIVE QUEUE ; ;***** ;***** DATA PACKETS ARE DE-QUEUED FROM THIS TASKS RECEIVE QUEUE. ;***** THE PACKETS ARE NOT MADE AVAILABLE TO THE USER AND THE ;***** QUEUE IS CLEARED. PACKETS MAY BE FLUSHED FOR A NAMED TASK ;***** ONLY, LEAVING OTHER PACKETS QUEUED. ;***** ; ; --- CONVERT TASK NAME - A NULL TASK NAME WILL CAUSE THE QUEUE ; --- TO BE CLEARED COMPLETELY. ; CLRQUE: MOV #CLTSK,R0 MOV #7,R1 CALL $CAT5 ;CONVERT FIRST 5 CHARS MOV R1,OVRTSK CALL $CAT5 MOV R1,OVRTSK+2 CLR COUNT ;INIT PACKET COUNT ; ; --- NOW FLUSH RECEIVE QUEUE OF REQUIRED PACKETS ; 10$: RCVD$S #OVRTSK,#DUMMY ;DE-QUEUE PACKET BCS 20$ ;BR IF NOT SUCCESSFUL INC COUNT ;ESLE - COUNT PACKETS BR 10$ ; & GET NEXT ; 20$: TST COUNT BLE 30$ ;BR IF NO PACKETS DE-QUEUE MOV #MS9,R0 MOV COUNT,R1 MOV #<<47*400>+10.>,R2 CALL $CBTA ;CONVERT PACKET COUNT MOV #MS9,R5 MOV #ML9,R4 CALL OUTPUT ;REPORT PACKETS DE-QUEUED ; 30$: TST OVRTSK BNE 40$ ;BR IF A TASK NAME WAS USED CLRB RCVFLG ;ELSE - NOTE THIS 'AST' SERVICED ; 40$: CLC RETURN .SBTTL LIST CHOSEN STATUS ; ;***** ;***** THE REQUIRED STATUS LIST IS DISPLAYED. ;***** "ALL" = ALL STATUS LISTS ;***** "TSK" = TASK NAME LIST ;***** "PKT" = PACKET STATISTICS ;***** "ID" = THIS TASK IMAGE DATA ;***** ; ; --- DETERMINE WHICH LIST(S) ARE REQUIRED ; STATUS: CMP #"AL,LITYP BEQ STSID ;BR IF ALL LISTS REQUIRED CMP #"TS,LITYP BEQ STSTSK ;BR IF TASK NAME LIST REQUIRED CMP #"ID,LITYP BEQ STSID ;BR IF TASK IMAGE PARAMETERS REQUIRED CMP #"PK,LITYP BNE 10$ ;BR IF UNRECOGNISED SWITCH VALUE JMP STSPKT ;ELSE - LIST PACKET STATUSES ; 10$: MOV #6,ERROR SEC RETURN ;EXIT - COMMAND ERROR ; ;***** ;***** LIST THE IDENTIFICATION PARAMETERS FOR THIS TASK IMAGE ;***** ; STSID: MOV #LG,R5 MOV #LGL,R4 CALL PRINT CMP #"AL,LITYP BEQ STSTSK ;DO NEXT LIST IF "ALL" JMP STSFIX ; ;***** ;***** LIST ALL THE DEFINED DESTINATION TASK NAMES ;***** ; STSTSK: CLR COUNT CALL STSFIX ;OUTPUT BLANK LINE MOV #TASKS,R3 MOVB #,LINES ; 10$: CALL CLRBUF ;INITIALISE THE PRINT BUFFER MOVB #4,COLS ; ; --- FORMAT THE TASK ENTRY ID & THE TASK NAME ; 20$: ADD #4,R0 MOVB #'T,(R0)+ MOV COUNT,R1 MOV #7,R2 CALL $CBTMG ;CONVERT TASK NUMBER INC R0 MOVB #'=,(R0)+ INC R0 MOV (R3)+,R1 CALL $C5TA ;CONVERT FIRST 3 CHARS MOV (R3)+,R1 CALL $C5TA ;CONVERT LAST 3 CHARS INC COUNT ;COUNT TASK NAMES DECB COLS BGT 20$ ;BR IF LINE NOT COMPLETE ; ; --- PRINT LINE COMPLETE - SO DISPLAY IT ; CALL PRINTX DECB LINES BGT 10$ ;BR IF MORE LINES TO DO CMP #"AL,LITYP BEQ STSPKT ;BR IF LIST TYPE = "ALL" JMP STSFIX ; ;***** ;***** LIST THE STATISTICS FOR ALL SEND & RECEIVE(D) PACKETS ;***** ; STSPKT: CLR R3 CALL STSFIX MOVB #MAXPKT,LINES ; 10$: CALL CLRBUF ;INITIALISE THE PRINT BUFFER ADD #4,R0 ; ; --- FORMAT THE RECEIVE(D) PACKET TYPE & ID + TASK NAME & USAGE COUNT ; 20$: MOVB RCVTAB+PK.TYP(R3),(R0)+ MOVB RCVTAB+PK.ID(R3),(R0)+ INC R0 MOV RCVTAB+PK.PKT(R3),R4 MOV (R4)+,R1 CALL $C5TA ;CONVERT FIRST 3 CHARS MOV (R4)+,R1 CALL $C5TA ;CONVERT LAST 3 CHARS INC R0 MOV RCVTAB+PK.CNT(R3),R1 MOV #<<66*400>+10.>,R2 CALL $CBTA ;CONVERT USAGE COUNT ; ; --- FORMAT THE SEND PACKET TYPE & ID + TASK NAME & USAGE COUNT ; MOV #PRNTBF+36.,R0 MOVB SNDTAB+PK.TYP(R3),(R0)+ MOVB SNDTAB+PK.ID(R3),(R0)+ INC R0 MOV SNDTAB+PK.PKT(R3),R4 MOV (R4)+,R1 CALL $C5TA ;CONVERT FIRST 3 CHARS MOV (R4)+,R1 CALL $C5TA ;CONVERT LAST 3 CHARS INC R0 MOV SNDTAB+PK.CNT(R3),R1 MOV #<<66*400>+10.>,R2 CALL $CBTA ;CONVERT USAGE COUNT ; ; --- DISPLAY THE PRINT LINE & REPEAT IF MORE LINES TO DO ; CALL PRINTX ADD #PK.LEN,R3 ;STEP ON TO NEXT ENTRY DECB LINES BGT 10$ ;CONTINUE IF MORE TO DO ; ;***** ;***** OUTPUT A BLANK LINE ;***** ; STSFIX: CALL CLRBUF CALL PRINTX CLC RETURN .SBTTL EDIT SEND/RECEIVE PACKET ; ;***** ;***** THIS IS THE SECOND LEVEL OF COMMAND. ;***** ANY PACKET MAY BE EDITED OR DUMPED IN ANY FORMAT. ;***** THIS ROUTINE OBTAINS & VALIDATES AN EDIT COMMAND ;***** & CONTROLS THE EXECUTION OF THE COMMAND FUNCTIONS. ;***** ; ; --- ENTRY FROM FIRST COMMAND LEVEL ; EDIT: MOVB #2,EDIFLG ;SET EDIT MODE MOV #EDPKT,R0 ;POINT TO PACKET TYPE & ID CALL EDISEL ; & GET PACKET ID BCC EDIT2 ;BR IF PACKET FOUND JMP EDERR ; ;***** ;***** NOW PROCESS EDIT COMMAND ;***** ; EDIT2: CALL GETCMD ;GET COMMAND CLRB E.STS ;INITIALISE DATA MODE STATUS MOV #EDICMD,R5 MOV #CMDBF+4,R0 ;POINT TO START OF COMMAND ; ; --- LOCATE COMMAND IN COMMAND TABLE ; 10$: CMPB D.CHR(R5),(R0) BEQ 20$ ;BR IF COMMAND FOUND ADD #D.LEN,R5 ;ELSE - STEP ON TO NEXT ENTRY TST (R5) BNE 10$ ; & CONTINUE IF NOT END-OF-LIST ; ; --- COMMAND NOT FOUND ; JMP EDERR1 ;INVALID COMMAND ; ; --- COMMAND FOUND - CHECK COMMAND SIZE DOES EXCEED MAX ; 20$: MOVB (R0)+,R2 ;ADJUST POINTER & GET NEXT CHARACTER CMPB D.SIZ(R5),SIZE BGE EDIT3 ;BR IF VALID COMMAND STRING SIZE JMP EDERR1 ; ;***** ;***** PARSE EDIT COMMAND IF A PARSING DESCRIPTOR EXISTS ;***** ; EDIT3: TST D.PRS(R5) BEQ 100$ ;BR IF PARSING NOT REQUIRED MOV R5,-(SP) ;SAVE COMMAND ID POINTER MOV D.PRS(R5),R5 ; & POINT TO PARSING TABLE ; ; --- IF "$SIZ" & SIZE MATCHES - INVOKE ROUTINE ; 10$: BITB #$SIZ,ET.STS(R5) BEQ 20$ ;BR IF NOT "$SIZ" CMPB ET.CHR(R5),SIZE BEQ 60$ ;SIZES MATCH - SELECT ROUTINE BR 80$ ;ELSE - STEP ON TO NEXT ENTRY ; ; --- IF "$CHR" & CHARACTERS MATCH - INVOKE ROUTINE ; 20$: BITB #$CHR,ET.STS(R5) BEQ 30$ ;BR IF NOT "$CHR" CMPB ET.CHR(R5),(R0)+ BEQ 70$ ;BR IF CHARACTERS MATCH MOV (SP)+,R5 JMP EDERR1 ;ELSE - ERROR ; ; --- IF "$OCT" - CONVERT NUMBER & STORE IT ; 30$: BITB #$OCT,ET.STS(R5) BEQ 40$ ;BR IF NOT "$OCT" CALL $COTB ;CONVERT NUMBER MOV R1,@ET.OPT(R5) ; & STORE IT DEC R0 ;STEP BACK TO TERMINATOR BR 70$ ;AN OPTION ROUTINE IS NOT ALLOWED ; ; --- IF "$ASC" - STORE CHARACTERS ; 40$: BIT #$ASC,ET.STS(R5) BEQ 50$ ;BR IF NOT "$ASC" MOV ET.OPT(R5),R1 MOVB (R0)+,(R1)+ MOVB (R0)+,(R1)+ BR 70$ ; ; --- IF "$R50" - CONVERT CHARACTERS TO RADIX-50 & STORE THEM ; 50$: BIT #$R50,ET.STS(R5) BEQ 60$ ;BR IF NOT "$R50" MOV #7,R1 CALL $CAT5 ;CONVERT TO RADIX-50 MOV R1,@ET.OPT(R5) DEC R0 ;STEP BACK TO TERMINATOR BR 70$ ; ; --- SELECT OPTION ROUTINE IF PRESENT ; 60$: TST ET.OPT(R5) BEQ 70$ ;BR IF NO OPTION ROUTINE CALL @ET.OPT(R5) ;SELECT OPTION BCC 70$ ;BR IF OK MOV (SP)+,R5 BR EDERR ; 70$: BITB #$XIT,ET.STS(R5) BNE 90$ ;BR IF END ; 80$: ADD #ET.LEN,R5 ;STEP ON TO NEXT ENTRY BR 10$ ; & REPEAT ; ; --- PARSING NOW COMPLETE - INVOKE PROCESSING ROUTINE IF REQUIRED ; 90$: MOV (SP)+,R5 ; 100$: TST D.RTN(R5) BEQ EDIT2 ;BR IF NO ROUTINE CALL @D.RTN(R5) ;SELECT ROUITNE BCC EDIT2 ;BR IF OK BR EDERR ;ELSE - REPORT ERROR ; ; --- ERROR - INVALID PACKET ID ; EDERR1: MOV #1,ERROR ;COMMAND SYNTAX ERROR ; EDERR: CALL ERR2 ;REPORT ERROR JMP EDIT2 ; & GET NEXT COMMAND ; ;***** ;***** EDIT TERMINATION ;***** ; EDIXIT: TST (SP)+ ;REMOVE RETURN TO PARSER CLRB EDIFLG JMP NXTCMD ; & GET NEXT "FIRST LEVEL" COMMAND .SBTTL EDIT - CHANGE PACKET LOCATION ; ;***** ;***** SET PACKET LOCATION AS ASCII ;***** ; EDIASC: BIT #ED.DMP,E.STS BNE 50$ ;BR IF DUMP PERFORMED MOVB #ED.ASC,E.STS MOV E.PKT,R5 ADD E.OFF,R5 ;POINT TO LOCATION ADD #4,R5 MOVB E.REP,(R5)+ ;COPY FIRST BYTE BIT #ED.BYT,E.STS BNE 50$ ;BR IF ACCESS MODE = BYTE MOVB E.REP+1,(R5)+ ;ELSE - COPY NEXT BYTE 50$: RETURN ; ;***** ;***** SET PACKET LOCATION AS OCTAL ;***** ; EDIOCT: BIT #ED.DMP,E.STS BNE 50$ ;BR IF DUMP PERFORMED MOVB #ED.OCT,E.STS ;SET DATA TYPE = OCTAL MOV E.PKT,R5 ADD E.OFF,R5 ;POINT TO LOCATION ADD #4,R5 MOVB E.REP,(R5) ;SET BYTE VALUE BIT #ED.BYT,E.STS BNE 50$ ;BR IF ACCESS MODE = BYTE MOV E.REP,(R5) ;ELSE - SET WORD 50$: RETURN ; ;***** ;***** SET PACKET LOCATION AS RADIX-50 ;***** ; EDIR50: BIT #ED.DMP,E.STS BNE 50$ ;BR ID DUMP PERFORMED MOVB #ED.R50,E.STS MOV E.PKT,R5 ADD E.OFF,R5 ;POINT TO LOCATION ADD #4,R5 MOV E.REP,(R5) ; & SET VALUE 50$: RETURN .SBTTL EDIT - LIST PACKET TYPE + ID & RECEIVER/SENDER NAME ; ;***** ;***** IDENTIFY THE CURRENT PACKET ;***** ; EDILST: CALL CLRBUF ;INITIALISE THE PRINT BUFFER ; ; --- INSERT LISTING IDENTIFICATION ; MOV #LSTTXT,R1 ; 10$: MOVB (R1)+,(R0)+ ;COPY TEXT BYTE TSTB (R1) BNE 10$ ;CONTINUE IF MORE BYTES TO COPY ; ; --- SET PACKET TYPE & ID ; MOVB E.TYP,(R0)+ MOVB E.ID,(R0)+ ADD #4,R0 ; ; --- FORMAT RECEIVER/SENDER TASK NAME ; MOV E.PKT,R5 MOV (R5)+,R1 CALL $C5TA ;CONVERT FIRST 3 CHARS MOV (R5)+,R1 CALL $C5TA ;CONVERT LAST 3 CHARS ; ; --- DISPLAY DATA ; MOV #PRNTBF,R5 MOV R0,R4 SUB R5,R4 ;SET LINE LENGTH CALL PRINT ;DISPLAY LINE RETURN .SBTTL EDIT - DISPLAY AND/OR CHANGE MASK ; ;***** ;***** DISPLAY MASK - COMPLETE WORD ALWAYS DISPLAYED ;***** ; EDIMSK: CALL CLRBUF ;INITIALISE PRINT BUFFER ; ; --- INSERT MASK IDENTIFICATION TEXT ; MOV #MSKTXT,R1 ; 10$: MOVB (R1)+,(R0)+ ;COPY TEXT BYTE TSTB (R1) BNE 10$ ;CONTINUE IF MORE TO COPY ; ; --- OPEN MASK FOR POSSIBLE MODIFICATION ; MOV #MASK,R3 ;SET MASK POINTER CALL EDYLOC ; & OPEN IT FOR EDIT CLC RETURN ; ; ;============================================================ ; ; ; .SBTTL EDIT - DISPLAY AND/OR CHANGE PACKET LOCATION ; ;***** ;***** DISPLAY PACKET LOCATION - COMPLETE WORD ALWAYS DISPLAYED ;***** ; ; --- ENSURE THAT THE OFFSET IS A WORD ADDRESS & SET THE NUMBER ; --- OF WORDS TO THE END OF THE PACKET ; EDIINS: BIT #1,E.OFF BEQ 10$ ;BR IF OFFSET IS A WORD ADDRESS DEC E.OFF ;ELSE - POINT TO LOW BYTE OF WORD ; 10$: MOV #26.,R1 SUB E.OFF,R1 ;CALCULATE BYTES TO END OF PACKET ASR R1 MOV R1,E.REP ; & STORE IT AS WORDS TO END ; ; --- ADDRESS START LOCATION OF PACKET ; MOV E.PKT,R3 ADD #4,R3 ADD E.OFF,R3 ; ; --- INITIALISE PRINT LINE ; 20$: CALL CLRBUF ;INITIALISE PRINT BUFFER MOVB E.TYP,(R0)+ ;SET PACKET TYPE MOVB E.ID,(R0)+ ; ... & PACKET ID INC R0 MOV E.OFF,R1 MOV #7,R2 CALL $CBTMG ;FORMAT WORD OFFSET IN PACKET MOVB #'-,(R0)+ MOVB #11,(R0)+ ; ; --- OPEN LOCATION FOR POSSIBLE MODIFICATION ; CALL EDYLOC ;OPEN LOCATION CMP #IS.ESC,IOS BEQ 50$ ;BR IF IS TERMINATOR - STOP ADD #2,E.OFF ;ELSE - INCREMENT LOCATION POINTER DEC E.REP BGT 20$ ;CONTINUE IF NOT AT END OF PACKET ; ; --- ALL POSSIBLE (REQUIRED) LOCATIONS NOW EXAMINED/CHANGED ; 50$: CLC RETURN .SBTTL EDIT - OPEN LOCATION FOR POSSIBLE MODIFICATION ; ;***** ;***** THE LOCATION (ADDRESSED BY R3) IS OPENED FOR POSSIBLE ;***** MODIFICATION. A COMPLETE WORD IS ALWAYS DISPLAYED - BUT ;***** IF BYTE MODE IS BEING USED, THEN 2 CONSECUTIVE BYTES ;***** ARE DISPLAYED. ;***** ; EDYLOC: MOV (R3),R1 ;GET DATA WORD ; ; --- IF ASCII THEN DUMP TWO ASCII BYTES ; BIT #ED.ASC,E.STS BEQ 10$ ;BR IF NOT ASCII MOV R1,-(SP) CALL $BTASC ;CONVERT LOW BYTE TO ASCII MOV (SP)+,R1 SWAB R1 CALL $BTASC ;CONVERT HIGH BYTE TO ASCII BR EDLOC1 ; ; --- IF OCTAL THEN DUMP OCTAL WORD ; 10$: BIT #ED.OCT,E.STS BEQ 30$ ;BR IF NOT OCTAL BIT #ED.BYT,E.STS BEQ 20$ ;BR IF WORD ACCESS MODE MOV R1,-(SP) MOV #7,R2 CALL $CBTMG ;FORMAT FIRST BYTE INC R0 MOV (SP)+,R1 SWAB R1 MOV #7,R2 CALL $CBTMG ;FORMAT HIGH BYTE BR EDLOC1 ; 20$: MOV #7,R2 CALL $CBOMG ;CONVERT WORD TO OCTAL BR EDLOC1 ; ; --- MUST BE RADIX-50 - SO DUMP RADIX-50 WORD ; 30$: CALL $C5TA ;CONVERT TO RADIX-50 ; ; --- DISPLAY DATA WORD & GET NEW VALUE ; EDLOC1: INC R0 MOVB #'-,(R0)+ INC R0 SUB #PRNTBF,R0 MOV R0,PLEN+4 ;SET LINE SIZE MOVB #4,EDIFLG CALL GETCMD ;GET NEW VALUE MOVB #2,EDIFLG TST SIZE BLE 100$ ;BR IF LOCATION NOT TO BE CHANGED ; ; --- IF ASCII - COPY TWO ASCII BYTES ; BIT #ED.ASC,E.STS BEQ 10$ ;BR IF NOT ASCII MOVB (R0)+,(R3) CMPB #',,(R0)+ BNE 100$ ;BR IF NOT ANOTHER BYTE MOVB (R0)+,1(R3) ;ELSE - GET NEXT BYTE BR 100$ ; ; --- IF OCTAL - SET OCTAL VALUE ; 10$: BIT #ED.OCT,E.STS BEQ 30$ ;BR IF NOT OCTAL CALL $COTB BIT #ED.BYT,E.STS BEQ 20$ ;BR IF WORD ACCESS MODE MOVB R1,(R3) ;ELSE - SET LOW BYTE CMPB #',,R2 BNE 100$ ;BR IF NOT ANOTHER BYTE CALL $COTB ;ELSE - CONVERT IT MOVB R1,1(R3) ; & STORE IT BR 100$ ; 20$: MOV R1,(R3) BR 100$ ; ; --- MUST BE RADIX-50 ; 30$: MOV #7,R1 CALL $CAT5 MOV R1,(R3) ; ; --- NEW VALUE NOW SET ; 100$: TST (R3)+ ;STEP ON TO NEXT LOCATION CLC RETURN .SBTTL EDIT - FILL OR ZERO PACKET ; ;***** ;***** SET PACKET LOCATIONS WITH MASK VALUES ;***** ; EDIFIL: MOV MASK,R5 BR EDYSET ; ;***** ;***** ZERO PACKET LOCATIONS ;***** ; EDICLR: CLR R5 ; ; --- COMMON PROCESSING - FILL LOCATIONS ; EDYSET: MOV E.PKT,R4 ADD E.OFF,R4 ;POINT TO FIRST LOCATION ADD #4,R4 MOV E.REP,R3 ; ; --- NOW FILL PACKET LOCTIONS BY WORD OR BYTE ; 10$: BIT #ED.BYT,E.STS BEQ 20$ ;BR IF WORD MODE MOVB R5,(R4)+ ;ELSE - SET BYTE BR 30$ ; 20$: MOV R5,(R4)+ ;SET WORD ; 30$: SOB R3,10$ ;REPEAT FOR ALL LOCATIONS RETURN .SBTTL EDIT - SELECT PACKET FOR EDIT ; ;***** ;***** SELECT PACKET FOR EDIT ;***** ; EDISEL: CALL EDYID ;GET PACKET TYPE BCC 10$ ;BR IF VALID PACKET TYPE RETURN ; ; --- CHECK SYNTAX & GET PACKET DESCRIPTOR ; 10$: MOVB (R0)+,R4 CALL GETPKT ;GET PACKET BCC 20$ ;BR IF PACKET FOUND RETURN ; 20$: MOV PK.PKT(R3),E.PKT ;SET PACKET ADDRESS MOVB PK.TYP(R3),E.TYP ;SET PACKET TYPE MOVB PK.ID(R3),E.ID ; ... & ID CLC RETURN ; ;***** ;***** GET ADDRESS OF DESTINATION PACKET FOR COPY ;***** ; EDIDST: CALL EDYID ;GET PACKET TYPE BCC 10$ ;BR IF VALID TYPE RETURN ; 10$: MOVB (R0)+,R4 CALL GETPKT ;GET PACKET DESCRIPTOR BCC 20$ ;BR IF FOUND RETURN ; 20$: MOV PK.PKT(R3),E.DST;SET DESTINATION PACKET ADDRESS CLC RETURN ; ;***** ;***** GET ADDESS OF SOURCE PACKET FOR COPY ;***** ; EDISRC: CALL EDYID ;GET PACKET TYPE BCC 10$ ;BR IF VALID TYPE RETURN ; 10$: MOVB (R0)+,R4 CALL GETPKT ;GET PACKET DESCRIPTOR BCC 20$ ;BR IF FOUND RETURN ; 20$: MOV PK.PKT(R3),E.SRC;SET SOURCE PACKET ADDRESS CLC RETURN ; ;***** ;***** L O C A L S U B - R O U T I N E ;***** ;***** SET UP FOR FINDING PACKET DESCRIPTOR. PACKET TYPE IS ;***** S = SEND R = RECEIVE ;***** ; EDYID: MOV #RCVTAB,R3 CMPB #'R,(R0) BEQ 10$ ;BR IF RECEIVE PACKET MOV #SNDTAB,R3 CMPB #'S,(R0) BEQ 10$ ;BR IF SEND PACKET MOV #7,ERROR SEC RETURN ;EXIT - INVALID PACKET TYPE ; 10$: INC R0 CLC RETURN .SBTTL EDIT - PACKET DATA AREA COPY ; ;***** ;***** THIS ROUTINE COPIES THE DATA AREA OF ONE PACKET ;***** TO THE DATA AREA OF ANOTHER PACKET. THE COPY MODE ;***** MAY BE WORDS OR BYTES & ANY NUMBER OF WORDS/BYTES ;***** MAY BE COPIED, PROVIDING THE REPEAT COUNT DOES ;***** NOT EXCEED THE LIMITS OF EITHER PACKET. ;***** ; EDICPY: ; ; --- CHECK DESTINATION PACKET LIMITS ; MOV E.DST+2,R4 ;SET OFFSET CALL EDLIM3 ;CHECK ACCESS BCS 90$ ;BR IF ERROR ; ; --- NOW CHECK SOURCE PACKET LIMITS ; MOV E.SRC+2,R4 ;SET OFFSET CALL EDLIM3 ;CHECK ACCESS BCS 90$ ;BR IF ERROR ; ; --- VALID COMMAND & LIMITS - SO COPY IN DEFINED MODE ; MOV E.DST,R5 ADD E.DST+2,R5 ;POINT TO DESTINATION ADD #4,R5 MOV E.SRC,R4 ADD E.SRC+2,R4 ;POINT TO SOURCE ADD #4,R4 MOV E.REP,R3 ; 10$: BIT #ED.BYT,E.STS BNE 20$ ;BR IF BYTE ACCESS MODE MOV (R4)+,(R5)+ ;ELSE - COPY WORD BR 30$ ; 20$: MOVB (R4)+,(R5)+ ;COPY BYTE ; 30$: SOB R3,10$ ;REPEAT FOR ALL LOCATIONS CLC RETURN ;EXIT - OK ; ; --- ERROR RETURNS ; 90$: SEC RETURN .SBTTL EDIT - VALIDATE PACKET OFFSET + REPEAT COUNT ; ;***** ;***** CHECK EDIT COMMAND OFFSET VALUE ;***** ; ; --- VALIDATE OFFSET ONLY ; EDLIM1: MOV E.OFF,R4 BR EDLIM ; ; --- VALIDATE OFFSET + REPEAT COUNT ; EDLIM2: MOV E.OFF,R4 ; ; --- VALIDATE (R4) + REPEAT COUNT ; EDLIM3: TST E.REP BGT 10$ ;BR IF REPEAT COUNT > 0 MOV #1,E.REP ;ELSE - DEFAULT TO 1 ; 10$: ADD E.REP,R4 BIT #ED.BYT,E.STS BNE EDLIM ;BR IF BYTE ACCESS MODE ADD E.REP,R4 ;ELSE - ADJUST COUNT FOR WORDS ; ; --- VALIDATE (FINAL) PACKET OFFSET FOR ACCESS MODE & LIMITS ; EDLIM: CMP #27.,R4 BLT 30$ ;BR IF INVALID BIT #ED.BYT,E.STS BNE 20$ ;BR IF BYTE ACCESS MODE BIT #1,R4 BNE 30$ ;BR IF ODD OFFSET FOR WORDS ; 20$: CLC RETURN ; 30$: MOV #15.,ERROR SEC RETURN ;INVALID OFFSET .SBTTL EDIT - VALIDATE DATA TYPE MODE ; ;***** ;***** THE DATA TYPE MODE IS VALIDATED ;***** THE LEGAL TYPES ARE - A,O,R ;***** ; EDYDAT: MOVB (R0)+,R2 ;GET DATA TYPE MODE MOVB #ED.ASC,E.STS ;ASSUME ASCII CMPB #'A,R2 BEQ 10$ ;BR IF ASCII MOVB #ED.OCT,E.STS ;ASSUME OCTAL CMPB #'O,R2 BEQ 10$ ;BR IF OCTAL MOVB #ED.R50,E.STS ;ASSUME RADIX-50 CMPB #'R,R2 BEQ 10$ ;BR IF RADIX-50 MOV #14.,ERROR SEC RETURN ;EXIT - INVALID DATA TYPE ; 10$: CLC RETURN ;EXIT - VALID DATA TYPE ; ;============================================================ ; .SBTTL EDIT - VALIDATE DATA ACCESS MODE ; ;***** ;***** CHECK EDIT COMMAND ACCESS MODE ;***** ; EDYMOD: MOVB (R0)+,R2 ;GET MODE CHARACTER CMPB #40,R2 BEQ 30$ ;BR IF MODE NOT CHANGED CMPB #'/,R2 BNE 10$ ;BR IF NOT WORD EDIWRD = . BIC #ED.BYT,E.STS ;ELSE - SET WORD ACCESS MODE BR 30$ ; 10$: CMPB #'\,R2 BNE 20$ ;BR IF NOT BYTE EDIBYT = . BIS #ED.BYT,E.STS ;SET BYTE ACCESS MODE BR 30$ ; 20$: MOV #13.,ERROR SEC RETURN ; 30$: CLC RETURN .SBTTL EDIT - DUMP DATA AREA OF PACKET ; ;***** ;***** A DUMP IS REQUIRED - INITAILISE DUMP MODE ;***** ; ; --- DUMP IN ASCII MODE ; DUMPA: MOVB #ED.ASC!ED.DMP,E.STS BR DUMP ; ; --- DUMP IN OCTAL MODE ; DUMPO: MOVB #ED.OCT!ED.DMP,E.STS BR DUMP ; ; --- DUMP IN RADIX-50 MODE ; DUMPR: MOVB #ED.R50!ED.DMP,E.STS ; ;***** ;***** THE DATA AREA OF THE PACKET IS OUTPUT IN THE CHOSEN ;***** DATA FORMAT. EACH PRINT LINE CONSISTS OF THE PACKET ;***** ID & AN OFFSET FOLLOWED BY 4 WORDS OF DATA. THE DATA ;***** MODE ONLY AFFECTS THE OUTPUT FORMAT & NOT THE NUMBER ;***** OF ELIMENTS PER LINE. ;***** ; DUMP: MOV R5,-(SP) MOVB #4,LINES ;SET LINE COUNT CLR LOC ;SET OFFSET MOV E.PKT,R5 ;GET PACKET ADDRESS ADD #4,R5 ; & POINT TO DATA AREA ; ; --- CLEAR OUTPUT BUFFER ; 10$: CALL CLRBUF ;INITIALISE PRINT BUFFER ; ; --- SET UP PACKET ID & OFFSET OF FIRST LOCATION ; 20$: MOVB E.TYP,(R0)+ ;SET PACKET TYPE MOVB E.ID,(R0)+ ; ... & ID INC R0 MOV LOC,R1 MOV #7,R2 CALL $CBTMG ;SET PACKET OFFSET MOVB #'-,(R0)+ ADD #4,R0 ; ; --- INITIALISE FOR FORMATTING OF ONE LINE ; MOVB #4,COLS CMPB #1,LINES BNE 30$ ;BR IF NOT LAST LINE MOVB #1,COLS ;ELSE - SET ENTRY COUNT FOR LAST LINE ; ; --- FORMAT PACKET LOCATIONS ACCORDING TO FORMAT MODE ; --- IF RADIX-50 - FORMAT ONE RADIX-50 WORD ; 30$: MOV (R5)+,R1 ;GET DATA WORD BIT #ED.R50,E.STS BEQ 40$ ;BR IF NOT RADIX-50 CALL $C5TA ;CONVERT RADIX-50 BR 100$ ; ; --- IF ASCII - FORMAT TWO ASCII BYTES ; 40$: BIT #ED.ASC,E.STS BEQ 50$ ;BR IF NOT ASCII MOV R1,-(SP) ;SAVE VALUE CALL $BTASC ;CONVERT LOW BYTE MOV (SP)+,R1 SWAB R1 CALL $BTASC ;CONVERT HIGH BYTE BR 100$ ; ; --- IF OCTAL - FORMAT TWO BYTES OR ONE WORD ; 50$: BIT #ED.BYT,E.STS BEQ 60$ ;BR IF NOT BYTE MOV R1,-(SP) ;SAVE DATA WORD MOV #7,R2 CALL $CBTMG ;FORMAT LOW BYTE ADD #2,R0 ;SEPARATE DATA BYTES MOV (SP)+,R1 SWAB R1 MOV #7,R2 CALL $CBTMG ;FORMAT HIGH BYTE BR 100$ ; 60$: MOV #7,R2 CALL $CBOMG ;CONVERT WORD TO OCTAL ; ; --- DATA WORD HAS BEEN FORMATED. IF LINE IS COMPLETE PRINT IT ; 100$: ADD #4,R0 DECB COLS BGT 30$ ;FORMAT NEXT WORD IF LINE NOT FULL CALL PRINTX ;DIPSLAY DATA ADD #10,LOC ;INCREAMENT LOCATION COUNTER DECB LINES BLE 110$ ;BR IF DUMP NOW COMPLETE JMP 10$ ;ESLE - CONTINUE FOR NEXT LINE ; 110$: MOV (SP)+,R5 CLC RETURN .SBTTL GET COMMAND LINE ; ;***** ;***** THE COMMAND LINE IS OBTAINED IN THE COMMAND BUFFER. NULL ;***** LINES ARE IGNORED. DEVICE INPUT ERRORS RESULT IN THE ;***** APPROPRIATE PROMPT BEING RE-DISPLAYED. IN EDIT MODE ;***** (^Z) IS TREATED AS AN ERROR & NULL LINES ARE ALLOWED. ;***** ; GETCMD: MOV #CMDBF+CMDSZ,R0 MOV #CMDSZ-4,R1 ; 10$: CLRB -(R0) SOB R1,10$ ; ; --- IF A PACKET HAS BEEN RECEIVED, INFORM THE USER ; 20$: TSTB RCVFLG BLE 30$ ;BR IF NO PACKETS IN QUEUE TSTB EDIFLG BNE 30$ ;BR IF INPUT TO EDIT MASK MOV #MS4,R5 MOV #ML4,R4 CALL OUTPUT ;REPORT PACKET RECEIVED ; ; --- DETERMINE WHICH PROMPT IS REQUIRED & ISSUE IT ; 30$: MOVB EDIFLG,R5 ;GET PROMPT ID MOV PLEN(R5),R4 MOV PTXT(R5),R5 CALL PRINT ;DISPLAY PROMPT ; ; --- NOW GET REPLY ; DIR$ #INPUT WTSE$S #1 ;WAIT FOR I/O COMPLETION TSTB IOS BPL 50$ ;BR IF I/O OK CTLZ == . ;***** REFERENCE LABEL FOR PATCHING OUT ^Z TSTB EDIFLG BNE 20$ ;BR IF EDIT MODE - TRY AGAIN CMPB #IE.EOF,IOS BNE 20$ ;ERROR - TRY AGAIN INC MCRFLG ;CONTROL Z - FORCE EXIT JMP XIT ; ; --- CHECK LINE SIZE ; 50$: TSTB EDIFLG BNE 60$ ;BR IF EDIT - NULL LINE ALLOWED TST SIZE BLE 20$ ;IGNORE NULL LINES ; 60$: RETURN .SBTTL GENERAL ROUTINES ; ;***** ;***** INITIALISE PRINT BUFFER ;***** INSERT & SPACE FILL ;***** ; CLRBUF: MOV #PRNTSZ,R1 MOV #PRNTBF+PRNTSZ,R0 ; 10$: MOVB #40,-(R0) ;SPACE FILE BUFFER SOB R1,10$ MOVB #15,(R0)+ MOVB #12,(R0)+ RETURN ; ;***** ;***** LOCATE PACKET DESCRIPTOR ;***** ; GETPKT: CMPB R4,PK.ID(R3) BEQ 10$ ;BR IF FOUND ADD #PK.LEN,R3 ;ELSE - STEP ON TO NEXT ENTRY TST (R3) BNE GETPKT ;CONTINUE IF NOT END-OF-LIST MOV #8.,ERROR SEC RETURN ;PACKET NOT FOUND ; 10$: CLC RETURN ;PACKET FOUND ; ;***** ;***** GENERAL PRINT LINE OUTPUT ;***** ; PRINTX: MOV R5,-(SP) MOV R4,-(SP) MOV #PRNTBF,R5 ;GET BUFFER ADDRESS MOV R0,R4 SUB R5,R4 ; & SET LINE SIZE CALL PRINT MOV (SP)+,R4 MOV (SP)+,R5 RETURN ; ;***** ;***** ERROR & DATA MESSAGE OUTPUT ;***** ; OUTPUT: DIR$ #MSGID ;DISPLAY TASK ID WTSE$S #TI ; PRINT: QIO$S #IO.WLB,#TI,#TI,,,, WTSE$S #TI RETURN ; ;***** ;***** VALIDATE TASK LIST ENTRY ID ;***** ; TSKREF: CMP #,R1 BGT 20$ ;BR IF TASK ID IS VALID ; 10$: MOV #11.,ERROR SEC RETURN ;ERROR - INVALID REFERENCE ; 20$: ASL R1 ;SET ENRTY POINTER ASL R1 ADD R1,R0 ; & POINT TO ENTRY CLC RETURN ;RETURN - ENTRY REFERENCE IS VALID .SBTTL CONVERT BINARY BYTE TO PRINTABLE ASCII ; ;***** ;***** A SINGLE BINARY BYTE IS CONVERTED TO A PRINTABLE ASCII ;***** CHARACTER STRING OF 4 BYTES. ;***** ; $BTASC: MOVB #40,(R0)+ ;SET LEADING SPACE BIC #177600,R1 ;REMOVE TOP BYTE CMPB #40,R1 BLE 10$ ;BR IF NOT A CONTROL CHARACTER MOVB #'^,(R0)+ ;SET CONTROL ID ADD #100,R1 ; & MAKE CHARACTER PRINTABLE BR 30$ ; 10$: CMPB #140,R1 BGT 20$ ;BR IF A PRINTABLE CHARACTER MOVB #'%,(R0)+ ;SET NON-CONTROL + NON-PRINTING ID SUB #40,R1 ; & MAKE CHARACTER PRINTABLE BR 30$ ; 20$: MOVB #40,(R0)+ ;CHARACTER IS PRINTABLE ; 30$: MOVB R1,(R0)+ ;SET (CONVERTED) CHARACTER MOVB #40,(R0)+ ;SET TRAILING SPACE RETURN .SBTTL RECEIVE DATA AST ; ;***** ;***** THIS AST IF FIRED WHEN A PACKET IS QUEUED TO THIS TASK ;***** BUT ONLY IF THE RECEIVE QUEUE IS EMPTY. ;***** WHEN A PACKET IS QUEUED, THE USER CAN NOT BE INFORMED ;***** IMEDIATELY AS THERE IS PROBALY AN OUTSTANDING I/O ;***** PRESENT. A FLAG IS SET TO NOTIFY THE COMMAND INPUT ;***** ROUTINE THAT A SPECIFIC MESSAGE IS TO BE OUTPUT BEFORE ;***** THE NEXT PROMPT IS DISPLAYED. ;***** ; RCVAST: INCB RCVFLG ;NOTE PACKET(S) IN QUEUE ASTX$S ; ; ; ; ;============================================================ ; ; ; ; ; .SBTTL POWER RECOVERY AST ; ;***** ;***** THIS AST IS USED ON A POWER RECOVERY. ITS PURPOSE IS ;***** TO DELAY ANY IMMEDIATE ACTION TO ALLOW THE SYSTEM TO ;***** RECOVER. ;***** ; PWFAST: MRKT$S #3,#1,#2 ;REQUEST A 1 SECOND SLEEP WTSE$S #3 ; & WAIT ASTX$S .SBTTL ERROR PROCESSING & TASK TERMINATION ; ;***** ;***** ERROR MESSAGE OUTPUT ;***** ; ; --- FATAL ERROR - UNABLE TO ISSUE DIRECTIVE ; ERR1: MOV #MS1,R5 MOV #ML1,R4 JMP OUTPUT ; ; --- COMMAND PARSING ERROR ; ERR2: MOV #MS2A,R0 MOV ERROR,R1 MOV #<<37*400>+10.>,R2 CALL $CBTA ;CONVERT ERROR CODE MOV #MS2,R5 MOV #ML2,R4 JMP OUTPUT ; ; --- DIRECTIVE ERROR ; ERR3: MOV #MS8,R0 CALL $C5TA ;CONVERT DIRECTIVE ID MOV #MS8A,R0 MOV ERROR,R1 MOV #<<37*400>+10.>,R2 CALL $CBTA ;CONVERT ERROR CODE MOV #MS8,R5 MOV #ML8,R4 JMP OUTPUT ; ;***** ;***** TASK TERMINATION PROCEDURE ;***** ; XIT: TSTB MCRFLG BNE 10$ ;BR IF AN "MCR" ROUTINE JMP NXTCMD ;ELSE - GET NEXT COMMAND ; 10$: CLR OVRTSK ;SET TO FLUSH QUEUE COMPLETELY CLR OVRTSK+2 CALL CLRQUE ;FLUSH QUEUE EXIT$S ; .END START