PAGE 60 TITLE 'ENTAB - REPLACE SPACES WITH TABS V1.3 2/5/81' ; ; A SOFTWARE TOOL AS DESRIBED 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. ; BDOS EQU 5 ;CPM ENTRY FCB EQU 5CH ;DEFAULT FCB ; PRINT EQU 9 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 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 GTFCB SGNMSG: DB CR,LF,'ENTAB V1.3 2/5/81',CR,LF,DOLLAR ; GTFCB: 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 ;GET DESTINATION DRIVE ORA A ;HAS USER ENTERED VALUE JZ DEL SBI 'A'-1 ;MAKE IT A NUMBER STA FCB2 ;FILL IT IN ; DEL: MVI A,0 ;MAKE NEXT RECORD 0 STA FCB1+32 STA FCB2+32 LXI D,FCB2 MVI C,DELETE CALL BDOS ;DELETE IT JUST IN CASE ; LXI D,FCB2 MVI C,CREATE CALL BDOS ;NOW CREATE IT INR A JNZ ENTAB ;FILE CREATED LXI D,CRMSG ;'NO DIRECTORY SPACE' MVI C,PRINT CALL BDOS JMP EXIT ;CAN'T KEEP GOING CRMSG: DB 'CANT CREATE DESTINATION FILE',CR,LF,DOLLAR ; ; ENTAB: MVI A,0 ;COL=0 STA COL NXTCHR: LDA COL ;NEWCOL=COL STA NEWCOL BLNK: CALL GETC ;GET A CHARACTER STA CHAR CPI BLANK ;IS IT A BLANK? JNZ NTBLNK LDA NEWCOL INR A STA NEWCOL ;NEWCOL=NEWCOL+1 ANI 7 ;CHECK FOR TAB POS JNZ BLNK ;GUESS NOT! MVI C,TAB CALL PUTC LDA NEWCOL STA COL JMP BLNK ;GET ANOTHER NTBLNK: LDA CHAR CPI TAB JNZ NOTTAB LDA NEWCOL ;HAVE A TAB SO ADI 8 ;.GET TO NEXT ANI 0F8H ;.TAB POSITION STA NEWCOL ;UPDATE POINTERS STA COL MVI C,TAB ;NOW PUT OUT THE TAB CHAR CALL PUTC JMP BLNK ;GO FOR MORE CHARACTERS NOTTAB: LDA COL ;IF COL (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,C ;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,WERMSG ;'WRITE ERROR' MVI C,PRINT CALL BDOS JMP EXIT ;THIS WILL FIX STACK WERMSG: DB 'WRITE ERROR',CR,LF,DOLLAR DS 48 ;SOME STACK SPACE STACK: DW 0 COL: DB 0 NEWCOL: 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