ALWAYS 23MAR4 HEX ;23MAR4 .SBTTL INTRODUCTION ;**-1 ;************************************************************************ ;* * ;* HEX: Hex file management utility * ;* * ;* Author: Kevin Angley * ;* * ;* Date: 30-AUG-82 * ;* * ;* **** BASE LEVEL: 30-AUG-82 * ;* * ;* EDIT HISTORY: * ;* * ;* 29AUG3 Insert CR after each line in RSM (read summary message) * ;* * ;* Dec-83 to Feb-84, Chris Doran, Sira Ltd. * ;* Support STEP/EVEN/ODD option in FROM-THRU. * ;* Move out some messages and keywords used once only to * ;* appropriate modules for overlaying efficiency. * ;* Put MEMORY in its own PSECT, $$$$$$, which goes last, * ;* so it can be allocated by an EXTTSK, saving 64 blocks * ;* of task file space. * ;* Never time out if TIME = 0. * ;* Add new commands HELP, .(=CLI), NAME, CSUM, APPEND, * ;* ECHO, NOECHO, EXIT, arithmetic operations. * ;* Use common command line compression routine, shared * ;* with EDIT. * ;* * ;* 23MAR4 Scott Smith, Telex Computer Products, Raleigh NC * ;23MAR4 ;* Included a conditional assembly block that changes most * ;23MAR4 ;* .LDA default file extentions to .HEX and included * ;23MAR4 ;* 'USE FOR READ' modifications. * ;23MAR4 ;* * ;23MAR4 ;************************************************************************ .PAGE .SBTTL MCALLS AND LOCAL EQUATES .MCALL FSRSZ$ .MCALL FINIT$ .MCALL FDOF$L,FCSBT$ .MCALL QIOW$,DIR$,CALLR ;23MAR4 .MCALL EXIT$S,GCMLB$,GCML$,GCMLD$,RCML$ ;**-1 .MCALL FDBDF$,FDAT$A,FDRC$A,FDOP$A .MCALL MRKT$C,ASTX$S,CMKT$S,QIOW$C,WTSE$C ; ;**** EQUATES ; CMILUN == 1 ; LUN FOR COMMAND LINE INPUT TILUN == 2 ; LUN for TI: I/O IOLUN == 3 ; LUN FOR DISK I/O ; Set TIME to 0 to disable command timeouts. TIME = 0. ; NUMBER OF SECONDS TO WAIT FOR A COMMAND MEMLOW == 000000 ; LOW LIMIT ON VIRTUAL MEMORY MEMHIGH == 077777 ; MEMORY HIGH LIMIT (7FFFH) MEMSIZE == 040000 ; SIZE OF VIRTUAL MEMORY IN WORDS CR == 15 ; CARRIAGE RETURN LF == 12 ; LINE FEED SPACE == <' > ; SPACE TAB == <' > ; TAB HYPHEN == '- RECLEN == 512. ; MAXIMUM SIZE OF RECORD BUFFER .PAGE .SBTTL FILE CONTROL SERVICES DATA AREAS FSRSZ$ 2 ; DEFINE 2 FILE STORAGE REGIONS FDB:: FDBDF$ ; DEFINE THE FILE DESCRIPTOR BLOCK FDOF$L ; Define FDB offsets locally FCSBT$ ; Define attribute bits locally FDAT$A R.VAR,FD.CR ; INITIALIZE FILE ATTRIBUTES FDRC$A ,RECORD,RECLEN ; INITIALIZE RECORD ATTRIBUTES FDOP$A IOLUN,DSPT ; FILE OPEN INITIALIZATION .PAGE .SBTTL HEX - ENTRY AND INITIALIZATION .PSECT HEX I,RO .EVEN START: FINIT$ CALL INITAL ; INITIALIZE MEMORY, CLEAR OFFSET ; TRANSFER, PROCESSOR (PROGRAM INITIATED) CMD: 1$: .IIF NE TIME, MRKT$C ,TIME,2,TIMOUT,HEX ; ESTABLISH A TIMEOUT FOR COMMAND INPUT BISB #GE.LC,GCLBLK+G.MODE ; Pass LC chars unchanged GCML$ #GCLBLK ; COLLECT COMMAND LINE BCC 3$ .IIF NE TIME, CMKT$S ; CANCEL MARK TIME IF BAD COMMAND CMPB #GE.EOF,GCLBLK+G.ERR ; CHECK STATUS BNE 2$ ; NE: REAL ERROR JMP EXIT ; EOF, RETURN TO EXECUTIVE 2$: OUTPUT CIE ; COMMAND INPUT ERROR ERROR BR CMD ; GO GET ANOTHER 3$: .IIF NE TIME, CMKT$S ; CANCEL MARK TIME IF GOOD COMMAND MOV GCLBLK+G.CMLD,R2 ; COMMAND STRING LENGTH IN R2 BLE CMD ; LE: NULL COMMAND - REPROMPT MOV GCLBLK+G.CMLD+2,R0 ; "FROM" ADDRESS IN R0 MOVB GCLBLK+F.RCTL,QUIET+1 ; Hi byte of QUIET flag set BICB #^CFD.TTY,QUIET+1 ; if input from terminal MOV R0,OUTDIR+Q.IOPL ; Load address and length to echo MOV R2,OUTDIR+Q.IOPL+2 ; command line, but don't do it yet MOV %0,%1 ; Copy start of command line ADD %2,%1 ; Point to end CLRB @%1 ; and make it ASCIZ ; Check for a "." CLI command and execute it immediately if so, before line gets ; compressed. Note that the CLI command processor expects the command line ; length (including ".") to be in %2. 6$: CALL SPCTAB ; Trim leading spaces and tabs BNE 15$ 10$: INC %0 ; Ignore either if found DEC %2 BEQ CMD ; Give up if line is just blanks BR 6$ ; Else keep looking 15$: CMPB (%0)+,#'. ; Did command start "." -- CLI command? BNE 20$ ; No, go compress CALL ECHOIF ; Echo command line if echo on CALL CLI ; Issue CLI command JMP 50$ ; Finish up as usual 20$: DEC %0 ; Point back to start of command CALL COMPRESS ; Compress line and make UC ; Separate check again for NOECHO command, which isn't itself echoed if ; commands are coming from a file. CASE NOECHO ; If NOECHO, process, then JMP 50$ ; Return here only if not NOECHO. MOV #RECORD,OUTDIR+Q.IOPL ; Uncompressed copy in RECORD should CALL ECHOIF ; be echoed if echo on CMPB #'*,(R0) ; IS THIS A DISPLAYABLE COMMENT? BNE 45$ ; NE: NEED TO DISPLAY JMP 50$ ; EQ: ALREADY DISPLAYED 45$: ; CASE AND ; IF CMD, PROCESS, THEN JMP 50$ CASE APPEND ; IF CMD, PROCESS, THEN JMP 50$ CASE COMPARE ; IF CMD, PROCESS, THEN JMP 50$ CASE COMPLEMENT ; IF CMD, PROCESS, THEN JMP 50$ CASE COPY ; IF CMD, PROCESS, THEN JMP 50$ CASE CRC ; IF CMD, PROCESS, THEN JMP 50$ CASE CSUM ; IF CMD, PROCESS, THEN JMP 50$ CASE DECREMENT ; IF CMD, PROCESS, THEN JMP 50$ CASE DISPLAY ; IF CMD, PROCESS, THEN JMP 50$ CASE DIVIDE ; IF CMD, PROCESS, THEN JMP 50$ CASE ECHO ; IF CMD, PROCESS, THEN JMP 50$ CASE EDIT ; IF CMD, PROCESS, THEN JMP 50$ CASE EXIT ; IF CMD, PROCESS, THEN JMP 50$ CASE FILL ; IF CMD, PROCESS, THEN JMP 50$ CASE FORMAT ; IF CMD, PROCESS, THEN JMP 50$ CASE HELP ; IF CMD, PROCESS, THEN JMP 50$ CASE IDENT ; IF CMD, PROCESS, THEN JMP 50$ CASE INCREMENT ; IF CMD, PROCESS, THEN JMP 50$ CASE INIT ; IF CMD, PROCESS, THEN JMP 50$ CASE MOVE ; IF CMD, PROCESS, THEN JMP 50$ CASE MULTIPLY ; IF CMD, PROCESS, THEN JMP 50$ CASE NAME ; IF CMD, PROCESS, THEN JMP 50$ CASE NEGATE ; IF CMD, PROCESS, THEN JMP 50$ CASE OR ; IF CMD, PROCESS, THEN JMP 50$ CASE QM ; '?' = HELP CASE READ ; IF CMD, PROCESS, THEN JMP 50$ CASE REMAINDER ; IF CMD, PROCESS, THEN JMP 50$ CASE REVERSE ; IF CMD, PROCESS, THEN JMP 50$ CASE ROTATE ; IF CMD, PROCESS, THEN JMP 50$ CASE SEARCH ; IF CMD, PROCESS, THEN JMP 50$ CASE SHIFT ; IF CMD, PROCESS, THEN JMP 50$ CASE SUM ; IF CMD, PROCESS, THEN JMP 50$ CASE OFFSET ; IF CMD, PROCESS, THEN JMP 50$ CASE TRANSFER ; IF CMD, PROCESS, THEN JMP 50$ CASE USE ; IF CMD, PROCESS, THEN JMP 50$ ;23MAR4 CASE WRITE ; IF CMD, PROCESS, THEN JMP 50$ CASE XOR ; IF CMD, PROCESS, THEN JMP 50$ ; ELSE - COMMAND NOT FOUND OUTPUT IC ; ILLEGAL COMMAND SEC ; ; Common return point. If the operation failed (carry set) abort processing ; of a command file (if this is one). 50$: BCC 255$ ; Continue if all OK .IIF DF P$$OFF, MOV #EX$ERR,EXSTAT ; Failed -- set error exit status TSTB QUIET+1 ; Command from TTY? BNE 255$ ; Yes, just get another OUTPUT CAB ; No, file, say "aborted" RCML$ #GCLBLK ; Back to top level 255$: JMP CMD ;GO GET ANOTHER COMMAND EXIT: .IF DF P$$OFF MOV EXSTAT,%0 ; Load exit status CALLR $EXST ; Exit with it .IFF EXIT$S ; PROGRAM EXIT .ENDC .PAGE .SBTTL COMMAND LINE ECHO CONTROL ; Echo required. ECHO: MOVB #377,QUIET ; Set at least lo byte of QUIET CLC ; Must succeed RETURN ; Suppress echo, but only if reading from file. NOECHO: CLRB QUIET ; Clear lo byte RETURN ; That's all ; Display command line if echo is on (QUIET<>0) and it wasn't already done ; by a fetch from TI: ECHOIF: TSTB QUIET+1 ; Yes, see if we should echo BNE 10$ ; Not if hi byte set, done by TI: fetch TSTB QUIET ; Commands from file, ECHO on? BEQ 10$ ; EQ = no, just execute DIR$ #OUTDIR ; NE = yes, echo now 10$: RETURN ; Return anyway .PAGE .SBTTL MATCH - MATCH KEYWORD IF POSSIBLE ; ; ENTRY PARAMETERS: ; ; R0 POINTS TO THE ASCIZ COMMAND LINE BEING PROCESSED ; R1 POINTS TO THE TARGET KEYWORD ASCIZ STRING ; ; IF THE KEYWORD BEGINS AT (R0), THE Z FLAG IS SET TO INDICATE ; EQUALITY. ELSE, THE Z FLAG IS RESET TO INDICATE DIFFERENCE. ; ; EXIT PARAMETERS: ; ; R0 (IF MATCH) POINTS TO NEXT BYTE AFTER KEYWORD IN COMMAND STRING ; R0 (IF NO MATCH) SAME AS ON ENTRY ; R1 (EITHER CASE) GARBAGE ; MATCH:: PUSH R0 ; SAVE COMMAND STRING POINTER 10$: TSTB (R1) ; DONE WITH MATCH IF END OF KEYWORD BEQ 30$ ; YES - RETURN MATCH TSTB (R0) ; NO MATCH IF NO MORE COMMAND STRING BEQ 20$ ; YES - RETURN NO MATCH CMPB (R0)+,(R1)+ ; KEEP COMPARING CHARACTERS BEQ 10$ ; YES - SAME, SO KEEP LOOKING ; NO - NO MATCH 20$: POP R0 ; NO MATCH - RESTORE COMMAND STRING POINTER CLZ ; CLEAR ZERO FLAG TO SHOW NOT EQUAL RETURN 30$: TST (SP)+ ; CLEAN UP THE STACK SEZ ; SET ZERO FLAG TO SHOW MATCH RETURN .PAGE .SBTTL VALID - OFFSET AND VALIDATE INPUT ADDR ; ; ENTRY PARAMETERS: ; ; R3 CONTAINS THE LOW WORD OF A 32-BIT ADDRESS ; R4 CONTAINS THE HIGH WORD OF A 32-BIT ADDRESS ; ; EXIT PARAMETERS: ; ; R2 CONTAINS THE 16-BIT OFFSETTED ADDRESS ; R3 CONTAINS THE LOW WORD OF A 32-BIT ADDRESS ; R4 CONTAINS THE HIGH WORD OF A 32-BIT ADDRESS ; NO OTHER REGISTERS ARE AFFECTED ; CARRY FLAG INDICATES VALID (CLEAR) OR NOT VALID (SET) ; VALID:: PUSH R3 ; SAVE REAL 32-BIT ADDRESS PUSH R4 SUB OFFST,R3 ; SUBTRACT OFFSET (LOW WORD) SBC R4 ; SUBTRACT CARRY FROM HIGH WORD SUB OFFST+2,R4 ; SUBTRACT OFFSET (HIGH WORD) CMP #16.,MODE ; ARE WE IN 16-BIT MODE? BEQ 5$ ; EQ: NEED NOT (SHOULD NOT) TEST HIGH WORD CMP #24.,MODE ; ARE WE IN 24-BIT MODE? BNE 3$ ; NE: NO ; FOR 24-BIT MODE, TO ALLOW WRAP AT FFFFFF, BIC #177400,R4 ; CLEAR HIGH BYTE OF HIGH WORD 3$: TST R4 ; R3/R4 SHOULD NOW BE A 15-BIT VALUE BNE 8$ ; NE: ADDRESS MUST BE OUT OF RANGE 5$: MOV R3,R2 ; KEEP 16-BIT OFFSETTED ADDRESS IN R2 ROL R3 ; IS HIGH BIT ON? BCC 10$ ; CC: NO 8$: OUTPUT AOR ; ADDRESS OUT OF RANGE SEC ; SET CARRY 10$: POP R4 ; RESTORE REAL 32-BIT ADDRESS POP R3 ; (Carry unaffected by POP = MOV) RETURN ; EXIT .PAGE .SBTTL UNOFFSET - UNOFFSET OFFSETTED 16-BIT ADDRESS INTO 32-BIT ; ; ENTRY PARAMETERS: ; ; R2 CONTAINS THE 16-BIT OFFSETTED ADDRESS ; ; EXIT PARAMETERS: ; ; R2 CONTAINS THE 16-BIT OFFSETTED ADDRESS ; R3 CONTAINS THE 32-BIT ADDRESS (LOW WORD) ; R4 CONTAINS THE 32-BIT ADDRESS (HIGH WORD) ; NO OTHER REGISTERS ARE AFFECTED ; UNOFFSET:: MOV OFFST,R3 ; SET UP OFFSET IN R3/R4 MOV OFFST+2,R4 ADD R2,R3 ; ADD OFFSETTED ADDRESS ADC R4 ; ADD CARRY TO HIGH WORD RETURN ; EXIT .PAGE .SBTTL FROMTH - COLLECT FROM/THRU ADDRESSES ; ; ENTRY PARAMETERS: ; ; R0 POINTS TO THE ASCIZ COMMAND LINE IN PROCESS ; ; EXIT PARAMETERS: ; ; R0 POINTS JUST BEYOND THE "THRU" ADDRESS ; (IF SUCCESSFUL) ; R1 and FROM contain the offsetted FROM address ; R2 and THRU contain the offsetted THRU address ; LOBOUND contains unoffsetted FROM address, for READ ; HIBOUND contains unoffsetted THRU address, ditto ; STEP contains the STEP value (2 if ODD/EVEN option given), default 1 ; R3 and COUNT contain (THRU-FROM+1)/STEP count ; ; R4 and R5 are preserved. ; ; IF THE CARRY FLAG IS CLEAR UPON EXIT, THE ; FOLLOWING CONDITIONS ARE ASSURED: ; ; 1) THE KEYWORDS/ADDRESSES WERE FOUND ; 2) THE HEX CONVERSION WAS SUCCESSFUL ; 3) THRU>=FROM AND BOTH ARE VALID ; ; IF THERE ARE ERRORS, THE CARRY ; FLAG IS SET, AND A MESSAGE PUT OUT. ; FROMTH:: MOV #2,STEP ; Default STEP is 2 if ODD or EVEN CLR MASK ; EVEN requires MASK 000000 PUSH R4 GETKEY EVEN ; See if EVEN BEQ 5$ ; Yes, keep STEP/MASK INC MASK ; No, set flag to 000001 for ODD GETKEY ODD ; ODD keyword? BEQ 5$ ; Yes, branch COM MASK ; No, set MASK -ve for normal case DEC STEP ; When default STEP is 1 5$: GETKEY FROM ; COLLECT "FROM" KEYWORD BEQ 10$ ; EQ: YES OUTPUT MSK ; MISSING "FROM" KEYWORD JMP 250$ ; ERROR EXIT 10$: GETKEY LOW ; TRY FOR "LOW" KEYWORD BNE 15$ ; NE: MUST BE REAL VALUE MOV LOADDR,R1 ; GET LOW ADDRESS LOW WORD MOV LOADDR+2,R2 ; GET LOW ADDRESS HIGH WORD BR 18$ ; SKIP GETTING REAL VALUE 15$: CALL GETHXL ; GET "FROM" ADDRESS BCS 250$ ; CS: FAILURE 18$: ; If ODD/EVEN option given, advance FROM to appropriate boundary. MOV MASK,%3 ; Copy and check flag BMI 19$ ; -ve means no ODD/EVEN XOR %1,%3 ; See if MASK and FROM lo ROR %3 ; Have same bit 0 setting ADC %1 ; Increment %1 (lo), ADC %2 ; with carry to %2 (hi) if not 19$: MOV R1,LOBOUND ; SAVE "FROM" ADDRESS IN DP MOV R2,LOBOUND+2 ; FOR READ BOUNDS GETKEY THRU ; COLLECT "THRU" KEYWORD BEQ 20$ ; EQ: YES OUTPUT MSK ; MISSING "THRU" KEYWORD BR 250$ ; ERROR EXIT 20$: GETKEY HIGH ; TRY FOR "HIGH" KEYWORD BNE 25$ ; NE: MUST BE REAL VALUE MOV HIADDR,R1 ; GET HIGH ADDRESS LOW WORD MOV HIADDR+2,R2 ; GET HIGH ADDRESS HIGH WORD BR 28$ ; SKIP GETTING REAL VALUE 25$: CALL GETHXL ; GET TO ADDRESS BCS 250$ ; ERROR EXIT 28$: MOV R1,R3 ; PUT REAL ADDRESS WHERE IT BELONGS MOV R2,R4 GETKEY STEP ; See if we have a STEP option BNE 30$ ; No, keep default set above CALL GETHX2 ; Yes, get 2-digit STEP value BCS 250$ ; with error check MOVB %1,STEP ; OK, save required value ; Compute number of steps = (THRU-FROM+1)/STEP, reducing THRU if necessary, so ; that end address is exact. 30$: PUSH %0 ; Save pointer .IF DF M$$EIS LO=%1 ; Lo and HI=%0 ; high word registers for DIV instruction QUOT=%0 ; Quotient appears in %0 REM=%1 ; and remainder in %1 .IFF LO=%2 ; Lo and HI=%1 ; high word registers for $DDIV routine QUOT=%2 ; Quotient (lo) appears in %2 (hi in %1) REM=%0 ; and remainder in %0 .IFTF MOV %3,LO ; Copy lo MOV %4,HI ; and hi words of THRU SUB LOBOUND,LO ; Subtract FROM SBC HI ; in double-precision SUB LOBOUND+2,HI ; Giving THRU-FROM .IFT DIV STEP,%0 ; Divide by STEP BVC 35$ ; Make sure it doesn't overflow .IFF MOV STEP,%0 ; Get STEP CALL $DDIV ; and divide by it TST %1 ; Must have a 16-bit result BEQ 35$ ; OK if so .ENDC OUTPUT AOR ; Else step out of range POP %0 ; Restore line pointer BR 250$ ; Exit cs 35$: INC QUOT ; OK, add 1 to count for inclusive operations MOV QUOT,COUNT ; Save for later DECR34 REM ; Reduce THRU by remainder for exact end addr MOV %3,HIBOUND ; Set in hi bound for READ MOV %4,HIBOUND+2 POP %0 ; Restore line pointer CALL VALID ; VALIDATE "THRU" ADDRESS BCS 250$ ; ERROR EXIT WITH STACK CLEANUP ; "THRU" ADDR GOES IN R2 MOV LOBOUND+2,R4 ; RESTORE "FROM" ADDRESS MOV LOBOUND,R3 MOV R2,THRU ; SAVE "THRU" OFFSETTED ADDRESS CALL VALID ; VALIDATE "FROM" ADDRESS BCS 250$ ; CS: BAD FROM ADDRESS - TAKE ERROR EXIT ; ERROR EXIT WITH STACK CLEANUP MOV R2,FROM ; SAVE IN GLOBAL VARIABLE FROM MOV R2,R1 ; PUT OFFSETTED "FROM" ADDRESS IN R1 MOV THRU,R2 ; RESTORE OFFSETTED "THRU" ADDRESS CMP R2,R1 ; THRU > FROM? BHIS 40$ ; HS: O.K. OUTPUT AOR ; ADDRESS OUT OF RANGE BR 250$ ; ERROR EXIT 40$: MOV COUNT,R3 ; PUT COUNT IN R3 TST (PC)+ ; Clear carry and skip SEC 250$: SEC ; ERROR EXIT-SET CARRY 255$: POP R4 ; RESTORE R4 RETURN .PAGE .SBTTL EXTRA - PROCESS SUPERFLUOUS COMMAND STRING ; ; ENTRY PARAMETERS: ; ; R0 POINTS TO THE COMMAND STRING IN PROCESS ; Carry is set if an error already found, else clear. ; ; EXIT PARAMETERS: ; ; CARRY: Clear if no junk found, else as on entry. ; ; FUNCTION: AT THIS POINT, ALL USEFUL INFORMATION HAS BEEN PROCESSED ; FROM THE COMMAND LINE. THIS ROUTINE MERELY INFORMS THE USER IF THEIR ; IS SUPERFLUOUS INFORMATION REMAINING IN THE COMMAND LINE. ; ; DESTROYS: R0 ; EXTRA:: ROL -(SP) ; Save entry value of carry TSTB (R0) ; IS THERE SOME EXTRA INFO ? BEQ 255$ ; EQ: NO - JUST RETURN, CC FROM TST PUSH R1 ; SAVE R1 CLR R1 ; INITIAL COUNT OF GARBAGE IS ZERO PUSH R0 ; SAVE POINTER TO EXCESS 10$: INC R1 ; INCREMENT GARBAGE COUNT TSTB (R0)+ ; LOOK FOR THE END BNE 10$ ; NE: NOT YET OUTPUT SCI ; SUPERFLUOUS COMMAND STRING IGNORED POP R0 ; RESTORE POINTER TO BEGINNING OF EXCESS MOV R0,OUTDIR+Q.IOPL ; SET UP TO SHOW USER MOV R1,OUTDIR+Q.IOPL+2 DIR$ #OUTDIR POP R1 ; RESTORE R1 BIS #1,@SP ; Set error flag definately 255$: ROR (SP)+ ; Return error flag in carry RETURN .PAGE .SBTTL PARSE - PARSE FILE DESCRIPTOR INTO NAMEBLOCK ; ; PARSE - PARSE FILE DESCRIPTOR INTO NAMEBLOCK ; ; INPUT PARAMETERS: ; ; R0 POINTS TO COMMAND LINE IN PROCESS ; ; OUTPUT PARAMETERS: ; ; R0 POINTS JUST BEYOND FILE DESCRIPTOR (IF SUCCESSFUL) ; ; CARRY FLAG INDICATES SUCCESS (CLEAR) OR FAILURE (SET) ; ; FUNCTION: SETS UP DATASET DESCRIPTOR BLOCK DSPT ACCORDING TO FILE ; SPECIFICATION IN COMMAND LINE. IF NO DEVICE/UIC IS ; SPECIFIED, THE ENTRY FOR DEVICE/UIC IS ZEROED. ; ; AUTHOR: KEVIN ANGLEY ; ; DATE: 06-JUL-82 ; ; REVISED BY: Chris Doran, Sira Ltd ; ; DATE: 23-Dec-83 ; Set up file access modes according to FORMAT to allow for ; binary files. ; FORMAT also determines default filetype appropriate to ; assembler/linker. PARSE:: MOV #DSPT,R1 ; MAKE SOME DEFAULT ASSUMPTIONS MOV #SYSLEN,(R1)+ ; SY: IS THE DEVICE MOV #SYS,(R1)+ CLR (R1) ; AND NO UIC (DEFAULT IS CURRENT) MOV R0,R1 ; SAVE POINTER TO SPECIFICATION 10$: ; PARSE DEVICE SPEC (IF ANY) TSTB (R1) ; AT THE END YET? BEQ 20$ ; EQ: YES, AND NO DEVICE SPEC CMPB #':,(R1)+ ; HAVE WE SEEN A COLON? BNE 10$ ; NE: NO, KEEP LOOKING MOV R0,DSPTDP ; START OF SPEC IS START OF DEVICE SPEC PUSH R1 ; SAVE POINTER TO UIC/NAME SPEC SUB R0,R1 ; COMPUTE LENGTH OF DEVICE SPEC MOV R1,DSPTDL ; SET DEVICE SPEC LENGTH POP R0 ; RESTORE POINTER TO UIC/NAME SPEC TO R0 20$: ; PARSE UIC SPECIFICATION CMPB #'[,(R0) ; DO WE HAVE A UIC SPECIFIED? BNE 30$ ; NE: NO, GO PROCESS NAME MOV R0,DSPTUP ; SET START OF UIC SPECIFICATION INC R0 ; MOVE PAST THE LEFT BRACKET 25$: TSTB (R0) ; AT THE END YET? BNE 28$ ; NO, KEEP LOOKING OUTPUT FNS ; FILE NAME SYNTAX ERROR BR 250$ 28$: CMPB #'],(R0)+ ; SEARCH FOR RIGHT BRACKET BNE 25$ ; NE: KEEP LOOKING PUSH R0 ; GOT IT - SAVE POINTER TO NAME SPEC SUB DSPTUP,R0 ; COMPUTE LENGTH OF UIC SPEC MOV R0,DSPTUL ; SET UIC SPEC LENGTH POP R0 ; RESTORE POINTER TO NAME SPEC 30$: ; PARSE NAME SPECIFICATION MOV #RECORD,R1 ; USE RECORD FOR FILENAME WORK AREA MOV R1,DSPTNP ; SET POINTER TO FILENAME ; File access modes and default filetype are given in FILTPS list, q.v. PUSH %2 ; Save %2 MOV RWFORMAT,%2 ; For format code ASL %2 ; *2 ADD #FILTPS,%2 ; Point to FILTPS table entry for this FORMAT MOVB #R.VAR,FDB+F.RTYP ; Variable length records MOVB #FD.CR,FDB+F.RATT ; Printed with CR+LF's MOVB (%2)+,FDB+F.RACC ; Load record access -- FD.PLC, or 0 BEQ 35$ ; 0 => variable length records MOVB #R.FIX,FDB+F.RTYP ; <>0 (FD.PLC) => fixed 35$: TSTB (R0) ; AT END OF COMMAND LINE? BEQ 40$ ; EQ: yes - put in default filetype CMPB #'.,(R0) ; . SPECIFIED? BEQ 50$ ; EQ: YES - JUST COPY REMAINDER CMPB #';,(R0) ; VERSION SPECIFIED? BEQ 40$ ; EQ: YES, INSERT .HEX, THEN COPY REMAINDER MOVB (R0)+,(R1)+ ; GARDEN VARIETY CHARACTER BR 35$ ; KEEP PROCESSING PRE-EXTENSION PART 40$: CMPB @%2,#SPACE ; Unless filetype is explicitly blank BEQ 50$ ; which causes an OPEN$ error MOVB #'.,(R1)+ ; INSERT . MOVB (%2)+,(R1)+ ; and three letters MOVB (%2)+,(R1)+ ; INSERT of default filetype MOVB (%2)+,(R1)+ 50$: ; COPY REMAINDER OF STRING TSTB (R0) ; AT END OF SOURCE STRING? BEQ 60$ ; EQ: YES, THAT'S ALL MOVB (R0)+,(R1)+ ; COPY STRING BR 50$ ; KEEP PROCESSING POST-EXTENSION PART 60$: ; END OF STRING - COMPUTE LENGTH POP %2 ; Finished with table SUB #RECORD,R1 ; SUBTRACT BEGINNING MOV R1,DSPTNL ; SET NAME LENGTH CLC ; SET SUCCESS FLAG BR 255$ ; AND EXIT 250$: ; ERROR EXIT SEC ; SET CARRY FLAG 255$: RETURN .PAGE .SBTTL COMPRESS - COMPRESS COMMAND LINE ; ; COMPRESS - Compress command line in place ; ; INPUT PARAMETER: ; ; %0 points to .ASCIZ command line to compress. ; ; OUTPUT PARAMETERS: ; ; %1 points to terminating null of compressed line. ; RECORD contains a copy of the uncompressed line, for possible echo. ; ; DESTROYS: %3 ; ; All other registers (including entry value of %0) are preserved. ; ; FUNCTION: Removes embedded spaces and tabs in a command line, and ; converts all lower-case letters to upper-case, except that ; the single character after a quote ('), minus (-), tilde (~), ; or caret (^), or the pair after double-quote (") are copied ; unchanged. Used by mainline code to pre-process the command ; line, and by EDIT, for replacement value pre-processing. ; ; AUTHOR: Chris Doran ; ; DATE: 05-Jan-84 COMPRESS:: PUSH %0 ; Save start of line pointer MOV R0,R1 ; Copy it MOV #RECORD,%3 ; Load pointer to copy area 30$: MOVB (R0),(%3)+ ; Copy char. At the end yet? BEQ 50$ ; EQ: yes - done CALL SPCTAB ; See if space or tab BEQ 35$ ; EQ: yes - ignore MOVB @R0,(R1)+ ; Copy byte CMPB @%0,#'a ; Lower-case? BLO 35$ ; Not if < 'a' CMPB @%0,#'z ; or > 'z' BHI 35$ BICB #40,-(%1) ; Yes, convert to upper case CMPB (%0)+,(%1)+ ; Advance pointers BR 30$ ; and repeat 35$: CMPB #'',@%0 ; Is it a prime? BEQ 45$ ; Yes, copy 1 more char CMPB #'^,@%0 ; No, caret? BEQ 45$ ; Yes, one more CMPB #'-,@%0 ; Minus BEQ 45$ ; ditto CMPB #'~,@%0 ; All prefix a non-compressible char BEQ 45$ 40$: CMPB #'",(%0)+ ; No, double-prime? BNE 30$ ; No, try next MOVB @%0,(%1)+ ; Yes, copy characters MOVB @%0,(%3)+ BEQ 49$ ; unless null 45$: INC %0 ; Address next char MOVB @%0,(%1)+ ; without any translation/compression MOVB (%0)+,(%3)+ BNE 30$ ; Repeat 49$: DEC %1 ; Unless null, when point to it 50$: CLRB @%1 ; Make sure output line is ASCIZ POP %0 ; Restore start of line pointer RETURN ; and return with it ; SUBROUTINE SPCTAB: ; ; Return z set if character addressed by %0 is space or tab, else clear. ; No registers affected. SPCTAB: CMPB #SPACE,(R0) ; Is it a space? BEQ 10$ ; EQ: yes - return z set CMPB #TAB,(R0) ; Is it a tab? 10$: RETURN ; Return with flags .IF NE TIME .PAGE .SBTTL TIMOUT - HANDLE COMMAND TIMEOUT AST ; AST SERVICE ROUTINE ; TASK ENTERS AST WITH STACK AS FOLLOWS ; SP+10 EVENT FLAG MASK WORD ; SP+ 6 PS OF TASK PRIOR TO AST ; SP+ 4 PC OF TASK PRIOR TO AST ; SP+ 2 DSW OF TASK PRIOR TO AST ; SP+ 0 EVENT FLAG NUMBER OF ZERO TIMOUT: QIOW$C IO.KIL,CMILUN,3,,,,,HEX ; KILL ALL I/O ON LUN CMILUN WTSE$C 3,HEX ; WAIT FOR I/O TO BE CLEANED UP OUTPUT CIT ; COMMAND INPUT TIMEOUT MESSAGE MOV #EXIT,4(SP) ; WILL CONTINUE EXECUTION AT 'EXIT' TST (SP)+ ; EF MUST BE REMOVED ASTX$S ; EXIT AST .ENDC ; Command timeout processor .PAGE .SBTTL DATA - HEX DATA AREAS .PSECT DATA .EVEN MODE:: .WORD 16. ; Size (in bits) of maximum address allowed. ; Possibilities are: 16, 24, and 32. ; Default is 16. ; This is set by the offset command and ; is not reset by INIT. OFFST:: .BLKW ; CURRENT OFFSET VALUE - LOW WORD .BLKW ; CURRENT OFFSET VALUE - HIGH WORD TRNSFR:: .BLKW ; CURRENT TRANSFER VALUE - LOW WORD .BLKW ; CURRENT TRANSFER VALUE - HIGH WORD FROM:: .BLKW ; STORED VALUE FROM LAST FROM/THRU/STEP PARSE THRU:: .BLKW ; STORED VALUE THRU LAST FROM/THRU/STEP PARSE LOBOUND:: .BLKL ; Unoffsetted FROM HIBOUND:: .BLKL ; Unoffsetted THRU STEP:: .BLKW ; Stored value STEP last FROM/THRU/STEP parse COUNT:: .BLKW ; Stored value (THRU-FROM+1)/STEP MASK=COUNT ; Used temporarily for ODD/EVEN mask RWFORMAT:: .WORD F.INTEL ; READ/WRITE object format SEPTOR:: .BYTE SPACE ; Data separator for HEX/OCTAL formats .EVEN LOADDR:: .BLKL ; LOWEST ADDRESS ENCOUNTERED SO FAR HIADDR:: .BLKL ; HIGHEST ADDRESS ENCOUNTERED SO FAR RDDOM:: .BLKW ; Domain used for read ;23MAR4 RDRAN:: .BLKW ; Range used for read ;23MAR4 ; PSEUDO-REGISTERS 00-FF REGISTER:: .BLKB 256. ; .EVEN ; RECORD MUST BE ON EVEN BOUNDARY BCOUNT:: .BLKW ; NUMBER OF BYTES LOADED THIS READ ;23MAR4 USECNT:: .BLKW ; 'USE FOR READ' Place counter ;23MAR4 .EVEN ;**-5 RCD:: ; RCD = RECORD, for OUTPUT macro;23MAR4 RECORD:: .BLKB RECLEN+1 ; A GENERAL BUFFER FOR RECORD PR;23MAR4 ; + 1 null for .ASCIZ'ing ;23MAR4 .EVEN ;**-2 GCLBLK:: GCMLB$ 1,HEX,CMDBUF,CMILUN ; GET COMMAND LINE CONTROL BLOCK;23MAR4 PROMPT==GCLBLK+G.DPRM+2 ; Start of HEX> for GBLPAT ;23MAR4 .EVEN ;23MAR4 CMDBUF:: .BLKB 80. ; COMMAND LINE BUFFER ; ; ; DSPT:: ; FILE NAME DESCRIPTOR BLOCK DSPTDL:: .WORD ; DEVICE DESCRIPTOR LENGTH DSPTDP:: .WORD ; DEVICE DESCRIPTOR POINTER DSPTUL:: .WORD ; UIC DESCRIPTOR LENGTH DSPTUP:: .WORD ; UIC DESCRIPTOR POINTER DSPTNL:: .WORD ; NAME DESCRIPTOR LENGTH DSPTNP:: .WORD ; NAME DESCRIPTOR POINTER ; Putting memory in its own PSECT makes it possible to overlay it with a NODSK ; option if overlaid, or (by calling it $$$$$$) at the top of a non-overlaid ; task, where it can be EXTTSK'd, saving 64 blocks of task file space. .PSECT $$$$$$,RW,D,GBL MEMORY:: ; VIRTUAL MEMORY ARRAY .PAGE .SBTTL PURE - PURE DATA AREAS (READ ONLY) .PSECT PURE RO,D ; KEYTBL:: ; KEYWORD ASCIZ TABLE ; ; *** COMMAND KEYWORDS *** ; KEY AND KEY APPEND KEY COMPARE KEY COMPLEMENT KEY COPY KEY CRC KEY CSUM KEY DECREMENT KEY DISPLAY KEY DIVIDE KNOECHO:.ASCII "NO" KEY ECHO KEY EDIT KEY EXIT KEY FILL KEY FORMAT KEY HELP KEY IDENT KEY INCREMENT KEY INIT KEY MOVE KEY MULTIPLY KEY NAME KEY NEGATE KEY OFFSET KEY OR KEY READ KEY REMAINDER KEY ROTATE KEY SEARCH KEY SHIFT KEY SUM KEY USE ;23MAR4 KEY TRANSFER KEY WRITE KEY XOR KQM: .ASCIZ "?" ; ? = HELP ; ; *** COMMON ARGUMENT KEYWORDS (others in specific modules) *** ; KEY FILE KEY FROM KEY HIGH KEY LOW KEY MINUS KEY OF ;23MAR4 KEY PARTIAL KEY PLUS KEY REVERSE KEY THRU KEY TO KEY ODD KEY EVEN KEY STEP KEY WITH ; Define format type codes. Note that FILTPS table here, and corresponding ; ones in FORMAT, READ, and WRITE, must match these codes. They are all ; EVEN, for word table lookups. F.LIST == -2 ; Special code for DISPLAY's list file F.INTEL == 0 ; Intel F.MOTOROLA == 2 ; Motorola F.ROCKWELL == 4 ; Rockwell F.RCA == 6 ; RCA F.TEKHEX == 10 ; Standard Tektronix (Tekhex) F.EXTENDED == 12 ; Extended Tekhex F.TEXAS == 14 ; Texas F.MOSTEK == 16 ; Mostek F.WHITESMITHS == 20 ; Whitesmiths' F.RIM == 22 ; PDP-8 Read-In-Mode F.BIN == 24 ; PDP-8 binary F.HEX == 26 ; Hex F.OCTAL == 30 ; Octal F.TCI == 32 ; TCI F.SIRA == 34 ; Sira binary F.OBJECT == 36 ; DEC MACRO assembler ABS output F.ABSOLUTE == 40 ; DEC absolute loader format (RT-11 LINK /L) F.TASK == 42 ; RSX-11M TKB output F.MAX == 42 ; Largest allocated ; Default record access bytes, and filetypes depending on FILFMT. ; 0 for PUT$/GET$ move mode, FD.RWM for READ$/WRITE$ + 3 letters of type. .MACRO TYPE FILTYP,ACCESS .ASCII "FILTYP" .ENDM TYPE TYPE LST 0 ; -2 special code for DISPLAY's list file .IF DF TCP ;23MAR4 FILTPS: TYPE HEX 0 ; 0 Intel ;23MAR4 TYPE HEX 0 ; 2 Motorola ;23MAR4 TYPE HEX 0 ; 4 Rockwell ;23MAR4 TYPE HEX 0 ; 6 RCA ;23MAR4 TYPE HEX 0 ; 10 Standard Tektronix (Tekhex) ;23MAR4 TYPE HEX 0 ; 12 Extended Tekhex ;23MAR4 TYPE OBJ 0 ; 14 Texas ;**-6 TYPE HEX 0 ; 16 Mostek ;23MAR4 TYPE < > FD.PLC ; 20 Whitesmiths' (XEQ.) ;**-1 TYPE RIM 0 ; 22 PDP-8 RIM TYPE BIN 0 ; 24 PDP-8 Binary TYPE PRM 0 ; 26 Hex-space TYPE PRM 0 ; 30 Octal-space TYPE HEX 0 ; 32 TCI ;23MAR4 .IFF ;23MAR4 FILTPS: TYPE LDA 0 ; 0 Intel ;23MAR4 TYPE LDA 0 ; 2 Motorola ;23MAR4 TYPE LDA 0 ; 4 Rockwell ;23MAR4 TYPE LDA 0 ; 6 RCA ;23MAR4 TYPE LDA 0 ; 10 Standard Tektronix (Tekhex) ;23MAR4 TYPE LDA 0 ; 12 Extended Tekhex ;23MAR4 TYPE OBJ 0 ; 14 Texas ;23MAR4 TYPE LDA 0 ; 16 Mostek ;23MAR4 TYPE < > FD.PLC ; 20 Whitesmiths' (XEQ.) ;23MAR4 TYPE RIM 0 ; 22 PDP-8 RIM ;23MAR4 TYPE BIN 0 ; 24 PDP-8 Binary ;23MAR4 TYPE PRM 0 ; 26 Hex-space ;23MAR4 TYPE PRM 0 ; 30 Octal-space ;23MAR4 TYPE LDA 0 ; 32 TCI .ENDC ;23MAR4 TYPE LDA 0 ; 34 Sira binary TYPE OBJ 0 ; 36 MACRO-11 absolute binary TYPE LDA 0 ; 40 PDP-11 paper-tape absolute loader TYPE SYS FD.PLC ; 42 TKB output .IIF NE TIME, DEFM CIT DEFM IC DEFM AOR
DEFM HCE DEFM MSK DEFM SCI DEFM CIE DEFM FNS DEFM UFS DEFM BET DEFM CAB .EVEN .PAGE .SBTTL DIRECTIVES AND MESSAGES .EVEN .PSECT DATA D,RW OUTDIR:: QIOW$ IO.WVB,TILUN,1,,,,<0,0,40> ; SKELETAL OUTPUT DIRECTIVE .IIF DF P$$OFF,EXSTAT:: .WORD EX$SUC ; Exit status -- default success .EVEN ; Put next 2 bytes on word boundary for TST QUIET:: .BYTE 377 ; <>0 = echo all commands from file .BYTE FD.TTY ; <>0 = ignore NOECHO if from TI: DEFM FOE DEFM IOE RSM:: DEFM RDL ; RSM MESSAGES ARE ORDERED! .BYTE CR .BYTE LF DEFM RDH .BYTE CR .BYTE LF DEFM RDC .BYTE CR .BYTE LF DEFM RDS SMO==RDS ; Same message for SMO SMOLEN==10. ; But only up to end of 0000 RSSLEN==.-RSM ; Short RSM w/o transfer address (not given) .BYTE CR .BYTE LF DEFM RDT RSMLEN == .-RSM FLT:: .ASCII \ File: 00000000\ FLTLEN == .-FLT DEFM ADR <00000000> DEFM BGO ;23MAR4 ;; DEFM NYI DEFM FNM PRGNAM==FNM+FNMLEN-8. RNM:: .ASCII " File: " RNMLEN==.-RNM SYS:: .ASCII \SY:\ SYSLEN == .-SYS .EVEN .END START