.TITLE BOILER .IDENT /01/ ;For History Comments .ENABLE LC ; ; This small program calculates Block Checksums for Files-11 Files ; ; History: ; 01 P.A. Stephensen-Payne 28-Aug-80 ; .PAGE .SBTTL Macros .MACRO FERR,X,P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14 .IIF NB , MOV P1,ARGBLK ;Arguments for insertion .IIF NB , MOV P2,ARGBLK+2 .IIF NB , MOV P3,ARGBLK+4 .IIF NB , MOV P4,ARGBLK+6 .IIF NB , MOV P5,ARGBLK+8. .IIF NB , MOV P6,ARGBLK+10. .IIF NB , MOV P7,ARGBLK+12. .IIF NB , MOV P8,ARGBLK+14. .IIF NB , MOV P9,ARGBLK+16. .IIF NB , MOV P10,ARGBLK+18. .IIF NB , MOV P11,ARGBLK+20. .IIF NB , MOV P12,ARGBLK+22. .IIF NB , MOV P13,ARGBLK+24. .IIF NB , MOV P14,ARGBLK+26. MOV #I.'X,R1 ;Address of Error String JMP FERR .ENDM .MACRO DIAG,X,P1,P2,P3,P4 .IIF NB , MOV P1,ARGBLK .IIF NB , MOV P2,ARGBLK+2 .IIF NB , MOV P3,ARGBLK+4 .IIF NB , MOV P4,ARGBLK+6 MOV #I.'X,R1 CALL DIAG .ENDM ; .MCALL CSI$,CSI$1,CSI$2,CSI$SW,CSI$SV,CSI$ND ; for CSI .MCALL GCMLB$,GCMLD$,GCML$,SPWN$,DIR$ ; for GCML .MCALL FSRSZ$,FINIT$,FDBDF$,FDOP$A,FDAT$A ; for FILES-11 .MCALL FDRC$A,FDBK$A,FDBF$A,NMBLK$ ; .MCALL OPEN$,CLOSE$,GET$,PUT$,READ$,WRITE$,WAIT$ ; .MCALL QIOW$S,EXIT$S,ALUN$S,WTSE$S,SVTK$S ;general use .PAGE .SBTTL Offset Definitions ; CMDLUN=1 INPLUN=2 ERRLUN=5 .PAGE .SBTTL Data - Error Messages .NLIST BEX ; OUTBLK: .BLKB 80. ; To build error message in ARGBLK: .BLKW 15. ; Argument block for $EDMSG I.SST: .ASCII /CHK - SST Trap = %D at PC %P/<7><7> .ASCII /%N R0=%P, R1=%P, R2=%P, R3=%P/ .ASCIZ /%N R4=%P, R5=%P, R6=%P, (SP)=%P/ I.CHK: .ASCIZ /CHK - Checksum = %P/ I.GIND: .ASCIZ /CHK - Invalid Indirect Command File/<7> I.GCME: .ASCIZ /CHK - Command Read Error = %D/<7> I.CSI1: .ASCIZ /CHK - Command Line Parse Failure at Offset %D/<7> I.CS2I: .ASCIZ /CHK - Invalid Syntax in Input Filespec/<7> I.OPNI: .ASCIZ /CHK - Open Error = %D on Input File/<7> I.REDI: .ASCIZ /CHK - Read Error = %D on Input File/<7> I.MORO: .ASCIZ /CHK - Too Many Output Files Specified/<7> I.MORI: .ASCIZ /CHK - Too Many Input Files Specified/<7> .EVEN .PAGE .SBTTL Data - CSI & GCML Tables ; GCMBLK: GCMLB$ 1,CHK,,CMDLUN CSI$ CSIBLK: .BLKB C.SIZE ; CSI control block .EVEN HESW=1 CKSW=2 ; OSWTAB: ; Output switches CSI$ND ISWTAB: ; Input switches CSI$SW CK,CKSW,SWMSK$,SET,,CKTBL CSI$SW HE,HESW,SWMSK$,SET ; Help CSI$ND CKTBL: CSI$SV OCTAL,CKBLK+2,2 CSI$ND CKBLK: .WORD 0,0 SWMSK$: .WORD ; Default mask word HLSPWN: SPWN$ MCR...,,,,,1,,,HELCMD,HELCML HELCMD: .ASCII /HELP CHK/ HELCML=.-HELCMD .EVEN ; .PAGE .SBTTL Data - File Definitions ; FSRSZ$ 1 ; INPFDB: FDBDF$ FDRC$A FD.RWM FDBK$A BUFF,512. FDOP$A INPLUN,,INPDFN,FO.RD INPDFN: NMBLK$ ,,0,SY,0 ; ; .PAGE .SBTTL Data - User's Areas .LIST BEX SSTTAB: .WORD SSTOD ; Odd Address Trap .WORD SSTMP ; Memory Protect .WORD SSTBE ; BPT .WORD SSTIO ; IOT .WORD SSTIL ; Reserved Instruction .WORD SSTEM ; Non-RSX EMT .WORD SSTTE ; TRAP .WORD SSTFP ; Floating Point SSTNUM: .WORD 0 ; Store for SST Number ; BUFF: .BLKB 512. ; File buffer ; .PAGE .SBTTL Mainline Code ; ; This section of code governs the mainline operation of the program. ; START: SVTK$S #SSTTAB,#8. ; Specify SST Table ALUN$S #CMDLUN,#"TI,#0 ; Assign prompt lun to TI: FINIT$ ; Initialise the file section ; GETCMD: CLR SWMSK$ ; Clear Options Mask GCML$ #GCMBLK ; Get Command Line BCC 20$ ; If CC OK - carry on CMPB #GE.EOF,G.ERR(R0) ; Was it an end-of-file? BEQ 10$ ; If EQ yes - terminate program CMPB #GE.OPR,G.ERR(R0) ; Invalid command file? BNE 5$ ; If NE no - carry on DIAG GIND ; yes - log the message BR GETCMD ; and try again ; 5$: MOVB G.ERR(R0),R0 ; Sign-extend the error FERR GCME,R0 ; Else log error ; 10$: EXIT$S ; That's all ; 20$: MOV G.CMLD+2(R0),R1 ; Command start MOV G.CMLD(R0),R2 ; And length BEQ GETCMD ; If not there, Re-Prompt ; ; Now parse the command - this will depend a lot on whether you ; are allowing multiple input and output files, but the following ; might be a useful guideline. ; PARSE: CSI$1 #CSIBLK,R1,R2 ; Check the syntax BCC 10$ ; If CC OK - carry on MOV CSIBLK+C.FILD+2,R0 ; Get Address of Error SUB R1,R0 ; And hence offset INC R0 ; Starting at 1 DIAG CSI1,R0 ; Log the error BR GETCMD ; And get another command line ; 10$: BIT #CS.EQU*400,(R0) ; Was an "=" specified? BEQ 40$ ; If EQ no - OK DIAG MORO ; Don't allow output file BR GETCMD ; Get next command ; 40$: MOVB #CS.OUT,CSIBLK+C.TYPR ; No - pretend it's an output file CSI$2 #CSIBLK,,#ISWTAB ; Parse the input file BCC 60$ ; If CC OK - carry on DIAG CS2I ; No - Log Error BR 90$ ; and get next line ; 60$: ; ; You might want to check here to see if there was more than one ; input file specified, as follows. ; BITB #CS.MOR,C.STAT(R0) ; See if more input files BEQ 70$ ; If EQ OK - carry on DIAG MORI ; Else log error BR 90$ ; And get next line ; 70$: OPEN$ #INPFDB,,,#CSIBLK+C.DSDS ; Open the input file BCC 80$ ; If CC OK - carry on MOVB F.ERR(R0),R0 ; Sign-extend error code DIAG OPNI,R0 ; Else log an error BR 90$ ; ; 80$: BIT #HESW,SWMSK$ ; Help switch? BEQ 85$ ; If EQ no - process normally DIR$ #HLSPWN ; Yes - ask for help WTSE$S #1 ; Wait for it to finish BR 90$ ; Get next line ; 85$: CALL PROCESS ; Now process the command ; 90$: CLOSE$ #INPFDB ; JMP GETCMD ; Get the next line .PAGE .SBTTL Process Routines PROCESS: BIT #CKSW,SWMSK$ ; /CK specified? BEQ 90$ ; If EQ no - nothing to do MOV CKBLK+2,INPFDB+F.EFBK+2 ; Pretend there's enough space INC INPFDB+F.EFBK+2 ; MOV CKBLK+2,INPFDB+F.HIBK+2 ; INC INPFDB+F.HIBK+2 ; READ$ #INPFDB,,,#CKBLK ; Read the block BCS 10$ ; If CS error - log it WAIT$ #INPFDB ; Wait for it BCC 20$ ; If CC OK - Carry on ; 10$: MOVB F.ERR(R0),R0 ; Else sign-extend the error DIAG REDI,R0 ; Log it BR 90$ ; and exit ; 20$: MOV #BUFF,R0 ; Get address of buffer start MOV #377,R1 ; And number of words to check CLR R2 ; Initialise store ; 30$: ADD (R0)+,R2 ; Add up all the words SOB R1,30$ ; DIAG CHK,R2 ; Output the result ; 90$: RETURN .PAGE .SBTTL SST SST Handling Routines ; ; This routine handles any SSTs by logging an error, closing the file ; and exiting. This should make it easy to track down the error. ; SSTFP: INC SSTNUM ; Floating Point SSTTE: INC SSTNUM ; TRAP SSTEM: INC SSTNUM ; Non-RSX EMT SSTIL: INC SSTNUM ; Reserved Instruction SSTIO: INC SSTNUM ; IOT SSTBE: INC SSTNUM ; BPT SSTMP: INC SSTNUM ; Memory Protect SSTOD: ; Odd Address Trap TST SSTNUM ; Have we been here before? BGE 20$ ; If GE no - carry on CMP SSTNUM,#-1000. ; Yes - twice? BLE 10$ ; If LE yes - don't even try to close the file MOV #-2000.,SSTNUM ; Stop second level of recursion ; 10$: EXIT$S ; Exit ; 20$: CMP SSTNUM,#1 ; Memory Protect? BNE 30$ ; If NE no - carry on ADD #6,SP ; Yes - chuck three words off the stack ; 30$: CMP SSTNUM,#5 ; TRAP or EMT? (ignore FP as impossible) BLT 40$ ; If LT no - carry on TST (SP)+ ; Yes - chuck a word off the stack ; 40$: MOV (SP)+,ARGBLK+28. ; Save the old PC TST (SP)+ ; Ignore the PS MOV SSTNUM,ARGBLK+26. ; Save the SST number MOV #-100.,SSTNUM ; And stop recursion FERR SST,ARGBLK+26.,ARGBLK+28.,R0,R1,R2,R3,R4,R5,SP,(SP) .PAGE .SBTTL Output Routines ; FERR: CALL DIAG ; Output the Message CLOSE$ #INPFDB ; EXIT$S ; Terminate the program ; DIAG: CALL OUT ; Output QIOW$S #IO.WLB,#ERRLUN,#1,,,,<#OUTBLK,R1,#40> ; Output to TI: RETURN ; Return ; OUT: MOV #OUTBLK,R0 ; Get Buffer for Output MOV #ARGBLK,R2 ; Get Address of any Parameters CALL $EDMSG ; Edit the Message RETURN .END START