home *** CD-ROM | disk | FTP | other *** search
-
- ; TITLE 'ENTAB - REPLACE SPACES WITH TABS V1.5 '
- ;
- ; A SOFTWARE TOOL AS DESCRIBED BY KERNIGAN AND PLAUGHER
- ; WHICH COMPRESSES SPACES INTO APPROPRIATE TABS AS PER
- ; CP/M CONVENTIONS. IT IS USEFUL FOR COMPACTING A PROGRAM
- ; AFTER A MODEM TRANSFER WHICH EXPANDS THE TABS.
- ;
- ;
- ; REVISION HISTORY
- ;
- ;10/10/81.
- ;
- ; ADDED EQU FOR MODIFIED CP/M AND QUOTE AS DEFAULT DELIM. T. SHAPIN
- ;
- ; 9/5/81
- ; 1. REWROTE COMPRESSION ROUTINE TO WORK PROPERLY
- ;
- ; 2. ADDED FEATURE TO DISABLE COMPRESSION INSIDE
- ; QUOTED STRINGS, SINCE SOME LANGUAGES AND
- ; ASSEMBLERS DON'T LIKE TABS IN THEIR STRINGS.
- ; FOR EXAMPLE, AN ASSEMBLY FILE MAY HAVE A LINE:
- ;
- ; PASSWORD: DB ' '
- ;
- ; IS THAT THE SAME THING AS THIS LINE?
- ;
- ; PASSWORD: DB 09H
- ;
- ; MOST DEFINITELY NOT, BUT THAT IS WHAT WE WOULD
- ; GET IF ENTAB COMPRESSED THOSE BLANKS INTO 1 TAB
- ; CHARACTER. ENTAB WILL PROMPT FOR THE STRING
- ; FIELD DELIMITING CHARACTER EACH TIME IT IS RUN
- ; (NORMALLY ' FOR ASSEMBLERS, AND " FOR BASICS).
- ;
- ; 3. MODIFIED OUTPUT FILE CODE TO SAVE THE ORIGINAL
- ; FILE AS A "BAK" FILE IF THE OUTPUT FILE IS GOING
- ; TO THE SAME DRIVE AS THE INPUT FILE. IF THE
- ; OUTPUT FILE IS GOING TO A DIFFERENT DRIVE, THEN
- ; THE ORIGINAL FILE WILL BE LEFT UNCHANGED.
- ; PREVIOUSLY, THE ORIGINAL FILE WAS ALWAYS ERASED.
- ;
- BIAS EQU 0H ; 0 FOR STANDARD CP/M, 4200H FOR MODIFIED
- BDOS EQU 5+BIAS ;CPM ENTRY
- FCB EQU 5CH+BIAS ;DEFAULT FCB
- ;
- PRINT EQU 9
- BUFFIN EQU 10
- OPEN EQU 15
- CLOSE EQU 16
- DELETE EQU 19
- READ EQU 20
- WRITE EQU 21
- CREATE EQU 22
- RENAME EQU 23
- SETDMA EQU 26
-
- BLANK EQU ' '
- TAB EQU 9
- CR EQU 0DH
- LF EQU 0AH
- EOF EQU 1AH ;CONTROL Z
- DOLLAR EQU '$'
- ;
- REC EQU 16 ;NUMBER OF SECTORS PER TRANSFER
- ;
- ORG 100H+BIAS
- LXI H,0 ;SET UP OUR OWN STACK
- DAD SP ;SAVE THEIRS
- SHLD STACK
- LXI SP,STACK
- ;
- LXI D,SGNMSG ;TELL THE FOLKS OUR NAME
- MVI C,PRINT
- CALL BDOS
- JMP GETFCB
- ;
- SGNMSG: DB CR,LF,'ENTAB - VERS 1.5 - 10/9/81',CR,LF,LF,'$'
- ;
- GETFCB: LXI H,FCB ;GET THE TYPED IN FILE NAME
- LXI D,FCB1
- MVI C,16
- CALL MOVE ;AND MOVE IT TO OUR OWN
- LXI H,FCB
- LXI D,FCB2
- MVI C,16
- CALL MOVE ;AND AGAIN
- ;
- LXI D,FCB1
- MVI C,OPEN
- CALL BDOS ;OPEN IT
- INR A
- JNZ FILSEC ;NO ERROR
- LXI D,FNFMSG ;'FILE NOT FOUND'
- MVI C,PRINT
- CALL BDOS
- JMP EXIT
- ;
- FNFMSG: DB 'File Not Found',CR,LF,DOLLAR
- ;
- FILSEC: LXI H,FCB2+9 ;SEC NAME
- MVI M,DOLLAR ;MAKE IT '.$$$'
- INX H
- MVI M,DOLLAR
- INX H
- MVI M,DOLLAR
- LDA FCB+16 ;IF USER ENTERS A DESTINATION
- ORA A ;.. DRIVE CODE ...
- JNZ DEFALT
- LDA FCB1
- DEFALT: STA FCB2 ;.. STASH IT IN OUTPUT FILE FCB
- ;
- DEL: MVI A,0 ;MAKE NEXT RECORD 0
- STA FCB1+32
- STA FCB2+32
- LXI D,FCB2 ;DELETE ANY EXISTING TEMPORARY FILES
- MVI C,DELETE
- CALL BDOS
- ;
- LXI D,FCB2
- MVI C,CREATE
- CALL BDOS ;NOW CREATE TEMPORARY OUTPUT FILE
- INR A
- JNZ GTDEL ;FILE CREATED
- LXI D,DSKMSG ;'NO DIRECTORY SPACE'
- MVI C,PRINT
- CALL BDOS
- JMP EXIT ;CAN'T KEEP GOING
- ;
- PROMPT: DB 'Enter the String Delimiter (CR='') ? $'
- BEGMSG: DB CR,LF,'Beginning Blanks Compression',CR,LF,'$'
- ;
- GTDEL: LXI D,PROMPT ;ASK FOR DELIMITER CHARACTER
- MVI C,PRINT
- CALL BDOS
- ;
- ;WE INPUT THE DELIMITER CHARACTER BY USING THE BUFFER INPUT
- ;ROUTINE TO ALLOW THE USER TO CORRECT AN INPUT ERROR, OR TO
- ;ABORT TO CP/M. A SINGLE CONIN CALL, ALTHOUGH REQUIRING LESS
- ;CODE, WOULD NOT ALLOW ANY MARGIN FOR ERROR IN SPECIFYING THE
- ;DELIMITER CHARACTER.
- ;
- LXI D,CIBUF ;SETUP CONSOLE INPUT BUFFER
- MVI A,2
- STAX D ;ALLOW 2 CHARACTERS MAXIMUM
- MVI C,BUFFIN ;GET THE DELIMITER CHARACTER
- CALL BDOS
- LDA CIBUF+1 ;HOW MANY CHARACTERS ENTERED?
- ORA A
- MVI A,'''' ;DEFAULT TO QUOTE
- JZ SAVDEL ;USE DELIMITER OF 0 IF NO INPUT
- LDA CIBUF+2 ;ELSE, EXTRACT 1ST CHARACTER
- SAVDEL: STA DELIM+1 ;SAVE IT IN-LINE FOR COMPARISON
-
- LXI D,BEGMSG ;TELL USER WE'VE BEGUN
- MVI C,PRINT
- CALL BDOS
- ;
- ;BEGIN SCANNING INPUT BUFFER AND PACK THE SPACES INTO TABS
- ;
- ENTAB: XRA A
- STA COLUMN ;INITIALIZE TAB POSITION
- STA BLANKS ;CLEAR BLANK ACCUMULATOR
- STA SFLG ;CLEAR STRING FLAG
- NEXCHR: CALL GETC ;GET NEXT CHARACTER FROM FILE
- STA CHAR ;SAVE INPUT CHARACTER
- CPI TAB
- JNZ NOTAB
- CALL DUMBLK ;ON TAB, DUMP PENDING BLANKS
- TABIT: MVI A,TAB ;PASS THE TAB ALONG
- CALL PUTC
- XRA A
- STA COLUMN ;CLEAR TAB POSITION
- JMP NEXCHR ;GET THE NEXT CHARACTER
- ;
- NOTAB: CPI LF ;END OF LINE MARKERS?
- JZ EOL
- CPI CR
- JNZ NOEOL
- EOL: CALL DUMBLK ;DUMP TRAILING BLANKS IF SO
- LDA CHAR ;THEN DUMP THE CR OR LF
- CALL PUTC
- JMP ENTAB ;AND START NEXT LINE
- ;
- NOEOL: CPI BLANK ;SPACE CHARACTER?
- JNZ NOBLK
- LXI H,BLANKS ;INCREMENT BLANK COUNTER
- INR M
- LDA SFLG ;ARE WE IN A QUOTED STRING?
- ORA A
- JNZ STRING ;BLANK NOT SIGNIFICANT IF SO
- CALL BUMCOL ;BUMP TAB POSITION
- JNZ NEXCHR ;CONTINUE SCANNING IF NOT AT TAB STOP
- STA BLANKS ;OTHERWISE, CLEAR BLANKS COUNTER
- JMP TABIT ;PUT TAB INTO OUTPUT FILE
- ;
- STRING: CALL BUMCOL ;INSIDE QUOTED STRING, BUMP TAB POSITION
- JMP NEXCHR ;CONTINUE SCANNING TIL END OF STRING
- ;
- NOBLK: CPI EOF ;CP/M FILE EOF?
- JZ EOFILE
- CPI 0FFH ;GETBUF EOF?
- JZ EOFILE
- CALL DUMBLK ;CHARACTER NONE OF ABOVE - FLUSH BLANKS
- CALL BUMCOL ;BUMP TAB POSITION
- LDA CHAR
- PUSH PSW
- CALL PUTC ;SEND LITERAL CHARACTER
- POP PSW
- DELIM: CPI 0 ;IS CHARACTER STRING DELIMITER?
- JNZ NEXCHR
- LDA SFLG ;TOGGLE STRING FLAG IF SO
- CMA
- STA SFLG
- JMP NEXCHR ;SCAN FOR NEXT CHARACTER
- ;
- DUMBLK: LDA BLANKS ;FLUSH THE ACCUMULATED BLANKS
- ORA A
- RZ
- DCR A
- STA BLANKS
- MVI A,' '
- CALL PUTC
- JMP DUMBLK
- ;
- BUMCOL: LDA COLUMN ;INCREMENT TAB POSITION
- INR A
- ANI 7
- STA COLUMN
- RET
- ;
- EOFILE: CALL PUTC ;OUTPUT EOF CHARACTER
- CALL PUTBUF ;WRITE UNFINISHED BUFFER
- LXI D,FCB2
- MVI C,CLOSE
- CALL BDOS ;CLOSE THE NEW FILE
- ;
- LDA FCB2 ;GET DESTINATION DR CODE TO INPUT FCB
- STA FCB1
- LXI H,FCB1 ;SETUP RENAME FCB FOR ORIGINAL FILENAME
- LXI D,FCB1+16
- PUSH D ;SAVE POINTER TO 2ND RENAME FIELD
- PUSH D
- MVI C,9
- CALL MOVE ;MOVE FILENAME TO 2ND RENAME FIELD
- XCHG
- MVI M,'B' ;MAKE 2ND RENAME FILETYPE="BAK"
- INX H
- MVI M,'A'
- INX H
- MVI M,'K'
- POP D ;RECALL POINTER TO 2ND RENAME FIELD
- MVI C,DELETE ;ERASE ANY EXISTING BAK FILE ON OUTPUT DRIVE
- CALL BDOS
- POP H ;RECALL RENAME FIELD POINTER AGAIN
- MVI M,0 ;CLEAR DR IN 2ND RENAME FIELD
- ;
- LXI D,FCB1 ;RENAME ANY FILE ON OUTPUT DRIVE WITH INPUT
- MVI C,RENAME ;..FILENAME TO TYPE "BAK"
- CALL BDOS
- ;
- KEEPIT: LXI H,FCB1+1 ;MOVE THE NEW FILE NAME
- LXI D,FCB2+16 ;TO FCB2
- XRA A
- STAX D
- INX D
- MVI C,11
- CALL MOVE
- ;
- LXI D,FCB2
- MVI C,RENAME
- CALL BDOS ;RENAME .$$$ TO ORIGINAL
- ;
- LXI D,DNMSG ;TELL THEM WE'RE DONE
- MVI C,PRINT
- CALL BDOS
- JMP EXIT
- ;
- DNMSG: DB 'Blanks Compression Completed',CR,LF,DOLLAR
- ;
- EXIT: LXI D,80H+BIAS ;RESET DEFAULT DMA
- MVI C,SETDMA
- CALL BDOS
- ;
- LHLD STACK
- SPHL
- RET ;BACK TO CP/M
- ;
- ;
- ; MOVE -MOVE (HL -> (DE) FOR C BYTES
- ;
- MOVE: MOV A,M
- STAX D
- INX H
- INX D
- DCR C
- JNZ MOVE
- RET
- ;
- ;
- GETC: LHLD CICNT ;ANY CHAR IN BUFFER?
- MOV A,H
- ORA L
- CZ GETBUF ;GET SOME IF NOT
- LHLD CIPNT ;POINTER TO CHAR
- MOV A,M ;GET THE CHARACTER
- INX H ;INCREMENT THE POINTER
- SHLD CIPNT
- LHLD CICNT ;REDUCE THE COUNT
- DCX H
- SHLD CICNT
- RET
-
- ;
- GETBUF: MVI A,REC ;RECORDS PER BUFFER
- LXI H,0
- SHLD CICNT ;INIT FO READ
- LXI H,CIBUF
- SHLD CIPNT ;INIT THE POINTER
- GBUF: SHLD DMAADD ;IPDATE DMA ADDRESS
- XCHG ;FOR BDOS CALL
- STA SECCNT ;UPDATE SECTORS TO GO
- ORA A
- RZ ;RETURN IF NONE
- MVI C,SETDMA
- CALL BDOS ;SET LOAD ADDRESS
- LXI D,FCB1
- MVI C,READ
- CALL BDOS ;GET A SECTOR
- PUSH PSW ;SAVE DISK STATUS
- LHLD CICNT
- LXI D,128 ;# OF BYTES READ
- DAD D
- SHLD CICNT ;UPDATE IT
- LHLD DMAADD ;UPDATE POINTER
- POP PSW ;GET DISK STATUS
- ORA A
- JZ ROK ;READ WAS OK
- MVI M,0FFH ;OUR OWN END OF FILE
- RET
-
- ROK: DAD D ;THIS TO
- LDA SECCNT
- DCR A ;ONE LESS LEFT
- JMP GBUF
- ;
- PUTC: LHLD COPNT ;POINTER
- MOV M,A ;PUT CHAR IN BUFFER
- INX H
- SHLD COPNT ;INCREMENT POINTER
- LHLD COCNT
- INX H ;BUMP IT
- SHLD COCNT
- MOV A,H ;SEE IF END OF BUFFER
- CPI REC*128/256
- CZ PUTBUF
- RET
- ;
- PUTBUF: LHLD COCNT ;# OF CHAR IN BUFFER
- SHLD TEMP
- LXI H,0
- SHLD COCNT ;REINIT FOR NEXT TIME
- LXI H,COBUF
- SHLD COPNT ;REINIT FOR NEXT TIME
- PBUF: SHLD DMAADD ;UPDATE WRITE ADDRESS
- XCHG ;TO DE FOR CPM CALL
- LHLD TEMP ;ANY LEFT TO WRITE
- MOV A,L
- ORA H
- RZ ;IF NOT
- MVI C,SETDMA
- CALL BDOS
- LXI D,FCB2 ;WRITE FILE BLOCK
- MVI C,WRITE
- CALL BDOS
- ORA A ;CHECK FOR ERROR
- JNZ WRERR ;.AND TAKE CARE OF IT
- LHLD TEMP ;BYTE COUNT
- LXI D,-128 ;PER SECTOR
- DAD D ;THIS MANY LEFT
- SHLD TEMP
- MOV A,H ;GET SIGN BIT
- ORA A ;TEST IT
- RM ;ALL DATA WRITTEN (NOT A FULL BUFFER)
- LHLD DMAADD ;UPDATE BUFFER
- LXI D,128
- DAD D
- JMP PBUF
- ;
- WRERR: LXI D,DSKMSG ;'WRITE ERROR'
- MVI C,PRINT
- CALL BDOS
- JMP EXIT ;THIS WILL FIX STACK
- ;
- DSKMSG: DB 'Disk or Directory Full',CR,LF,DOLLAR
- ;
- DS 48 ;SOME STACK SPACE
- STACK: DW 0
- COLUMN: DB 0
- BLANKS: DB 0
- SFLG: DB 0
- CHAR: DB 0 ;INPUT CHAR
- SECCNT: DB 0 ;SECTORS TO READ
- CICNT: DW 0
- COCNT: DW 0
- TEMP: DW 0
- DMAADD: DW 0
- FCB1: DS 33
- FCB2: DS 33
- CIPNT: DW CIBUF
- COPNT: DW COBUF
- CIBUF: DS 128*REC
- COBUF: DS 128*REC
- END
- @