home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol065
/
entab.asm
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
9KB
|
415 lines
; 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
@